summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kernel/sys.h3
-rw-r--r--include/signal.h4
-rw-r--r--include/unistd.h3
-rw-r--r--kernel/memory.c2
-rw-r--r--kernel/panic.s4
-rw-r--r--kernel/sched.c52
-rw-r--r--kernel/serial.c19
-rw-r--r--lib/signal.c4
-rw-r--r--usrbin/main.c16
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++);
}
}