From 0f3e1668bb1606bd6c9af6f028035ebafc014cb0 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Mon, 30 Jan 2023 14:17:09 +0100 Subject: [PATCH] Kernel/aarch64: Execute first userspace process This adds the necessary code to init.cpp to be able to execute the first userspace process. To do this, first the filesystem code is initialized, which will use the ramdisk embedded into the kernel image. Then the first userspace process, /bin/SystemServer is executed. :^) The ramdisk code is used as it is useful for the bring-up of the aarch64 port, however once the kernel has support for better ram-based filesystems, the ramdisk code will be removed again. --- Kernel/Arch/aarch64/Dummy.cpp | 8 +----- Kernel/Arch/aarch64/init.cpp | 53 ++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/Kernel/Arch/aarch64/Dummy.cpp b/Kernel/Arch/aarch64/Dummy.cpp index 9442c269d7..101adf32f1 100644 --- a/Kernel/Arch/aarch64/Dummy.cpp +++ b/Kernel/Arch/aarch64/Dummy.cpp @@ -12,12 +12,6 @@ #include #include -namespace Kernel { - -ProcessID g_init_pid { 0 }; - -} - // Delay.cpp namespace Kernel { @@ -32,7 +26,7 @@ void microseconds_delay(u32) namespace Kernel::PCI { bool g_pci_access_io_probe_failed { false }; -bool g_pci_access_is_disabled_from_commandline { false }; +bool g_pci_access_is_disabled_from_commandline { true }; } diff --git a/Kernel/Arch/aarch64/init.cpp b/Kernel/Arch/aarch64/init.cpp index 3f569867d1..78ad3c91ce 100644 --- a/Kernel/Arch/aarch64/init.cpp +++ b/Kernel/Arch/aarch64/init.cpp @@ -24,12 +24,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include typedef void (*ctor_func_t)(); extern ctor_func_t start_heap_ctors[]; @@ -65,41 +68,41 @@ ALWAYS_INLINE static Processor& bootstrap_processor() Atomic g_boot_console; +VirtualConsole* tty0; +ProcessID g_init_pid { 0 }; + static void init_stage2(void*); void init_stage2(void*) { Process::register_new(Process::current()); - // This thread is created to show that kernel scheduling is working! - LockRefPtr some_work_thread; - (void)Process::create_kernel_process(some_work_thread, MUST(KString::try_create("Some Work Thread"sv)), [] { - Aarch64::Asm::wait_cycles(50000000); - dmesgln("Starting \033[0;31msome work\033[0m:"); - for (int i = 1; i <= 500; i++) { - if (i % 20 == 0) - dmesgln(" Working on \033[0;31msome work\033[0m: {}", i); - - Aarch64::Asm::wait_cycles(400000); - } - dmesgln("Finished \033[0;31msome work\033[0m!"); - }); - auto firmware_version = query_firmware_version(); dmesgln("Firmware version: {}", firmware_version); - LockRefPtr more_work_thread; - (void)Process::create_kernel_process(more_work_thread, MUST(KString::try_create("More Work Thread"sv)), [] { - dmesgln("Starting \033[0;34mmore work\033[0m:"); - for (int i = 1; i <= 300; i++) { - if (i % 20 == 0) - dmesgln(" Working on \033[0;34mmore work\033[0m: {}", i); + VirtualFileSystem::initialize(); - Aarch64::Asm::wait_cycles(1000000); - } - dmesgln("Finished \033[0;34mmore work\033[0m!"); - }); + StorageManagement::the().initialize(kernel_command_line().root_device(), kernel_command_line().is_force_pio(), kernel_command_line().is_nvme_polling_enabled()); + if (VirtualFileSystem::the().mount_root(StorageManagement::the().root_filesystem()).is_error()) { + PANIC("VirtualFileSystem::mount_root failed"); + } - dmesgln("Finished init stage"); + // Switch out of early boot mode. + g_in_early_boot = false; + + LockRefPtr thread; + auto userspace_init = kernel_command_line().userspace_init(); + auto init_args = kernel_command_line().userspace_init_args(); + + auto init_or_error = Process::try_create_user_process(thread, userspace_init, UserID(0), GroupID(0), move(init_args), {}, tty0); + if (init_or_error.is_error()) + PANIC("init_stage2: Error spawning init process: {}", init_or_error.error()); + + g_init_pid = init_or_error.value()->pid(); + + thread->set_priority(THREAD_PRIORITY_HIGH); + + Process::current().sys$exit(0); + VERIFY_NOT_REACHED(); } extern "C" [[noreturn]] void init()