diff options
author | Franklin Wei <frankhwei536@gmail.com> | 2015-03-02 21:37:44 -0500 |
---|---|---|
committer | Franklin Wei <frankhwei536@gmail.com> | 2015-03-02 21:37:44 -0500 |
commit | a0721b4caa79b81e021678089fde0b8467daa1cd (patch) | |
tree | 56af15c29704cc4c6738345ccd6c9db3782fd8d1 | |
parent | 46e94578765d3d2f03b83421d752e5dfc3e56d34 (diff) | |
download | kappa-master.zip kappa-master.tar.gz kappa-master.tar.bz2 kappa-master.tar.xz |
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | OBJ | 2 | ||||
-rw-r--r-- | cdrom/grub.cfg | 1 | ||||
-rw-r--r-- | docs/FILESYSTEM | 34 | ||||
-rw-r--r-- | include/arch/i686/drivers/ps2kbd.h | 2 | ||||
-rw-r--r-- | include/kernel/heap.h | 2 | ||||
-rw-r--r-- | include/kernel/multiboot.h | 12 | ||||
-rw-r--r-- | include/kernel/vfs.h | 48 | ||||
-rw-r--r-- | include/string.h | 3 | ||||
-rw-r--r-- | kernel/heap.c | 5 | ||||
-rw-r--r-- | kernel/main.c | 33 | ||||
-rw-r--r-- | kernel/vfs.c | 91 | ||||
-rw-r--r-- | libc/string.c | 22 |
13 files changed, 254 insertions, 2 deletions
@@ -28,6 +28,7 @@ kappa.iso: kappa.bin @echo "Building ISO under $(ISODIR)/..." @mkdir -p $(ISODIR) @mkdir -p $(ISODIR)/boot + @cp initrd $(ISODIR)/initrd.img @cp kappa.bin $(ISODIR)/efi.img @cp kappa.bin $(ISODIR)/boot/kappa.bin @mkdir -p $(ISODIR)/boot/grub @@ -27,11 +27,13 @@ arch/i686/paging.o drivers/gfx_font.o drivers/ps2_keymaps.o kernel/heap.o +kernel/initrd.o kernel/io.o kernel/log.o kernel/main.o kernel/panic.o kernel/timer.o +kernel/vfs.o libc/stdio.o libc/stdlib.o libc/string.o diff --git a/cdrom/grub.cfg b/cdrom/grub.cfg index ec245cc..ae75d37 100644 --- a/cdrom/grub.cfg +++ b/cdrom/grub.cfg @@ -1,3 +1,4 @@ menuentry 'Project Kappa' { multiboot /efi.img + module /initrd.img } diff --git a/docs/FILESYSTEM b/docs/FILESYSTEM new file mode 100644 index 0000000..a1bdc1e --- /dev/null +++ b/docs/FILESYSTEM @@ -0,0 +1,34 @@ +=== Virtual Filesystem Design === + +The virtual (in-RAM) filesystem is made of levels of nodes. + + NULL + | + [/] --- NULL + | + [bin] --------------------------- [etc] ---------------------- [home] --- [var] --- NULL + | | + [cat] --- [cd] --- [ls] --- NULL [group] --- [passwd] --- NULL + +=== Sample Implementation === + +struct vfs_node { + unsigned int flags; + unsigned int name_len; + char *name; + uint64_t file_len; + unsigned char *contents; + struct vfs_node *parent; + struct vfs_node *next; + struct vfs_node *child; +}; + +=== The 'flags' field === + += Bits 0-1 = + +The next three values are mutually exclusive. + +0: directory +1: regular file +2: special file diff --git a/include/arch/i686/drivers/ps2kbd.h b/include/arch/i686/drivers/ps2kbd.h index 9e353ee..a9e2bf9 100644 --- a/include/arch/i686/drivers/ps2kbd.h +++ b/include/arch/i686/drivers/ps2kbd.h @@ -50,6 +50,8 @@ struct ps2_specialkeys_t { struct ps2_keyevent { const struct ps2_specialkeys_t *special_keys; char ascii; + uint8_t scancode; + uint8_t ps2_scancode_set; }; /* returns which arrow keys are down */ diff --git a/include/kernel/heap.h b/include/kernel/heap.h index dfadf36..abb9bdf 100644 --- a/include/kernel/heap.h +++ b/include/kernel/heap.h @@ -1,5 +1,7 @@ #include <stddef.h> +#include <stdint.h> void *kmalloc(size_t); void *kmalloc_a(size_t); void *kmalloc_p(size_t, void**); void *kmalloc_ap(size_t, void**); +void kmalloc_set_addr(uint32_t); diff --git a/include/kernel/multiboot.h b/include/kernel/multiboot.h index e1f7cf0..2d415bf 100644 --- a/include/kernel/multiboot.h +++ b/include/kernel/multiboot.h @@ -1,3 +1,6 @@ +#ifndef _MULTIBOOT_H_ +#define _MULTIBOOT_H_ + #include <stdint.h> struct multiboot_aout_symbol_table_t @@ -38,6 +41,13 @@ struct vbe_info_t { uint16_t reserved2; } __attribute__((packed)); +struct multiboot_mod_t { + uint32_t mod_start; + uint32_t mod_end; + uint32_t mod_str; + uint32_t reserved; +} __attribute__((packed)); + struct multiboot_info_t { /* Multiboot info version number */ @@ -88,3 +98,5 @@ struct multiboot_info_t uint16_t vbe_interface_off; uint16_t vbe_interface_len; } __attribute__((packed)); + +#endif diff --git a/include/kernel/vfs.h b/include/kernel/vfs.h new file mode 100644 index 0000000..4977665 --- /dev/null +++ b/include/kernel/vfs.h @@ -0,0 +1,48 @@ +#include <stdint.h> + +#define VFS_DIR 0 +#define VFS_REG 1 +#define VFS_SPEC 2 + +#define VFS_TYPEMASK 0x3 + +struct vfs_node { + unsigned int flags; + char *name; + uint64_t file_len; + unsigned char *contents; + struct vfs_node *parent; + struct vfs_node *next; + struct vfs_node *child; +}; + +#define DT_BLK (1<<0) +#define DT_CHR (1<<1) +#define DT_DIR (1<<2) +#define DT_FIFO (1<<3) +#define DT_LNK (1<<4) +#define DT_REG (1<<5) +#define DT_SOCK (1<<6) +#define DT_UNKNOWN (1<<7) + +struct dirent { + unsigned char d_type; + char d_name[256]; +}; + +/* initializes an empty filesystem on the heap */ +struct vfs_node *vfs_init(void); + +/* creates a new, empty directory UNDER a directory node */ +int vfs_mkdir(struct vfs_node*, const char *name); + +/* creates a new, empty, regular file under a directory node */ +int vfs_creat(struct vfs_node*, const char *name); + +typedef struct DIR { + struct vfs_node *node; +} DIR; + +DIR *vfs_opendir(struct vfs_node*); + +struct dirent *vfs_readdir(DIR *dirp); diff --git a/include/string.h b/include/string.h index 05050a0..b829978 100644 --- a/include/string.h +++ b/include/string.h @@ -1,4 +1,5 @@ #include <stddef.h> -int strlen(const char*); +size_t strlen(const char*); void* memset(void*, int, size_t); void* memcpy(void*, void*, size_t); +char* strdup(const char*); diff --git a/kernel/heap.c b/kernel/heap.c index bb18fb4..bfe3302 100644 --- a/kernel/heap.c +++ b/kernel/heap.c @@ -44,3 +44,8 @@ void *kmalloc_ap(size_t sz, void **phys) { return kmalloc_int(sz, 1, phys); } + +void kmalloc_set_addr(uint32_t addr) +{ + kmalloc_addr = addr; +} diff --git a/kernel/main.c b/kernel/main.c index 540bdcc..e05eb99 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -6,6 +6,7 @@ #include "gfx.h" #include "gfx_font.h" #include "idt.h" +#include "initrd.h" #include "isr.h" #include "irq.h" #include "log.h" @@ -17,6 +18,7 @@ #include "fpu.h" #include "timer.h" #include "version.h" +#include "vfs.h" #include "vgatext.h" void gpf(struct regs_t *regs) @@ -104,6 +106,9 @@ bool boot(struct multiboot_info_t *hdr, uint32_t magic) { fpu_enable(); + /* load initrd if any, this will also prevent modules from being clobbered by kmalloc */ + initrd_init(hdr); + /* this should go to port e9, which is the Bochs debug port */ printf("Testing early I/O\n"); @@ -272,9 +277,37 @@ static void keyhandler(const struct ps2_keyevent *ev) } } +void fs_test(void) +{ + struct vfs_node *fs = vfs_init(); + vfs_mkdir(fs, "bin"); + vfs_mkdir(fs, "etc"); + vfs_mkdir(fs, "bin"); + vfs_creat(fs, "file1.txt"); + vfs_creat(fs, "file2.txt"); + vfs_creat(fs, "file3.txt"); + vfs_creat(fs, "file4.txt"); + vfs_creat(fs, "main.c"); + DIR *file = vfs_opendir(fs); + struct dirent *dir; + printf("=== File listing of / ===\n"); + do { + dir = vfs_readdir(file); + if(!dir) + break; + printf("%s", dir->d_name); + if(dir->d_type == DT_DIR) + putchar('/'); + putchar('\n'); + } while(dir); +} + void main(struct multiboot_info_t *hdr, uint32_t magic) { bool gfx_status = boot(hdr, magic); + + fs_test(); + gfx_set_foreground(0x80FF80); printf("Hello, world!\n"); gfx_set_foreground(GFX_WHITE); diff --git a/kernel/vfs.c b/kernel/vfs.c new file mode 100644 index 0000000..cc6152f --- /dev/null +++ b/kernel/vfs.c @@ -0,0 +1,91 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "heap.h" +#include "vfs.h" + +`static struct vfs_node *new_node(void) +{ + struct vfs_node *ret = kmalloc(sizeof(struct vfs_node)); + memset(ret, 0, sizeof(struct vfs_node)); + return ret; +} + +struct vfs_node *vfs_init(void) +{ + struct vfs_node *root = new_node(); + root->flags = VFS_DIR; + root->name = malloc(1); + root->name[0] = '\0'; + + return root; +} + +int vfs_mkdir(struct vfs_node *node, const char *name) +{ + if(!node) + return 0; + if((node->flags & VFS_TYPEMASK) != VFS_DIR) + return 0; + /* insert a new element at the beginning of the linked list of the directory's children */ + struct vfs_node *newdir = new_node(); + newdir->flags = VFS_DIR; + newdir->name = strdup(name); + newdir->parent = node; + newdir->next = node->child; + + node->child = newdir; + return 1; +} + +int vfs_creat(struct vfs_node *node, const char *name) +{ + if(!node) + return 0; + if((node->flags & VFS_TYPEMASK) != VFS_DIR) + return 0; + struct vfs_node *newfile = new_node(); + newfile->flags = VFS_REG; + newfile->name = strdup(name); + newfile->parent = node; + newfile->next = node->child; + + node->child = newfile; + return 1; +} + +DIR *vfs_opendir(struct vfs_node *node) +{ + DIR *dirp = malloc(sizeof(DIR)); + dirp->node = node->child; + return dirp; +} + +struct dirent *vfs_readdir(DIR *dirp) +{ + if(!dirp->node) + return NULL; + static struct dirent ret; + memcpy(ret.d_name, dirp->node->name, MIN(strlen(dirp->node->name)+1, sizeof(ret.d_name))); + switch(dirp->node->flags & VFS_TYPEMASK) + { + case VFS_DIR: + ret.d_type = DT_DIR; + break; + case VFS_REG: + ret.d_type = DT_REG; + break; + /* fall through */ + case VFS_SPEC: + default: + ret.d_type = DT_UNKNOWN; + } + dirp->node = dirp->node->next; + return &ret; +} + +char *vfs_path(struct vfs_node *node) +{ + struct vfs_node * +} diff --git a/libc/string.c b/libc/string.c index 11d398f..290aec4 100644 --- a/libc/string.c +++ b/libc/string.c @@ -2,7 +2,7 @@ #include <stddef.h> #include "string.h" -int strlen(const char *str) +size_t strlen(const char *str) { int len = 0; while(*str++) @@ -25,3 +25,23 @@ void* memcpy(void *dest, void *src, size_t sz) *(char*)dest++ = *(char*)src++; return dest; } + +char* strdup(const char *str) +{ + int len = strlen(str); + /* allocate room for the string and it's NULL terminator */ + char *ret = malloc(len + 1); + memcpy(ret, str, len + 1); + return ret; +} + +char* strncat(char *dest, const char *src, size_t n) +{ + /* save this for the return */ + char *d = dest; + while(*dest++); + while(n && (*dest++ = *src++)) --n; + if(*dest) + *dest = '\0'; + return d; +} |