loader: initial loader code

This commit is contained in:
Loïc Grégoire
2026-07-16 19:48:01 -04:00
parent 26ec72fb36
commit a79c7a07cb
35 changed files with 1197 additions and 548 deletions
+64
View File
@@ -0,0 +1,64 @@
const r = @import("root");
const std = @import("std");
fn load_kernel(kernel: *anyopaque) usize {
const elf: *std.elf.Elf64.Ehdr = @ptrCast(@alignCast(kernel));
const ident = elf.ident;
if (!std.mem.eql(u8, ident[0..4], std.elf.MAGIC)) {
@panic("loader: Invalid ELF magic");
}
if (ident[std.elf.EI_CLASS] != std.elf.ELFCLASS64) {
@panic("loader: invalid ELF class");
}
if (elf.type != std.elf.ET.EXEC) {
@panic("loader: invalid ELF type (expected ET_EXEC)");
}
var phdr: *std.elf.Elf64.Phdr = @ptrFromInt(@intFromPtr(kernel) + elf.phoff);
for (0..elf.phnum) |_| {
switch (phdr.type) {
.LOAD => {
r.mem.pagemap.map_range_allocating(phdr.vaddr, std.mem.alignForward(usize, phdr.memsz, r.page_size), .{
.execute = phdr.flags.X,
// Gotta have RW access for loading it.
// XXX remap the pages and set protections properly...
.read = true,
.write = true,
.global = true,
});
const off: [*]u8 = @ptrFromInt(@intFromPtr(kernel) + phdr.offset);
const source = off[0..phdr.filesz];
const va: [*]u8 = @ptrFromInt(phdr.vaddr);
const dest = va[0..phdr.filesz];
// Copy the file data.
@memcpy(dest, source);
// Fill the rest of memsz with 0.
const zero_dest = va[phdr.filesz..phdr.memsz];
@memset(zero_dest, 0);
},
else => {},
}
phdr = @ptrFromInt(@intFromPtr(phdr) + elf.phentsize);
}
return elf.entry;
}
extern fn jump_to_kernel(loader_info: usize, stack: usize, entry: usize) void;
pub fn loader_main(kernel: *anyopaque) void {
r.mem.init();
const entry = load_kernel(kernel);
const stack = r.mem.alloc(1024 * 32);
std.log.info("jumping to {x} with stack {x}", .{ entry, stack });
jump_to_kernel(@intFromPtr(&r.loader_info), stack + (1024 * 32), entry);
}