diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/boot.s | 24 | ||||
| -rw-r--r-- | kernel/sys.c | 6 | ||||
| -rw-r--r-- | kernel/timer.s | 13 | ||||
| -rw-r--r-- | kernel/traps.s | 14 |
4 files changed, 42 insertions, 15 deletions
diff --git a/kernel/boot.s b/kernel/boot.s index db846c9..d609611 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -2,6 +2,7 @@ global gdt global idt global kboot global register_isr +global register_trap extern con_init extern hd_init extern kmain @@ -191,8 +192,27 @@ register_isr: mov eax, [ebp+12] and al, 3 shl al, 5 - mov cl, [edx+5] - and cl, 0x9F + mov cl, 0x8E + or cl, al + mov [edx+5], cl + pop ebp + ret + +; void register_trap(uint8_t n, uint8_t dpl, void *handler); +register_trap: + push ebp + mov ebp, esp + mov edx, [ebp+8] + shl edx, 3 + add edx, idt + mov eax, [ebp+16] + mov [edx], ax + shr eax, 16 + mov [edx+6], ax + mov eax, [ebp+12] + and al, 3 + shl al, 5 + mov cl, 0x8F or cl, al mov [edx+5], cl pop ebp diff --git a/kernel/sys.c b/kernel/sys.c index 86fae41..20494de 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -7,13 +7,7 @@ #include <time.h> #include <unistd.h> -extern uint32_t ticks; - int sys_puts(char *s) { - uint32_t sigs = 5; - printk("[kernel] Setting signals %01x for PID 0x%04x\n", sigs, ctask->pid); - ctask->signal |= sigs; - printk("[%04x] ", ctask->pid); return printk(s); } diff --git a/kernel/timer.s b/kernel/timer.s index c3af34b..b96e1f1 100644 --- a/kernel/timer.s +++ b/kernel/timer.s @@ -1,9 +1,11 @@ +global ticked global ticks global timer_init extern check_signals extern register_isr extern sched_tick +ticked: dd 0 ticks: dd 0 tick_handler: @@ -17,17 +19,20 @@ tick_handler: mov es, ax mov fs, ax mov gs, ax - ; handle the timer tick + mov dword [ticked], 1 inc dword [ticks] mov al, 0x20 out 0x20, al - - ; call the scheduler + ; check that the user isn't executing in kernel space + mov eax, [esp+38] + test eax, 0x03 + jz .end + ; if it isn't, call the scheduler call sched_tick ; handle any pending signals before returning to normal execution call check_signals - +.end: ; restore the data segment selectors pop ax mov ds, ax diff --git a/kernel/traps.s b/kernel/traps.s index 73e7f64..36b3423 100644 --- a/kernel/traps.s +++ b/kernel/traps.s @@ -11,8 +11,10 @@ extern ctask extern idt extern panic extern printk -extern register_isr +extern register_trap +extern reschedule extern sighandler_default +extern ticked ; here we define offsets into task_struct. ; if task_struct is modified, this must be @@ -269,6 +271,7 @@ exc_reserved: syscall_handler: SAVE + mov dword [ticked], 0 ; push the arguments onto the stack, then ; calculate the offset for the appropriate ; handler function and call it @@ -282,8 +285,13 @@ syscall_handler: add esp, 12 ; preserve the syscall's return value mov [esp+30], eax - mov eax, esp + ; check if the timer fired while we were in kernel mode + mov eax, [ticked] + jz .skip + call reschedule +.skip: ; check pending signals and handle them (if any) + mov eax, esp push eax call check_signals add esp, 4 @@ -379,7 +387,7 @@ syscall_init: push syscall_handler push dword 3 push dword 0x80 - call register_isr + call register_trap add esp, 12 pop ebp ret |
