summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/boot.s24
-rw-r--r--kernel/sys.c6
-rw-r--r--kernel/timer.s13
-rw-r--r--kernel/traps.s14
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