#include #include #include #include #include #include #include #include "../Common/bootinfo.h" void ModuleLoad(BootModule* module) { OSProcess* userProc = HeapAllocate(sizeof(OSProcess)); MemorySet(userProc, 0, sizeof(OSProcess)); userProc->id = 1; // TODO: id gen userProc->state = OSTaskStateRunning; StringCopy(userProc->name, module->name); Address userL0Phys = (Address)PMMAllocatePage(); Address* userL0Virt = (Address*)VMPhysToHHDM(userL0Phys); MemorySet(userL0Virt, 0, kVMPageSize); userProc->l0Table = userL0Virt; Address physBase = module->physicalBase; Address virtBase = module->virtualBase; Size modSize = module->size; UInt64 codeFlags = kPTENormalMem | kPTEUser | kPTEAccessRW | kPTEPrivNX; // TODO: kill RWX for (Size i = 0; i < modSize; i += kVMPageSize) { VMMMapPage((Address*)userL0Phys, physBase + i, virtBase + i, codeFlags); } CPUCleanAndInvalidateCode((void*)VMPhysToHHDM(physBase), modSize); Address stackPhys = (Address)PMMAllocatePage(); Address userStackVirt = 0x80000000; UInt64 stackFlags = kPTENormalMem | kPTEUser | kPTEAccessRW | kPTEPrivNX | kPTEUserNX; VMMMapPage((Address*)userL0Phys, stackPhys, userStackVirt, stackFlags); void (*userEntryPoint)() = (void(*)())module->entry; if ((Address)userEntryPoint == 0x0) { OSLog("Skipping module %s: entry point is 0x0.\n", module->name); return; } SchedulerSpawn(userEntryPoint, userProc, true, userStackVirt + kVMPageSize); }