diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 5c7448f56b..5c6b233a50 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -133,8 +133,10 @@ void Process::register_new(Process& process) { // Note: this is essentially the same like process->ref() RefPtr new_process = process; - ScopedSpinLock lock(g_processes_lock); - g_processes->prepend(process); + { + ScopedSpinLock lock(g_processes_lock); + g_processes->prepend(process); + } ProcFSComponentRegistry::the().register_new_process(process); } @@ -180,7 +182,7 @@ RefPtr Process::create_user_process(RefPtr& first_thread, const return process; } -RefPtr Process::create_kernel_process(RefPtr& first_thread, String&& name, void (*entry)(void*), void* entry_data, u32 affinity) +RefPtr Process::create_kernel_process(RefPtr& first_thread, String&& name, void (*entry)(void*), void* entry_data, u32 affinity, RegisterProcess do_register) { auto process = Process::create(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), true); if (!first_thread || !process) @@ -193,9 +195,8 @@ RefPtr Process::create_kernel_process(RefPtr& first_thread, Str first_thread->regs().rdi = FlatPtr(entry_data); // entry function argument is expected to be in regs.rdi #endif - if (process->pid() != 0) { + if (do_register == RegisterProcess::Yes) register_new(*process); - } ScopedSpinLock lock(g_scheduler_lock); first_thread->set_affinity(affinity); diff --git a/Kernel/Process.h b/Kernel/Process.h index 8a0d42c8a5..5ce44dcd20 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -163,14 +163,19 @@ public: delete func; } + enum class RegisterProcess { + No, + Yes + }; + template - static RefPtr create_kernel_process(RefPtr& first_thread, String&& name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT) + static RefPtr create_kernel_process(RefPtr& first_thread, String&& name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes) { auto* entry_func = new EntryFunction(move(entry)); - return create_kernel_process(first_thread, move(name), &Process::kernel_process_trampoline, entry_func, affinity); + return create_kernel_process(first_thread, move(name), &Process::kernel_process_trampoline, entry_func, affinity, do_register); } - static RefPtr create_kernel_process(RefPtr& first_thread, String&& name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT); + static RefPtr create_kernel_process(RefPtr& first_thread, String&& name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes); static RefPtr create_user_process(RefPtr& first_thread, const String& path, uid_t, gid_t, ProcessID ppid, int& error, Vector&& arguments = Vector(), Vector&& environment = Vector(), TTY* = nullptr); static void register_new(Process&); ~Process(); diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 7ab1dfebb9..2f21bfe111 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -404,7 +404,7 @@ UNMAP_AFTER_INIT void Scheduler::initialize() g_ready_queues = new ThreadReadyQueue[g_ready_queue_buckets]; g_finalizer_has_work.store(false, AK::MemoryOrder::memory_order_release); - s_colonel_process = Process::create_kernel_process(idle_thread, "colonel", idle_loop, nullptr, 1).leak_ref(); + s_colonel_process = Process::create_kernel_process(idle_thread, "colonel", idle_loop, nullptr, 1, Process::RegisterProcess::No).leak_ref(); VERIFY(s_colonel_process); VERIFY(idle_thread); idle_thread->set_priority(THREAD_PRIORITY_MIN); diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 69ccc11dc3..d6af14a8a9 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -142,39 +142,21 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init() InterruptManagement::initialize(); ACPI::initialize(); - // Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging - SysFSComponentRegistry::initialize(); + __stack_chk_guard = get_fast_random(); + ProcFSComponentRegistry::initialize(); - PCI::initialize(); - PCISerialDevice::detect(); - - VirtualFileSystem::initialize(); - - dmesgln("Starting SerenityOS..."); + Thread::initialize(); + Process::initialize(); TimeManagement::initialize(0); - __stack_chk_guard = get_fast_random(); - - NullDevice::initialize(); - if (!get_serial_debug()) - (void)SerialDevice::must_create(0).leak_ref(); - (void)SerialDevice::must_create(1).leak_ref(); - (void)SerialDevice::must_create(2).leak_ref(); - (void)SerialDevice::must_create(3).leak_ref(); - - VMWareBackdoor::the(); // don't wait until first mouse packet - HIDManagement::initialize(); - - Thread::initialize(); - Process::initialize(); Scheduler::initialize(); - WorkQueue::initialize(); + dmesgln("Starting SerenityOS..."); { RefPtr init_stage2_thread; - Process::create_kernel_process(init_stage2_thread, "init_stage2", init_stage2, nullptr); + Process::create_kernel_process(init_stage2_thread, "init_stage2", init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No); // We need to make sure we drop the reference for init_stage2_thread // before calling into Scheduler::start, otherwise we will have a // dangling Thread that never gets cleaned up @@ -218,6 +200,13 @@ extern "C" UNMAP_AFTER_INIT void init_finished(u32 cpu) void init_stage2(void*) { + // This is a little bit of a hack. We can't register our process at the time we're + // creating it, but we need to be registered otherwise finalization won't be happy. + // The colonel process gets away without having to do this because it never exits. + Process::register_new(*Process::current()); + + WorkQueue::initialize(); + if (APIC::initialized() && APIC::the().enabled_processor_count() > 1) { // We can't start the APs until we have a scheduler up and running. // We need to be able to process ICI messages, otherwise another @@ -226,6 +215,23 @@ void init_stage2(void*) APIC::the().boot_aps(); } + // Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging + SysFSComponentRegistry::initialize(); + PCI::initialize(); + PCISerialDevice::detect(); + + VirtualFileSystem::initialize(); + + NullDevice::initialize(); + if (!get_serial_debug()) + (void)SerialDevice::must_create(0).leak_ref(); + (void)SerialDevice::must_create(1).leak_ref(); + (void)SerialDevice::must_create(2).leak_ref(); + (void)SerialDevice::must_create(3).leak_ref(); + + VMWareBackdoor::the(); // don't wait until first mouse packet + HIDManagement::initialize(); + GraphicsManagement::the().initialize(); ConsoleManagement::the().initialize();