Compare commits

..

No commits in common. "6c10c57bfaacf47883c1d828f43ac39c707911da" and "eb454300e694e350f66099d1e5c6656efd44a700" have entirely different histories.

12 changed files with 93 additions and 79 deletions

View File

@ -1,7 +1,6 @@
#include "include/mammoth/process.h" #include "include/mammoth/process.h"
#include <zcall.h> #include <zcall.h>
#include <zerrors.h>
#include "include/mammoth/debug.h" #include "include/mammoth/debug.h"
@ -69,7 +68,7 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) {
dbgln("Map Local"); dbgln("Map Local");
uint64_t vaddr; uint64_t vaddr;
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, mem_cap, &vaddr)); check(ZAddressSpaceMap(Z_INIT_AS_SELF, 0, mem_cap, &vaddr));
dbgln("Copy"); dbgln("Copy");
memcpy(base + program.offset, program.filesz, vaddr); memcpy(base + program.offset, program.filesz, vaddr);
@ -95,6 +94,4 @@ uint64_t SpawnProcessFromElfRegion(uint64_t program) {
dbgln("Thread start"); dbgln("Thread start");
check(ZThreadStart(thread_cap, entry_point, 0, 0)); check(ZThreadStart(thread_cap, entry_point, 0, 0));
return Z_OK;
} }

View File

@ -1,9 +1,7 @@
#include "mammoth/thread.h" #include "include/mammoth/thread.h"
#include <zcall.h> #include <zcall.h>
#include "mammoth/debug.h"
namespace { namespace {
extern "C" void thread_entry(Thread::Entry entry, void* arg1) { extern "C" void thread_entry(Thread::Entry entry, void* arg1) {
@ -15,8 +13,7 @@ extern "C" void thread_entry(Thread::Entry entry, void* arg1) {
} // namespace } // namespace
Thread::Thread(Entry e, const void* arg1) { Thread::Thread(Entry e, const void* arg1) {
check(ZThreadCreate(Z_INIT_PROC_SELF, &thread_cap_)); ZThreadCreate(Z_INIT_PROC_SELF, &thread_cap_);
check(ZThreadStart(thread_cap_, reinterpret_cast<uint64_t>(thread_entry), ZThreadStart(thread_cap_, reinterpret_cast<uint64_t>(thread_entry),
reinterpret_cast<uint64_t>(e), reinterpret_cast<uint64_t>(e), reinterpret_cast<uint64_t>(arg1));
reinterpret_cast<uint64_t>(arg1)));
} }

View File

@ -1,12 +1,11 @@
#include <mammoth/debug.h> #include <mammoth/debug.h>
#include <mammoth/process.h> #include <mammoth/process.h>
#include <zcall.h>
constexpr uint64_t prog2 = 0x00000020'00000000;
int main() { int main() {
dbgln("Testing"); dbgln("Testing");
uint64_t vaddr; check(SpawnProcessFromElfRegion(prog2));
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, Z_INIT_BOOT_VMMO, &vaddr));
check(SpawnProcessFromElfRegion(vaddr));
dbgln("Return"); dbgln("Return");
return 0; return 0;
} }

View File

@ -16,6 +16,7 @@
#define ZC_PROC_SPAWN_THREAD 0x101 #define ZC_PROC_SPAWN_THREAD 0x101
#define Z_INIT_PROC_SELF 0x1 #define Z_INIT_PROC_SELF 0x1
#define Z_INIT_AS_SELF 0x2
// Thread Calls. // Thread Calls.
#define Z_THREAD_CREATE 0x10 #define Z_THREAD_CREATE 0x10
@ -26,19 +27,15 @@
#define Z_ADDRESS_SPACE_MAP 0x21 #define Z_ADDRESS_SPACE_MAP 0x21
#define Z_ADDRESS_SPACE_UNMAP 0x22 #define Z_ADDRESS_SPACE_UNMAP 0x22
#define Z_INIT_VMAS_SELF 0x20
#define Z_MEMORY_OBJECT_CREATE 0x30 #define Z_MEMORY_OBJECT_CREATE 0x30
#define Z_INIT_BOOT_VMMO 0x31
// Debugging Calls. // Debugging Calls.
#define Z_DEBUG_PRINT 0x10000000 #define Z_DEBUG_PRINT 0x10000000
void ZProcessExit(uint64_t code); void ZProcessExit(uint64_t code);
[[nodiscard]] uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t* new_proc_cap, [[nodiscard]] uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t* new_proc_cap,
uint64_t* new_vmas_cap); uint64_t* new_as_cap);
// UNUSED for now, I think we can get away with just starting a thread. // UNUSED for now, I think we can get away with just starting a thread.
[[nodiscard]] uint64_t ZProcessStart(uint64_t proc_cap, uint64_t thread_cap, [[nodiscard]] uint64_t ZProcessStart(uint64_t proc_cap, uint64_t thread_cap,
@ -52,8 +49,8 @@ void ZProcessExit(uint64_t code);
void ZThreadExit(); void ZThreadExit();
[[nodiscard]] uint64_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset, [[nodiscard]] uint64_t ZAddressSpaceMap(uint64_t as_cap, uint64_t offset,
uint64_t vmmo_cap, uint64_t* vaddr); uint64_t mem_cap, uint64_t* vaddr);
[[nodiscard]] uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap); [[nodiscard]] uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* mem_cap);
[[nodiscard]] uint64_t ZDebug(const char* message); [[nodiscard]] uint64_t ZDebug(const char* message);

