Spawn Processes using memory primitives rather than and elf loader.
This allows us to remove the temporary syscall for that style of process spawn.
This commit is contained in:
parent
b06c76e477
commit
23895b5c6c
26 changed files with 403 additions and 94 deletions
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
extern KernelStackManager* gKernelStackManager;
|
||||
|
||||
AddressSpace AddressSpace::ForRoot() {
|
||||
RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
||||
uint64_t cr3 = 0;
|
||||
asm volatile("mov %%cr3, %0;" : "=r"(cr3));
|
||||
return {cr3};
|
||||
return MakeRefCounted<AddressSpace>(cr3);
|
||||
}
|
||||
|
||||
AddressSpace::AddressSpace() {
|
||||
|
|
@ -22,6 +22,10 @@ uint64_t AddressSpace::AllocateUserStack() {
|
|||
}
|
||||
|
||||
uint64_t AddressSpace::GetNextMemMapAddr(uint64_t size) {
|
||||
if (size == 0) {
|
||||
panic("Zero size memmap");
|
||||
}
|
||||
size = ((size - 1) & ~0xFFF) + 0x1000;
|
||||
uint64_t addr = next_memmap_addr_;
|
||||
next_memmap_addr_ += size;
|
||||
if (next_memmap_addr_ >= 0x30'00000000) {
|
||||
|
|
@ -35,6 +39,12 @@ void AddressSpace::MapInMemoryObject(uint64_t vaddr,
|
|||
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
||||
}
|
||||
|
||||
uint64_t AddressSpace::MapInMemoryObject(const RefPtr<MemoryObject>& mem_obj) {
|
||||
uint64_t vaddr = GetNextMemMapAddr(mem_obj->size());
|
||||
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
uint64_t* AddressSpace::AllocateKernelStack() {
|
||||
return gKernelStackManager->AllocateKernelStack();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
// 0xFFFFFFFF 40000000 - 0xFFFFFFFF 7FFFFFFF : KERNEL_HEAP (1 GiB)
|
||||
// 0xFFFFFFFF 80000000 - 0xFFFFFFFF 80FFFFFF : KERNEL_CODE (16 MiB)
|
||||
// 0xFFFFFFFF 90000000 - 0xFFFFFFFF 9FFFFFFF : KERNEL_STACK (256 MiB)
|
||||
class AddressSpace {
|
||||
class AddressSpace : public KernelObject {
|
||||
public:
|
||||
enum MemoryType {
|
||||
UNSPECIFIED,
|
||||
|
|
@ -40,7 +40,7 @@ class AddressSpace {
|
|||
KERNEL_STACK,
|
||||
};
|
||||
|
||||
static AddressSpace ForRoot();
|
||||
static RefPtr<AddressSpace> ForRoot();
|
||||
|
||||
AddressSpace();
|
||||
AddressSpace(const AddressSpace&) = delete;
|
||||
|
|
@ -56,6 +56,8 @@ class AddressSpace {
|
|||
// Note this is unsafe for now as it may clobber other mappings.
|
||||
void MapInMemoryObject(uint64_t vaddr, const RefPtr<MemoryObject>& mem_obj);
|
||||
|
||||
uint64_t MapInMemoryObject(const RefPtr<MemoryObject>& mem_obj);
|
||||
|
||||
// Kernel Mappings.
|
||||
uint64_t* AllocateKernelStack();
|
||||
|
||||
|
|
@ -63,6 +65,7 @@ class AddressSpace {
|
|||
bool HandlePageFault(uint64_t vaddr);
|
||||
|
||||
private:
|
||||
friend class MakeRefCountedFriend<AddressSpace>;
|
||||
AddressSpace(uint64_t cr3) : cr3_(cr3) {}
|
||||
uint64_t cr3_ = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,13 @@ RefPtr<Process> Process::Create() {
|
|||
proc->caps_.PushBack(
|
||||
new Capability(proc, Capability::PROCESS, Z_INIT_PROC_SELF,
|
||||
ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD));
|
||||
proc->caps_.PushBack(new Capability(proc->vmas(), Capability::ADDRESS_SPACE,
|
||||
Z_INIT_AS_SELF, ZC_WRITE));
|
||||
return proc;
|
||||
}
|
||||
|
||||
Process::Process() : id_(gNextId++), state_(RUNNING) {}
|
||||
Process::Process()
|
||||
: id_(gNextId++), vmm_(MakeRefCounted<AddressSpace>()), state_(RUNNING) {}
|
||||
|
||||
RefPtr<Thread> Process::CreateThread() {
|
||||
RefPtr<Thread> thread = MakeRefCounted<Thread>(*this, next_thread_id_++);
|
||||
|
|
@ -77,3 +80,22 @@ uint64_t Process::AddCapability(const RefPtr<Thread>& thread) {
|
|||
caps_.PushBack(new Capability(thread, Capability::THREAD, cap_id, ZC_WRITE));
|
||||
return cap_id;
|
||||
}
|
||||
|
||||
uint64_t Process::AddCapability(const RefPtr<Process>& p) {
|
||||
uint64_t cap_id = next_cap_id_++;
|
||||
caps_.PushBack(new Capability(p, Capability::PROCESS, cap_id,
|
||||
ZC_WRITE | ZC_PROC_SPAWN_THREAD));
|
||||
return cap_id;
|
||||
}
|
||||
uint64_t Process::AddCapability(const RefPtr<AddressSpace>& as) {
|
||||
uint64_t cap_id = next_cap_id_++;
|
||||
caps_.PushBack(
|
||||
new Capability(as, Capability::ADDRESS_SPACE, cap_id, ZC_WRITE));
|
||||
return cap_id;
|
||||
}
|
||||
uint64_t Process::AddCapability(const RefPtr<MemoryObject>& mo) {
|
||||
uint64_t cap_id = next_cap_id_++;
|
||||
caps_.PushBack(
|
||||
new Capability(mo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE));
|
||||
return cap_id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,16 @@ class Process : public KernelObject {
|
|||
static RefPtr<Process> Create();
|
||||
|
||||
uint64_t id() const { return id_; }
|
||||
AddressSpace& vmm() { return vmm_; }
|
||||
RefPtr<AddressSpace> vmas() { return vmm_; }
|
||||
|
||||
RefPtr<Thread> CreateThread();
|
||||
RefPtr<Thread> GetThread(uint64_t tid);
|
||||
|
||||
SharedPtr<Capability> GetCapability(uint64_t cid);
|
||||
uint64_t AddCapability(const RefPtr<Thread>& t);
|
||||
uint64_t AddCapability(const RefPtr<Process>& p);
|
||||
uint64_t AddCapability(const RefPtr<AddressSpace>& as);
|
||||
uint64_t AddCapability(const RefPtr<MemoryObject>& mo);
|
||||
// Checks the state of all child threads and transitions to
|
||||
// finished if all have finished.
|
||||
void CheckState();
|
||||
|
|
@ -41,7 +44,7 @@ class Process : public KernelObject {
|
|||
Process();
|
||||
Process(uint64_t id) : id_(id), vmm_(AddressSpace::ForRoot()) {}
|
||||
uint64_t id_;
|
||||
AddressSpace vmm_;
|
||||
RefPtr<AddressSpace> vmm_;
|
||||
State state_;
|
||||
|
||||
uint64_t next_thread_id_ = 0;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ RefPtr<Thread> Thread::Create(Process& proc, uint64_t tid) {
|
|||
}
|
||||
|
||||
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
||||
uint64_t* stack_ptr = proc.vmm().AllocateKernelStack();
|
||||
uint64_t* stack_ptr = proc.vmas()->AllocateKernelStack();
|
||||
// 0: rip
|
||||
*(stack_ptr) = reinterpret_cast<uint64_t>(thread_init);
|
||||
// 1-4: rax, rcx, rdx, rbx
|
||||
|
|
@ -37,7 +37,7 @@ Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
|||
*(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.vmm().cr3();
|
||||
*(stack_ptr - 16) = proc.vmas()->cr3();
|
||||
rsp0_ = reinterpret_cast<uint64_t>(stack_ptr - 16);
|
||||
rsp0_start_ = reinterpret_cast<uint64_t>(stack_ptr);
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ void Thread::Start(uint64_t entry, uint64_t arg1, uint64_t arg2) {
|
|||
|
||||
void Thread::Init() {
|
||||
dbgln("Thread start.", pid(), id_);
|
||||
uint64_t rsp = process_.vmm().AllocateUserStack();
|
||||
uint64_t rsp = process_.vmas()->AllocateUserStack();
|
||||
SetRsp0(rsp0_start_);
|
||||
jump_user_space(rip_, rsp, arg1_, arg2_);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue