/* ------------------------------------------- Copyright ZKA Technologies. ------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Kernel::Property cKernelVersion; Kernel::Property cAutoFormatDisk; EXTERN Kernel::Boolean kAllocationInProgress; EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; struct HEAP_ALLOC_INFO final { Kernel::VoidPtr fThe; Kernel::Size fTheSz; }; struct PROCESS_BLOCK_INFO final { THREAD_INFORMATION_BLOCK* fTIB; THREAD_INFORMATION_BLOCK* fGIB; }; struct PROCESS_EXIT_INFO final { STATIC constexpr auto cReasonLen = 512; Kernel::Int64 fCode; Kernel::Char fReason[cReasonLen]; }; namespace Kernel::HAL { /// @brief Gets the system cores using the MADT. /// @param rsdPtr The 'RSD PTR' data structure. EXTERN void hal_system_get_cores(Kernel::voidPtr rsdPtr); } // namespace Kernel::HAL /* GDT. */ STATIC Kernel::HAL::Detail::NewOSGDT cGdt = { {0, 0, 0, 0x00, 0x00, 0}, // null entry {0, 0, 0, 0x9a, 0xaf, 0}, // kernel code {0, 0, 0, 0x92, 0xaf, 0}, // kernel data {0, 0, 0, 0x00, 0x00, 0}, // null entry {0, 0, 0, 0x9a, 0xaf, 0}, // user code {0, 0, 0, 0x92, 0xaf, 0}, // user data }; Kernel::Void hal_real_init(Kernel::Void) noexcept; static Kernel::User* cRoot; EXTERN_C void hal_init_platform( Kernel::HEL::HandoverInformationHeader* HandoverHeader) { /* Setup globals. */ kHandoverHeader = HandoverHeader; if (kHandoverHeader->f_Magic != kHandoverMagic && kHandoverHeader->f_Version != kHandoverVersion) { return; } hal_real_init(); } Kernel::Void hal_real_init(Kernel::Void) noexcept { // reset kAllocationInProgress field to zero. kAllocationInProgress = false; // get page size. kKernelVirtualSize = kHandoverHeader->f_VirtualSize; // get virtual address start (for the heap) kKernelVirtualStart = reinterpret_cast( reinterpret_cast(kHandoverHeader->f_VirtualStart)); // get physical address start. kKernelPhysicalStart = reinterpret_cast( reinterpret_cast(kHandoverHeader->f_PhysicalStart)); // Load memory descriptors. Kernel::HAL::RegisterGDT gdtBase; gdtBase.Base = reinterpret_cast(&cGdt); gdtBase.Limit = sizeof(Kernel::HAL::Detail::NewOSGDT) - 1; CONST Kernel::HAL::GDTLoader cGDT; cGDT.Load(gdtBase); // Load IDT now. Kernel::HAL::Register64 idtBase; idtBase.Base = (Kernel::UIntPtr)kInterruptVectorTable; idtBase.Limit = 0; CONST Kernel::HAL::IDTLoader cIDT; cIDT.Load(idtBase); // Register the basic system calls. constexpr auto cTlsInterrupt = 0x11; constexpr auto cTlsInstallInterrupt = 0x12; constexpr auto cNewInterrupt = 0x13; constexpr auto cDeleteInterrupt = 0x14; constexpr auto cExitInterrupt = 0x15; constexpr auto cLastExitInterrupt = 0x16; constexpr auto cCatalogOpen = 0x17; constexpr auto cForkRead = 0x18; constexpr auto cForkWrite = 0x19; constexpr auto cCatalogClose = 0x20; constexpr auto cCatalogRemove = 0x21; constexpr auto cCatalogCreate = 0x22; constexpr auto cRebootInterrupt = 0x23; constexpr auto cShutdownInterrupt = 0x24; constexpr auto cLPCSendMsg = 0x25; constexpr auto cLPCOpenMsg = 0x26; constexpr auto cLPCCloseMsg = 0x27; kSyscalls[cTlsInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { if (tls_check_syscall_impl(rdx) == false) { Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Crash(); } }; kSyscalls[cNewInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { // get HAC struct. HEAP_ALLOC_INFO* rdxInf = reinterpret_cast(rdx); if (!rdxInf) return; // assign the fThe field with the pointer. rdxInf->fThe = Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().New(rdxInf->fTheSz); }; kSyscalls[cDeleteInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { // get HAC struct. HEAP_ALLOC_INFO* rdxInf = reinterpret_cast(rdx); if (!rdxInf) return; // delete ptr with sz in mind. Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Delete(rdxInf->fThe, rdxInf->fTheSz); }; kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { PROCESS_BLOCK_INFO* rdxPb = reinterpret_cast(rdx); if (!rdxPb) return; // install the fTIB and fGIB. rt_install_tib(rdxPb->fTIB, rdxPb->fGIB); }; kSyscalls[cExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { PROCESS_EXIT_INFO* rdxEi = reinterpret_cast(rdx); if (!rdxEi) return; Kernel::kcout << "newoskrnl: " << rdxEi->fReason << "\r"; Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Exit(rdxEi->fCode); }; kSyscalls[cLastExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { PROCESS_EXIT_INFO* rdxEi = reinterpret_cast(rdx); if (!rdxEi) return; rdxEi->fCode = Kernel::sched_get_exit_code(); }; kSyscalls[cRebootInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { Kernel::PowerFactoryInterface pow(kHandoverHeader->f_HardwareTables.f_VendorPtr); pow.Reboot(); }; kSyscalls[cShutdownInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { Kernel::PowerFactoryInterface pow(kHandoverHeader->f_HardwareTables.f_VendorPtr); pow.Shutdown(); }; kSyscalls[cTlsInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cDeleteInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cNewInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cExitInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cLastExitInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cShutdownInterrupt].Leak().Leak()->fHooked = true; kSyscalls[cRebootInterrupt].Leak().Leak()->fHooked = true; Kernel::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); Kernel::kcout << "newoskrnl: Creating filesystem and such.\r"; auto fs = new Kernel::NewFilesystemManager(); MUST_PASS(fs); MUST_PASS(fs->GetParser()); Kernel::NewFilesystemManager::Mount(fs); delete fs->GetParser()->CreateCatalog("\\Users\\", 0, kNewFSCatalogKindDir); Kernel::kcout << "newoskrnl: Created filesystem and now creating " << kSuperUser << "..." << Kernel::endl; cRoot = new Kernel::User(Kernel::RingKind::kRingSuperUser, kSuperUser); #ifdef __DEBUG__ const auto cPassword = "6aa162f3-20f6-4143-92f9-5dd37066aedc"; #else const auto cPassword = "password"; #endif Kernel::UserManager::The()->fRootUser = cRoot; Kernel::kcout << "newoskrnl: Root is " << kSuperUser << "." << Kernel::endl; cRoot->TrySave(cPassword); Kernel::UserManager::The()->TryLogIn(cRoot, cPassword); Kernel::ke_stop(RUNTIME_CHECK_FAILED); }