From 2c429f6e1ac51ea27f203005eeef20d2b05c759e Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Sat, 23 Jun 2018 08:28:19 +1000 Subject: Re-wrote interrupt handling. Now, flush_idt only initializes IDT entries 32-255. A separate routine in the new file traps.s initializes the first 32 entries with addresses pointing to exception handlers within said file. Modified the register_isr function to now accept a descriptor privilege level which it will assign to the modified IDT entry. Added a task state segment and corresponding entry to the GDT. The TSS will store the kernel's stack pointer and stack segment when switching to userspace. NOTE: The stack pointer MUST be saved manually before switching to userspace! Added the framework for a system call interface at interrupt vector 0x80 (128). --- kernel/traps.s | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 kernel/traps.s (limited to 'kernel/traps.s') diff --git a/kernel/traps.s b/kernel/traps.s new file mode 100644 index 0000000..7b7446b --- /dev/null +++ b/kernel/traps.s @@ -0,0 +1,227 @@ +; +; traps.s provides entry points to the exception handlers +; as well as the system call interface. +; + +global syscall_init +global traps_init +extern idt +extern register_isr +extern syscall + +%macro SAVE 0 + pusha + ; save the data segment selectors + mov ax, ds + push ax + ; switch to kernel data segments + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro + +%macro SAVE_ERR 0 + pusha + ; fetch the error code that was pushed + mov ebx, [esp+32] + ; save the data segment selectors + mov ax, ds + push ax + ; switch to kernel data segments + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro + +%macro RESTORE 0 + ; restore the data segment selectors + pop ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + iret +%endmacro + +%macro RESTORE_ERR 0 + ; restore the data segment selectors + pop ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + add esp, 4 + iret +%endmacro + +traps: + dd exc_div + dd exc_debug + dd exc_nmi + dd exc_brk + dd exc_ovf + dd exc_bounds + dd exc_invop + dd exc_nomath + dd exc_dbf + dd exc_coseg + dd exc_invtss + dd exc_segnotpres + dd exc_stackf + dd exc_gprot + dd exc_pagef + dd exc_reserved + dd exc_mathf + dd exc_alignchk + dd exc_machinechk + dd exc_simdfp + dd exc_virt + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + dd exc_reserved + +traps_init: + push ebp + mov ebp, esp + mov ecx, 0 + mov edx, idt +.loop: + mov eax, ecx + shl eax, 2 + add eax, traps + mov eax, [eax] + mov [edx], ax + shr eax, 16 + mov [edx+6], ax + mov word [edx+2], 0x08 + mov byte [edx+4], 0x00 + mov byte [edx+5], 0x8E + inc ecx + cmp ecx, 32 + je .end + add edx, 8 + jmp .loop +.end: + pop ebp + ret + +exc_div: + SAVE + RESTORE + +exc_debug: + SAVE + RESTORE + +exc_nmi: + SAVE + RESTORE + +exc_brk: + SAVE + RESTORE + +exc_ovf: + SAVE + RESTORE + +exc_bounds: + SAVE + RESTORE + +exc_invop: + SAVE + RESTORE + +exc_nomath: + SAVE + RESTORE + +exc_dbf: + SAVE_ERR + RESTORE_ERR + +exc_coseg: + SAVE + RESTORE + +exc_invtss: + SAVE_ERR + RESTORE_ERR + +exc_segnotpres: + SAVE_ERR + RESTORE_ERR + +exc_stackf: + SAVE_ERR + RESTORE_ERR + +exc_gprot: + SAVE_ERR + RESTORE_ERR + +exc_pagef: + SAVE_ERR + RESTORE_ERR + +exc_mathf: + SAVE + RESTORE + +exc_alignchk: + SAVE + RESTORE + +exc_machinechk: + SAVE + RESTORE + +exc_simdfp: + SAVE + RESTORE + +exc_virt: + SAVE + RESTORE + +exc_reserved: + SAVE + RESTORE + +syscall_handler: + SAVE + + ; pass the saved ESP value to the REAL handler + mov eax, [esp+46] + push eax + call syscall + add esp, 4 + + RESTORE + + +syscall_init: + push ebp + mov ebp, esp + push syscall_handler + push dword 3 + push dword 0x80 + call register_isr + add esp, 12 + pop ebp + ret -- cgit v1.3