summaryrefslogtreecommitdiff
path: root/kernel/entry.cpp
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-01-13 16:43:49 -0500
committerBenji Dial <benji@benjidial.net>2024-01-13 16:43:49 -0500
commit4130562b1555cabe441efe9420cebe12e7ed8d39 (patch)
treebeaf0012373aab2c3a13fe0147a5cda4af28ef78 /kernel/entry.cpp
parent882e74b2191c059a9226cbd8bcb51c97da36247c (diff)
downloadhilbert-os-4130562b1555cabe441efe9420cebe12e7ed8d39.tar.gz
application loading
Diffstat (limited to 'kernel/entry.cpp')
-rw-r--r--kernel/entry.cpp140
1 files changed, 56 insertions, 84 deletions
diff --git a/kernel/entry.cpp b/kernel/entry.cpp
index 445d560..f7ba71d 100644
--- a/kernel/entry.cpp
+++ b/kernel/entry.cpp
@@ -1,5 +1,6 @@
#include <mercury/kernel/storage/bd/memory.hpp>
#include <mercury/kernel/storage/fs/tarfs.hpp>
+#include <mercury/kernel/application.hpp>
#include <mercury/kernel/framebuffer.hpp>
#include <mercury/kernel/terminal.hpp>
#include <mercury/kernel/limine.hpp>
@@ -103,6 +104,8 @@ uint64_t initfs_len;
[[noreturn]] static void with_kernel_p4();
+extern "C" void load_gdt_and_idt();
+
extern "C" [[noreturn]] void entry() {
//TODO?: maybe we should check if the limine requests were
@@ -113,9 +116,9 @@ extern "C" [[noreturn]] void entry() {
paging::mark_all_pram_used();
auto memmap = memmap_request.response;
for (uint64_t i = 0; i < memmap->entry_count; ++i) {
- //we don't start allocating physical pages until after we are done using
- //limine structures (specifically at the call to paging::map_kernel_stack),
- //so we consider bootloader reclaimable to be free. usable and bootloader
+ //we don't allocate any physical pages until after we are done using limine
+ //structures (specifically at the call to paging::map_kernel_stacks), so
+ //we consider bootloader reclaimable to be free. usable and bootloader
//reclaimable are guaranteed by limine spec to be page-aligned.
auto entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE ||
@@ -175,79 +178,29 @@ extern "C" [[noreturn]] void entry() {
//switch to kernel p4
- paging::map_kernel_stack();
+ paging::map_kernel_stacks();
+ load_gdt_and_idt();
switch_to_kernel_p4(&with_kernel_p4);
}
+static void print_mem() {
+ uint64_t used_vram_mib = (paging::get_used_vram_page_count() + 128) / 256;
+ uint64_t free_pram_mib = (paging::get_free_pram_page_count() + 128) / 256;
+ terminal::put_int_decimal(used_vram_mib);
+ terminal::put_string_sz(" MiB kernel memory mapped.\n");
+ terminal::put_int_decimal(free_pram_mib);
+ terminal::put_string_sz(" MiB physical memory free.\n");
+}
+
[[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(
- const vfile::vfile &root, const vfile::vfile &f, unsigned indent
-) {
-
- 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
- for (unsigned i = 0; i < children.count; ++i)
- dir_tree(root, children.buffer[i], indent + 4);
- break;
-
- }
-
-}
+extern "C" [[noreturn]] void start_user_mode(
+ uint64_t rip, uint64_t rsp, uint64_t p4_paddr);
[[noreturn]] static void with_kernel_p4() {
@@ -257,27 +210,46 @@ static void dir_tree(
storage::fs::tarfs_instance initfs_fs(&initfs_bd);
initfs_bd.mounted_as = &initfs_fs;
- terminal::put_string_sz("kernel initialization complete.\n");
-
- int used_vram_kib = paging::get_used_vram_page_count() * 4;
- int free_pram_kib = paging::get_free_pram_page_count() * 4;
+ vfile::vfile vfs_root;
+ vfs_root.bd = &initfs_bd;
+ vfs_root.dir_entry.type = storage::file_type::directory;
+ vfs_root.path.absolute = true;
- terminal::put_int_decimal(used_vram_kib);
- terminal::put_string_sz(" kiB kernel memory mapped.\n");
- terminal::put_int_decimal(free_pram_kib);
- terminal::put_string_sz(" kiB physical memory free.\n");
+ if (initfs_fs.get_root_node(vfs_root.dir_entry.node) !=
+ storage::fs_result::success)
+ print_and_halt("failed to get root node of initfs.");
- vfile::vfile root;
- root.bd = &initfs_bd;
- root.dir_entry.type = storage::file_type::directory;
- root.path.absolute = true;
+ utility::string init_path_string("/bin/init.elf", 13);
+ vfile::canon_path init_path;
+ vfile::canonize_path(init_path_string, init_path);
- if (initfs_fs.get_root_node(root.dir_entry.node) !=
+ std::optional<vfile::vfile> init_file;
+ if (vfile::lookup_path(vfs_root, init_path, init_file) !=
storage::fs_result::success)
- print_and_halt("failed to get root node.");
-
- terminal::put_string_sz("initfs");
- dir_tree(root, root, 0);
- print_and_halt("halting.");
+ print_and_halt("failed to look up /bin/init.elf.");
+ if (!init_file)
+ print_and_halt("/bin/init.elf does not exist.");
+
+ terminal::put_string_sz("/bin/init.elf is ");
+ terminal::put_int_decimal(init_file->dir_entry.length);
+ terminal::put_string_sz(" bytes long.\n");
+
+ application::app_instance *init;
+ if (application::create_app(*init_file, init) !=
+ application::create_app_result::success)
+ print_and_halt("failed to parse /bin/init.elf.");
+
+ terminal::put_string_sz("/bin/init.elf loaded:\n instruction pointer 0x");
+ terminal::put_int_hex(init->saved_regs.rip, 8);
+ terminal::put_string_sz("\n stack pointer 0x");
+ terminal::put_int_hex(init->saved_regs.rsp, 8);
+ terminal::put_string_sz("\n ");
+ terminal::put_int_decimal(init->count_mapped_vram_pages() * 2);
+ terminal::put_string_sz(" MiB userspace memory used\n");
+
+ print_mem();
+ terminal::put_string_sz("switching to /bin/init.elf.\n");
+ application::running_app = init;
+ start_user_mode(init->saved_regs.rip, init->saved_regs.rsp, init->p4_paddr);
}