50 lines
1.5 KiB
C

#include "elf.h"
extern void* memset(void* dest, int ch, uptr count);
extern void* memcpy(void* dest, const void* src, uptr count);
[[noreturn]]
void ElfExecute(void* Binary, void* LoadAddr, struct boot_params* BootParams) {
struct Elf64_Ehdr* ElfHeader = (struct Elf64_Ehdr*)Binary;
// Here we would check if we have a valid elf binary
// unfortunately, we would have no way to notify the
// user, so we'll just pray it is
// Hopefully we have progtam headers
void* ProgramHeaders = Binary + ElfHeader->e_phoff;
// Load everything into memory
for (int i = 0; i < ElfHeader->e_phnum; i++) {
struct Elf64_Phdr* ProgramHeader = (struct Elf64_Phdr*)ProgramHeaders;
// Only load loadable segments
if (ProgramHeader->p_type == PT_LOAD) {
void* FileStart = Binary + ProgramHeader->p_offset;
void* LoadStart = LoadAddr + ProgramHeader->p_vaddr;
uptr LoadSize = ProgramHeader->p_memsz;
if (LoadSize > ProgramHeader->p_filesz) LoadSize = ProgramHeader->p_filesz;
memset(LoadStart, 0, ProgramHeader->p_memsz);
memcpy(LoadStart, FileStart, LoadSize);
}
ProgramHeaders += ElfHeader->e_phentsize;
}
// Collect entry point
[[noreturn]] void fake_dont_call(struct boot_params*); // stupid hack
typeof(fake_dont_call)* KernelEntry = LoadAddr + ElfHeader->e_entry;
// Set boot parameters
struct setup_info* SetupInfo = (void*)BootParams + 0x1f1;
SetupInfo->code32_start = LoadAddr;
// Enter the kernel
KernelEntry(BootParams);
// we shouldnt ever end up here
__builtin_unreachable();
}