const std = @import("std"); const BootParams = @import("params.zig").BootParams; const early_serial_console = @import("early_serial_console.zig"); const Cmdline = @import("cmdline.zig").Cmdline; const payload = @import("payload.zig"); const multiboot = @import("multiboot.zig"); const Decompress = std.compress.flate.Decompress; const relocate = @import("relocate.zig"); const ident_map = @import("ident_map.zig"); comptime { @export(&relocate.relocateSelf, .{ .name = "relocateSelf", }); } fn decompress(target_addr: [*]u8) !void { var data_reader = std.Io.Reader.fixed(payload.getCompressedKernelData()); var work_buffer: [std.compress.flate.max_window_len]u8 = undefined; var decompressor = Decompress.init(&data_reader, .gzip, &work_buffer); var decompressor_reader = &decompressor.reader; var decompress_buf = target_addr; while (true) { const read_bytes = try decompressor_reader.readSliceShort(decompress_buf[0..4096]); if (read_bytes == 0) break; decompress_buf = decompress_buf[read_bytes..]; if ((@intFromPtr(decompress_buf) - @intFromPtr(target_addr) ) % 10240 == 0) { early_serial_console.dprint("Decompressed {d} bytes...\n", .{@intFromPtr(decompress_buf) - @intFromPtr(target_addr)}); } } } export fn extractKernel(multiboot_info: *u8, target_addr: usize) callconv(.c) noreturn { const params = multiboot.parseMultibootInfo(multiboot_info); const cmdline = Cmdline.init(params.cmdline); early_serial_console.earlyConsoleInit(&cmdline); early_serial_console.dprint("Starting kernel extraction...\n", .{}); early_serial_console.dprint("Kernel compressed size {d} bytes\n", .{payload.getCompressedKernelData().len}); early_serial_console.dprint("Kernel uncompressed size {d} bytes\n", .{payload.getUncompressedKernelSize()}); decompress(@ptrFromInt(target_addr)) catch |err| { early_serial_console.dprint("Kernel decompression failed: {s}\n", .{@errorName(err)}); while(true){} }; early_serial_console.dprint("Kernel extraction completed.\n", .{}); while(true){} }