lumine
UEFI x86_64 bootloader for linux kernel images
src/boot/linux/Initrd.zig
2540 bytes raw
1const std = @import("std");
2const uefi = std.os.uefi;
3
4const luefi = @import("../../luefi.zig");
5const Path = @import("../../Config.zig").Path;
6
7const Initrd = @This();
8
9protocol: LoadFile2 = .{},
10
11buffer: []align(4096) u8,
12pages: usize,
13
14pub fn load(path: Path) !*Initrd {
15 const buffer, const pages = blk: {
16 const file = try luefi.fileOpen(path);
17 defer file.close() catch unreachable;
18
19 break :blk try luefi.fileReadAlloc(file);
20 };
21 errdefer luefi.freePages(buffer, pages);
22
23 const self = try uefi.pool_allocator.create(Initrd);
24 self.* = .{ .buffer = buffer, .pages = pages };
25
26 try luefi.installProtocols(.{ &device_path, &self.protocol });
27
28 return self;
29}
30
31pub fn deinit(self: *Initrd) void {
32 luefi.freePages(self.buffer, self.pages);
33 uefi.pool_allocator.destroy(self);
34}
35
36pub const LoadFile2 = extern struct {
37 loadFile: *const @TypeOf(impl) = impl,
38
39 pub fn impl(
40 protocol: *LoadFile2,
41 _: *uefi.protocol.DevicePath,
42 _: bool,
43 buf_size: *usize,
44 buf_out: ?[*]u8,
45 ) callconv(uefi.cc) uefi.Status {
46 const initrd: *Initrd = @fieldParentPtr("protocol", protocol);
47
48 if (buf_out == null or buf_size.* < initrd.buffer.len) {
49 buf_size.* = initrd.buffer.len;
50 return .buffer_too_small;
51 }
52
53 @memcpy(buf_out.?, initrd.buffer);
54
55 return .success;
56 }
57
58 pub const guid: uefi.Guid = .{
59 .time_low = 0x4006c0c1,
60 .time_mid = 0xfcb3,
61 .time_high_and_version = 0x403e,
62 .clock_seq_high_and_reserved = 0x99,
63 .clock_seq_low = 0x6d,
64 .node = [_]u8{ 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d },
65 };
66};
67
68pub var device_path = struct {
69 vendor: uefi.DevicePath.Media.VendorDevicePath,
70 end: uefi.DevicePath.End.EndEntireDevicePath,
71
72 pub const guid = uefi.protocol.DevicePath.guid;
73}{
74 .vendor = uefi.DevicePath.Media.VendorDevicePath{
75 .type = .media,
76 .subtype = .vendor,
77 .length = @sizeOf(uefi.DevicePath.Media.VendorDevicePath),
78 .guid = .{
79 .time_low = 0x5568e427,
80 .time_mid = 0x68fc,
81 .time_high_and_version = 0x4f3d,
82 .clock_seq_high_and_reserved = 0xac,
83 .clock_seq_low = 0x74,
84 .node = [_]u8{ 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 },
85 },
86 },
87 .end = uefi.DevicePath.End.EndEntireDevicePath{
88 .type = .end,
89 .subtype = .end_entire,
90 .length = @sizeOf(uefi.DevicePath.End.EndEntireDevicePath),
91 },
92};