aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 16:09:04 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 16:09:04 +0100
commitf2c07854463763ed82e00857ae6d9bcbc924e42c (patch)
treeddeac108511835400cfba6525f7e9ca865afb1e4 /src
parent7e908dabaaf6c67ef5000406a0bb3a6a29beca01 (diff)
downloadkogata-f2c07854463763ed82e00857ae6d9bcbc924e42c.tar.gz
kogata-f2c07854463763ed82e00857ae6d9bcbc924e42c.zip
Make way for ISO 9660 driver.
Diffstat (limited to 'src')
-rw-r--r--src/common/include/string.h1
-rw-r--r--src/common/libc/string.c14
-rw-r--r--src/kernel/Makefile3
-rw-r--r--src/kernel/core/kmain.c127
-rw-r--r--src/kernel/fs/iso9660.c10
-rw-r--r--src/kernel/include/fs/iso9660.h5
6 files changed, 149 insertions, 11 deletions
diff --git a/src/common/include/string.h b/src/common/include/string.h
index 686382d..e655f2c 100644
--- a/src/common/include/string.h
+++ b/src/common/include/string.h
@@ -18,5 +18,6 @@ int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
char *strdup(const char* str);
+char *strndup(const char* str, size_t count);
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/common/libc/string.c b/src/common/libc/string.c
index dfc93e6..e5f7a53 100644
--- a/src/common/libc/string.c
+++ b/src/common/libc/string.c
@@ -114,7 +114,7 @@ void *memset(void *dest, int val, size_t count) {
}
char *strdup(const char* str) {
- int len = strlen(str) + 1;
+ size_t len = strlen(str) + 1;
char* ret = (char*)malloc(len);
if (ret == 0) return 0;
@@ -123,4 +123,16 @@ char *strdup(const char* str) {
return ret;
}
+char *strndup(const char* str, size_t count) {
+ size_t len = strlen(str);
+ if (count < len) len = count;
+
+ char* ret = (char*)malloc(len + 1);
+ if (ret == 0) return 0;
+
+ memcpy(ret, str, len);
+ ret[len] = 0;
+ return ret;
+}
+
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index a4e0edb..d6b973e 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -3,7 +3,8 @@ OBJ = core/loader.o core/dbglog.o \
core/gdt.o core/idt.o core/interrupt.o core/context_switch.o core/thread.o \
core/frame.o core/paging.o core/region.o core/kmalloc.o core/worker.o \
user/vfs.o user/nullfs.o user/process.o user/elf.o user/syscall.o \
- dev/pci.o dev/pciide.o
+ dev/pci.o dev/pciide.o \
+ fs/iso9660.o
LIB = ../common/libc/libc.lib ../common/libkogata/libkogata.lib ../common/libalgo/libalgo.lib
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index 9bf9d0d..eb5eb16 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -25,6 +25,7 @@
#include <dev/pci.h>
#include <dev/pciide.h>
+#include <fs/iso9660.h>
// ===== FOR TESTS =====
#define TEST_PLACEHOLDER_AFTER_IDT
@@ -48,6 +49,12 @@ void breakpoint_handler(registers_t *regs) {
}
void kernel_init_stage2(void* data);
+
+btree_t *parse_cmdline(const char* x);
+fs_t *setup_iofs(multiboot_info_t *mbd);
+fs_t *setup_rootfs(btree_t *cmdline, fs_t *iofs);
+void launch_init(btree_t *cmdline, fs_t *iofs, fs_t *rootfs);
+
void kmain(multiboot_info_t *mbd, int32_t mb_magic) {
// used for allocation of data structures before malloc is set up
// a pointer to this pointer is passed to the functions that might have
@@ -131,13 +138,69 @@ void kernel_init_stage2(void* data) {
// Create iofs
register_nullfs_driver();
- fs_t *iofs = make_fs("nullfs", 0, "");
- ASSERT(iofs != 0);
+ fs_t *iofs = setup_iofs(mbd);
+
+ TEST_PLACEHOLDER_AFTER_DEVFS;
// Scan for devices
pci_setup();
pciide_detect(iofs);
+ // Register FS drivers
+ register_iso9660_driver();
+
+ // Parse command line
+ btree_t *cmdline = parse_cmdline((const char*)mbd->cmdline);
+
+ fs_t *rootfs = setup_rootfs(cmdline, iofs);
+
+ launch_init(cmdline, iofs, rootfs);
+
+ // We are done here
+ dbg_printf("Reached kmain end! I'll just stop here and do nothing.\n");
+}
+
+btree_t *parse_cmdline(const char* x) {
+ btree_t *ret = create_btree(str_key_cmp_fun, free_key_val);
+ ASSERT(ret != 0);
+
+ x = strchr(x, ' ');
+ if (x == 0) return ret;
+
+ while ((*x) != 0) {
+ while (*x == ' ') x++;
+
+ char* eq = strchr(x, '=');
+ char* sep = strchr(x, ' ');
+ if (sep == 0) {
+ if (eq == 0) {
+ btree_add(ret, strdup(x), strdup(x));
+ } else {
+ btree_add(ret, strndup(x, eq - x), strdup(eq + 1));
+ }
+ break;
+ } else {
+ if (eq == 0 || eq > sep) {
+ btree_add(ret, strndup(x, sep - x), strndup(x, sep - x));
+ } else {
+ btree_add(ret, strndup(x, eq - x), strndup(eq + 1, sep - eq - 1));
+ }
+ x = sep + 1;
+ }
+ }
+
+ void iter(void* a, void* b) {
+ dbg_printf(" '%s' -> '%s'\n", a, b);
+ }
+ btree_iter(ret, iter);
+
+ return ret;
+}
+
+fs_t *setup_iofs(multiboot_info_t *mbd) {
+ fs_t *iofs = make_fs("nullfs", 0, "");
+ ASSERT(iofs != 0);
+
// Add kernel command line to iofs
{
dbg_printf("Kernel command line: '%s'\n", (char*)mbd->cmdline);
@@ -169,11 +232,58 @@ void kernel_init_stage2(void* data) {
len, false, FM_READ));
}
- TEST_PLACEHOLDER_AFTER_DEVFS;
+ return iofs;
+}
+
+fs_t *setup_rootfs(btree_t *cmdline, fs_t *iofs) {
+ char* root = (char*)btree_find(cmdline, "root");
+ char* root_opts = (char*)btree_find(cmdline, "root_opts");
+ if (root == 0) PANIC("No root device specified on kernel command line.");
+
+ char* sep = strchr(root, ':');
+ if (sep != 0) {
+ ASSERT(root[0] == 'i' && root[1] == 'o' && root[2] == ':');
+ root = root + 3; // ignore prefix, we are always on iofs
+ }
+
+ dbg_printf("Trying to open root device %s... ", root);
+ fs_handle_t *root_dev = fs_open(iofs, root, FM_READ | FM_WRITE | FM_IOCTL);
+ if (root_dev == 0) {
+ dbg_printf("read-only... ");
+ root_dev = fs_open(iofs, root, FM_READ | FM_WRITE | FM_IOCTL);
+ }
+ dbg_printf("\n");
+ if (root_dev == 0) PANIC("Could not open root device.");
+
+ fs_t *rootfs = make_fs(0, root_dev, (root_opts ? root_opts : ""));
+ if (rootfs == 0) PANIC("Could not mount root device.");
+
+ return rootfs;
+}
+
+void launch_init(btree_t *cmdline, fs_t *iofs, fs_t *rootfs) {
+ fs_t *init_fs = rootfs;
+ char* init_file = btree_find(cmdline, "init");
+ if (init_file != 0) PANIC("No init specified on kernel command line.");
+
+ dbg_printf("Launching init %s...\n", init_file);
+
+ char* sep = strchr(init_file, ':');
+ if (sep != 0) {
+ if (strncmp(init_file, "io:", 3) == 0) {
+ init_fs = iofs;
+ init_file = init_file + 3;
+ } else if (strncmp(init_file, "root:", 5) == 0) {
+ init_fs = rootfs;
+ init_file = init_file + 5;
+ } else {
+ PANIC("Invalid init file specification.");
+ }
+ }
// Launch INIT
- fs_handle_t *init_bin = fs_open(iofs, "/mod/init.bin", FM_READ);
- if (init_bin == 0) PANIC("No init.bin module provided!");
+ fs_handle_t *init_bin = fs_open(init_fs, init_file, FM_READ);
+ if (init_bin == 0) PANIC("Could not open init file.");
if (!is_elf(init_bin)) PANIC("init.bin is not valid ELF32 binary");
process_t *init_p = new_process(0);
@@ -181,16 +291,15 @@ void kernel_init_stage2(void* data) {
bool add_iofs_ok = proc_add_fs(init_p, iofs, "io");
ASSERT(add_iofs_ok);
+ bool add_rootfs_ok = proc_add_fs(init_p, rootfs, "root");
+ ASSERT(add_rootfs_ok);
proc_entry_t *e = elf_load(init_bin, init_p);
- if (e == 0) PANIC("Could not load ELF file init.bin");
+ if (e == 0) PANIC("Could not load init ELF file");
unref_file(init_bin);
start_process(init_p, e);
-
- // We are done here
- dbg_printf("Reached kmain end! I'll just stop here and do nothing.\n");
}
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c
new file mode 100644
index 0000000..8780c32
--- /dev/null
+++ b/src/kernel/fs/iso9660.c
@@ -0,0 +1,10 @@
+#include <debug.h>
+
+#include <fs/iso9660.h>
+
+void register_iso9660_driver() {
+ dbg_printf("Not implemented ISO9660.\n");
+ // TODO
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/include/fs/iso9660.h b/src/kernel/include/fs/iso9660.h
new file mode 100644
index 0000000..227a8da
--- /dev/null
+++ b/src/kernel/include/fs/iso9660.h
@@ -0,0 +1,5 @@
+#pragma once
+
+void register_iso9660_driver();
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/