improve kernel/main.cpp

This commit is contained in:
nakst 2021-11-03 18:52:24 +00:00
parent cd51bf4d6c
commit b66b27a9f4
9 changed files with 26 additions and 28 deletions

View File

@ -32,7 +32,7 @@
[extern ArchNextTimer] [extern ArchNextTimer]
[extern InterruptHandler] [extern InterruptHandler]
[extern KThreadTerminate] [extern KThreadTerminate]
[extern KernelMain] [extern KernelInitialise]
[extern PostContextSwitch] [extern PostContextSwitch]
[extern SetupProcessor2] [extern SetupProcessor2]
[extern Syscall] [extern Syscall]
@ -149,12 +149,12 @@ _start:
%assign i i+1 %assign i i+1
%endrep %endrep
; Setup the remaining things and call KernelMain. ; Setup the remaining things and call KernelInitialise
call SetupProcessor1 ; Need to get SSE up before calling into C code. call SetupProcessor1 ; Need to get SSE up before calling into C code.
call PCSetupCOM1 call PCSetupCOM1
call PCDisablePIC call PCDisablePIC
call PCProcessMemoryMap call PCProcessMemoryMap
call KernelMain call KernelInitialise
; Fall-through. ; Fall-through.
ProcessorReady: ProcessorReady:

View File

@ -45,7 +45,7 @@
[extern ArchNextTimer] [extern ArchNextTimer]
[extern InterruptHandler] [extern InterruptHandler]
[extern KThreadTerminate] [extern KThreadTerminate]
[extern KernelMain] [extern KernelInitialise]
[extern PostContextSwitch] [extern PostContextSwitch]
[extern SetupProcessor2] [extern SetupProcessor2]
[extern Syscall] [extern Syscall]
@ -157,9 +157,9 @@ _start:
; First stage of processor initilisation ; First stage of processor initilisation
call SetupProcessor1 call SetupProcessor1
; Call the KernelMain function ; Call the KernelInitialise function
and rsp,~0xF and rsp,~0xF
call KernelMain call KernelInitialise
ProcessorReady: ProcessorReady:
; Set the timer and become this CPU's idle thread. ; Set the timer and become this CPU's idle thread.

View File

