aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/core/kmain.c13
-rw-r--r--src/kernel/include/nullfs.h1
-rw-r--r--src/kernel/include/vfs.h1
-rw-r--r--src/kernel/user/nullfs.c115
-rw-r--r--src/kernel/user/vfs.c11
5 files changed, 129 insertions, 12 deletions
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index e5012b3..9b1cd12 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -271,9 +271,20 @@ void kernel_init_stage2(void* data) {
(void*)mods[i].mod_start,
mods[i].mod_end - mods[i].mod_start,
false,
- FM_READ));
+ FM_READ | FM_MMAP));
}
+ // TEST : read /cmdline
+ dbg_printf("Trying to read /cmdline... ");
+ fs_handle_t *f = fs_open(devfs_fs, "/cmdline", FM_READ);
+ ASSERT(f != 0);
+ char buf[256];
+ size_t l = file_read(f, 0, 255, buf);
+ ASSERT(l > 0);
+ buf[l] = 0;
+ unref_file(f);
+ dbg_printf("got '%s'.\n", buf);
+
//TODO :
// - (OK) populate devfs with information regarding kernel command line & modules
// - create user process with init module provided on command line
diff --git a/src/kernel/include/nullfs.h b/src/kernel/include/nullfs.h
index 045cc93..cfca023 100644
--- a/src/kernel/include/nullfs.h
+++ b/src/kernel/include/nullfs.h
@@ -12,7 +12,6 @@ typedef struct {
size_t (*read)(void* f, size_t offset, size_t len, char* buf);
size_t (*write)(void* f, size_t offset, size_t len, const char* buf);
void (*close)(void* f);
- void (*delete)(void* f);
void (*dispose)(void* f);
} nullfs_node_ops_t;
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index 5f7a0d8..0a6a955 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -31,6 +31,7 @@ typedef struct {
} fs_handle_ops_t;
typedef struct fs_handle {
+ struct fs *fs;
int refs;
fs_handle_ops_t *ops;
void* data;
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index 7aa2d24..5c6be94 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -116,11 +116,6 @@ void nullfs_i_shutdown(void* fs) {
free(f);
}
-bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, bool copy, int ok_modes) {
- // TODO
- return false;
-}
-
// Nullfs operations
bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) {
@@ -149,8 +144,13 @@ bool nullfs_i_delete(void* fs, const char* file) {
nullfs_t *f = (nullfs_t*)fs;
if (!f->can_delete) return false;
- // TODO
- return false;
+
+ nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file));
+ if (x == 0) return false;
+
+ hashtbl_remove(f->items, file);
+ nullfs_i_free_item(x);
+ return true;
}
size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf) {
@@ -171,4 +171,105 @@ void nullfs_i_close(void* f) {
free(h);
}
+// ====================================================== //
+// THE FUNCTIONS FOR HAVING RAM FILES (nullfs as ramdisk) //
+// ====================================================== //
+
+static void* nullfs_i_ram_open(void* f, int mode, fs_handle_t *h);
+static size_t nullfs_i_ram_read(void* f, size_t offset, size_t len, char* buf);
+static size_t nullfs_i_ram_write(void* f, size_t offset, size_t len, const char* buf);
+static void nullfs_i_ram_dispose(void* f);
+
+static nullfs_node_ops_t nullfs_ram_ops = {
+ .open = nullfs_i_ram_open,
+ .read = nullfs_i_ram_read,
+ .write = nullfs_i_ram_write,
+ .close = 0,
+ .dispose = nullfs_i_ram_dispose
+};
+
+typedef struct {
+ void* data;
+ bool data_owned;
+ size_t size;
+ int ok_modes;
+} nullfs_ram_file_t;
+
+bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, bool copy, int ok_modes) {
+ nullfs_ram_file_t *x = (nullfs_ram_file_t*)malloc(sizeof(nullfs_ram_file_t));
+ if (x == 0) return false;
+
+ if (copy) {
+ x->data = malloc(init_sz);
+ if (x->data == 0) {
+ free(x);
+ return false;
+ }
+ memcpy(x->data, data, init_sz);
+ x->data_owned = true;
+ } else {
+ x->data = data;
+ x->data_owned = false;
+ }
+ x->size = init_sz;
+ x->ok_modes = ok_modes;
+
+ if (!nullfs_add(f, name, x, &nullfs_ram_ops)) {
+ if (x->data_owned) free(x->data);
+ free(x);
+ return false;
+ }
+ return true;
+}
+
+void* nullfs_i_ram_open(void* fi, int mode, fs_handle_t *h) {
+ nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi;
+
+ if (mode & ~f->ok_modes) {
+ return 0;
+ }
+
+ h->mode = mode;
+ return fi;
+}
+
+size_t nullfs_i_ram_read(void* fi, size_t offset, size_t len, char* buf) {
+ nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi;
+
+ if (offset >= f->size) return 0;
+ if (offset + len > f->size) len = f->size - offset;
+
+ memcpy(buf, f->data + offset, len);
+ return len;
+}
+
+size_t nullfs_i_ram_write(void* fi, size_t offset, size_t len, const char* buf) {
+ nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi;
+
+ if (offset + len > f->size) {
+ // resize buffer (zero out new portion)
+ void* new_buffer = malloc(offset + len);
+ if (new_buffer == 0) return 0;
+
+ memcpy(new_buffer, f->data, f->size);
+ if (offset > f->size)
+ memset(new_buffer + f->size, 0, offset - f->size);
+ free(f->data);
+ f->data = new_buffer;
+ f->size = offset + len;
+ }
+
+ memcpy(f->data + offset, buf, len);
+ return len;
+}
+
+void nullfs_i_ram_dispose(void* fi) {
+ nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi;
+
+ if (f->data_owned) free(f->data);
+ free(f);
+}
+
+
+
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index 83f1377..32fcb03 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -94,6 +94,8 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
if (fs->ops->open(fs->data, file, mode, h)) {
h->refs = 1;
+ h->fs = fs;
+ ref_fs(fs);
return h;
} else {
free(h);
@@ -105,9 +107,10 @@ void ref_file(fs_handle_t *file) {
file->refs++;
}
-void unrefe_file(fs_handle_t *file) {
+void unref_file(fs_handle_t *file) {
file->refs--;
if (file->refs == 0) {
+ unref_fs(file->fs);
file->ops->close(file->data);
free(file);
}
@@ -116,13 +119,15 @@ void unrefe_file(fs_handle_t *file) {
size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) {
if (!(f->mode && FM_READ)) return 0;
- return f->ops->read && f->ops->read(f->data, offset, len, buf);
+ if (f->ops->read == 0) return 0;
+ return f->ops->read(f->data, offset, len, buf);
}
size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) {
if (!(f->mode && FM_WRITE)) return 0;
- return f->ops->write && f->ops->write(f->data, offset, len, buf);
+ if (f->ops->write == 0) return 0;
+ return f->ops->write(f->data, offset, len, buf);
}
int file_get_mode(fs_handle_t *f) {