lumine
UEFI x86_64 bootloader for linux kernel images
src/boot/linux/Kernel.zig
1483 bytes raw
1const std = @import("std");
2const uefi = std.os.uefi;
3const builtin = @import("builtin");
4
5const Path = @import("../../Config.zig").Path;
6const luefi = @import("../../luefi.zig");
7const Chainload = @import("../Chainload.zig");
8
9const log = std.log.scoped(.linux);
10
11const Kernel = @This();
12
13img_buffer: []align(4096) u8,
14img_pages: usize,
15
16pub fn load(path: Path) !Kernel {
17 log.info("loading kernel {f}", .{path});
18
19 const buffer, const pages = try luefi.pathReadAlloc(path);
20 return .{ .img_buffer = buffer, .img_pages = pages };
21}
22
23pub fn deinit(self: Kernel) void {
24 luefi.freePages(self.img_buffer, self.img_pages);
25}
26
27pub fn start(self: Kernel, cmdline: []const u8) !uefi.Status {
28 const allocator = uefi.pool_allocator;
29 const boot_svc = uefi.system_table.boot_services.?;
30
31 if (builtin.target.cpu.arch == .x86_64) {
32 const cmdline_utf16 = try std.unicode.utf8ToUtf16LeAllocZ(allocator, cmdline);
33 defer allocator.free(cmdline_utf16);
34
35 const handle, const loaded = try luefi.loadImage(self.img_buffer);
36 defer luefi.unloadImage(handle);
37
38 loaded.load_options = @ptrCast(cmdline_utf16);
39 loaded.load_options_size = @intCast(cmdline_utf16.len * @sizeOf(u16));
40
41 const exit_data = try boot_svc.startImage(handle);
42 try exit_data.code.err();
43 return .aborted;
44 } else {
45 log.err("this architecture doesnt support linux boot", .{});
46 return error.UnsupportedArchitecture;
47 }
48}