@ -324,8 +324,8 @@ CPULocalStorage *KGetCPULocal(uintptr_t index) {
#ifdef USE_ACPICA #ifdef USE_ACPICA
#include "acpica.cpp" #include "acpica.cpp"
#else #else
void ArchShutdown(uintptr_t action) { void ArchShutdown() {
if (action == SHUTDOWN_ACTION_RESTART) ProcessorReset(); if (shutdownAction == SHUTDOWN_ACTION_RESTART) ProcessorReset();
StartDebugOutput(); StartDebugOutput();
EsPrint("\nIt's now safe to turn off your computer.\n"); EsPrint("\nIt's now safe to turn off your computer.\n");
ProcessorDisableInterrupts(); ProcessorDisableInterrupts();

View File

@ -591,8 +591,8 @@ ACPI_STATUS ACPIWalkNamespaceCallback(ACPI_HANDLE object, uint32_t depth, void *
return AE_OK; return AE_OK;
} }
void ArchShutdown(uintptr_t action) { void ArchShutdown() {
if (action == SHUTDOWN_ACTION_RESTART) ProcessorReset(); if (shutdownAction == SHUTDOWN_ACTION_RESTART) ProcessorReset();
AcpiEnterSleepStatePrep(5); AcpiEnterSleepStatePrep(5);
ProcessorDisableInterrupts(); ProcessorDisableInterrupts();
AcpiEnterSleepState(5); AcpiEnterSleepState(5);

View File

@ -101,8 +101,8 @@ struct PhysicalMemoryRegion {
uint64_t pageCount; uint64_t pageCount;
}; };
void KernelInitialise(); extern "C" void KernelInitialise();
void KernelShutdown(uintptr_t action); void KernelMain(uintptr_t);
uintptr_t DoSyscall(EsSyscallType index, uintptr_t DoSyscall(EsSyscallType index,
uintptr_t argument0, uintptr_t argument1, uintptr_t argument2, uintptr_t argument3, uintptr_t argument0, uintptr_t argument1, uintptr_t argument2, uintptr_t argument3,
@ -110,6 +110,8 @@ uintptr_t DoSyscall(EsSyscallType index,
uint64_t timeStampTicksPerMs; uint64_t timeStampTicksPerMs;
EsUniqueIdentifier installationID; // The identifier of this OS installation, given to us by the bootloader. EsUniqueIdentifier installationID; // The identifier of this OS installation, given to us by the bootloader.
KEvent shutdownEvent;
uintptr_t shutdownAction;
// --------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------
// Architecture specific layer definitions. // Architecture specific layer definitions.
@ -117,7 +119,7 @@ EsUniqueIdentifier installationID; // The identifier of this OS installation, gi
extern "C" { extern "C" {
void ArchInitialise(); void ArchInitialise();
void ArchShutdown(uintptr_t action); void ArchShutdown();
void ArchNextTimer(size_t ms); // Schedule the next TIMER_INTERRUPT. void ArchNextTimer(size_t ms); // Schedule the next TIMER_INTERRUPT.
uint64_t ArchGetTimeMs(); // Called by the scheduler on the boot processor every context switch. uint64_t ArchGetTimeMs(); // Called by the scheduler on the boot processor every context switch.
InterruptContext *ArchInitialiseThread(uintptr_t kernelStack, uintptr_t kernelStackSize, struct Thread *thread, InterruptContext *ArchInitialiseThread(uintptr_t kernelStack, uintptr_t kernelStackSize, struct Thread *thread,

View File

@ -9,22 +9,21 @@
#define IMPLEMENTATION #define IMPLEMENTATION
#include "kernel.h" #include "kernel.h"
extern "C" void KernelMain() { void KernelInitialise() {
kernelProcess = scheduler.SpawnProcess(PROCESS_KERNEL); // Spawn the kernel process. kernelProcess = scheduler.SpawnProcess(PROCESS_KERNEL); // Spawn the kernel process.
MMInitialise(); // Initialise the memory manager.
KThreadCreate("KernelMain", KernelMain); // Create the KernelMain thread.
ArchInitialise(); // Start processors and initialise CPULocalStorage. ArchInitialise(); // Start processors and initialise CPULocalStorage.
scheduler.started = true; // Start the pre-emptive scheduler. scheduler.started = true; // Start the pre-emptive scheduler.
// Continues in KernelInitialise.
} }
void KernelInitialise() { void KernelMain(uintptr_t) {
desktopProcess = scheduler.SpawnProcess(PROCESS_DESKTOP); // Spawn the desktop process. desktopProcess = scheduler.SpawnProcess(PROCESS_DESKTOP); // Spawn the desktop process.
DriversInitialise(); // Load the root device. DriversInitialise(); // Load the root device.
desktopProcess->Start(EsLiteral(K_DESKTOP_EXECUTABLE)); // Start the desktop process. desktopProcess->Start(EsLiteral(K_DESKTOP_EXECUTABLE)); // Start the desktop process.
} KEventWait(&shutdownEvent, ES_WAIT_NO_TIMEOUT); // Wait for a shutdown request.
void KernelShutdown(uintptr_t action) {
scheduler.Shutdown(); // Kill user processes. scheduler.Shutdown(); // Kill user processes.
FSShutdown(); // Flush file cache and unmount filesystems. FSShutdown(); // Flush file cache and unmount filesystems.
DriversShutdown(); // Inform drivers of shutdown. DriversShutdown(); // Inform drivers of shutdown.
ArchShutdown(action); // Power off or restart the computer. ArchShutdown(); // Power off or restart the computer.
} }

View File

@ -771,8 +771,6 @@ Process *Scheduler::SpawnProcess(ProcessType processType) {
if (processType == PROCESS_KERNEL) { if (processType == PROCESS_KERNEL) {
EsCRTstrcpy(process->cExecutableName, "Kernel"); EsCRTstrcpy(process->cExecutableName, "Kernel");
scheduler.allProcesses.InsertEnd(&process->allItem); scheduler.allProcesses.InsertEnd(&process->allItem);
MMInitialise();
scheduler.SpawnThread("InitKernel", (uintptr_t) KernelInitialise);
} }
return process; return process;
@ -1370,9 +1368,7 @@ void Scheduler::Yield(InterruptContext *context) {
} }
void Scheduler::Shutdown() { void Scheduler::Shutdown() {
// Prevent the creation of new proceses or threads, scheduler.shutdown = true;
// or terminate this thread if we're already shutting down.
if (__sync_val_compare_and_swap(&scheduler.shutdown, false, true)) KThreadTerminate();
// Close our handle to the desktop process. // Close our handle to the desktop process.
CloseHandleToObject(desktopProcess->executableMainThread, KERNEL_OBJECT_THREAD); CloseHandleToObject(desktopProcess->executableMainThread, KERNEL_OBJECT_THREAD);

View File

@ -4,7 +4,7 @@
extern "C" int EsStringCompareRaw(const char *s1, size_t b1, const char *s2, size_t b2); extern "C" int EsStringCompareRaw(const char *s1, size_t b1, const char *s2, size_t b2);
void EsPrint(const char *format, ...); void EsPrint(const char *format, ...);
extern "C" void KernelMain(); extern "C" void KernelInitialise();
extern "C" void ProcessorHalt(); extern "C" void ProcessorHalt();
struct ExportedKernelFunction { struct ExportedKernelFunction {
@ -27,7 +27,7 @@ void *ResolveKernelSymbol(const char *name, size_t nameBytes) {
// As we get the function addresses before the kernel is linked (this file needs to be linked with the kernel), // As we get the function addresses before the kernel is linked (this file needs to be linked with the kernel),
// they are relative to wherever the kernel_all.o's text is placed in the executable's text section. // they are relative to wherever the kernel_all.o's text is placed in the executable's text section.
uintptr_t offset = (uintptr_t) ResolveKernelSymbol("KernelMain", 10) - (uintptr_t) KernelMain; uintptr_t offset = (uintptr_t) ResolveKernelSymbol("KernelInitialise", 10) - (uintptr_t) KernelInitialise;
for (uintptr_t i = 0; i < sizeof(exportedKernelFunctions) / sizeof(exportedKernelFunctions[0]); i++) { for (uintptr_t i = 0; i < sizeof(exportedKernelFunctions) / sizeof(exportedKernelFunctions[0]); i++) {
exportedKernelFunctions[i].address = (void *) ((uintptr_t) exportedKernelFunctions[i].address - offset); exportedKernelFunctions[i].address = (void *) ((uintptr_t) exportedKernelFunctions[i].address - offset);

View File

@ -1223,7 +1223,8 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_GET_STATE) {
SYSCALL_IMPLEMENT(ES_SYSCALL_SHUTDOWN) { SYSCALL_IMPLEMENT(ES_SYSCALL_SHUTDOWN) {
SYSCALL_PERMISSION(ES_PERMISSION_SHUTDOWN); SYSCALL_PERMISSION(ES_PERMISSION_SHUTDOWN);
KThreadCreate("Shutdown", [] (uintptr_t action) { KernelShutdown(action); }, argument0); shutdownAction = argument0;
KEventSet(&shutdownEvent, false, true);
SYSCALL_RETURN(ES_SUCCESS, false); SYSCALL_RETURN(ES_SUCCESS, false);
} }