summaryrefslogtreecommitdiff
path: root/kernel/entry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/entry.cpp')
-rw-r--r--kernel/entry.cpp151
1 files changed, 70 insertions, 81 deletions
diff --git a/kernel/entry.cpp b/kernel/entry.cpp
index aa6568a..445d560 100644
--- a/kernel/entry.cpp
+++ b/kernel/entry.cpp
@@ -1,9 +1,10 @@
+#include <mercury/kernel/storage/bd/memory.hpp>
+#include <mercury/kernel/storage/fs/tarfs.hpp>
#include <mercury/kernel/framebuffer.hpp>
-#include <mercury/kernel/bd/memory.hpp>
-#include <mercury/kernel/fs/tarfs.hpp>
#include <mercury/kernel/terminal.hpp>
#include <mercury/kernel/limine.hpp>
#include <mercury/kernel/paging.hpp>
+#include <mercury/kernel/vfile.hpp>
using namespace mercury::kernel;
@@ -182,78 +183,67 @@ extern "C" [[noreturn]] void entry() {
[[noreturn]] static void print_and_halt(const char *msg) {
terminal::put_string_sz(msg);
while (1)
- ;
+ asm ("hlt");
+}
+
+static void draw_indent(unsigned indent) {
+ for (unsigned i = 0; i < indent; ++i)
+ terminal::put_char(' ');
}
static void dir_tree(
- storage::block_device *bd, storage::node_id_t node, unsigned indent
+ const vfile::vfile &root, const vfile::vfile &f, unsigned indent
) {
- storage::node_id_t child_node;
- storage::directory_iter_t dir_iter;
- storage::io_result result =
- bd->mounted_as->get_first_child(node, child_node, dir_iter);
- if (result == storage::io_result::not_found) {
- for (unsigned i = 0; i < indent; ++i)
- terminal::put_char(' ');
- terminal::put_string_sz("[empty]\n");
- return;
- }
- else if (result)
- print_and_halt("error getting first child.");
-
- while (true) {
-
- unsigned name_len;
- if (bd->mounted_as->get_name_length(child_node, name_len))
- print_and_halt("failed to get name length.");
- char *name_buf = new char[name_len];
- if (bd->mounted_as->get_name(child_node, name_buf, name_len))
- print_and_halt("failed to get name.");
-
- for (unsigned i = 0; i < indent; ++i)
- terminal::put_char(' ');
- terminal::put_string(name_buf, name_len);
- terminal::put_string(":\n", 2);
-
- delete[] name_buf;
-
- storage::file_type type;
- if (bd->mounted_as->get_file_type(child_node, type))
- print_and_halt("failed to get type.");
-
- if (type == storage::file_type::directory)
- dir_tree(bd, child_node, indent + 2);
-
- else {
- uint64_t len;
- if (bd->mounted_as->get_file_length(child_node, len))
- print_and_halt("failed to get length.");
- char *contents = new char[len];
- if (bd->mounted_as->read_bytes_from_file(child_node, 0, len, contents))
- print_and_halt("failed to read file.");
-
- if (contents[len - 1] == '\n')
- len--;
-
- for (unsigned i = 0; i < indent + 2; ++i)
- terminal::put_char(' ');
- if (len == 0)
+ draw_indent(indent);
+ terminal::put_string(f.dir_entry.name);
+ terminal::put_char('\n');
+
+ std::optional<vfile::vfile> followed;
+ utility::vector<vfile::vfile> children;
+
+ switch (f.dir_entry.type) {
+
+ case storage::file_type::regular_file:
+ draw_indent(indent + 2);
+ terminal::put_string_sz("type: regular file\n");
+ draw_indent(indent + 2);
+ terminal::put_string_sz("length: ");
+ terminal::put_int_decimal(f.dir_entry.length);
+ terminal::put_string_sz(" bytes\n");
+ break;
+
+ case storage::file_type::symlink:
+ draw_indent(indent + 2);
+ terminal::put_string_sz("type: symlink\n");
+ draw_indent(indent + 2);
+ terminal::put_string_sz("target: ");
+ terminal::put_string(f.dir_entry.target);
+ terminal::put_char('\n');
+ if (f.follow_symlinks(root, followed) != storage::fs_result::success)
+ print_and_halt("failed to follow symlink.");
+ if (!followed) {
+ draw_indent(indent + 4);
+ terminal::put_string_sz("[broken]\n");
+ }
+ dir_tree(root, *followed, indent + 4);
+ break;
+
+ case storage::file_type::directory:
+ if (f.get_children(children) != storage::fs_result::success)
+ print_and_halt("failed to get children.");
+ draw_indent(indent + 2);
+ terminal::put_string_sz("type: directory\n");
+ draw_indent(indent + 2);
+ terminal::put_string_sz("children:\n");
+ if (children.count == 0) {
+ draw_indent(indent + 4);
terminal::put_string_sz("[empty]\n");
- else {
- terminal::put_string(contents, len);
- terminal::put_char('\n');
}
-
- delete[] contents;
- }
-
- storage::io_result result
- = bd->mounted_as->get_next_child(node, child_node, dir_iter);
- if (result == storage::io_result::not_found)
- return;
- else if (result)
- print_and_halt("error getting next child.");
+ else
+ for (unsigned i = 0; i < children.count; ++i)
+ dir_tree(root, children.buffer[i], indent + 4);
+ break;
}
@@ -262,16 +252,10 @@ static void dir_tree(
[[noreturn]] static void with_kernel_p4() {
terminal::init_terminal();
- storage::init_storage();
-
- storage::block_device *initfs_bd = new bd::memory(initfs, initfs_len);
- storage::block_devices->insert_end(initfs_bd);
- storage::canon_path root;
- storage::canonize_path("/", 1, root);
-
- if (storage::mount_device(initfs_bd, root, &fs::tarfs_mounter))
- print_and_halt("failed to mount initfs.");
+ storage::bd::memory initfs_bd(initfs, initfs_len);
+ storage::fs::tarfs_instance initfs_fs(&initfs_bd);
+ initfs_bd.mounted_as = &initfs_fs;
terminal::put_string_sz("kernel initialization complete.\n");
@@ -283,12 +267,17 @@ static void dir_tree(
terminal::put_int_decimal(free_pram_kib);
terminal::put_string_sz(" kiB physical memory free.\n");
- storage::node_id_t root_node;
- if (initfs_bd->mounted_as->get_root_node(root_node))
- print_and_halt("failed to get root initfs node.");
+ vfile::vfile root;
+ root.bd = &initfs_bd;
+ root.dir_entry.type = storage::file_type::directory;
+ root.path.absolute = true;
+
+ if (initfs_fs.get_root_node(root.dir_entry.node) !=
+ storage::fs_result::success)
+ print_and_halt("failed to get root node.");
- terminal::put_string_sz("initfs:\n");
- dir_tree(initfs_bd, root_node, 2);
+ terminal::put_string_sz("initfs");
+ dir_tree(root, root, 0);
print_and_halt("halting.");
}