Issue with Program Loading
Posted: Wed Mar 18, 2020 6:59 pm
Hello,
I am currently making an operating system called NexOS, and am working a program loader that can load PE programs made by MinGW for Linux. It has an Image Base of 4MB. When i execute it, it page faults. Here is the program loading code:
The execute_internal function looks like this:
The full source repo is at https://github.com/NexSuite/NexOS
I am currently making an operating system called NexOS, and am working a program loader that can load PE programs made by MinGW for Linux. It has an Image Base of 4MB. When i execute it, it page faults. Here is the program loading code:
Code: Select all
int entryPoint;
int stack;
extern void execute_internal();
int create_process(char* path)
{
IMAGE_DOS_HEADER* dosHeader;
IMAGE_NT_HEADERS* peHeader;
int size;
process* proc;
pdirectory* addressSpace;
void* buffer = read_file(path, &size);
dosHeader =(IMAGE_DOS_HEADER*)buffer;
if(dosHeader->e_magic != 0x5A4D)
{
return -1;
}
peHeader = (dosHeader->e_lfanew + (uint32_t)buffer);
addressSpace = get_directory();
proc = kernel_heap_alloc(sizeof(process));
proc->addressSpace = addressSpace;
proc->threads = kernel_heap_alloc(sizeof(thread) * 10);
proc->threads[0].state.eip = peHeader->OptionalHeader.ImageBase + peHeader->OptionalHeader.AddressOfEntryPoint;
proc->threads[0].state.eflags = 0x200;
if(!(size & 0xFFFFF000))
{
size &= 0xFFFFF000;
size += 0x1000;
}
for(int i = 0; i < size; i += 4096)
{
void* block = alloc_block();
map_address(addressSpace, peHeader->OptionalHeader.ImageBase + i, (uint32_t)block, I86_PTE_PRESENT | I86_PTE_WRITABLE | I86_PTE_USER);
memcpy(peHeader->OptionalHeader.ImageBase + i, buffer, 4096);
buffer += 4096;
}
void* stackVirt = peHeader->OptionalHeader.ImageBase + peHeader->OptionalHeader.SizeOfImage + 4096;
void* stackPhys = alloc_block();
map_address(addressSpace, (uint32_t)stackVirt, (uint32_t)stackPhys, I86_PTE_PRESENT | I86_PTE_WRITABLE | I86_PTE_USER);
proc->threads[0].stack = stackVirt;
proc->threads[0].state.esp = (uint32_t)stackVirt;
proc->threads[0].state.ebp = (uint32_t)stackVirt;
entryPoint = proc->threads[0].state.eip;
stack = proc->threads[0].state.esp;
execute_internal();
return 0;
}
Code: Select all
extern entryPoint
extern stack
global execute_internal
execute_internal:
cli
mov ax, 0x23
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push 0x23
mov eax, [stack]
push eax
push 0x200
push 0x1b
mov eax, [entryPoint]
push eax
iretd