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