mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-29 14:38:21 +00:00
65 lines
2.1 KiB
Zig
65 lines
2.1 KiB
Zig
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 * 16);
|
|
|
|
std.log.info("jumping to {x} with stack {x}", .{ entry, stack });
|
|
jump_to_kernel(@intFromPtr(&r.loader_info), stack + (1024 * 16), entry);
|
|
}
|