working on reading elf from initrd, and getting it launched with the new scheduler

This commit is contained in:
2026-06-30 19:26:31 -05:00
parent ce81d4eb31
commit af6c1c94cf
21 changed files with 253 additions and 151 deletions

View File

@@ -4,6 +4,7 @@
#include "scheduler.h"
#include "common.h"
#include "vfs.h"
#include "elf.h"
#include <lib/print.h>
#include <lib/stream.h>
@@ -51,26 +52,73 @@ vfs_node_t* load_initrd() {
return cpio_read_fs(initrd_module->mod_start);
}
void load_origin_program() {
vfs_node_t* vfs_root = vfs_create_root();
vfs_node_t* initrd_root = load_initrd();
if (initrd_root) {
mount(vfs_root, initrd_root);
kprintf("initrd read, mounted @ /\n");
void load_program(const char* path) {
void* cr3 = create_task_pd();
load_pd(cr3);
flush_tlb();
int fd = open("/origin.elf", 0);
if (fd == -1) {
kprintf("failed to read origin program\n");
}
void* buf = kalloc(512);
int rd = read(fd, buf, 512);
if (rd > 0) {
kprintf("read %d bytes from origin.elf\n", rd);
}
int fd = open(path, 0);
if (fd == -1) {
kprintf("failed to open program: %s\n", path);
return;;
}
exit();
elf_header_t* e_hdr = kalloc(sizeof(elf_header_t));
memset((void*)e_hdr, 0, sizeof(elf_header_t));
uint32_t bytes_rd = read(fd, e_hdr, sizeof(elf_header_t));
if (bytes_rd <= 0) {
kprintf("failed to read program data for %s\n", path);
return;
}
uint32_t ph_table_ptr = e_hdr->e_phoff;
elf_program_header_t* ph = kalloc(sizeof(elf_program_header_t));
uint32_t heap_start = 0;
for (uint32_t i = 0; i < e_hdr->e_phnum; i++) {
fseek(fd, ph_table_ptr);
memset((void*)ph, 0, sizeof(elf_program_header_t));
read(fd, ph, sizeof(elf_program_header_t));
if (ph->p_type == PT_LOAD) {
uint32_t vstart = ph->p_vaddr;
uint32_t vend = vstart + ph->p_memsz;
if (vend > heap_start) {
heap_start = vend;
}
uint32_t page_start = vstart & ~(PAGE_SIZE - 1);
uint32_t page_end = (vend + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
for (uint32_t v = page_start; v < page_end; v += PAGE_SIZE) {
void* phys_frame = p_alloc_frame();
map_page(v, (uint32_t)phys_frame, 0x07);
}
uint32_t data_ptr = ph->p_offset;
fseek(fd, data_ptr);
read(fd, (void*)vstart, ph->p_memsz);
// 0 out bss
if (ph->p_memsz > ph->p_filesz) {
size_t bss_size = ph->p_memsz - ph->p_filesz;
memset((void*)(vstart + ph->p_filesz), 0, bss_size);
}
}
ph_table_ptr += sizeof(elf_program_header_t);
}
uint32_t esp = 0xBFFF0000;
void* pesp = p_alloc_frame();
map_page(esp - PAGE_SIZE, (uint32_t)pesp, 0x07);
create_task(e_hdr->e_entry, fetch_cr3(), 1);
}
void start_origin() {
load_program("/origin.elf");
}
void kmain(uint32_t magic, multiboot_info* mbi) {
@@ -96,9 +144,19 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
kprintf("basic initializations complete\n");
vfs_node_t* vfs_root = vfs_create_root();
vfs_node_t* initrd_root = load_initrd();
if (!initrd_root) {
kprintf("failed to load initrd\n");
}
mount(vfs_root, initrd_root);
kprintf("initrd read, mounted @ /\n");
disable_interrupts();
init_scheduler();
enable_interrupts();
create_task((uint32_t)load_origin_program, fetch_cr3());
kprintf("loading user program\n");
start_origin();
}