Move PML4 initialization into the VirtualMemory class.
This commit is contained in:
		
							parent
							
								
									f22dd66c8d
								
							
						
					
					
						commit
						1db93e5b12
					
				|  | @ -48,7 +48,7 @@ typedef struct { | |||
| 
 | ||||
| }  // namespace
 | ||||
| 
 | ||||
| uint64_t LoadElfProgram(uint64_t cr3, uint64_t base, uint64_t offset) { | ||||
| uint64_t LoadElfProgram(Process& dest_proc, uint64_t base, uint64_t offset) { | ||||
|   Elf64Header* header = reinterpret_cast<Elf64Header*>(base); | ||||
|   dbgln("phoff: %u phnum: %u", header->phoff, header->phnum); | ||||
|   Elf64ProgramHeader* programs = | ||||
|  | @ -60,7 +60,7 @@ uint64_t LoadElfProgram(uint64_t cr3, uint64_t base, uint64_t offset) { | |||
|         "filesz: %u, memsz: %u, align: %u", | ||||
|         program.type, program.flags, program.offset, program.vaddr, | ||||
|         program.paddr, program.filesz, program.memsz, program.align); | ||||
|     CopyIntoNonResidentProcess(base + program.offset, program.filesz, cr3, | ||||
|     CopyIntoNonResidentProcess(base + program.offset, program.filesz, dest_proc, | ||||
|                                program.vaddr); | ||||
|   } | ||||
|   return header->entry; | ||||
|  |  | |||
|  | @ -2,5 +2,7 @@ | |||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "scheduler/process.h" | ||||
| 
 | ||||
| // Loads the elf program and returns its entry point.
 | ||||
| uint64_t LoadElfProgram(uint64_t cr3, uint64_t base, uint64_t length); | ||||
| uint64_t LoadElfProgram(Process& dest_proc, uint64_t base, uint64_t length); | ||||
|  |  | |||
|  | @ -43,12 +43,11 @@ void LoadInitProgram() { | |||
|   SharedPtr<Process> proc = MakeShared<Process>(); | ||||
|   gProcMan->InsertProcess(proc); | ||||
| 
 | ||||
|   uint64_t entry = | ||||
|       LoadElfProgram(proc->cr3(), reinterpret_cast<uint64_t>(init_prog.address), | ||||
|                      init_prog.size); | ||||
|   uint64_t entry = LoadElfProgram( | ||||
|       *proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size); | ||||
| 
 | ||||
|   CopyIntoNonResidentProcess(reinterpret_cast<uint64_t>(prog2.address), | ||||
|                              prog2.size, proc->cr3(), | ||||
|                              prog2.size, *proc, | ||||
|                              proc->vmm().GetNextMemMapAddr(prog2.size)); | ||||
| 
 | ||||
|   proc->CreateThread(entry); | ||||
|  |  | |||
|  | @ -174,15 +174,15 @@ void EnsureResident(uint64_t addr, uint64_t size) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void CopyIntoNonResidentProcess(uint64_t base, uint64_t size, uint64_t dest_cr3, | ||||
|                                 uint64_t dest_virt) { | ||||
| void CopyIntoNonResidentProcess(uint64_t base, uint64_t size, | ||||
|                                 Process& dest_proc, uint64_t dest_virt) { | ||||
|   if (size > 0x1000) { | ||||
|     panic("Unimplemented NR copy > 1 page"); | ||||
|   } | ||||
|   if (dest_virt & 0xFFF) { | ||||
|     panic("Unimplemented NR copy to non page aligned"); | ||||
|   } | ||||
|   uint64_t phys = AllocatePageIfNecessary(dest_virt, dest_cr3); | ||||
|   uint64_t phys = AllocatePageIfNecessary(dest_virt, dest_proc.vmm().cr3()); | ||||
|   uint8_t* src = reinterpret_cast<uint8_t*>(base); | ||||
|   uint8_t* dest = | ||||
|       reinterpret_cast<uint8_t*>(phys + boot::GetHigherHalfDirectMap()); | ||||
|  |  | |||
|  | @ -2,10 +2,12 @@ | |||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "scheduler/process.h" | ||||
| 
 | ||||
| void InitializePml4(uint64_t pml4_physical_addr); | ||||
| 
 | ||||
| uint64_t AllocatePageIfNecessary(uint64_t addr, uint64_t cr3 = 0); | ||||
| void EnsureResident(uint64_t addr, uint64_t size); | ||||
| 
 | ||||
| void CopyIntoNonResidentProcess(uint64_t base, uint64_t size, uint64_t dest_cr3, | ||||
|                                 uint64_t dest_virt); | ||||
| void CopyIntoNonResidentProcess(uint64_t base, uint64_t size, | ||||
|                                 Process& dest_proc, uint64_t dest_virt); | ||||
|  |  | |||
|  | @ -1,9 +1,22 @@ | |||
| #include "memory/virtual_memory.h" | ||||
| 
 | ||||
| #include "memory/kernel_stack_manager.h" | ||||
| #include "memory/paging_util.h" | ||||
| #include "memory/physical_memory.h" | ||||
| 
 | ||||
| extern KernelStackManager* gKernelStackManager; | ||||
| 
 | ||||
| VirtualMemory VirtualMemory::ForRoot() { | ||||
|   uint64_t cr3 = 0; | ||||
|   asm volatile("mov %%cr3, %0;" : "=r"(cr3)); | ||||
|   return {cr3}; | ||||
| } | ||||
| 
 | ||||
| VirtualMemory::VirtualMemory() { | ||||
|   cr3_ = phys_mem::AllocatePage(); | ||||
|   InitializePml4(cr3_); | ||||
| } | ||||
| 
 | ||||
| uint64_t* VirtualMemory::AllocateKernelStack() { | ||||
|   return gKernelStackManager->AllocateKernelStack(); | ||||
| } | ||||
|  |  | |||
|  | @ -38,16 +38,21 @@ class VirtualMemory { | |||
|     KERNEL_STACK, | ||||
|   }; | ||||
| 
 | ||||
|   VirtualMemory() {} | ||||
|   static VirtualMemory ForRoot(); | ||||
| 
 | ||||
|   VirtualMemory(); | ||||
|   VirtualMemory(const VirtualMemory&) = delete; | ||||
|   VirtualMemory(VirtualMemory&&) = delete; | ||||
| 
 | ||||
|   uint64_t cr3() { return cr3_; } | ||||
| 
 | ||||
|   uint64_t GetNextMemMapAddr(uint64_t size); | ||||
| 
 | ||||
|   // Kernel
 | ||||
|   uint64_t* AllocateKernelStack(); | ||||
| 
 | ||||
|  private: | ||||
|   VirtualMemory(uint64_t cr3) : cr3_(cr3) {} | ||||
|   uint64_t cr3_ = 0; | ||||
| 
 | ||||
|   uint64_t next_memmap_addr_ = 0x20'00000000; | ||||
|  |  | |||
|  | @ -13,19 +13,14 @@ static uint64_t gNextId = 1; | |||
| } | ||||
| 
 | ||||
| SharedPtr<Process> Process::RootProcess() { | ||||
|   uint64_t pml4_addr = 0; | ||||
|   asm volatile("mov %%cr3, %0;" : "=r"(pml4_addr)); | ||||
|   SharedPtr<Process> proc(new Process(0, pml4_addr)); | ||||
|   SharedPtr<Process> proc(new Process(0)); | ||||
|   proc->threads_.PushBack(Thread::RootThread(*proc)); | ||||
|   proc->next_thread_id_ = 1; | ||||
| 
 | ||||
|   return proc; | ||||
| } | ||||
| 
 | ||||
| Process::Process() : id_(gNextId++), state_(RUNNING) { | ||||
|   cr3_ = phys_mem::AllocatePage(); | ||||
|   InitializePml4(cr3_); | ||||
| } | ||||
| Process::Process() : id_(gNextId++), state_(RUNNING) {} | ||||
| 
 | ||||
| void Process::CreateThread(uint64_t entry) { | ||||
|   Thread* thread = new Thread(*this, next_thread_id_++, entry); | ||||
|  |  | |||
|  | @ -21,7 +21,6 @@ class Process { | |||
|   Process(); | ||||
| 
 | ||||
|   uint64_t id() const { return id_; } | ||||
|   uint64_t cr3() const { return cr3_; } | ||||
|   VirtualMemory& vmm() { return vmm_; } | ||||
| 
 | ||||
|   void CreateThread(uint64_t entry); | ||||
|  | @ -34,10 +33,9 @@ class Process { | |||
|   State GetState() { return state_; } | ||||
| 
 | ||||
|  private: | ||||
|   Process(uint64_t id, uint64_t cr3) : id_(id), cr3_(cr3) {} | ||||
|   Process(uint64_t id) : id_(id), vmm_(VirtualMemory::ForRoot()) {} | ||||
|   uint64_t id_; | ||||
|   VirtualMemory vmm_; | ||||
|   uint64_t cr3_; | ||||
|   State state_; | ||||
| 
 | ||||
|   uint64_t next_thread_id_ = 0; | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ Thread::Thread(Process& proc, uint64_t tid, uint64_t entry) | |||
|   *(stack_ptr - 5) = reinterpret_cast<uint64_t>(stack_ptr + 1); | ||||
|   // 6-15: rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15
 | ||||
|   // 16: cr3
 | ||||
|   *(stack_ptr - 16) = proc.cr3(); | ||||
|   *(stack_ptr - 16) = proc.vmm().cr3(); | ||||
|   rsp0_ = reinterpret_cast<uint64_t>(stack_ptr - 16); | ||||
|   rsp0_start_ = reinterpret_cast<uint64_t>(stack_ptr); | ||||
| } | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ uint64_t ProcessSpawn(ZProcessSpawnReq* req) { | |||
|   dbgln("Proc spawn: %u:%u", req->elf_base, req->elf_size); | ||||
|   SharedPtr<Process> proc = MakeShared<Process>(); | ||||
|   gProcMan->InsertProcess(proc); | ||||
|   uint64_t entry = LoadElfProgram(proc->cr3(), req->elf_base, req->elf_size); | ||||
|   uint64_t entry = LoadElfProgram(*proc, req->elf_base, req->elf_size); | ||||
|   proc->CreateThread(entry); | ||||
|   return 0; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue