diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-06-23 08:28:19 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-06-23 08:28:19 +1000 |
| commit | 2c429f6e1ac51ea27f203005eeef20d2b05c759e (patch) | |
| tree | 5d9ba6851e87876a97a4780905a3248af165f33e /kernel/traps.s | |
| parent | ce9932308abed8000f9f6e06a61f726b29aa9e3a (diff) | |
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).
Diffstat (limited to 'kernel/traps.s')
| -rw-r--r-- | kernel/traps.s | 227 |
1 files changed, 227 insertions, 0 deletions
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 |