View File

@ -2,7 +2,6 @@
#include "boot/boot_info.h" #include "boot/boot_info.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "include/zcall.h"
#include "lib/ref_ptr.h" #include "lib/ref_ptr.h"
#include "memory/paging_util.h" #include "memory/paging_util.h"
#include "object/process.h" #include "object/process.h"
@ -108,6 +107,7 @@ const limine_file& GetInitProgram(const char* path) {
void LoadInitProgram() { void LoadInitProgram() {
DumpModules(); DumpModules();
const limine_file& init_prog = GetInitProgram("/sys/test"); const limine_file& init_prog = GetInitProgram("/sys/test");
const limine_file& prog2 = GetInitProgram("/sys/test2");
RefPtr<Process> proc = Process::Create(); RefPtr<Process> proc = Process::Create();
gProcMan->InsertProcess(proc); gProcMan->InsertProcess(proc);
@ -115,11 +115,9 @@ void LoadInitProgram() {
uint64_t entry = LoadElfProgram( uint64_t entry = LoadElfProgram(
*proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size); *proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size);
const limine_file& prog2 = GetInitProgram("/sys/test2"); CopyIntoNonResidentProcess(reinterpret_cast<uint64_t>(prog2.address),
RefPtr<MemoryObject> prog2_vmmo = MakeRefCounted<MemoryObject>(prog2.size); prog2.size, *proc,
prog2_vmmo->CopyBytesToObject(reinterpret_cast<uint64_t>(prog2.address), proc->vmas()->GetNextMemMapAddr(prog2.size));
prog2.size);
proc->AddCapability(Z_INIT_BOOT_VMMO, prog2_vmmo);
proc->CreateThread()->Start(entry, 0, 0); proc->CreateThread()->Start(entry, 0, 0);
} }

View File

@ -97,6 +97,22 @@ uint64_t CurrCr3() {
return pml4_addr; return pml4_addr;
} }
void CopyPageIntoNonResidentProcess(uint64_t base, uint64_t size,
Process& dest_proc, uint64_t dest_virt) {
if (size > 0x1000) {
panic("NR copy > 1 page");
}
if (dest_virt & 0xFFF) {
panic("NR copy to non page aligned");
}
uint64_t phys = AllocatePageIfNecessary(dest_virt, dest_proc.vmas()->cr3());
uint8_t* src = reinterpret_cast<uint8_t*>(base);
uint8_t* dest =
reinterpret_cast<uint8_t*>(phys + boot::GetHigherHalfDirectMap());
for (uint64_t i = 0; i < size; i++) {
dest[i] = src[i];
}
}
} // namespace } // namespace
void InitializePml4(uint64_t pml4_physical_addr) { void InitializePml4(uint64_t pml4_physical_addr) {
@ -151,8 +167,10 @@ void MapPage(uint64_t cr3, uint64_t vaddr, uint64_t paddr) {
} }
} }
uint64_t AllocatePageIfNecessary(uint64_t addr) { uint64_t AllocatePageIfNecessary(uint64_t addr, uint64_t cr3) {
uint64_t cr3 = CurrCr3(); if (cr3 == 0) {
cr3 = CurrCr3();
}
uint64_t phys = PagePhysIfResident(cr3, addr); uint64_t phys = PagePhysIfResident(cr3, addr);
if (phys) { if (phys) {
return phys; return phys;
@ -173,3 +191,16 @@ void EnsureResident(uint64_t addr, uint64_t size) {
addr += 0x1000; addr += 0x1000;
} }
} }
void CopyIntoNonResidentProcess(uint64_t base, uint64_t size,
Process& dest_proc, uint64_t dest_virt) {
while (size > 0) {
uint64_t to_copy = size > 0x1000 ? 0x1000 : size;
CopyPageIntoNonResidentProcess(base, to_copy, dest_proc, dest_virt);
size -= to_copy;
base += 0x1000;
dest_virt += 0x1000;
}
}

View File

@ -8,5 +8,8 @@ void InitializePml4(uint64_t pml4_physical_addr);
void MapPage(uint64_t cr3, uint64_t vaddr, uint64_t paddr); void MapPage(uint64_t cr3, uint64_t vaddr, uint64_t paddr);
uint64_t AllocatePageIfNecessary(uint64_t addr); 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,
Process& dest_proc, uint64_t dest_virt);

