From 58d2af14429be02b580cde5b3e23978530d8ab74 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 21 May 2025 10:19:07 +0200 Subject: feat(kernel): Architectural changes, and introducing a kKernelVM. see code for more details. Signed-off-by: Amlal El Mahrouss --- dev/kernel/ArchKit/ArchKit.h | 8 +++- dev/kernel/FirmwareKit/Handover.h | 2 + dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 22 +++------- dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 48 +++++++++++++++----- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 51 +--------------------- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 22 ---------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 27 ++++++++++-- dev/kernel/HALKit/AMD64/Processor.h | 2 - dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 2 +- dev/kernel/HALKit/ARM64/Processor.h | 2 - dev/kernel/KernelKit/KernelTaskScheduler.h | 2 +- dev/kernel/src/HardwareThreadScheduler.cc | 4 +- dev/kernel/src/UserProcessScheduler.cc | 23 +++++++--- 13 files changed, 96 insertions(+), 119 deletions(-) (limited to 'dev/kernel') diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index 41a36e69..d511658f 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -77,8 +77,14 @@ struct HalSyscallEntry final { operator bool() { return fHooked; } }; +EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); + inline Kernel::Array kSysCalls; inline Kernel::Array kKernCalls; -EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + +inline Kernel::VoidPtr kKernelVM = nullptr; + +#endif // __NE_VIRTUAL_MEMORY_SUPPORT__ \ No newline at end of file diff --git a/dev/kernel/FirmwareKit/Handover.h b/dev/kernel/FirmwareKit/Handover.h index d3ccc724..cda27e52 100644 --- a/dev/kernel/FirmwareKit/Handover.h +++ b/dev/kernel/FirmwareKit/Handover.h @@ -63,6 +63,8 @@ struct BootInfoHeader final { SizeT f_KernelSz; VoidPtr f_StartupImage; SizeT f_StartupSz; + VoidPtr f_StackTop; + SizeT f_StackSz; WideChar f_FirmwareVendorName[32]; SizeT f_FirmwareVendorLen; diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index e4ad1024..ada2ee3f 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -113,27 +113,17 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { if (thrdid > kSMPCount) return NO; - if (!mp_is_smp()) { - if (stack_frame) { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; - sched_jump_to_task(stack_frame); + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - return YES; - } - } else { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - - return YES; - } + sched_jump_to_task(stack_frame); - return NO; + return YES; } /***********************************************************************************/ diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index 230f50ed..d0ce2418 100644 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm @@ -56,6 +56,8 @@ extern hal_system_call_enter global mp_system_call_handler mp_system_call_handler: + push rbp + mov rbp, rsp push r8 push r9 @@ -77,7 +79,9 @@ mp_system_call_handler: pop r9 pop r8 - o64 sysret + pop rbp + + o64 iret section .text @@ -88,12 +92,40 @@ sched_jump_to_task: push rbp mov rbp, rsp - mov ax, 0x20 + mov ax, 0x30 mov ds, ax mov es, ax mov fs, ax mov gs, ax + mov ax, 0x18 + ltr ax + + push 0x30 + mov rdx, [rcx + 0x08] + push rdx + o64 pushf + push 0x28 + mov rdx, [rcx + 0x00] + push rdx + + call sched_recover_registers + + o64 iret + +global sched_idle_task + +sched_idle_task: + mov ax, cs + and ax, 3 + + jmp $ + ret + +sched_recover_registers: + push rbp + mov rbp, rsp + mov r8, [rcx + 0x10] mov r9, [rcx + 0x18] mov r10, [rcx + 0x20] @@ -103,14 +135,6 @@ sched_jump_to_task: mov r14, [rcx + 0x40] mov r15, [rcx + 0x48] - mov rax, [rcx + 0x00] - mov rsp, [rcx + 0x08] - - o64 sysret - int 3 ;; Never continue here. + pop rbp -global sched_idle_task - -sched_idle_task: - jmp $ - ret + ret \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 51fc4f0e..633adccb 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,14 +37,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: General Access Fault.\r"; process.Leak().Signal.SignalArg = rsp; @@ -63,15 +55,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; @@ -104,14 +87,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Math error (division by zero?).\r"; process.Leak().Signal.SignalArg = rsp; @@ -130,15 +105,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); Kernel::kout << "Kernel: Access Process Fault.\r"; @@ -152,19 +118,9 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - - if (!process) { - while (YES) - ; - } - hal_idt_send_eoi(3); - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); @@ -189,11 +145,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - while (YES) - ; - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index a6b194d3..5e82f969 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -20,8 +20,6 @@ __NE_INT_%1: std - add rsp, 8 - o64 iret %endmacro @@ -61,8 +59,6 @@ __NE_INT_0: std - add rsp, 8 - o64 iret __NE_INT_1: @@ -83,8 +79,6 @@ __NE_INT_2: std - add rsp, 8 - o64 iret ;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. @@ -96,8 +90,6 @@ __NE_INT_3: std - add rsp, 8 - o64 iret __NE_INT_4: @@ -109,16 +101,12 @@ __NE_INT_4: std - add rsp, 8 - o64 iret __NE_INT_5: cld std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -130,8 +118,6 @@ __NE_INT_6: std - add rsp, 8 - o64 iret __NE_INT_7: @@ -142,8 +128,6 @@ __NE_INT_7: std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -156,8 +140,6 @@ __NE_INT_8: std - add rsp, 8 - o64 iret IntNormal 9 @@ -187,8 +169,6 @@ __NE_INT_14: std - add rsp, 8 - o64 iret IntNormal 15 @@ -247,8 +227,6 @@ __NE_INT_40: std - add rsp, 8 - o64 iret IntNormal 41 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 4de43f27..5394645a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -38,9 +38,9 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, handover_hdr->f_HardwareTables.f_ImageHandle); - kKernelCR3 = kHandoverHeader->f_PageStart; + kKernelVM = kHandoverHeader->f_PageStart; - hal_write_cr3(kKernelCR3); + hal_write_cr3(kKernelVM); /************************************** */ /* INITIALIZE BIT MAP. */ @@ -54,7 +54,12 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /* INITIALIZE GDT AND SEGMENTS. */ /************************************** */ - STATIC CONST auto kGDTEntriesCount = 6; + STATIC CONST auto kGDTEntriesCount = 8; + + STATIC HAL::Detail::NE_TSS kKernelTSS{}; + + kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop; + kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS); /* The GDT, mostly descriptors for user and kernel segments. */ STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { @@ -76,6 +81,8 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data + {}, // TSS data low + {}, // TSS data high {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, @@ -90,6 +97,20 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fBaseHigh = 0}, // User data }; + kGDTArray[3].fLimitLow = sizeof(HAL::Detail::NE_TSS) - 1; + kGDTArray[3].fBaseLow = ((UIntPtr) &kKernelTSS) & 0xFFFF; + kGDTArray[3].fBaseMid = (((UIntPtr) &kKernelTSS) >> 16) & 0xFF; + kGDTArray[3].fAccessByte = 0x89; // Present, type 9 = 64-bit available TSS + kGDTArray[3].fFlags = 0x20 | ((((UIntPtr) &kKernelTSS) >> 24) & 0x0F); + kGDTArray[3].fBaseHigh = (((UIntPtr) &kKernelTSS) >> 24) & 0xFF; + + kGDTArray[4].fLimitLow = ((UIntPtr) &kKernelTSS >> 32) & 0xFFFF; + kGDTArray[4].fBaseLow = 0; + kGDTArray[4].fBaseMid = 0; + kGDTArray[4].fAccessByte = 0; + kGDTArray[4].fFlags = 0; + kGDTArray[4].fBaseHigh = 0; + // Load memory descriptors. Kernel::HAL::Register64 gdt_reg; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index c574f8d5..3bf0ad3e 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -285,6 +285,4 @@ EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr) inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelCR3 = nullptr; - #endif // __NE_AMD64__ */ \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 5be41e4e..70a5e2d9 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -113,7 +113,7 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { MUST_PASS(Detail::kGICEnabled); if (!stack_frame) return NO; diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index f52b854f..ba1ed11e 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -72,8 +72,6 @@ inline Void hal_wfi(Void) { inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelPDE = nullptr; - #include #endif // __NE_ARM64__ \ No newline at end of file diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h index f4ff4125..57b83ccb 100644 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -16,7 +16,7 @@ namespace Kernel { class KERNEL_TASK final { -public: + public: Char Name[kSchedNameLen] = {"KERNEL_TASK"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemDriver}; HAL::StackFramePtr StackFrame{nullptr}; diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index b801632c..23365af5 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -21,7 +21,7 @@ namespace Kernel { /***********************************************************************************/ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame); -EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid); +EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid); STATIC HardwareThreadScheduler kHardwareThreadScheduler; @@ -94,7 +94,7 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { Bool HardwareThread::Switch(HAL::StackFramePtr frame) { this->fStack = frame; - Bool ret = mp_register_process(fStack, this->fPID); + Bool ret = mp_register_task(fStack, this->fPID); return ret; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 0de38532..a901e6d0 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -21,6 +21,7 @@ #include #include #include +#include "NewKit/Macros.h" ///! BUGS: 0 @@ -125,7 +126,7 @@ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr(-kErrorHeapOutOfMemory); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto vm_register = kKernelCR3; + auto vm_register = kKernelVM; hal_write_cr3(this->VMRegister); auto ptr = mm_new_ptr(sz, Yes, Yes, pad_amount); @@ -271,7 +272,7 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { auto memory_ptr_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = kKernelCR3; + auto pd = kKernelVM; hal_write_cr3(this->VMRegister); #endif @@ -384,7 +385,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = kKernelCR3; + process.VMRegister = kKernelVM; #else process.VMRegister = 0UL; #endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ @@ -401,6 +402,15 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im process.StackFrame->IP = reinterpret_cast(code); process.StackFrame->SP = reinterpret_cast(&process.StackReserve[0] + process.StackSize); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + HAL::mm_map_page((VoidPtr) process.StackFrame->IP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->IP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); + HAL::mm_map_page((VoidPtr) process.StackFrame->SP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->SP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + process.StackSize = kSchedMaxStackSz; rt_set_memory(process.StackReserve, 0, process.StackSize); @@ -494,6 +504,8 @@ SizeT UserProcessScheduler::Run() noexcept { if (UserProcessHelper::CanBeScheduled(process)) { kout << process.Name << " will be scheduled...\r"; + this->TheCurrentProcess() = process; + if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { process.PTime = static_cast(process.Affinity); @@ -606,6 +618,7 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) { (Void)(kout << "AP_" << hex_number(index)); kout << " is busy\r"; + continue; } @@ -627,10 +640,6 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; - HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - - UserProcessScheduler::The().TheCurrentProcess() = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; return YES; } -- cgit v1.2.3