diff --git a/Makefile b/Makefile index c4564c7..825ff4d 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ 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 + 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 & diff --git a/bin/boot.bin b/bin/boot.bin index 9a84534..1a008f3 100644 Binary files a/bin/boot.bin and b/bin/boot.bin differ diff --git a/bin/kernel.bin b/bin/kernel.bin index 746678e..959dbee 100755 Binary files a/bin/kernel.bin and b/bin/kernel.bin differ diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o index 987d3fc..8ed7c05 100644 Binary files a/obj/kernel/kernel.o and b/obj/kernel/kernel.o differ diff --git a/obj/kernel/platform/interrupts/int.o b/obj/kernel/platform/interrupts/int.o index 14dbc95..dab89eb 100644 Binary files a/obj/kernel/platform/interrupts/int.o and b/obj/kernel/platform/interrupts/int.o differ diff --git a/obj/kernel/platform/interrupts/int_lowlevel.o b/obj/kernel/platform/interrupts/int_lowlevel.o index 98f9819..c3f6326 100644 Binary files a/obj/kernel/platform/interrupts/int_lowlevel.o and b/obj/kernel/platform/interrupts/int_lowlevel.o differ diff --git a/os-image.bin b/os-image.bin index 5d875f0..4683e53 100644 Binary files a/os-image.bin and b/os-image.bin differ diff --git a/src/boot/protected/gdt.asm b/src/boot/protected/gdt.asm index 2618221..db35b41 100644 --- a/src/boot/protected/gdt.asm +++ b/src/boot/protected/gdt.asm @@ -14,12 +14,12 @@ gdt_code: ; GDT for data segment gdt_data: - dw 0xffff - dw 0x0 - db 0x0 - db 10010010b - db 11001111b - db 0x0 + 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: diff --git a/src/kernel/platform/interrupts/int.c b/src/kernel/platform/interrupts/int.c index 3e63985..4b77162 100644 --- a/src/kernel/platform/interrupts/int.c +++ b/src/kernel/platform/interrupts/int.c @@ -1,8 +1,14 @@ #include "int.h" #include "../../print.h" -void exception_handler() { +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) { diff --git a/src/kernel/platform/interrupts/int.h b/src/kernel/platform/interrupts/int.h index a58b890..3f36fc9 100644 --- a/src/kernel/platform/interrupts/int.h +++ b/src/kernel/platform/interrupts/int.h @@ -21,8 +21,15 @@ typedef struct { 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(void); +void exception_handler(registers_t r); void idt_set_descriptor(u8 vector, void* isr, u8 flags); diff --git a/src/kernel/platform/interrupts/int_lowlevel.asm b/src/kernel/platform/interrupts/int_lowlevel.asm index a38fd41..0d2f397 100644 --- a/src/kernel/platform/interrupts/int_lowlevel.asm +++ b/src/kernel/platform/interrupts/int_lowlevel.asm @@ -1,16 +1,64 @@ %macro isr_err_stub 1 isr_stub_%+%1: - call exception_handler - iret + 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: - call exception_handler - iret + 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