tasking: fix ELF file execution
This commit is contained in:
@@ -8,6 +8,10 @@
|
||||
|
||||
#define DivRoundUp(number, divisor) ((number + divisor - 1) / divisor)
|
||||
|
||||
#define USER_STACK_TOP 0xBFFFFFF0//0xC0000000 // Top of user space memory
|
||||
#define USER_STACK_SIZE 0x4000 // 16KB stack (4 pages)
|
||||
#define USER_STACK_BOTTOM (USER_STACK_TOP - USER_STACK_SIZE)
|
||||
|
||||
disk_ops_t ops1 =
|
||||
{
|
||||
.read = ata_read,
|
||||
@@ -19,16 +23,16 @@ static fat_t g_fat;
|
||||
int read_file(const char* path, uint8_t** buffer)
|
||||
{
|
||||
file_t file;
|
||||
int err = fat_fopen(&file, path, "r");
|
||||
if (err)
|
||||
return err;
|
||||
int err = fat_fopen(&file, path, "r");
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
uint32_t file_size = fat_fsize(&file);
|
||||
printf("file_size: %X\n", file_size);
|
||||
|
||||
uint8_t buf[512];
|
||||
//memset(buf, 0, 512);
|
||||
printf("heh\n");
|
||||
uint8_t buf[512];
|
||||
//memset(buf, 0, 512);
|
||||
printf("heh\n");
|
||||
|
||||
*buffer = (uint8_t*)malloc(file_size);
|
||||
//memset(*buffer, 0, file_size);
|
||||
@@ -36,35 +40,35 @@ int read_file(const char* path, uint8_t** buffer)
|
||||
printf("eeee\n");
|
||||
|
||||
|
||||
int cnt = fat_fread(&file, *buffer, file_size);
|
||||
int cnt = fat_fread(&file, *buffer, file_size);
|
||||
|
||||
/*for (;;)
|
||||
{
|
||||
int cnt = fat_fread(&file, buf, 512);
|
||||
if (cnt < 0)
|
||||
return cnt;
|
||||
/*for (;;)
|
||||
{
|
||||
int cnt = fat_fread(&file, buf, 512);
|
||||
if (cnt < 0)
|
||||
return cnt;
|
||||
|
||||
//printf("%s\n", buf);
|
||||
memcpy(current, buf, 512);
|
||||
current += 512;
|
||||
|
||||
if (cnt < 512)
|
||||
break;
|
||||
}*/
|
||||
|
||||
//printf("%s\n", buf);
|
||||
memcpy(current, buf, 512);
|
||||
current += 512;
|
||||
|
||||
if (cnt < 512)
|
||||
break;
|
||||
}*/
|
||||
|
||||
|
||||
return fat_fclose(&file);
|
||||
return fat_fclose(&file);
|
||||
}
|
||||
|
||||
void exec_from_file(const char* filename)
|
||||
{
|
||||
asm volatile("cli");
|
||||
asm volatile("cli");
|
||||
int err, cnt;
|
||||
err = fat_mount(&ops1, 0, &g_fat, "ebalo");
|
||||
|
||||
uint8_t* file;
|
||||
|
||||
int result = read_file("/ebalo/testfile", &file);
|
||||
int result = read_file("/ebalo/aaa", &file);
|
||||
printf("result: %X\n", result);
|
||||
printf("buffer: %s\n", file);
|
||||
|
||||
@@ -86,47 +90,74 @@ void exec_from_file(const char* filename)
|
||||
|
||||
for(int i = 0; i < program_header_table_entry_count; i++)
|
||||
{
|
||||
Elf32_Phdr *elf_phdr = (Elf32_Phdr *)((uint32_t)file + elf_ehdr->e_phoff +
|
||||
i * elf_ehdr->e_phentsize);
|
||||
Elf32_Phdr *elf_phdr = (Elf32_Phdr *)((uint32_t)file + elf_ehdr->e_phoff +
|
||||
i * elf_ehdr->e_phentsize);
|
||||
|
||||
printf("HEADER %X, type: 0x%X, vaddr: 0x%X, paddr: 0x%X, memsz: 0x%X\n", i, elf_phdr->p_type, elf_phdr->p_vaddr, elf_phdr->p_paddr, elf_phdr->p_memsz);
|
||||
if(elf_phdr->p_type != PT_LOAD)
|
||||
{
|
||||
printf("not PT_LOAD, skipping...\n");
|
||||
continue;
|
||||
}
|
||||
int pages_needed = (elf_phdr->p_memsz / 0x1000) + 1;
|
||||
printf("pages needed: %X\n", pages_needed);
|
||||
printf("HEADER %X, type: 0x%X, vaddr: 0x%X, paddr: 0x%X, memsz: 0x%X\n", i, elf_phdr->p_type, elf_phdr->p_vaddr, elf_phdr->p_paddr, elf_phdr->p_memsz);
|
||||
if(elf_phdr->p_type != PT_LOAD)
|
||||
{
|
||||
printf("not PT_LOAD, skipping...\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < pages_needed; j++)
|
||||
{
|
||||
uint32_t vaddr = (elf_phdr->p_vaddr & ~0xFFF) + j * 0x1000;
|
||||
void* phys_addr = alloc_page();
|
||||
int pages_needed = DivRoundUp(elf_phdr->p_memsz, 0x1000);//(elf_phdr->p_memsz / 0x1000) + 1;
|
||||
printf("pages needed: %X\n", pages_needed);
|
||||
|
||||
printf("mapping 0x%X -> 0x%X\n", phys_addr, vaddr);
|
||||
//map_page_in_directory(proc_pd, phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER);
|
||||
map_page(phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER);
|
||||
}
|
||||
for(int j = 0; j < pages_needed; j++)
|
||||
{
|
||||
uint32_t vaddr = (elf_phdr->p_vaddr & ~0xFFF) + j * 0x1000;
|
||||
void* phys_addr = alloc_page();
|
||||
|
||||
|
||||
printf("mapping 0x%X -> 0x%X\n", phys_addr, vaddr);
|
||||
map_page(phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER);
|
||||
}
|
||||
|
||||
memcpy((void*)elf_phdr->p_vaddr, file+elf_phdr->p_offset, elf_phdr->p_filesz);
|
||||
memcpy((void*)elf_phdr->p_vaddr, file+elf_phdr->p_offset, elf_phdr->p_filesz);
|
||||
|
||||
if (elf_phdr->p_memsz > elf_phdr->p_filesz) {
|
||||
uint32_t bss_start = elf_phdr->p_vaddr + elf_phdr->p_filesz;
|
||||
uint32_t bss_end = elf_phdr->p_vaddr + elf_phdr->p_memsz;
|
||||
memset((void*)bss_start, 0, bss_end - bss_start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t file_start = (elf_phdr->p_vaddr & ~0xFFF) + elf_phdr->p_filesz;
|
||||
uint32_t file_end = (elf_phdr->p_vaddr & ~0xFFF) + pages_needed * 0x1000;
|
||||
memset((void*)file_start, 0, file_end - file_start);
|
||||
|
||||
printf("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz);
|
||||
|
||||
|
||||
|
||||
printf("================================\n\n\n\n");
|
||||
printf("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz);
|
||||
printf("================================\n\n\n\n");
|
||||
}
|
||||
|
||||
set_page_dir(curr_pd_phys);
|
||||
Process* p_task1 = task_create(elf_ehdr->e_entry, NULL, 0, 3, proc_pd);
|
||||
|
||||
asm volatile("sti");
|
||||
|
||||
printf("setting up the user stack...\n");
|
||||
|
||||
//TODO: i think this thing allocates more pages than needed
|
||||
for (uint32_t vaddr = USER_STACK_BOTTOM; vaddr <= USER_STACK_TOP; vaddr += PAGE_SIZE) {
|
||||
void* phys_addr = alloc_page();
|
||||
if(!phys_addr)
|
||||
{
|
||||
printf("error allocating user stack page, aborting...\n");
|
||||
set_page_dir(curr_pd_phys);
|
||||
//TODO: free previously allocated pages
|
||||
return;
|
||||
}
|
||||
map_page(phys_addr, (void*)(vaddr & ~0xFFF), PAGE_PRESENT | PAGE_RW | PAGE_USER);
|
||||
printf("mapping stack 0x%X -> 0x%X (0x%X)\n", (uint32_t)phys_addr, vaddr, (vaddr & ~0xFFF));
|
||||
memset((void*)(vaddr & ~0xFFF), 0, PAGE_SIZE); // Add this
|
||||
}
|
||||
/*
|
||||
uint32_t user_esp = USER_STACK_TOP;
|
||||
|
||||
// envp (environment pointer array) = NULL terminator
|
||||
user_esp -= 4;
|
||||
*(uint32_t*)user_esp = 0;
|
||||
|
||||
// argv (argument pointer array) = NULL terminator
|
||||
user_esp -= 4;
|
||||
*(uint32_t*)user_esp = 0;
|
||||
|
||||
// argc (argument count) = 0
|
||||
user_esp -= 4;
|
||||
*(uint32_t*)user_esp = 0;
|
||||
*/
|
||||
|
||||
set_page_dir(curr_pd_phys);
|
||||
Process* p_task1 = task_create(elf_ehdr->e_entry, USER_STACK_TOP, 3, proc_pd);
|
||||
|
||||
asm volatile("sti");
|
||||
}
|
||||
Reference in New Issue
Block a user