diff options
-rw-r--r-- | kernel/drivers/ide.c | 1 | ||||
-rw-r--r-- | kernel/drivers/keyboard.c | 34 | ||||
-rw-r--r-- | kernel/features/fs.c | 67 | ||||
-rw-r--r-- | kernel/features/proc.c | 8 | ||||
-rw-r--r-- | kernel/features/syscall.c | 7 | ||||
-rw-r--r-- | kernel/inc/fs.h | 4 | ||||
-rw-r--r-- | libc/inc/sys.h | 2 |
7 files changed, 111 insertions, 12 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index f3d0f6e..5a51cb8 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -147,6 +147,7 @@ void ata_probe(void) struct vfs *vfs = malloc(sizeof(*vfs)); vfs->type = VFS_EXT2; vfs->read = ext2_read; + vfs->ready = ext2_ready; vfs->stat = ext2_stat; dev->vfs = vfs; vfs_mount(dev, "/"); diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index 7f3247f..6936c22 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -2,12 +2,17 @@ #include <cpu.h> #include <def.h> +#include <fs.h> #include <interrupts.h> #include <mem.h> #include <print.h> +#include <proc.h> +#include <stack.h> +#include <str.h> #include <sys.h> static struct event_keyboard *event = NULL; +static struct stack *queue = NULL; static int state = 0; static int merged = 0; @@ -33,10 +38,13 @@ void keyboard_handler() event->magic = KEYBOARD_MAGIC; event->press = (scancode & 0x80) == 0; event->scancode = event->press ? scancode : scancode & ~0x80; - //event_trigger(EVENT_KEYBOARD, event); + stack_push_bot(queue, event); state = 0; merged = 0; + + // TODO: Only enable waiting procs + proc_current()->state = PROC_RUNNING; } void keyboard_acknowledge(void) @@ -52,8 +60,32 @@ void keyboard_rate(void) outb(0x60, 0x0); // Rate{00000} Delay{00} 0 } +u32 keyboard_read(void *buf, u32 offset, u32 count, struct device *dev) +{ + (void)dev; + if (stack_empty(queue)) + return 0; + + struct event *e = stack_pop(queue); + memcpy(buf, (u8 *)e + offset, count); + return count; +} + +u32 keyboard_ready() +{ + return !stack_empty(queue); +} + void keyboard_install(void) { //keyboard_rate(); TODO: Fix keyboard rate? irq_install_handler(1, keyboard_handler); + + queue = stack_new(); + struct device *dev = malloc(sizeof(*dev)); + dev->name = strdup("kbd"); + dev->type = DEV_CHAR; + dev->read = keyboard_read; + dev->ready = keyboard_ready; + device_add(dev); } diff --git a/kernel/features/fs.c b/kernel/features/fs.c index 13ed0c2..45e744c 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -154,9 +154,32 @@ u32 vfs_write(const char *path, void *buf, u32 offset, u32 count) u32 vfs_stat(const char *path, struct stat *buf) { - struct device *dev = vfs_find_dev(path); - assert(dev && dev->vfs && dev->vfs->stat); - return dev->vfs->stat(path, buf, dev); + while (*path == ' ') + path++; + + struct mount_info *m = vfs_find_mount_info(path); + assert(m && m->dev && m->dev->vfs && m->dev->vfs->stat); + + u32 len = strlen(m->path); + if (len > 1) + path += len; + + return m->dev->vfs->stat(path, buf, m->dev); +} + +u32 vfs_ready(const char *path) +{ + while (*path == ' ') + path++; + + struct mount_info *m = vfs_find_mount_info(path); + assert(m && m->dev && m->dev->vfs && m->dev->vfs->ready); + + u32 len = strlen(m->path); + if (len > 1) + path += len; + + return m->dev->vfs->ready(path, m->dev); } void vfs_install(void) @@ -176,7 +199,7 @@ void device_add(struct device *dev) list_add(devices, dev); } -struct device *device_get(u32 id) +struct device *device_get_by_id(u32 id) { struct node *iterator = devices->head; while (iterator) { @@ -187,11 +210,33 @@ struct device *device_get(u32 id) return NULL; } +struct device *device_get_by_name(const char *name) +{ + struct node *iterator = devices->head; + while (iterator) { + if (!strcmp(((struct device *)iterator->data)->name, name)) + return iterator->data; + iterator = iterator->next; + } + return NULL; +} + u32 devfs_read(const char *path, void *buf, u32 offset, u32 count, struct device *dev) { - assert(dev && dev->read); - printf("%s - off: %d, cnt: %d, buf: %x, dev %x\n", path, offset, count, buf, dev); - return dev->read(buf, offset, count, dev); + struct device *target = device_get_by_name(path + 1); + if (!target || !target->read) + return 0; + return target->read(buf, offset, count, dev); +} + +u32 devfs_ready(const char *path, struct device *dev) +{ + (void)dev; + + struct device *target = device_get_by_name(path + 1); + if (!target || !target->ready) + return 0; + return target->ready(); } void device_install(void) @@ -201,6 +246,7 @@ void device_install(void) struct vfs *vfs = malloc(sizeof(*vfs)); vfs->type = VFS_DEVFS; vfs->read = devfs_read; + vfs->ready = devfs_ready; struct device *dev = malloc(sizeof(*dev)); dev->name = "dev"; dev->type = DEV_CHAR; @@ -406,3 +452,10 @@ u32 ext2_stat(const char *path, struct stat *buf, struct device *dev) return 0; } + +u32 ext2_ready(const char *path, struct device *dev) +{ + (void)path; + (void)dev; + return 1; +} diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 79bc6c8..8fbb4c5 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -44,8 +44,12 @@ void scheduler(struct regs *regs) } else if (((struct proc *)proc_list->head->data)->state == PROC_RUNNING) { current = proc_list->head; } else { - print("TODO: All processes are sleeping!\n"); // TODO! - /* loop(); */ + /* sti(); */ + /* hlt(); */ + /* cli(); */ + //print("TODO: All processes are sleeping!\n"); // TODO! + //loop(); + return; } memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs)); diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index dbb7033..c5570c3 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -37,7 +37,12 @@ void syscall_handler(struct regs *r) break; } case SYS_READ: { - r->eax = (u32)vfs_read((char *)r->ebx, (void *)r->ecx, r->edx, r->esi); + if (vfs_ready((char *)r->ebx)) { + r->eax = (u32)vfs_read((char *)r->ebx, (void *)r->ecx, r->edx, r->esi); + } else { + proc_current()->state = PROC_SLEEPING; + scheduler(r); + } break; } case SYS_WRITE: { diff --git a/kernel/inc/fs.h b/kernel/inc/fs.h index ff14361..1b2b073 100644 --- a/kernel/inc/fs.h +++ b/kernel/inc/fs.h @@ -20,6 +20,7 @@ struct device { void *data; u32 (*read)(void *buf, u32 offset, u32 count, struct device *dev); u32 (*write)(void *buf, u32 offset, u32 count, struct device *dev); + u32 (*ready)(); }; void device_install(void); @@ -38,6 +39,7 @@ struct vfs { u32 (*read)(const char *path, void *buf, u32 offset, u32 count, struct device *dev); u32 (*write)(const char *path, void *buf, u32 offset, u32 count, struct device *dev); u32 (*stat)(const char *path, struct stat *buf, struct device *dev); + u32 (*ready)(const char *path, struct device *dev); }; struct mount_info { @@ -53,6 +55,7 @@ u32 vfs_mount(struct device *dev, const char *path); u32 vfs_read(const char *path, void *buf, u32 offset, u32 count); u32 vfs_write(const char *path, void *buf, u32 offset, u32 count); u32 vfs_stat(const char *path, struct stat *buf); +u32 vfs_ready(const char *path); /** * EXT2 @@ -147,5 +150,6 @@ struct ext2_file { u32 ext2_read(const char *path, void *buf, u32 offset, u32 count, struct device *dev); u32 ext2_stat(const char *path, struct stat *buf, struct device *dev); +u32 ext2_ready(const char *path, struct device *dev); #endif diff --git a/libc/inc/sys.h b/libc/inc/sys.h index e345ce8..14f83dd 100644 --- a/libc/inc/sys.h +++ b/libc/inc/sys.h @@ -96,7 +96,7 @@ static inline u32 getpid() return buf; } -// Hacky, one-digit solution - TODO! +// Hacky one-digit solution - TODO! #include <mem.h> #include <str.h> static inline u32 pidof(const char *name) |