diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 243e19f5..5e0d96ee 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -53,7 +53,17 @@ void kmain(){ vmm_init(); alloc_init(); + + acpi_init(); + apic_init(); + + apic_lapicinit(); + + hpet_init(); + + arch_schedtimer_calibrate(); + vfs_init(); printf("Mounting tmpfs in /\n"); @@ -63,17 +73,9 @@ void kmain(){ initrd_parse(); - acpi_init(); - - apic_init(); - - apic_lapicinit(); - + devman_init(); + pci_enumerate(); - - hpet_init(); - - arch_schedtimer_calibrate(); smp_init(); diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 38904424..133499a8 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -3,6 +3,7 @@ #include #include #include +#include dirnode_t* vfsroot; hashtable fsfuncs; @@ -66,8 +67,9 @@ int vfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset } if(type == TYPE_BLOCKDEV || type == TYPE_CHARDEV){ - *error = ENOSYS; - return -1; // TODO change this when the device manager is implemented :) + int writecount = devman_write(error, node->st.st_rdev, buff, count, offset); + + return writecount; } int writecount = node->fs->calls->write(error, node, buff, count, offset); @@ -86,8 +88,8 @@ int vfs_read(int* error, vnode_t* node, void* buff, size_t count, size_t offset) } if(type == TYPE_BLOCKDEV || type == TYPE_CHARDEV){ - *error = ENOSYS; - return -1; // TODO change this when the device manager is implemented :) + int readcount = devman_read(error, node->st.st_rdev, buff, count, offset); + return readcount; } int readcount = node->fs->calls->read(error, node, buff, count, offset); diff --git a/src/include/kernel/alloc.h b/src/include/kernel/alloc.h index b23e2e75..4c7aa72c 100644 --- a/src/include/kernel/alloc.h +++ b/src/include/kernel/alloc.h @@ -5,6 +5,7 @@ void* alloc(size_t); void free(void*); +void* realloc(void*, size_t); void alloc_init(); diff --git a/src/include/kernel/devman.h b/src/include/kernel/devman.h new file mode 100644 index 00000000..900f7ca2 --- /dev/null +++ b/src/include/kernel/devman.h @@ -0,0 +1,17 @@ +#ifndef _DEVMAN_H_INCLUDE +#define _DEVMAN_H_INCLUDE + +#include + + +typedef struct{ + int (*read)(int* error, int minor, void* buff, size_t count, size_t offset); + int (*write)(int* error, int minor, void* buff, size_t count, size_t offset); +} devcalls; + +int devman_read(int *error, int dev, void* buff, size_t count, size_t offset); +int devman_write(int *error, int dev, void* buff, size_t count, size_t offset); +int devman_newdevice(char* name, int type, int major, int minor, devcalls* calls); +void devman_init(); + +#endif diff --git a/src/sys/devman.c b/src/sys/devman.c new file mode 100644 index 00000000..bc1fd766 --- /dev/null +++ b/src/sys/devman.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static devcalls** majorcalls; +static size_t highestmajor = 0; + +int devman_newdevice(char* name, int type, int major, int minor, devcalls* calls){ + + if(major > highestmajor){ + void* addr = realloc(majorcalls, major*sizeof(devcalls*)+1); + if(!addr) + return ENOMEM; + majorcalls = addr; + } + + majorcalls[major] = calls; + + return devfs_newdevice(name, type, makedev(major, minor), 0777); + +} + +int devman_write(int *error, int dev, void* buff, size_t count, size_t offset){ + + if(major(dev) > highestmajor) + return ENODEV; + + + return majorcalls[major(dev)]->write(error, minor(dev), buff, count, offset); + + +} + +int devman_read(int *error, int dev, void* buff, size_t count, size_t offset){ + + if(major(dev) > highestmajor) + return ENODEV; + + + return majorcalls[major(dev)]->read(error, minor(dev), buff, count, offset); + + +} + +void devman_init(){ + + devfs_init(); + + size_t err = vfs_mkdir(vfs_root(), "dev", 0777); + if(err && err != EEXIST){ + printf("Failed to mkdir /dev: %lu\n", err); + _panic("Devman initialization failed", 0); + } + + err = vfs_mount(vfs_root(), NULL, "dev", "devfs", 0, NULL); + + if(err){ + printf("Failed to mount devfs in /dev: %lu\n", err); + _panic("Devman initialization failed", 0); + } + + printf("devfs mounted in /dev\n"); + + majorcalls = alloc(sizeof(devcalls*)); + + +} diff --git a/src/sys/mm/alloc.c b/src/sys/mm/alloc.c index 2bae5a6a..25b40e3a 100644 --- a/src/sys/mm/alloc.c +++ b/src/sys/mm/alloc.c @@ -1,5 +1,6 @@ #include #include +#include void* alloc(size_t size){ return slab_alloc(size); @@ -12,3 +13,16 @@ void free(void* addr){ void alloc_init(){ slab_init(); } + +void* realloc(void* addr, size_t size){ + void* tmp = alloc(size); + if(!tmp) + return NULL; + + memcpy(tmp, addr, size); + + free(addr); + + return tmp; + +}