View File

@ -26,12 +26,12 @@ RefPtr<Process> Process::Create() {
new Capability(proc, Capability::PROCESS, Z_INIT_PROC_SELF, new Capability(proc, Capability::PROCESS, Z_INIT_PROC_SELF,
ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD)); ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD));
proc->caps_.PushBack(new Capability(proc->vmas(), Capability::ADDRESS_SPACE, proc->caps_.PushBack(new Capability(proc->vmas(), Capability::ADDRESS_SPACE,
Z_INIT_VMAS_SELF, ZC_WRITE)); Z_INIT_AS_SELF, ZC_WRITE));
return proc; return proc;
} }
Process::Process() Process::Process()
: id_(gNextId++), vmas_(MakeRefCounted<AddressSpace>()), state_(RUNNING) {} : id_(gNextId++), vmm_(MakeRefCounted<AddressSpace>()), state_(RUNNING) {}
RefPtr<Thread> Process::CreateThread() { RefPtr<Thread> Process::CreateThread() {
RefPtr<Thread> thread = MakeRefCounted<Thread>(*this, next_thread_id_++); RefPtr<Thread> thread = MakeRefCounted<Thread>(*this, next_thread_id_++);
@ -87,20 +87,15 @@ uint64_t Process::AddCapability(const RefPtr<Process>& p) {
ZC_WRITE | ZC_PROC_SPAWN_THREAD)); ZC_WRITE | ZC_PROC_SPAWN_THREAD));
return cap_id; return cap_id;
} }
uint64_t Process::AddCapability(const RefPtr<AddressSpace>& vmas) { uint64_t Process::AddCapability(const RefPtr<AddressSpace>& as) {
uint64_t cap_id = next_cap_id_++; uint64_t cap_id = next_cap_id_++;
caps_.PushBack( caps_.PushBack(
new Capability(vmas, Capability::ADDRESS_SPACE, cap_id, ZC_WRITE)); new Capability(as, Capability::ADDRESS_SPACE, cap_id, ZC_WRITE));
return cap_id; return cap_id;
} }
uint64_t Process::AddCapability(const RefPtr<MemoryObject>& vmmo) { uint64_t Process::AddCapability(const RefPtr<MemoryObject>& mo) {
uint64_t cap_id = next_cap_id_++; uint64_t cap_id = next_cap_id_++;
caps_.PushBack( caps_.PushBack(
new Capability(vmmo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE)); new Capability(mo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE));
return cap_id; return cap_id;
} }
void Process::AddCapability(uint64_t cap_id, const RefPtr<MemoryObject>& vmmo) {
caps_.PushBack(
new Capability(vmmo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE));
}

View File

