diff --git a/src/user/srv.init/j6romfs.cpp b/src/user/srv.init/j6romfs.cpp index 45020c7..3a9ef52 100644 --- a/src/user/srv.init/j6romfs.cpp +++ b/src/user/srv.init/j6romfs.cpp @@ -1,7 +1,9 @@ #include #include #include + #include +#include #include "j6romfs.h" @@ -37,31 +39,13 @@ fs::fs(util::const_buffer data) : util::const_buffer fs::load_simple(char const *path) const { - if (!path) + const inode *in = lookup_inode(path); + if (!in || in->type != inode_type::file) return {0, 0}; - char element [buf_size]; - inode const *in = m_root; - - while (*path) { - path = copy_path_element(path, element); - in = lookup_inode_in_dir(in, element); - - if (!in) { - // entry was not found - break; - } else if (*path && in->type == inode_type::file) { - // a directory was expected - break; - } else if (in->type == inode_type::file) { - // load the file - uint8_t *data = new uint8_t [in->size]; - size_t total = load_inode_data(in, util::buffer::from(data, in->size)); - return util::buffer::from(data, total); - } - } - - return {0, 0}; + uint8_t *data = new uint8_t [in->size]; + size_t total = load_inode_data(in, util::buffer::from(data, in->size)); + return util::buffer::from(data, total); } size_t @@ -80,10 +64,43 @@ fs::load_inode_data(const inode *in, util::buffer dest) const size_t decom = ZSTD_decompress(dest.pointer, dest.count, src.pointer, in->compressed); - assert(!ZSTD_isError(decom) && "Error decompressing"); + if (ZSTD_isError(decom)) { + ZSTD_ErrorCode err = ZSTD_getErrorCode(decom); + const char *name = ZSTD_getErrorString(err); + assert(!name); + } + return decom; } +const inode * +fs::lookup_inode(const char *path) const +{ + if (!path) + return nullptr; + + char element [buf_size]; + inode const *in = m_root; + + while (*path) { + path = copy_path_element(path, element); + in = lookup_inode_in_dir(in, element); + + if (!in) { + // entry was not found + break; + } else if (!*path) { + // found it + return in; + } else if (*path && in->type == inode_type::file) { + // a directory was expected + break; + } + } + + return nullptr; +} + const inode * fs::lookup_inode_in_dir(const inode *dir, const char *name) const { diff --git a/src/user/srv.init/j6romfs.h b/src/user/srv.init/j6romfs.h index 3b4b213..a2c68e1 100644 --- a/src/user/srv.init/j6romfs.h +++ b/src/user/srv.init/j6romfs.h @@ -50,9 +50,36 @@ public: fs(util::const_buffer data); util::const_buffer load_simple(char const *path) const; + size_t load_inode_data(const inode *in, util::buffer dest) const; + + template + size_t for_each(const char *root, callback &&cb) const + { + const inode *in = lookup_inode(root); + if (!in || in->type != inode_type::directory) + return 0; + + uint8_t *dir_data = new uint8_t [in->size]; + load_inode_data(in, util::buffer::from(dir_data, in->size)); + const dirent *entries = reinterpret_cast(dir_data); + + size_t i = 0, max = in->size / sizeof(dirent); + for (; i < max; ++i) { + const dirent &e = entries[i]; + const char *name = reinterpret_cast(dir_data + e.name_offset); + + cb(&m_inodes[e.inode], name); + + size_t new_max = e.name_offset / sizeof(dirent); + if (new_max < max) max = new_max; + } + + delete [] dir_data; + return i; + } private: - size_t load_inode_data(const inode *in, util::buffer dest) const; + const inode * lookup_inode(const char *path) const; const inode * lookup_inode_in_dir(const inode *in, const char *name) const; util::const_buffer m_data; diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index e2b7ef9..cb5549d 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -141,7 +141,6 @@ load_program( return false; } - delete [] reinterpret_cast(data.pointer); return true; } diff --git a/src/user/srv.init/main.cpp b/src/user/srv.init/main.cpp index d2f04cc..6f014f3 100644 --- a/src/user/srv.init/main.cpp +++ b/src/user/srv.init/main.cpp @@ -25,24 +25,6 @@ uintptr_t _arg_modules_phys; // This gets filled in in _start extern j6_handle_t __handle_self; -util::const_buffer -load_driver_for(const char *name, const j6romfs::fs &initrd) -{ - char driver[256]; - snprintf(driver, sizeof(driver), "/jsix/drivers/drv.%s.elf", name); - - return initrd.load_simple(driver); -} - -util::const_buffer -load_service(const char *name, const j6romfs::fs &initrd) -{ - char service[256]; - snprintf(service, sizeof(service), "/jsix/services/srv.%s.elf", name); - - return initrd.load_simple(service); -} - int main(int argc, const char **argv) { @@ -113,23 +95,45 @@ main(int argc, const char **argv) // have driver_source objects.. j6romfs::fs initrd {initrd_module->data}; - char err_msg [128]; + char message[256]; - util::const_buffer uart_elf = load_driver_for("uart", initrd); - if (uart_elf.pointer) { - if (!load_program("UART driver", uart_elf, sys_child, slp_mb_child, err_msg)) { - j6_log(err_msg); - return 1; - } - } + initrd.for_each("/jsix/drivers", + [=, &message](const j6romfs::inode *in, const char *name) { + if (in->type != j6romfs::inode_type::file) + return; - util::const_buffer logger_elf = load_service("logger", initrd); - if (uart_elf.pointer) { - if (!load_program("logger service", logger_elf, sys_child, slp_mb_child, err_msg)) { - j6_log(err_msg); - return 1; + sprintf(message, "Loading driver: %s", name); + j6_log(message); + + uint8_t *data = new uint8_t [in->size]; + util::buffer program {data, in->size}; + + initrd.load_inode_data(in, program); + if (!load_program(name, program, sys_child, slp_mb_child, message)) { + j6_log(message); } - } + + delete [] data; + }); + + initrd.for_each("/jsix/services", + [=, &message](const j6romfs::inode *in, const char *name) { + if (in->type != j6romfs::inode_type::file) + return; + + sprintf(message, "Loading service: %s", name); + j6_log(message); + + uint8_t *data = new uint8_t [in->size]; + util::buffer program {data, in->size}; + + initrd.load_inode_data(in, program); + if (!load_program(name, program, sys_child, slp_mb_child, message)) { + j6_log(message); + } + + delete [] data; + }); service_locator_start(slp_mb); return 0;