mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-29 22:48:20 +00:00
loader: initial loader code
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user