summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asm/interrupt.h1
-rw-r--r--include/kernel/sched.h1
-rw-r--r--kernel/boot.s24
-rw-r--r--kernel/sys.c6
-rw-r--r--kernel/timer.s13
-rw-r--r--kernel/traps.s14
-rw-r--r--usrbin/main.c8
7 files changed, 45 insertions, 22 deletions
diff --git a/include/asm/interrupt.h b/include/asm/interrupt.h
index 5e0178b..d1ea6c1 100644
--- a/include/asm/interrupt.h
+++ b/include/asm/interrupt.h
@@ -1 +1,2 @@
void register_isr(uint8_t n, uint8_t dpl, void *handler);
+void register_trap(uint8_t n, uint8_t dpl, void *handler);
diff --git a/include/kernel/sched.h b/include/kernel/sched.h
index ac508b9..3d6699c 100644
--- a/include/kernel/sched.h
+++ b/include/kernel/sched.h
@@ -55,6 +55,7 @@ struct task_struct {
} __attribute__((packed));
extern struct task_struct *ctask;
+extern uint32_t ticks;
void sched_init(void);
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
diff --git a/usrbin/main.c b/usrbin/main.c
index 2e409fd..2afcf0e 100644
--- a/usrbin/main.c
+++ b/usrbin/main.c
@@ -1,21 +1,15 @@
-#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
-void sig_handler(int s) {
- printf("Handled the signal!\n");
-}
-
void main(void) {
int x = 0;
- /* signal(0, &sig_handler); */
printf("We did it ma!\n");
while(1) {
- /* sleep(1); */
+ sleep(1);
printf("0x%04x:0x%08x: 0x%08x, 0x%08x\n", getpid(), (uint32_t) getpdir(), time(), x++);
}
}