@ -23,7 +23,7 @@ class Process : public KernelObject {
static RefPtr<Process> Create(); static RefPtr<Process> Create();
uint64_t id() const { return id_; } uint64_t id() const { return id_; }
RefPtr<AddressSpace> vmas() { return vmas_; } RefPtr<AddressSpace> vmas() { return vmm_; }
RefPtr<Thread> CreateThread(); RefPtr<Thread> CreateThread();
RefPtr<Thread> GetThread(uint64_t tid); RefPtr<Thread> GetThread(uint64_t tid);
@ -31,10 +31,8 @@ class Process : public KernelObject {
SharedPtr<Capability> GetCapability(uint64_t cid); SharedPtr<Capability> GetCapability(uint64_t cid);
uint64_t AddCapability(const RefPtr<Thread>& t); uint64_t AddCapability(const RefPtr<Thread>& t);
uint64_t AddCapability(const RefPtr<Process>& p); uint64_t AddCapability(const RefPtr<Process>& p);
uint64_t AddCapability(const RefPtr<AddressSpace>& vmas); uint64_t AddCapability(const RefPtr<AddressSpace>& as);
uint64_t AddCapability(const RefPtr<MemoryObject>& vmmo); uint64_t AddCapability(const RefPtr<MemoryObject>& mo);
void AddCapability(uint64_t cap_id, const RefPtr<MemoryObject>& vmmo);
// Checks the state of all child threads and transitions to // Checks the state of all child threads and transitions to
// finished if all have finished. // finished if all have finished.
void CheckState(); void CheckState();
@ -44,9 +42,9 @@ class Process : public KernelObject {
private: private:
friend class MakeRefCountedFriend<Process>; friend class MakeRefCountedFriend<Process>;
Process(); Process();
Process(uint64_t id) : id_(id), vmas_(AddressSpace::ForRoot()) {} Process(uint64_t id) : id_(id), vmm_(AddressSpace::ForRoot()) {}
uint64_t id_; uint64_t id_;
RefPtr<AddressSpace> vmas_; RefPtr<AddressSpace> vmm_;
State state_; State state_;
uint64_t next_thread_id_ = 0; uint64_t next_thread_id_ = 0;

View File

@ -72,7 +72,7 @@ uint64_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
gProcMan->InsertProcess(proc); gProcMan->InsertProcess(proc);
resp->proc_cap = curr_proc.AddCapability(proc); resp->proc_cap = curr_proc.AddCapability(proc);
resp->vmas_cap = curr_proc.AddCapability(proc->vmas()); resp->as_cap = curr_proc.AddCapability(proc->vmas());
return Z_OK; return Z_OK;
} }
@ -120,34 +120,33 @@ uint64_t ThreadStart(ZThreadStartReq* req) {
uint64_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) { uint64_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap); auto as_cap = curr_proc.GetCapability(req->as_cap);
auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap); auto mem_cap = curr_proc.GetCapability(req->mem_cap);
if (vmas_cap.empty() || vmmo_cap.empty()) { if (as_cap.empty() || mem_cap.empty()) {
return ZE_NOT_FOUND; return ZE_NOT_FOUND;
} }
if (!vmas_cap->CheckType(Capability::ADDRESS_SPACE) || if (!as_cap->CheckType(Capability::ADDRESS_SPACE) ||
!vmmo_cap->CheckType(Capability::MEMORY_OBJECT)) { !mem_cap->CheckType(Capability::MEMORY_OBJECT)) {
return ZE_INVALID; return ZE_INVALID;
} }
if (!vmas_cap->HasPermissions(ZC_WRITE) || if (!as_cap->HasPermissions(ZC_WRITE) || !mem_cap->HasPermissions(ZC_WRITE)) {
!vmmo_cap->HasPermissions(ZC_WRITE)) {
return ZE_DENIED; return ZE_DENIED;
} }
auto vmas = vmas_cap->obj<AddressSpace>(); auto as = as_cap->obj<AddressSpace>();
auto vmmo = vmmo_cap->obj<MemoryObject>(); auto mo = mem_cap->obj<MemoryObject>();
// FIXME: Validation necessary. // FIXME: Validation necessary.
if (req->vmas_offset != 0) { if (req->offset != 0) {
vmas->MapInMemoryObject(req->vmas_offset, vmmo); as->MapInMemoryObject(req->offset, mo);
resp->vaddr = req->vmas_offset; resp->vaddr = req->offset;
} else { } else {
resp->vaddr = vmas->MapInMemoryObject(vmmo); resp->vaddr = as->MapInMemoryObject(mo);
} }
} }
uint64_t MemoryObjectCreate(ZMemoryObjectCreateReq* req, uint64_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
ZMemoryObjectCreateResp* resp) { ZMemoryObjectCreateResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
resp->vmmo_cap = resp->mem_cap =
curr_proc.AddCapability(MakeRefCounted<MemoryObject>(req->size)); curr_proc.AddCapability(MakeRefCounted<MemoryObject>(req->size));
return Z_OK; return Z_OK;
} }

View File

@ -30,14 +30,14 @@ void ZProcessExit(uint64_t code) {
} }
uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t* new_proc_cap, uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t* new_proc_cap,
uint64_t* new_vmas_cap) { uint64_t* new_as_cap) {
ZProcessSpawnReq req{ ZProcessSpawnReq req{
.proc_cap = proc_cap, .proc_cap = proc_cap,
}; };
ZProcessSpawnResp resp; ZProcessSpawnResp resp;
uint64_t ret = SysCall2(Z_PROCESS_SPAWN, &req, &resp); uint64_t ret = SysCall2(Z_PROCESS_SPAWN, &req, &resp);
*new_proc_cap = resp.proc_cap; *new_proc_cap = resp.proc_cap;
*new_vmas_cap = resp.vmas_cap; *new_as_cap = resp.as_cap;
return ret; return ret;
} }
@ -64,25 +64,25 @@ uint64_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1,
void ZThreadExit() { SysCall0(Z_THREAD_EXIT); } void ZThreadExit() { SysCall0(Z_THREAD_EXIT); }
uint64_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset, uint64_t ZAddressSpaceMap(uint64_t as_cap, uint64_t offset, uint64_t mem_cap,
uint64_t vmmo_cap, uint64_t* vaddr) { uint64_t* vaddr) {
ZAddressSpaceMapReq req{ ZAddressSpaceMapReq req{
.vmas_cap = vmas_cap, .as_cap = as_cap,
.vmas_offset = vmas_offset, .offset = offset,
.vmmo_cap = vmmo_cap, .mem_cap = mem_cap,
}; };
ZAddressSpaceMapResp resp; ZAddressSpaceMapResp resp;
uint64_t ret = SysCall2(Z_ADDRESS_SPACE_MAP, &req, &resp); uint64_t ret = SysCall2(Z_ADDRESS_SPACE_MAP, &req, &resp);
*vaddr = resp.vaddr; *vaddr = resp.vaddr;
return ret; return ret;
} }
uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) { uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* mem_cap) {
ZMemoryObjectCreateReq req{ ZMemoryObjectCreateReq req{
.size = size, .size = size,
}; };
ZMemoryObjectCreateResp resp; ZMemoryObjectCreateResp resp;
uint64_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE, &req, &resp); uint64_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE, &req, &resp);
*vmmo_cap = resp.vmmo_cap; *mem_cap = resp.mem_cap;
return ret; return ret;
} }

View File

@ -8,7 +8,7 @@ struct ZProcessSpawnReq {
struct ZProcessSpawnResp { struct ZProcessSpawnResp {
uint64_t proc_cap; uint64_t proc_cap;
uint64_t vmas_cap; uint64_t as_cap;
}; };
struct ZThreadCreateReq { struct ZThreadCreateReq {
@ -27,9 +27,9 @@ struct ZThreadStartReq {
}; };
struct ZAddressSpaceMapReq { struct ZAddressSpaceMapReq {
uint64_t vmas_cap; uint64_t as_cap;
uint64_t vmas_offset; uint64_t offset;
uint64_t vmmo_cap; uint64_t mem_cap;
}; };
struct ZAddressSpaceMapResp { struct ZAddressSpaceMapResp {
@ -41,5 +41,5 @@ struct ZMemoryObjectCreateReq {
}; };
struct ZMemoryObjectCreateResp { struct ZMemoryObjectCreateResp {
uint64_t vmmo_cap; uint64_t mem_cap;
}; };