25 enum elf_class { CLASS_32_BIT = 1, CLASS_64_BIT };
28 enum elf_data { DATA_LITTLE_ENDIAN = 1, DATA_BIG_ENDIAN };
30 enum elf_type { TYPE_RELOCATABLE = 1, TYPE_EXECUTABLE, TYPE_SHARED, TYPE_CORE };
38 PT_NULL, PT_LOAD, PT_DYNAMIC, PT_INTERP, PT_NOTE, PT_SHLIB, PT_PHDR
46 PF_X = 0b1, PF_W = 0b10, PF_R = 0b100
57 if (elf->e_ident.EI_MAG0 !=
MAGIC_0 || elf->e_ident.EI_MAG1 !=
MAGIC_1 ||
58 elf->e_ident.EI_MAG2 !=
MAGIC_2 || elf->e_ident.EI_MAG3 !=
MAGIC_3) {
59 println(
"%4aELF magic not found%a");
62 if (elf->e_ident.EI_CLASS != CLASS_32_BIT) {
63 println(
"%4aELF not 32-bit%a");
66 if (elf->e_ident.EI_DATA != DATA_LITTLE_ENDIAN) {
67 println(
"%4aELF not little endian%a");
70 if (elf->e_ident.EI_VERSION !=
VERSION || elf->e_version !=
VERSION) {
71 println(
"%4aELF version not 1%a");
74 if (elf->e_type != TYPE_EXECUTABLE) {
75 println(
"%4aELF not executable%a");
78 if (elf->e_machine != MACHINE_X86) {
79 println(
"%4aELF target not x86%a");
97 logln(
"ELF",
"Program header entries:");
99 for (
int i = 0; i < elf->
e_phnum; i++) {
101 logln(
"ELF",
"[%d] type=%d offset=%08x vaddr=%08x paddr=%08x " 102 "filesz=%08x memsz=%08x flags=%03b align=%08x", i,
105 if (entry->
p_type == PT_LOAD) {
108 entry->
p_flags & PF_W ? VMM_USER | VMM_WRITABLE : VMM_USER);
133 for (
int i = 0; i < elf->
e_phnum; i++) {
135 if (entry->
p_type == PT_LOAD)
149 size_t user_stack_len) {
151 println(
"%4aELF not found%a");
157 kernel_stack_len, user_stack_len, elf);
page_directory_t * vmm_create_page_directory()
Creates an empty page directory.
uint8_t isr_enable_interrupts(uint8_t enable)
Enables or disables interrupts.
void * vmm_use_virtual_memory(void *vaddr, size_t len, vmm_flags_t flags)
Marks some page(s) as used and maps them into memory.
#define VERSION
only ELF version 1 is supported (the current version)
elf_data
little or big endian
static page_directory_t * page_directory
the current page directory
void vmm_modified_page_directory()
Ends a page directory modification.
#define MAGIC_1
magic value expected at the beginning of an ELF file
task_pid_t task_create_user(void *entry_point, page_directory_t *page_directory, size_t kernel_stack_len, size_t user_stack_len, void *elf)
Creates a user task.
void elf_destroy_task(task_pid_t pid)
Destroys a user task running the code of an ELF file.
#define MAGIC_3
magic value expected at the beginning of an ELF file
static uint8_t old_interrupts
for temporary modifications
task_pid_t elf_create_task(elf_t *elf, size_t kernel_stack_len, size_t user_stack_len)
Creates a user task running the code of an ELF file.
uint32_t task_pid_t
unique process ID
#define MAGIC_2
magic value expected at the beginning of an ELF file
static uint8_t elf_check(elf_t *elf)
Checks whether a pointer points to a valid ELF file for this OS.
void vmm_free(void *vaddr, size_t len)
Frees the given page(s) and unmaps them from memory.
void * elf_load(elf_t *elf, page_directory_t *page_directory)
Loads the segments of an ELF file into memory.
An entry in a page directory.
elf_machine
targeted ISA, we are only interested in x86
void vmm_modify_page_directory(page_directory_t *new_directory)
Loads a page directory for temporary modification.
page_directory_t * task_get_page_directory(task_pid_t pid)
Returns a task's page directory.
void elf_unload(elf_t *elf, page_directory_t *page_directory)
Frees the segments of an ELF file in memory.
void * task_get_elf(task_pid_t pid)
Returns a task's ELF file.
void task_destroy(task_pid_t pid)
Destroys a task.
#define MAGIC_0
magic value expected at the beginning of an ELF file