Improving kernel ELF loader

This commit is contained in:
Ali Mashtizadeh 2014-10-12 20:22:52 -07:00
parent b2c2b7c45a
commit 4e76a9a922
4 changed files with 69 additions and 14 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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);
}