#include "Log.h" #include "arch/CPU.h" #include "arch/Timer.h" #include "binfmt/BinaryFormat.h" #include "boot/Init.h" #include "config.h" #include "fs/InitRD.h" #include "fs/devices/DeviceRegistry.h" #include "fs/tmpfs/FileSystem.h" #include "memory/MemoryManager.h" #include "thread/Scheduler.h" #include #ifdef ARCH_X86_64 #include "arch/x86_64/disk/ATA.h" #endif extern void set_host_name(StringView); void reap_thread() { while (true) { CPU::disable_interrupts(); auto dying_threads = Scheduler::check_for_dying_threads(); CPU::enable_interrupts(); dying_threads.consume([](Thread* thread) { Scheduler::reap_thread(thread); }); kernel_wait_for_event(); } } [[noreturn]] void init() { { kinfoln("Starting Moon %s %s", MOON_VERSION, MOON_RELEASE); // Default hostname if nobody from userspace changes it set_host_name("moon"_sv); kinfoln("Current platform: %s", CPU::platform_string().chars()); kinfoln("Current processor: %s", CPU::identify().value_or("(unknown)"_sv).chars()); auto root = mark_critical(TmpFS::FileSystem::create(), "Failed to create initial ramfs"); mark_critical(VFS::mount_root(root), "Failed to mount the initial ramfs as the root filesystem"); mark_critical(InitRD::populate_vfs(), "Failed to load files from the initial ramdisk"); mark_critical(DeviceRegistry::init(), "Failed to register initial devices"); mark_critical(BinaryFormat::init(), "Failed to register initial binary formats"); auto init = mark_critical(VFS::resolve_path("/bin/preinit", Credentials {}), "Can't find init in the initial ramfs!"); auto init_thread = mark_critical(Scheduler::new_userspace_thread(init, "/bin/preinit"), "Failed to create PID 1 process for init"); auto reap = mark_critical(Scheduler::new_kernel_thread(reap_thread, "[reap]"), "Failed to create the process reaper kernel thread"); Scheduler::set_reap_thread(reap); #ifdef ARCH_X86_64 ATA::Controller::scan(); #endif // Disable console logging before transferring control to userspace. setup_log(log_debug_enabled(), log_serial_enabled(), false); init_thread->wake_up(); } kernel_exit(); } extern "C" [[noreturn]] void _start() { Init::check_magic(); Init::early_init(); Timer::init(); Thread::init(); Scheduler::init(); Scheduler::new_kernel_thread(init, "[kinit]"); CPU::platform_finish_init(); CPU::enable_interrupts(); CPU::idle_loop(); }