47 lines
2.1 KiB
Zig
47 lines
2.1 KiB
Zig
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){}
|
|
}
|