summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/memory.c2
-rw-r--r--kernel/panic.s4
-rw-r--r--kernel/sched.c52
-rw-r--r--kernel/serial.c19
4 files changed, 70 insertions, 7 deletions
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);