diff options
| -rw-r--r-- | kernel/boot.s | 92 | ||||
| -rw-r--r-- | kernel/kmain.c | 4 | ||||
| -rw-r--r-- | kernel/syscall.c | 12 | ||||
| -rw-r--r-- | kernel/timer.s | 3 | ||||
| -rw-r--r-- | kernel/traps.s | 227 | ||||
| -rw-r--r-- | kernel/usrbin/usrbin.bin | bin | 76 -> 59 bytes | |||
| -rw-r--r-- | kernel/usrbin/usrbin.s | 26 | ||||
| -rw-r--r-- | kernel/usrspace.s | 7 |
8 files changed, 320 insertions, 51 deletions
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 diff --git a/kernel/kmain.c b/kernel/kmain.c index 81fe741..bf6b9ae 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -10,8 +10,8 @@ extern void userspace_init(void); void kmain(void) { con_init(); - printf("Kernel booting...\n\n"); - printf("\nKernel booted!\n"); + printf("Kernel booting...\n"); + printf("Kernel booted!\n\n"); userspace_init(); } diff --git a/kernel/syscall.c b/kernel/syscall.c new file mode 100644 index 0000000..8fa5da0 --- /dev/null +++ b/kernel/syscall.c @@ -0,0 +1,12 @@ +#include <kernel/con.h> +#include <stdarg.h> +#include <stdint.h> + +/* main syscall handler */ +void syscall(va_list ap) { + uint8_t call; + char *s; + + printf("Call Number: 0x%02x\n", va_arg(ap, uint8_t)); + printf(va_arg(ap, char*)); +} diff --git a/kernel/timer.s b/kernel/timer.s index de01ea6..53c81ed 100644 --- a/kernel/timer.s +++ b/kernel/timer.s @@ -17,9 +17,10 @@ timer_init: mov ebp, esp ; register the tick_handler push tick_handler + push dword 0 push dword 0x20 call register_isr - add esp, 8 + add esp, 12 ; initialize the pit mov ax, 0x36 out 0x43, al 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 diff --git a/kernel/usrbin/usrbin.bin b/kernel/usrbin/usrbin.bin Binary files differindex a7d7730..bdf8c29 100644 --- a/kernel/usrbin/usrbin.bin +++ b/kernel/usrbin/usrbin.bin diff --git a/kernel/usrbin/usrbin.s b/kernel/usrbin/usrbin.s index 91dd94a..248d823 100644 --- a/kernel/usrbin/usrbin.s +++ b/kernel/usrbin/usrbin.s @@ -3,30 +3,10 @@ org 0x100000 main: push .msg - call puts + push byte 0 + int 0x80 add esp, 4 .loop: ; loop forever jmp .loop -.msg: db "Hello World from Userspace!", 0 - -puts: - push ebp - mov ebp, esp - push esi - push edi - mov esi, [ebp+8] - mov edi, 0xB8000 -.loop: - lodsb - cmp al, 0 - je .end - mov [edi], al - mov byte [edi+1], 0x07 - add edi, 2 - jmp .loop -.end: - pop edi - pop esi - pop ebp - ret +.msg: db "Hello World from Userspace, using syscalls!", 10, 0 diff --git a/kernel/usrspace.s b/kernel/usrspace.s index e52f2e0..1d20f71 100644 --- a/kernel/usrspace.s +++ b/kernel/usrspace.s @@ -1,6 +1,7 @@ global userspace_init -extern _binary_usrbin_bin_start extern _binary_usrbin_bin_size +extern _binary_usrbin_bin_start +extern tss userspace_init: push ebp @@ -32,8 +33,10 @@ usrcall: mov fs, ax mov gs, ax mov eax, esp + ; save ESP in the TSS + mov [tss+4], eax push dword 0x23 - push eax + push dword 0x00180000 pushf push dword 0x1B push dword 0x00100000 |
