aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--menu_cdrom.lst8
-rw-r--r--src/common/libc/string.c1
-rw-r--r--src/kernel/core/kmain.c8
-rw-r--r--src/kernel/fs/iso9660.c12
-rw-r--r--src/kernel/include/vfs.h3
-rw-r--r--src/kernel/user/nullfs.c9
-rw-r--r--src/kernel/user/vfs.c86
-rw-r--r--src/tests/utests/fs1/test.c3
-rwxr-xr-xsrc/tests/utests/run_qemu_test.sh2
9 files changed, 72 insertions, 60 deletions
diff --git a/menu_cdrom.lst b/menu_cdrom.lst
index cc9f50d..f055427 100644
--- a/menu_cdrom.lst
+++ b/menu_cdrom.lst
@@ -1,5 +1,11 @@
timeout 10
+default 1
-title Macroscope
+
+title kogata OS
kernel /kernel.bin root=io:/atapi0 init=root:/init.bin
+title kogata OS without root
+kernel /kernel.bin init=io:/mod/init.bin
+module /init.bin
+
diff --git a/src/common/libc/string.c b/src/common/libc/string.c
index e5f7a53..82c290f 100644
--- a/src/common/libc/string.c
+++ b/src/common/libc/string.c
@@ -64,6 +64,7 @@ int strncmp(const char *s1, const char *s2, size_t n) {
s2++;
i++;
}
+ if (i == n) return 0;
return (*(unsigned char*)s1 - *(unsigned char*)s2);
}
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index eb5eb16..7bdf27d 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -152,7 +152,8 @@ void kernel_init_stage2(void* data) {
// Parse command line
btree_t *cmdline = parse_cmdline((const char*)mbd->cmdline);
- fs_t *rootfs = setup_rootfs(cmdline, iofs);
+ fs_t *rootfs = 0;
+ if (btree_find(cmdline, "root") != 0) rootfs = setup_rootfs(cmdline, iofs);
launch_init(cmdline, iofs, rootfs);
@@ -264,7 +265,7 @@ fs_t *setup_rootfs(btree_t *cmdline, fs_t *iofs) {
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.");
+ if (init_file == 0) PANIC("No init specified on kernel command line.");
dbg_printf("Launching init %s...\n", init_file);
@@ -276,10 +277,9 @@ void launch_init(btree_t *cmdline, fs_t *iofs, fs_t *rootfs) {
} else if (strncmp(init_file, "root:", 5) == 0) {
init_fs = rootfs;
init_file = init_file + 5;
- } else {
- PANIC("Invalid init file specification.");
}
}
+ if (init_fs == 0) PANIC("Invalid file system specification for init file.");
// Launch INIT
fs_handle_t *init_bin = fs_open(init_fs, init_file, FM_READ);
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c
index 60e9a81..b17a975 100644
--- a/src/kernel/fs/iso9660.c
+++ b/src/kernel/fs/iso9660.c
@@ -3,16 +3,14 @@
#include <fs/iso9660.h>
static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t);
-static bool iso9660_detect(fs_handle_t *source);
static fs_driver_ops_t iso9660_driver_ops = {
.make = iso9660_make,
- .detect = iso9660_detect,
};
void register_iso9660_driver() {
- ASSERT(sizeof(iso9660_vdt_entry_t) == 2048);
- ASSERT(sizeof(iso9660_dr_t) == 34);
+ //ASSERT(sizeof(iso9660_vdt_entry_t) == 2048);
+ //ASSERT(sizeof(iso9660_dr_t) == 34);
register_fs_driver("iso9660", &iso9660_driver_ops);
}
@@ -21,7 +19,7 @@ void register_iso9660_driver() {
// FILESYSTEM DETECTION AND SETUP //
// ============================== //
-static bool iso9660_detect(fs_handle_t *source) {
+static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t) {
stat_t st;
if (!file_stat(source, &st)) return false;
if ((st.type & FT_BLOCKDEV) != 0) return false;
@@ -32,8 +30,4 @@ static bool iso9660_detect(fs_handle_t *source) {
return false; // TODO
}
-static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t) {
- return false; // TODO
-}
-
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index 82b02f4..0890663 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -128,7 +128,7 @@ typedef struct fs {
fs_ops_t *ops;
fs_ptr data;
// Filled by both according to what is specified for fs_node_t
- fs_node_t root;
+ fs_node_t *root;
} fs_t;
// -------------------------------------------
@@ -136,7 +136,6 @@ typedef struct fs {
typedef struct {
bool (*make)(fs_handle_t *source, const char* opts, fs_t *d);
- bool (*detect)(fs_handle_t *source);
} fs_driver_ops_t;
// -------------------------------------------
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index a925ab5..a44e4b3 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -37,7 +37,6 @@ static void nullfs_fh_close(fs_handle_ptr f);
// VTables that go with it
static fs_driver_ops_t nullfs_driver_ops = {
.make = nullfs_fs_make,
- .detect = 0,
};
static fs_ops_t nullfs_ops = {
@@ -134,6 +133,8 @@ void register_nullfs_driver() {
}
bool nullfs_fs_make(fs_handle_t *source, const char* opts, fs_t *fs_s) {
+ if (source != 0) return false;
+
nullfs_t *fs = (nullfs_t*)malloc(sizeof(nullfs_t));
if (fs == 0) return false;
@@ -159,8 +160,8 @@ bool nullfs_fs_make(fs_handle_t *source, const char* opts, fs_t *fs_s) {
fs_s->ops = &nullfs_ops;
fs_s->data = fs;
- fs_s->root.ops = &nullfs_d_ops;
- fs_s->root.data = root;
+ fs_s->root->ops = &nullfs_d_ops;
+ fs_s->root->data = root;
return true;
}
@@ -173,7 +174,7 @@ void nullfs_fs_shutdown(fs_ptr fs) {
bool nullfs_add_node(fs_t *fs, const char* name, fs_node_ptr data, fs_node_ops_t *ops) {
char file_name[DIR_MAX];
- fs_node_t *n = fs_walk_path_except_last(&fs->root, name, file_name);
+ fs_node_t *n = fs_walk_path_except_last(fs->root, name, file_name);
if (n == 0) return false;
if (n->ops != &nullfs_d_ops) return false;
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index c20caa0..1c841f7 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -29,31 +29,35 @@ void register_fs_driver(const char* name, fs_driver_ops_t *ops) {
// ================================== //
fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) {
- // Look for driver
- fs_driver_t *d = 0;
- for(fs_driver_t *i = drivers; i != 0; i = i->next) {
- if (drv_name != 0 && strcmp(i->name, drv_name) == 0) d = i;
- if (drv_name == 0 && source != 0 && i->ops->detect && i->ops->detect(source)) d = i;
- if (d != 0) break;
- }
- if (d == 0) return 0; // driver not found
-
// Open file system
fs_t *fs = (fs_t*)malloc(sizeof(fs_t));
- if (fs == 0) return 0;
+ if (fs == 0) goto fail;
+
+ fs->root = (fs_node_t*)malloc(sizeof(fs_node_t));
+ if (fs->root == 0) goto fail;
fs->refs = 1;
- fs->root.refs = 1; // root node is never disposed of (done by fs->shutdown)
- fs->root.fs = fs;
- fs->root.parent = 0;
- fs->root.children = 0;
+ fs->root->refs = 1;
+ fs->root->fs = fs;
+ fs->root->parent = 0;
+ fs->root->children = 0;
- if (d->ops->make(source, opts, fs)) {
- return fs;
- } else {
- free(fs);
- return 0;
+ // Look for driver
+ for(fs_driver_t *i = drivers; i != 0; i = i->next) {
+ if ((drv_name != 0 && strcmp(i->name, drv_name) == 0) || (drv_name == 0 && source != 0)) {
+ if (i->ops->make(source, opts, fs)) {
+ return fs;
+ } else {
+ goto fail;
+ }
+ }
}
+
+
+fail:
+ if (fs && fs->root) free(fs->root);
+ if (fs) free(fs);
+ return 0;
}
bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts) {
@@ -67,8 +71,7 @@ void ref_fs(fs_t *fs) {
void unref_fs(fs_t *fs) {
fs->refs--;
if (fs->refs == 0) {
- // don't unref root node, don't call dispose on it
- // (done by fs->shutdown)
+ unref_fs_node(fs->root);
fs->ops->shutdown(fs->data);
free(fs);
}
@@ -87,19 +90,26 @@ void unref_fs_node(fs_node_t *n) {
mutex_lock(&n->lock);
n->refs--;
if (n->refs == 0) {
- ASSERT(n != &n->fs->root);
- ASSERT(n->parent != 0);
- ASSERT(n->name != 0);
+ if (n != n->fs->root) {
+ ASSERT(n->parent != 0);
+ ASSERT(n->name != 0);
- mutex_lock(&n->parent->lock);
- hashtbl_remove(n->parent->children, n->name);
- if (n->ops->dispose) n->ops->dispose(n->data);
- mutex_unlock(&n->parent->lock);
+ mutex_lock(&n->parent->lock);
+ hashtbl_remove(n->parent->children, n->name);
+ if (n->ops->dispose) n->ops->dispose(n->data);
+ mutex_unlock(&n->parent->lock);
- unref_fs_node(n->parent);
- unref_fs(n->fs);
+ unref_fs_node(n->parent);
+ unref_fs(n->fs);
+ } else {
+ ASSERT(n->fs->refs == 0);
+ if (n->ops->dispose) n->ops->dispose(n->data);
+ }
- if (n->children != 0) delete_hashtbl(n->children);
+ if (n->children != 0) {
+ ASSERT(hashtbl_count(n->children) == 0);
+ delete_hashtbl(n->children);
+ }
free(n->name);
free(n);
} else {
@@ -251,7 +261,7 @@ fs_node_t* fs_walk_path_except_last(fs_node_t* from, const char* path, char* las
bool fs_create(fs_t *fs, const char* file, int type) {
char name[DIR_MAX];
- fs_node_t *n = fs_walk_path_except_last(&fs->root, file, name);
+ fs_node_t *n = fs_walk_path_except_last(fs->root, file, name);
if (n == 0) return false;
mutex_lock(&n->lock);
@@ -265,7 +275,7 @@ bool fs_create(fs_t *fs, const char* file, int type) {
bool fs_delete(fs_t *fs, const char* file) {
char name[DIR_MAX];
- fs_node_t* n = fs_walk_path_except_last(&fs->root, file, name);
+ fs_node_t* n = fs_walk_path_except_last(fs->root, file, name);
if (n == 0) return false;
if (n->children != 0) {
@@ -283,11 +293,11 @@ bool fs_delete(fs_t *fs, const char* file) {
bool fs_move(fs_t *fs, const char* from, const char* to) {
char old_name[DIR_MAX];
- fs_node_t *old_parent = fs_walk_path_except_last(&fs->root, from, old_name);
+ fs_node_t *old_parent = fs_walk_path_except_last(fs->root, from, old_name);
if (old_parent == 0) return false;
char new_name[DIR_MAX];
- fs_node_t *new_parent = fs_walk_path_except_last(&fs->root, to, new_name);
+ fs_node_t *new_parent = fs_walk_path_except_last(fs->root, to, new_name);
if (new_parent == 0) {
unref_fs_node(old_parent);
return false;
@@ -343,7 +353,7 @@ end:
}
bool fs_stat(fs_t *fs, const char* file, stat_t *st) {
- fs_node_t* n = fs_walk_path(&fs->root, file);
+ fs_node_t* n = fs_walk_path(fs->root, file);
if (n == 0) return false;
mutex_lock(&n->lock);
@@ -359,10 +369,10 @@ bool fs_stat(fs_t *fs, const char* file, stat_t *st) {
// =================== //
fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
- fs_node_t *n = fs_walk_path(&fs->root, file);
+ fs_node_t *n = fs_walk_path(fs->root, file);
if (n == 0 && (mode & FM_CREATE)) {
if (fs_create(fs, file, FT_REGULAR)) {
- n = fs_walk_path(&fs->root, file);
+ n = fs_walk_path(fs->root, file);
}
}
if (n == 0) return 0;
diff --git a/src/tests/utests/fs1/test.c b/src/tests/utests/fs1/test.c
index 247373d..7d6afd6 100644
--- a/src/tests/utests/fs1/test.c
+++ b/src/tests/utests/fs1/test.c
@@ -8,8 +8,9 @@
int main(int argc, char **argv) {
dbg_print("Hello, world! from user process.\n");
- fd_t f = open("dev:/", FM_READDIR);
+ fd_t f = open("io:/", FM_READDIR);
dbg_printf("openned /: %d\n", f);
+ ASSERT(f != 0);
dirent_t x;
while (readdir(f, &x)) {
dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
diff --git a/src/tests/utests/run_qemu_test.sh b/src/tests/utests/run_qemu_test.sh
index 68cf498..ea5166e 100755
--- a/src/tests/utests/run_qemu_test.sh
+++ b/src/tests/utests/run_qemu_test.sh
@@ -9,7 +9,7 @@ if [ $1 = 'watchdog' ]; then
exit 0
fi
-(qemu-system-i386 -kernel ../../../kernel/kernel.bin -initrd init.bin -serial stdio -m 16 -display none & echo $! >pid &
+(qemu-system-i386 -kernel ../../../kernel/kernel.bin -append 'init=io:/mod/init.bin' -initrd init.bin -serial stdio -m 16 -display none & echo $! >pid &
$0 watchdog) \
| tee >(grep -m 1 "TEST-" >result; kill -INT `cat pid`; kill -TERM `cat pid2`) \