Remove old
This commit is contained in:
parent
2039495d5a
commit
39f33a6386
56
old/Makefile
56
old/Makefile
|
@ -1,56 +0,0 @@
|
||||||
# $@ = target file
|
|
||||||
# $< = first dependency
|
|
||||||
# $^ = all dependencies
|
|
||||||
|
|
||||||
GDB = gdb
|
|
||||||
|
|
||||||
C_FILES = $(shell find src/ -type f -name '*.c')
|
|
||||||
CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
|
|
||||||
ASM_FILES = $(shell find src/kernel/ -type f -name '*.asm')
|
|
||||||
AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES))
|
|
||||||
ABIN_FILES = $(patsubst src/%.asm, bin/%.bin, $(ASM_FILES))
|
|
||||||
|
|
||||||
os-image.bin: bin/boot.bin bin/kernel.bin
|
|
||||||
cat $^ > $@
|
|
||||||
|
|
||||||
bin/boot.bin: src/boot/boot.asm bin/kernel.bin .FORCE
|
|
||||||
sed -i.orig "s@CH_REPLACE_BOOTSECTORCOUNT@$(shell ./getinblocks.py $(shell du -b "bin/kernel.bin" | cut -f 1))@g" src/boot/kernel.asm
|
|
||||||
nasm -Isrc/boot/ $< -f bin -o $@
|
|
||||||
mv src/boot/kernel.asm.orig src/boot/kernel.asm
|
|
||||||
|
|
||||||
.FORCE:
|
|
||||||
|
|
||||||
bin/kernel.bin: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
|
||||||
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
|
|
||||||
|
|
||||||
kernel.elf: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
|
||||||
i386-elf-ld -o $@ -Ttext 0x1000 $^
|
|
||||||
|
|
||||||
run: clean os-image.bin
|
|
||||||
qemu-system-x86_64 -hdd os-image.bin -d int
|
|
||||||
|
|
||||||
debug: clean os-image.bin kernel.elf
|
|
||||||
qemu-system-x86_64 -s -S -hdd os-image.bin &
|
|
||||||
${GDB} os-image.bin -ex "symbol-file kernel.elf" -ex "target remote localhost:1234"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
obj/%.o: src/%.c
|
|
||||||
mkdir -p "$(@D)"
|
|
||||||
i386-elf-gcc -g -ffreestanding -c $< -o $@
|
|
||||||
|
|
||||||
obj/%.o: src/%.asm
|
|
||||||
mkdir -p "$(@D)"
|
|
||||||
nasm -f elf $< -o $@
|
|
||||||
|
|
||||||
bin/%.bin: src/%.asm
|
|
||||||
mkdir -p "$(@D)"
|
|
||||||
nasm -f bin $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
find obj -type f -name '*.o' -exec rm {} +
|
|
||||||
find obj -type f -name '*.bin' -exec rm {} +
|
|
||||||
find bin -type f -name '*.o' -exec rm {} +
|
|
||||||
find bin -type f -name '*.bin' -exec rm {} +
|
|
||||||
find . -type f -name '*.dis' -exec rm {} +
|
|
||||||
rm -f kernel.elf
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
import sys, math
|
|
||||||
intg = int(sys.argv[1])
|
|
||||||
print(int(math.ceil(intg/512)), end='')
|
|
BIN
old/os-image.bin
BIN
old/os-image.bin
Binary file not shown.
|
@ -1,39 +0,0 @@
|
||||||
[org 0x7c00]
|
|
||||||
KERNEL_OFFSET equ 0x1000 ; Same one used while linking!
|
|
||||||
|
|
||||||
mov [BOOT_DRIVE], dl ; BIOS sets boot drive to 'dl' for us
|
|
||||||
mov bp, 0x9000
|
|
||||||
mov sp, bp
|
|
||||||
|
|
||||||
mov bx, MSG_REAL_MODE
|
|
||||||
call print
|
|
||||||
call print_nl
|
|
||||||
|
|
||||||
call load_kernel
|
|
||||||
call enable_protected
|
|
||||||
|
|
||||||
jmp $ ; never executed
|
|
||||||
|
|
||||||
%include "output/print.asm"
|
|
||||||
%include "output/print_hex.asm"
|
|
||||||
%include "disk/disk.asm"
|
|
||||||
%include "protected/gdt.asm"
|
|
||||||
%include "output/vga-print.asm"
|
|
||||||
%include "protected/protected-switch.asm"
|
|
||||||
%include "kernel.asm"
|
|
||||||
|
|
||||||
[bits 32]
|
|
||||||
BEGIN_PROTECTED:
|
|
||||||
mov ebx, MSG_PROT_MODE
|
|
||||||
call print_string_pm
|
|
||||||
|
|
||||||
call KERNEL_OFFSET ; give control to kernel
|
|
||||||
jmp $ ; infinite loop if kernel returns control to us
|
|
||||||
|
|
||||||
BOOT_DRIVE db 0
|
|
||||||
MSG_REAL_MODE db "llb: started, preparing protected mode initialization", 0
|
|
||||||
MSG_PROT_MODE db "llb: loaded protected mode successfully, jumping to llb2", 0
|
|
||||||
MSG_LOAD_KERNEL db "llb: loading kernel into memory at 0x1000", 0
|
|
||||||
|
|
||||||
times 510 - ($-$$) db 0
|
|
||||||
dw 0xaa55
|
|
|
@ -1,40 +0,0 @@
|
||||||
; load 'dh' sectors from drive 'dl' into ES:BX
|
|
||||||
disk_load:
|
|
||||||
pusha
|
|
||||||
push dx ; save dx to stack for later use, as it needs to be overwritten
|
|
||||||
|
|
||||||
mov ah, 0x02 ; ah: int 0x13 function. 0x02 = 'read'
|
|
||||||
mov al, dh ; al: number of sectors to read (0x01 .. 0x80)
|
|
||||||
mov cl, 0x02 ; cl: sector (0x01 .. 0x11). 0x01 is boot sector, 0x02 is first 'avaliable' sector
|
|
||||||
mov ch, 0x00 ; ch: cylinder (0x0 .. 0x3FF, upper 2 bits in 'cl')
|
|
||||||
; dl: drive number. caller sets it as param and gets it from bios
|
|
||||||
; 0 = floppy, 1 = floppy2, 0x80 = hdd, 0x81 = hdd2
|
|
||||||
mov dh, 0x00 ; dh: head number (0x0 .. 0xF)
|
|
||||||
|
|
||||||
; [es:bx] pointer to buf where data is stored
|
|
||||||
; caller sets it up, and is standard location for int 13h
|
|
||||||
int 13h
|
|
||||||
jc disk_error ; if error (in carry)
|
|
||||||
|
|
||||||
pop dx
|
|
||||||
cmp al, dh ; al is # of sectors read. compare it
|
|
||||||
jne sectors_error
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
disk_error:
|
|
||||||
mov bx, DISK_ERROR
|
|
||||||
call print
|
|
||||||
call print_nl
|
|
||||||
mov dh, ah ; ah = error code, dl = disk drive that caused error
|
|
||||||
call print_hex
|
|
||||||
|
|
||||||
sectors_error:
|
|
||||||
mov bx, SECTORS_ERROR
|
|
||||||
call print
|
|
||||||
|
|
||||||
disk_loop:
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
DISK_ERROR: db "Disk read error", 0
|
|
||||||
SECTORS_ERROR: db "Incorrect number of sectors read", 0
|
|
|
@ -1,11 +0,0 @@
|
||||||
[bits 16]
|
|
||||||
load_kernel:
|
|
||||||
mov bx, MSG_LOAD_KERNEL
|
|
||||||
call print
|
|
||||||
call print_nl
|
|
||||||
|
|
||||||
mov bx, KERNEL_OFFSET ; Read from disk and store at 0x1000
|
|
||||||
mov dh, CH_REPLACE_BOOTSECTORCOUNT ; Populated with kernel sector count at build (see makefile)
|
|
||||||
mov dl, [BOOT_DRIVE]
|
|
||||||
call disk_load
|
|
||||||
ret
|
|
|
@ -1,33 +0,0 @@
|
||||||
print:
|
|
||||||
pusha
|
|
||||||
|
|
||||||
; logic being implemented here:
|
|
||||||
; while ( string[i] != 0 ) { print string[i]; i++ }
|
|
||||||
|
|
||||||
start:
|
|
||||||
mov al, [bx]
|
|
||||||
cmp al, 0 ; check if al (byte we are printing) is a 0 (null byte)
|
|
||||||
je done ; if so, jump to done
|
|
||||||
|
|
||||||
; print with BIOS help
|
|
||||||
mov ah, 0x0e
|
|
||||||
int 0x10 ; char already in al
|
|
||||||
|
|
||||||
add bx, 1 ; increment pointer
|
|
||||||
jmp start ; repeat
|
|
||||||
|
|
||||||
done:
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
print_nl:
|
|
||||||
pusha
|
|
||||||
|
|
||||||
mov ah, 0x0e
|
|
||||||
mov al, 0x0a ; newline char
|
|
||||||
int 0x10
|
|
||||||
mov al, 0x0d ; carriage return
|
|
||||||
int 0x10
|
|
||||||
|
|
||||||
popa
|
|
||||||
ret
|
|
|
@ -1,38 +0,0 @@
|
||||||
; data in dx
|
|
||||||
print_hex:
|
|
||||||
pusha
|
|
||||||
|
|
||||||
mov cx, 0 ; index var
|
|
||||||
|
|
||||||
hex_loop:
|
|
||||||
cmp cx, 4 ; loop 4 times
|
|
||||||
je end
|
|
||||||
|
|
||||||
; 1) convert last char of 'dx' to ascii
|
|
||||||
mov ax, dx ; ax is working register
|
|
||||||
and ax, 0x000f ; 0x1234 -> 0x0004
|
|
||||||
add al, 0x30 ; add 0x30 to N to convert it to ascii "n"
|
|
||||||
cmp al, 0x39 ; if > 9, add extra 8 to represent a-f
|
|
||||||
jle step2
|
|
||||||
add al, 7 ; A is ascii 64 instead of 58, 65-58 = 7
|
|
||||||
|
|
||||||
step2:
|
|
||||||
; 2) get correct pos of string to place char
|
|
||||||
; bx <- base address + string length - index
|
|
||||||
mov bx, HEX_OUT + 5
|
|
||||||
sub bx, cx ; cx: index
|
|
||||||
mov [bx], al ; copy ascii char on al to pos pointed by bx
|
|
||||||
ror dx, 4 ; 1234 - 4123 - 3412 - 2341 - 1234
|
|
||||||
|
|
||||||
add cx, 1
|
|
||||||
jmp hex_loop
|
|
||||||
|
|
||||||
end:
|
|
||||||
mov bx, HEX_OUT
|
|
||||||
call print
|
|
||||||
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
HEX_OUT:
|
|
||||||
db '0x0000', 0 ; reserve memory for string
|
|
|
@ -1,26 +0,0 @@
|
||||||
[bits 32]
|
|
||||||
|
|
||||||
; defining constants
|
|
||||||
VIDEO_MEMORY equ 0xb8000
|
|
||||||
WHITE_ON_BLACK equ 0x0f ; color byte
|
|
||||||
|
|
||||||
print_string_pm:
|
|
||||||
pusha
|
|
||||||
mov edx, VIDEO_MEMORY
|
|
||||||
|
|
||||||
print_string_pm_loop:
|
|
||||||
mov al, [ebx] ; [ebx] is address of char
|
|
||||||
mov ah, WHITE_ON_BLACK
|
|
||||||
|
|
||||||
cmp al, 0 ; is end of string?
|
|
||||||
je print_string_pm_done
|
|
||||||
|
|
||||||
mov [edx], ax ; store char + attribute in video memory
|
|
||||||
add ebx, 1 ; next char
|
|
||||||
add edx, 2 ; next video memory position
|
|
||||||
|
|
||||||
jmp print_string_pm_loop
|
|
||||||
|
|
||||||
print_string_pm_done:
|
|
||||||
popa
|
|
||||||
ret
|
|
|
@ -1,32 +0,0 @@
|
||||||
|
|
||||||
gdt_start: ; use labels to compute sizes and jumps
|
|
||||||
; gdt starts with 8 byte null
|
|
||||||
dd 0x0
|
|
||||||
dd 0x0
|
|
||||||
|
|
||||||
; GDT for code segment, base = 0x00000000, length = 0xfffff
|
|
||||||
gdt_code:
|
|
||||||
dw 0xffff ; segment length
|
|
||||||
dw 0x0 ; segment base
|
|
||||||
db 0x0 ; segment base
|
|
||||||
db 10011010b ; flags
|
|
||||||
db 11001111b ; flags + segment length
|
|
||||||
db 0x0 ; segment base
|
|
||||||
|
|
||||||
; GDT for data segment
|
|
||||||
gdt_data:
|
|
||||||
dw 0xffff ; segment length
|
|
||||||
dw 0x0 ; segment base
|
|
||||||
db 0x0 ; segment base
|
|
||||||
db 10010010b ; flags
|
|
||||||
db 11001111b ; flags + segment length
|
|
||||||
db 0x0 ; segment base
|
|
||||||
|
|
||||||
gdt_end:
|
|
||||||
|
|
||||||
gdt_descriptor:
|
|
||||||
dw gdt_end - gdt_start - 1 ; size, always 1 less than what it actually is
|
|
||||||
dd gdt_start ; address
|
|
||||||
|
|
||||||
CODE_SEG equ gdt_code - gdt_start
|
|
||||||
DATA_SEG equ gdt_data - gdt_start
|
|
|
@ -1,24 +0,0 @@
|
||||||
[bits 16]
|
|
||||||
enable_protected:
|
|
||||||
cli ; Disable interrupts
|
|
||||||
lgdt [gdt_descriptor] ; load the GDT
|
|
||||||
mov eax, cr0
|
|
||||||
or eax, 0x1 ; set 32-bit mode bit
|
|
||||||
mov cr0, eax
|
|
||||||
jmp CODE_SEG:init_protected ; far jump into a different segment
|
|
||||||
|
|
||||||
[bits 32]
|
|
||||||
init_protected: ; now in 32bit
|
|
||||||
mov ax, DATA_SEG ; update segment registers
|
|
||||||
mov ds, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
; wipe registers clean
|
|
||||||
|
|
||||||
mov ebp, 0x90000 ; update stack to top of free space
|
|
||||||
mov esp, ebp
|
|
||||||
|
|
||||||
call BEGIN_PROTECTED ; call known label with useful code
|
|
|
@ -1,4 +0,0 @@
|
||||||
[bits 32]
|
|
||||||
[extern main] ; define callpoint, must have same name as kernel.c entrypoint
|
|
||||||
call main ; jump to fun, linker will figure out where it is
|
|
||||||
jmp $
|
|
|
@ -1,54 +0,0 @@
|
||||||
#include "./platform/drivers/ports.h"
|
|
||||||
#include "print.h"
|
|
||||||
#include "./platform/types.h"
|
|
||||||
#include "./platform/interrupts/int.h"
|
|
||||||
|
|
||||||
void dummy_test_entrypoint() {}
|
|
||||||
|
|
||||||
void kernel_welcome() {
|
|
||||||
print_str("Welcome to ");
|
|
||||||
print_set_color(PRINT_COLOR_CYAN, PRINT_COLOR_BLACK);
|
|
||||||
print_str("Shade");
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
|
||||||
print_str("!\n");
|
|
||||||
|
|
||||||
print_str("shadeOS kernel version ");
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
|
|
||||||
print_str("0.2.2");
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
|
||||||
print_newline();
|
|
||||||
|
|
||||||
print_str("Running on ");
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
|
|
||||||
print_str("shade-development");
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
|
||||||
|
|
||||||
print_newline();
|
|
||||||
}
|
|
||||||
|
|
||||||
// kMain
|
|
||||||
void main() {
|
|
||||||
// Initialize screen buffer
|
|
||||||
struct Char* buffer = (struct Char*) 0xb8000;
|
|
||||||
|
|
||||||
clear_all(); // Clear screen
|
|
||||||
set_cursor_pos(0, 0); // Set cursor position
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set print color
|
|
||||||
|
|
||||||
// welcome messages
|
|
||||||
kernel_msg_ok("Initialized display successfully\n");
|
|
||||||
kernel_welcome();
|
|
||||||
|
|
||||||
print_str("Copyright (c) e3team 2022. All rights reserved.\n");
|
|
||||||
print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n");
|
|
||||||
print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n");
|
|
||||||
|
|
||||||
idt_init();
|
|
||||||
kernel_msg_ok("Interrupts initialized");
|
|
||||||
|
|
||||||
__asm__ __volatile__("int $2");
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Read 1 byte from specified port
|
|
||||||
*/
|
|
||||||
unsigned char port_byte_in(unsigned short port) {
|
|
||||||
unsigned char result;
|
|
||||||
// source and dest are backwards.
|
|
||||||
// "=a (result)" set the C variable to the value of register e'a'x
|
|
||||||
// '"d" (port) map the C variable port into e'd'x register
|
|
||||||
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
void port_byte_out(unsigned short port, unsigned char data) {
|
|
||||||
// both regs are C vars, nothing is returned, so no '=' in asm syntax
|
|
||||||
// comma because two vars in input area and none in return area
|
|
||||||
__asm__("out %%al, %%dx" : : "a" (data), "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short port_word_in(unsigned short port) {
|
|
||||||
unsigned short result;
|
|
||||||
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void port_word_out(unsigned short port, unsigned short data) {
|
|
||||||
__asm__("out %%ax, %%dx" : : "a" (data), "d" (port));
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
unsigned char port_byte_in(unsigned short port);
|
|
||||||
void port_byte_out(unsigned short port, unsigned char data);
|
|
||||||
unsigned short port_word_in(unsigned short port);
|
|
||||||
void port_word_out(unsigned short port, unsigned short data);
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef GDT_H
|
|
||||||
#define GDT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// the GDT descriptor format makes literally no sense, who came up with this
|
|
||||||
typedef struct {
|
|
||||||
uint16_t limit_low16; // Low 16 bits of limit
|
|
||||||
uint16_t base_low16; // Low 16 bits of base
|
|
||||||
uint8_t base_mid8; // Middle 8 bits of base
|
|
||||||
uint8_t access; // 7: present, 6-5: priv level, 4: type, 3: executable, 2: dc, 1: rw, 0: accessed (zero)
|
|
||||||
uint8_t limit_flags; // High 4 bits of limit AND flags (?? why). flags: 3: granularity, 2: size, 1: long, 0: reserved
|
|
||||||
uint8_t base_high8; // High 8 bits of base
|
|
||||||
} __attribute__((packed)) gdt_entry_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t size; // GDT size (bytes) - 1
|
|
||||||
uint32_t offset; // Address of element 0 of the GDT
|
|
||||||
} __attribute__((packed)) gdt_ptr_t;
|
|
||||||
|
|
||||||
static gdt_entry_t gdt[8192];
|
|
||||||
static gdt_ptr_t gdtr;
|
|
||||||
|
|
||||||
void init_gdt();
|
|
||||||
void gdt_set_segment(int limit, int base, int access);
|
|
||||||
void load_gdt();
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,35 +0,0 @@
|
||||||
#include "int.h"
|
|
||||||
#include "../../print.h"
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
void exception_handler(registers_t r) {
|
|
||||||
print_str("I");
|
|
||||||
count++;
|
|
||||||
if (count > 4) {
|
|
||||||
__asm__ __volatile__("cli; hlt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void idt_set_descriptor(u8 vector, void* isr, u8 flags) {
|
|
||||||
idt_entry_t* descriptor = &idt[vector];
|
|
||||||
|
|
||||||
descriptor->isr_low = (u32)isr & 0xFFFF;
|
|
||||||
descriptor->kernel_cs = 0x08; // this value can be whatever offset your kernel code selector is in your GDT
|
|
||||||
descriptor->attributes = flags;
|
|
||||||
descriptor->isr_high = (u32)isr >> 16;
|
|
||||||
descriptor->reserved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void idt_init() {
|
|
||||||
idtr.base = (u32)&idt[0];
|
|
||||||
idtr.limit = (u16)sizeof(idt_entry_t) * 256 - 1;
|
|
||||||
|
|
||||||
for (u8 vector = 0; vector < 32; vector++) {
|
|
||||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
|
||||||
isr_stub_table[vector] = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT
|
|
||||||
__asm__ volatile ("sti"); // set the interrupt flag
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
#ifndef INT_H
|
|
||||||
#define INT_H
|
|
||||||
|
|
||||||
#include "../types.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u16 isr_low; // The lower 16 bits of the ISR's address
|
|
||||||
u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
|
||||||
u8 reserved; // Set to zero
|
|
||||||
u8 attributes; // Type and attributes; see the IDT page
|
|
||||||
u16 isr_high; // The higher 16 bits of the ISR's address
|
|
||||||
} __attribute__((packed)) idt_entry_t;
|
|
||||||
|
|
||||||
__attribute__((aligned(0x10)))
|
|
||||||
static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u16 limit;
|
|
||||||
u32 base;
|
|
||||||
} __attribute__((packed)) idtr_t;
|
|
||||||
|
|
||||||
static idtr_t idtr;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 ds; /* Data segment selector */
|
|
||||||
u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
|
||||||
u32 int_no, err_code; /* Interrupt number and error code (if applicable) */
|
|
||||||
u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
|
|
||||||
} registers_t;
|
|
||||||
|
|
||||||
__attribute__((noreturn))
|
|
||||||
void exception_handler(registers_t r);
|
|
||||||
|
|
||||||
void idt_set_descriptor(u8 vector, void* isr, u8 flags);
|
|
||||||
|
|
||||||
extern void* isr_stub_table[];
|
|
||||||
|
|
||||||
void idt_init(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,102 +0,0 @@
|
||||||
%macro isr_err_stub 1
|
|
||||||
isr_stub_%+%1:
|
|
||||||
push byte %1 ; Push interrupt no to stack
|
|
||||||
|
|
||||||
; 1. Save CPU state
|
|
||||||
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
|
||||||
mov ax, ds ; Lower 16-bits of eax = ds.
|
|
||||||
push eax ; save the data segment descriptor
|
|
||||||
mov ax, 0x10 ; kernel data segment descriptor
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
; 2. Call C handler
|
|
||||||
call exception_handler
|
|
||||||
|
|
||||||
; 3. Restore state
|
|
||||||
pop eax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
popa
|
|
||||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
|
||||||
sti
|
|
||||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
|
||||||
%endmacro
|
|
||||||
; if writing for 64-bit, use iretq instead
|
|
||||||
%macro isr_no_err_stub 1
|
|
||||||
isr_stub_%+%1:
|
|
||||||
push byte 0 ; No error occured
|
|
||||||
push byte %1 ; Push interrupt no to stack
|
|
||||||
|
|
||||||
; 1. Save CPU state
|
|
||||||
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
|
||||||
mov ax, ds ; Lower 16-bits of eax = ds.
|
|
||||||
push eax ; save the data segment descriptor
|
|
||||||
mov ax, 0x10 ; kernel data segment descriptor
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
; 2. Call C handler
|
|
||||||
call exception_handler
|
|
||||||
|
|
||||||
; 3. Restore state
|
|
||||||
pop eax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
popa
|
|
||||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
|
||||||
sti
|
|
||||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
extern exception_handler
|
|
||||||
|
|
||||||
isr_no_err_stub 0
|
|
||||||
isr_no_err_stub 1
|
|
||||||
isr_no_err_stub 2
|
|
||||||
isr_no_err_stub 3
|
|
||||||
isr_no_err_stub 4
|
|
||||||
isr_no_err_stub 5
|
|
||||||
isr_no_err_stub 6
|
|
||||||
isr_no_err_stub 7
|
|
||||||
isr_err_stub 8
|
|
||||||
isr_no_err_stub 9
|
|
||||||
isr_err_stub 10
|
|
||||||
isr_err_stub 11
|
|
||||||
isr_err_stub 12
|
|
||||||
isr_err_stub 13
|
|
||||||
isr_err_stub 14
|
|
||||||
isr_no_err_stub 15
|
|
||||||
isr_no_err_stub 16
|
|
||||||
isr_err_stub 17
|
|
||||||
isr_no_err_stub 18
|
|
||||||
isr_no_err_stub 19
|
|
||||||
isr_no_err_stub 20
|
|
||||||
isr_no_err_stub 21
|
|
||||||
isr_no_err_stub 22
|
|
||||||
isr_no_err_stub 23
|
|
||||||
isr_no_err_stub 24
|
|
||||||
isr_no_err_stub 25
|
|
||||||
isr_no_err_stub 26
|
|
||||||
isr_no_err_stub 27
|
|
||||||
isr_no_err_stub 28
|
|
||||||
isr_no_err_stub 29
|
|
||||||
isr_err_stub 30
|
|
||||||
isr_no_err_stub 31
|
|
||||||
|
|
||||||
global isr_stub_table
|
|
||||||
isr_stub_table:
|
|
||||||
%assign i 0
|
|
||||||
%rep 32
|
|
||||||
dd isr_stub_%+i ; use DQ instead if targeting 64-bit
|
|
||||||
%assign i i+1
|
|
||||||
%endrep
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
typedef unsigned int u32;
|
|
||||||
typedef int i32;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef short i16;
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef char i8;
|
|
||||||
|
|
||||||
#define high16(i32) (i32 & 0xffff)
|
|
||||||
#define low16(i32) ((i32>>16) & 0xffff)
|
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#define NULL 0
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,110 +0,0 @@
|
||||||
#include "print.h"
|
|
||||||
#include "./platform/drivers/ports.h"
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
int col = 0;
|
|
||||||
char color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4;
|
|
||||||
|
|
||||||
void clear_row(int row) {
|
|
||||||
struct Char* buffer = (struct Char*) 0xb8000;
|
|
||||||
|
|
||||||
struct Char empty = (struct Char) {
|
|
||||||
character: ' ',
|
|
||||||
color: color,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int x = 0; x < NUM_COLS; x++) {
|
|
||||||
buffer[x + NUM_COLS * row] = empty;
|
|
||||||
}
|
|
||||||
set_cursor_pos(col, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_all() {
|
|
||||||
for (int i = 0; i < NUM_ROWS; i++) {
|
|
||||||
clear_row(i);
|
|
||||||
}
|
|
||||||
set_cursor_pos(col, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_newline() {
|
|
||||||
struct Char* buffer = (struct Char*) 0xb8000;
|
|
||||||
|
|
||||||
col = 0;
|
|
||||||
|
|
||||||
if (row < NUM_ROWS - 1) {
|
|
||||||
row++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int row = 1; row < NUM_ROWS; row++) {
|
|
||||||
for (int col = 0; col < NUM_COLS; col++) {
|
|
||||||
struct Char character = buffer[col + NUM_COLS * row];
|
|
||||||
buffer[col + NUM_COLS * (row - 1)] = character;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_row(NUM_COLS - 1);
|
|
||||||
set_cursor_pos(col, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_char(char character) {
|
|
||||||
struct Char* buffer = (struct Char*) 0xb8000;
|
|
||||||
|
|
||||||
if (character == '\n') {
|
|
||||||
print_newline();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col > NUM_COLS) {
|
|
||||||
print_newline();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Char cr = (struct Char) {
|
|
||||||
character: character,
|
|
||||||
color: color,
|
|
||||||
};
|
|
||||||
buffer[col + NUM_COLS * row] = cr;
|
|
||||||
|
|
||||||
col++;
|
|
||||||
set_cursor_pos(col, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_str(char* str) {
|
|
||||||
for (int i = 0; 1; i++) {
|
|
||||||
char character = (char) str[i];
|
|
||||||
|
|
||||||
if (character == '\0') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_char(character);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_set_color(char foreground, char background) {
|
|
||||||
color = foreground + (background << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_cursor_pos(int col, int row) {
|
|
||||||
int offset = col + NUM_COLS * row;
|
|
||||||
port_byte_out(REG_SCREEN_CTRL, 14);
|
|
||||||
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
|
|
||||||
port_byte_out(REG_SCREEN_CTRL, 15);
|
|
||||||
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernel_msg_ok(char* msg) {
|
|
||||||
char ok_p1[] = "[ ";
|
|
||||||
char ok_p2[] = "OK ";
|
|
||||||
char ok_p3[] = "] ";
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
|
||||||
print_str(ok_p1);
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
|
|
||||||
print_str(ok_p2);
|
|
||||||
|
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
|
||||||
print_str(ok_p3);
|
|
||||||
print_str(msg);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef PRINT_H
|
|
||||||
#define PRINT_H
|
|
||||||
#define REG_SCREEN_CTRL 0x3d4
|
|
||||||
#define REG_SCREEN_DATA 0x3d5
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PRINT_COLOR_BLACK = 0,
|
|
||||||
PRINT_COLOR_BLUE = 1,
|
|
||||||
PRINT_COLOR_GREEN = 2,
|
|
||||||
PRINT_COLOR_CYAN = 3,
|
|
||||||
PRINT_COLOR_RED = 4,
|
|
||||||
PRINT_COLOR_MAGENTA = 5,
|
|
||||||
PRINT_COLOR_BROWN = 6,
|
|
||||||
PRINT_COLOR_LIGHT_GRAY = 7,
|
|
||||||
PRINT_COLOR_DARK_GRAY = 8,
|
|
||||||
PRINT_COLOR_LIGHT_BLUE = 9,
|
|
||||||
PRINT_COLOR_LIGHT_GREEN = 10,
|
|
||||||
PRINT_COLOR_LIGHT_CYAN = 11,
|
|
||||||
PRINT_COLOR_LIGHT_RED = 12,
|
|
||||||
PRINT_COLOR_PINK = 13,
|
|
||||||
PRINT_COLOR_YELLOW = 14,
|
|
||||||
PRINT_COLOR_WHITE = 15,
|
|
||||||
};
|
|
||||||
|
|
||||||
const static int NUM_COLS = 80;
|
|
||||||
const static int NUM_ROWS = 25;
|
|
||||||
|
|
||||||
struct Char {
|
|
||||||
char character;
|
|
||||||
char color;
|
|
||||||
};
|
|
||||||
|
|
||||||
void clear_row(int row);
|
|
||||||
void clear_all();
|
|
||||||
|
|
||||||
void print_newline();
|
|
||||||
void print_char(char character);
|
|
||||||
void print_set_color(char foreground, char background);
|
|
||||||
void print_str(char* str);
|
|
||||||
|
|
||||||
void set_cursor_pos(int col, int row);
|
|
||||||
|
|
||||||
void kernel_msg_ok(char* msg);
|
|
||||||
#endif
|
|
|
@ -1,48 +0,0 @@
|
||||||
#include "strings.h"
|
|
||||||
#include "./platform/types.h"
|
|
||||||
|
|
||||||
void itoa(int n, char str[]) {
|
|
||||||
int i, sign;
|
|
||||||
if ((sign = n) < 0) n = -n;
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
str[i++] = n % 10 + '0';
|
|
||||||
} while ((n /= 10) > 0);
|
|
||||||
|
|
||||||
if (sign < 0) str[i++] = '-';
|
|
||||||
str[i] = '\0';
|
|
||||||
|
|
||||||
strrev(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* K&R */
|
|
||||||
void strrev(char s[]) {
|
|
||||||
int c, i, j;
|
|
||||||
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
|
|
||||||
c = s[i];
|
|
||||||
s[i] = s[j];
|
|
||||||
s[j] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* K&R */
|
|
||||||
int strlen(char s[]) {
|
|
||||||
int i = 0;
|
|
||||||
while (s[i] != '\0') ++i;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* strcpy(char* strDest, const char* strSrc) {
|
|
||||||
if ( (strDest == NULL) || (strSrc == NULL) ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
char* strDestCopy = strDest;
|
|
||||||
while ((*strDest++=*strSrc++)!='\0');
|
|
||||||
return strDestCopy;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* strcnc(char* str1, char* str2) {
|
|
||||||
char* str_dest;
|
|
||||||
strcpy(str_dest, str1);
|
|
||||||
strcpy(str_dest, str2);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
#ifndef STRINGS_H
|
|
||||||
#define STRINGS_H
|
|
||||||
|
|
||||||
void itoa(int n, char str[]);
|
|
||||||
void strrev(char s[]);
|
|
||||||
int strlen(char s[]);
|
|
||||||
char* strcpy(char* strDest, const char* strSrc);
|
|
||||||
char* strcnc(char* str1, char* str2);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,25 +0,0 @@
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
void memcpy(char *source, char *dest, int nbytes) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < nbytes; i++) {
|
|
||||||
*(dest + i) = *(source + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void memset(char *dest, char val, int len) {
|
|
||||||
char *temp = (char *)dest;
|
|
||||||
for(; len !=0; len--) *temp++ = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void int_to_ascii(int n, char str[]) {
|
|
||||||
int i, sign;
|
|
||||||
if ((sign = n) < 0) n = -n;
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
str[i++] = n % 10 + '0';
|
|
||||||
} while ((n /= 10) > 0);
|
|
||||||
|
|
||||||
if (sign < 0) str[i++] = '-';
|
|
||||||
str[i] = '\0';
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef UTIL_H
|
|
||||||
#define UTIL_H
|
|
||||||
|
|
||||||
void memcpy(char *source, char *dest, int nbytes);
|
|
||||||
void memset(char *dest, char val, int len);
|
|
||||||
void int_to_ascii(int n, char str[]);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue