Improving kernel ELF loader
This commit is contained in:
parent
b2c2b7c45a
commit
4e76a9a922
@ -54,6 +54,7 @@ void PMap_Dump(AS *space);
|
||||
|
||||
// Manipulate User Memory
|
||||
bool PMap_Map(AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags);
|
||||
bool PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags);
|
||||
bool PMap_Unmap(AS *as, uint64_t virt, uint64_t pages);
|
||||
|
||||
// Manipulate Kernel Memory
|
||||
|
@ -239,6 +239,32 @@ PMap_Unmap(AS *as, uint64_t va, uint64_t pages)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags)
|
||||
{
|
||||
int i;
|
||||
uint64_t pages = (len + PGSIZE - 1) / PGSIZE;
|
||||
PageEntry *entry;
|
||||
|
||||
ASSERT((virt & PGMASK) == 0);
|
||||
|
||||
for (i = 0; i < pages; i++) {
|
||||
uint64_t va = virt + PGSIZE * i;
|
||||
PMapLookupEntry(as, va, &entry, PGSIZE);
|
||||
if (!entry) {
|
||||
kprintf("Map failed to allocate memory!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((*entry & PTE_P) != PTE_P) {
|
||||
void *pg = PAlloc_AllocPage();
|
||||
*entry = (uint64_t)DMVA2PA(pg) | PTE_P | PTE_U | flags;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PMap_SystemLookup(uint64_t va, PageEntry **entry, int size)
|
||||
{
|
||||
|
@ -68,10 +68,10 @@ memset(void *dst, int c, size_t length)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
|
||||
do {
|
||||
while (length-- != 0) {
|
||||
*p = c;
|
||||
p += 1;
|
||||
} while (--length != 0);
|
||||
};
|
||||
|
||||
return dst;
|
||||
}
|
||||
@ -82,11 +82,11 @@ memcpy(void *dst, const void *src, size_t length)
|
||||
uint8_t *d = (uint8_t *)dst;
|
||||
const uint8_t *s = (const uint8_t *)src;
|
||||
|
||||
do {
|
||||
while (length-- != 0) {
|
||||
*d = *s;
|
||||
d += 1;
|
||||
s += 1;
|
||||
} while (--length != 0);
|
||||
};
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
@ -38,13 +38,14 @@ Loader_CheckHeader(const Elf64_Ehdr *ehdr)
|
||||
}
|
||||
|
||||
bool
|
||||
Loader_Load(Thread *thr, void *buf, uint64_t len)
|
||||
Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
|
||||
{
|
||||
int i;
|
||||
const Elf64_Ehdr *ehdr;
|
||||
const Elf64_Phdr *phdr;
|
||||
AS *as = thr->space;
|
||||
|
||||
ehdr = (const Elf64_Ehdr *)buf;
|
||||
ehdr = (const Elf64_Ehdr *)(buf);
|
||||
phdr = (const Elf64_Phdr *)(buf + ehdr->e_phoff);
|
||||
|
||||
if (!Loader_CheckHeader(ehdr)) {
|
||||
@ -52,20 +53,46 @@ Loader_Load(Thread *thr, void *buf, uint64_t len)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
kprintf("%8s %16s %8s %8s\n", "Offset", "VAddr", "FileSize", "MemSize");
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
kprintf("%08llx %016llx %08llx %08llx\n", phdr[i].p_offset,
|
||||
phdr[i].p_vaddr, phdr[i].p_filesz, phdr[i].p_memsz);
|
||||
ASSERT(phdr[i].p_type != PT_DYNAMIC);
|
||||
if (phdr[i].p_type == PT_LOAD) {
|
||||
uint64_t va = phdr[i].p_vaddr;
|
||||
uint64_t memsz = phdr[i].p_memsz;
|
||||
kprintf("%08llx %016llx %08llx %08llx\n", phdr[i].p_offset,
|
||||
phdr[i].p_vaddr, phdr[i].p_filesz, phdr[i].p_memsz);
|
||||
|
||||
// Make sure it is page aligned
|
||||
va = va & ~(uint64_t)PGMASK;
|
||||
memsz += phdr[i].p_vaddr - va;
|
||||
|
||||
kprintf("%016llx %08llx\n", va, memsz);
|
||||
if (!PMap_AllocMap(as, va, phdr[i].p_memsz, PTE_W)) {
|
||||
// XXX: Cleanup!
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AS *as = thr->space;
|
||||
void *stack = PAlloc_AllocPage();
|
||||
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
|
||||
PMap_Map(as, (uint64_t)DMVA2PA(buf), phdr[0].p_vaddr, 1, 0);
|
||||
PMap_LoadAS(as); // Reload CR3
|
||||
//PMap_Dump(as);
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
ASSERT(phdr[i].p_type != PT_DYNAMIC);
|
||||
if (phdr[i].p_type == PT_LOAD) {
|
||||
if (phdr[i].p_filesz != 0) {
|
||||
VFS_Read(vn, (void *)phdr[i].p_vaddr,
|
||||
phdr[i].p_offset, phdr[i].p_filesz);
|
||||
}
|
||||
memset((void *)(phdr[i].p_vaddr + phdr[i].p_filesz),
|
||||
0,
|
||||
(uintptr_t)(phdr[i].p_memsz - phdr[i].p_filesz));
|
||||
}
|
||||
}
|
||||
|
||||
TrapFrame tf;
|
||||
memset(&tf, 0, sizeof(tf));
|
||||
@ -97,9 +124,10 @@ Loader_LoadInit()
|
||||
status = VFS_Read(init, pg, 0, 1024);
|
||||
if (status < 0)
|
||||
Panic("Reading init process failed!");
|
||||
VFS_Close(init);
|
||||
|
||||
Thread *thr = Thread_Current();
|
||||
Loader_Load(thr, pg, 1024);
|
||||
Loader_Load(thr, init, pg, 1024);
|
||||
|
||||
VFS_Close(init);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user