diff options
| -rw-r--r-- | include/kernel/sys.h | 3 | ||||
| -rw-r--r-- | include/signal.h | 4 | ||||
| -rw-r--r-- | include/unistd.h | 3 | ||||
| -rw-r--r-- | kernel/memory.c | 2 | ||||
| -rw-r--r-- | kernel/panic.s | 4 | ||||
| -rw-r--r-- | kernel/sched.c | 52 | ||||
| -rw-r--r-- | kernel/serial.c | 19 | ||||
| -rw-r--r-- | lib/signal.c | 4 | ||||
| -rw-r--r-- | usrbin/main.c | 16 |
9 files changed, 97 insertions, 10 deletions
diff --git a/include/kernel/sys.h b/include/kernel/sys.h index c428c72..2cefd09 100644 --- a/include/kernel/sys.h +++ b/include/kernel/sys.h @@ -9,6 +9,7 @@ extern int sys_alarm(void); extern int sys_pause(void); extern int sys_ctty(void); extern int sys_read(void); +extern int sys_kill(void); extern int sys_dummy(void); syscall_t call_table[256] = { @@ -21,7 +22,7 @@ syscall_t call_table[256] = { [6] = &sys_pause, [7] = &sys_ctty, [8] = &sys_read, - [9] = &sys_dummy, + [9] = &sys_kill, [10] = &sys_dummy, [11] = &sys_dummy, [12] = &sys_dummy, diff --git a/include/signal.h b/include/signal.h index fee6c2b..792a342 100644 --- a/include/signal.h +++ b/include/signal.h @@ -1,6 +1,8 @@ #ifndef _SIGNAL_H #define _SIGNAL_H +#include <unistd.h> + #define NRSIG 32 #define SIGHUP 1 @@ -32,4 +34,6 @@ void *signal(int, void (*)(int)); +int kill(pid_t, int); + #endif diff --git a/include/unistd.h b/include/unistd.h index ef6d059..c337e57 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -8,7 +8,7 @@ typedef int32_t ssize_t; #endif -typedef uint16_t pid_t; +typedef int16_t pid_t; #define __SYS_puts 0 #define __SYS_time 1 @@ -19,6 +19,7 @@ typedef uint16_t pid_t; #define __SYS_pause 6 #define __SYS_ctty 7 #define __SYS_read 8 +#define __SYS_kill 9 #define _syscall0(type, name) \ type name(void) { \ diff --git a/kernel/memory.c b/kernel/memory.c index 67ad69c..b369519 100644 --- a/kernel/memory.c +++ b/kernel/memory.c @@ -123,5 +123,5 @@ void paging_init(void) { "or $0x80000000, %%eax\n" "mov %%eax, %%cr0\n" :: "a" (&kpdir) - :); + ); } diff --git a/kernel/panic.s b/kernel/panic.s index f4e0f26..1f4605d 100644 --- a/kernel/panic.s +++ b/kernel/panic.s @@ -7,13 +7,13 @@ ; global panic -extern printf +extern printk panic: push ebp mov ebp, esp push .msg - call printf + call printk add esp, 4 cli hlt diff --git a/kernel/sched.c b/kernel/sched.c index ae2fb38..c502024 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1,4 +1,5 @@ #include <asm/system.h> +#include <errno.h> #include <kernel/con.h> #include <kernel/kernel.h> #include <kernel/memory.h> @@ -6,6 +7,7 @@ #include <signal.h> #include <string.h> #include <sys/types.h> +#include <unistd.h> /* * WARNING! @@ -75,7 +77,7 @@ struct task_struct *create_proc(void *bin, size_t len) { for(i = 0; i < NRTASKS; i++) { if(tasks[i].pid == nextpid) { /* TODO: handle PID exhaustion */ - nextpid++; + nextpid = (nextpid + 1) % 0x8000; if(nextpid == 0) nextpid++; i = 0; @@ -168,11 +170,32 @@ struct task_struct *create_proc(void *bin, size_t len) { "pushf\n" \ "pop %%eax" \ : "=a" (task->tss.eflags) \ - ::); + ); return task; } +void kill_proc(struct task_struct *task) { + int i, j; + uint32_t *x; + + task->pid = 0; + + for(i = 0; i < PGENT; i++) { + x = map_page((void*) task->tss.cr3); + if(!x[i]) + continue; + x = map_page((void*) (x[i] & 0xFFFFF000)); + for(j = 0; j < PGENT; j++) { + if(x[i] & 1) + free_physical_page((void*) (x[i] & 0xFFFFF000)); + } + } + free_physical_page((void*) task->tss.cr3); + + reschedule(); +} + void sched_init(void) { int i; struct task_struct *task; @@ -236,5 +259,28 @@ void wake_up(struct task_struct **task) { } void sighandler_default(uint32_t sig) { - printk("[kernel] Handling signal 0x%02x for PID 0x%04x\n", sig, ctask->pid); + switch(sig) { + case SIGKILL: + kill_proc(ctask); + break; + default: + printk("[kernel] Handling signal 0x%02x for PID 0x%04x\n", sig, ctask->pid); + break; + } +} + +int sys_kill(pid_t pid, int sig) { + int i; + + if(sig == 0) + return 0; + + for(i = 0; i < NRTASKS; i++) { + if(tasks[i].pid == pid) { + tasks[i].signal |= (1 << (sig - 1)); + return 0; + } + } + + return -ESRCH; } diff --git a/kernel/serial.c b/kernel/serial.c index d96359b..911f02c 100644 --- a/kernel/serial.c +++ b/kernel/serial.c @@ -1,5 +1,6 @@ #include <asm/interrupt.h> #include <asm/io.h> +#include <errno.h> #include <kernel/con.h> #include <kernel/sched.h> #include <sys/types.h> @@ -24,11 +25,16 @@ extern void rs_isr(void); +static char present; + static char rxbuf[256]; static unsigned rxread, rxwrite; static struct task_struct *waiting_task; int rsputs(char *s) { + if(!present) + return -ENXIO; + while(*s) { rswait(); if(*s == '\n' || *s == '\r') { @@ -45,6 +51,8 @@ int rsputs(char *s) { } void serial_init(void) { + present = 0; + outb(RSSCRATCH, 0x00); outb(RSSCRATCH, 0xAA); if(inb(RSSCRATCH) != 0xAA) { @@ -75,12 +83,16 @@ void serial_init(void) { rxread = 0; rxwrite = 1; waiting_task = NULL; + present = 1; } ssize_t rsread(void *buf, size_t len) { ssize_t n = len; char *b = buf; + if(!present) + return -ENXIO; + if(len == 0) return 0; @@ -88,9 +100,14 @@ ssize_t rsread(void *buf, size_t len) { if(rxread == rxwrite) { /* put the current task to sleep */ waiting_task = ctask; - ctask->state = TSTATE_UNINTERRUPTIBLE; + ctask->state = TSTATE_INTERRUPTIBLE; reschedule(); } + /* check again to see if anything was read, or we were interrupted */ + if(rxread == rxwrite) { + waiting_task = NULL; + return -EINTR; + } *b++ = rxbuf[rxread]; rxread = rxread + 1 % sizeof(rxbuf); diff --git a/lib/signal.c b/lib/signal.c index 343e2cc..b89985a 100644 --- a/lib/signal.c +++ b/lib/signal.c @@ -1,11 +1,13 @@ #include <unistd.h> +_syscall2(int, kill, pid_t, pid, int, sig); + void *signal(int sig, void (*func)(int)) { void *__res; __asm__ volatile ( "int $0x80" : "=a" (__res) : "a" (__SYS_signal), "b" (sig), "c" (func) - :); + ); return __res; } diff --git a/usrbin/main.c b/usrbin/main.c index 31d38c1..d1e3adc 100644 --- a/usrbin/main.c +++ b/usrbin/main.c @@ -1,17 +1,31 @@ +#include <errno.h> #include <signal.h> #include <stdint.h> #include <stdio.h> #include <time.h> #include <unistd.h> +void sighandler(int sig) { + printf("Signal received!\n"); +} + void pid1(void) { ssize_t in; char buf[2] = { 0, 0 }; printf("We did it ma!\n"); + signal(1, &sighandler); while(1) { in = read(buf, 1); + if(in <= 0) { + if(in == -EINTR) { + printf("Read call interrupted!\n"); + kill(getpid(), SIGKILL); + } else { + pause(); + } + } if(in > 0) puts(buf); } @@ -24,6 +38,8 @@ void pid2(void) { while(1) { sleep(1); + if(time() == 2) + kill(1, 1); printf("0x%04x:0x%08x: 0x%08x, 0x%08x\n", getpid(), (uint32_t) getpdir(), time(), x++); } } |
