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/boot.s | 92 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 23 deletions(-) (limited to 'kernel/boot.s') diff --git a/kernel/boot.s b/kernel/boot.s index 024abf0..bc42a5d 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -1,7 +1,12 @@ +global gdt +global idt global kboot global register_isr +global tss extern kmain +extern syscall_init extern timer_init +extern traps_init ; Multiboot header section .mboothdr @@ -15,15 +20,32 @@ section .text kboot: cli + ; put the stack pointer near the end of conventional memory + mov esp, 0x80000 + ; setup descriptor tables call flush_gdt call flush_idt - ;call timer_init + ; last minute setup, then transfer to kmain + call timer_init call kmain + ; if kmain decides to return (which it shouldn't), + ; disable interrupts and halt the system. cli hlt tss: - times 104 db 0 + dd 0 + dd 0 ; kernel stack pointer + dd 0x10 ; kernel stack segment + times 60 db 0 + dd 0x13 ; ES segment + dd 0x0B ; CS segment + dd 0x13 ; SS segment + dd 0x13 ; DS segment + dd 0x13 ; FS segment + dd 0x13 ; GS segment + times 8 db 0 +.end: gdt: ; null descriptor @@ -57,14 +79,31 @@ gdt: db 0xCF db 0x00 ; task state segment +.tss: + dq 0 ; we initialize this later +.end: gdtp: - dw ($-gdt-1) + dw (gdt.end-gdt-1) dd gdt flush_gdt: push ebp mov ebp, esp + ; initialize the TSS entry + mov eax, tss + mov [gdt.tss+2], ax + shr eax, 16 + mov [gdt.tss+4], al + mov [gdt.tss+7], ah + mov eax, (tss.end-tss-1) + mov [gdt.tss], ax + shr eax, 16 + and al, 0x0F + mov [gdt.tss+6], al + mov al, 0xE9 + mov [gdt.tss+5], al + ; now, load the GDT lgdt [gdtp] mov ax, 0x10 mov ds, ax @@ -74,65 +113,72 @@ flush_gdt: mov ss, ax jmp 0x08:.end .end: + ; initialize the task state register + mov ax, 0x002B + ltr ax pop ebp ret idt: times (256*8) db 0 +.end: idtp: - dw ($-idt-1) + dw (idt.end-idt-1) dd idt int_handler: iret -irq_handler: - iret - flush_idt: push ebp mov ebp, esp + ; install the exception handlers (vectors 0-31) + call traps_init + ; install the default handlers (vectors 32-255) mov ecx, 0 - mov edx, idt + lea edx, [idt+(32*8)] .loop: mov eax, int_handler - cmp ecx, 0x20 - jl .skip - cmp ecx, 0x2f - jg .skip - mov eax, irq_handler -.skip: mov [edx], ax - mov word [edx+2], 0x08 - mov byte [edx+4], 0 - mov byte [edx+5], 0x8E shr eax, 16 mov [edx+6], ax - add edx, 8 + mov word [edx+2], 0x08 + mov byte [edx+4], 0x00 + mov byte [edx+5], 0x8E inc ecx - cmp ecx, 256 + cmp ecx, (256-32) je .end + add edx, 8 jmp .loop .end: + ; install the system call handler + call syscall_init + ; load the IDT, initialize the PIC's, and enable interrupts lidt [idtp] call pic_init sti pop ebp ret -; void register_isr(uint8_t n, void *handler); +; void register_isr(uint8_t n, uint8_t dpl, void *handler); register_isr: push ebp mov ebp, esp mov edx, [ebp+8] shl edx, 3 add edx, idt - mov eax, [ebp+12] + mov eax, [ebp+16] mov [edx], ax - add edx, 6 shr eax, 16 - mov [edx], ax + mov [edx+6], ax + mov eax, [ebp+12] + and al, 3 + shl al, 5 + mov cl, [edx+5] + and cl, 0x9F + or cl, al + mov [edx+5], cl pop ebp ret -- cgit v1.3