aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-03-02 21:37:44 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-03-02 21:37:44 -0500
commita0721b4caa79b81e021678089fde0b8467daa1cd (patch)
tree56af15c29704cc4c6738345ccd6c9db3782fd8d1
parent46e94578765d3d2f03b83421d752e5dfc3e56d34 (diff)
downloadkappa-a0721b4caa79b81e021678089fde0b8467daa1cd.zip
kappa-a0721b4caa79b81e021678089fde0b8467daa1cd.tar.gz
kappa-a0721b4caa79b81e021678089fde0b8467daa1cd.tar.bz2
kappa-a0721b4caa79b81e021678089fde0b8467daa1cd.tar.xz
Virtual filesystem WIP!HEADmaster
-rw-r--r--Makefile1
-rw-r--r--OBJ2
-rw-r--r--cdrom/grub.cfg1
-rw-r--r--docs/FILESYSTEM34
-rw-r--r--include/arch/i686/drivers/ps2kbd.h2
-rw-r--r--include/kernel/heap.h2
-rw-r--r--include/kernel/multiboot.h12
-rw-r--r--include/kernel/vfs.h48
-rw-r--r--include/string.h3
-rw-r--r--kernel/heap.c5
-rw-r--r--kernel/main.c33
-rw-r--r--kernel/vfs.c91
-rw-r--r--libc/string.c22
13 files changed, 254 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index f2a11a7..0534d6a 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/OBJ b/OBJ
index ce6fff4..0470450 100644
--- a/OBJ
+++ b/OBJ
@@ -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;
+}