feat: add initial impl of efi-stub and kernel

This commit is contained in:
2026-01-28 16:01:38 +08:00
commit 1233ae9e9b
21 changed files with 845 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
const std = @import("std");
const uefi = std.os.uefi;
const unicode = std.unicode;
const SimpleTextOutput = uefi.protocol.SimpleTextOutput;
pub const UefiConsole = struct {
console_out: ?*SimpleTextOutput = null,
pub fn init(system_table: *uefi.tables.SystemTable) UefiConsole {
var console = UefiConsole{};
var con_out = system_table.con_out orelse return console;
con_out.clearScreen() catch return console;
con_out.setCursorPosition(0, 0) catch return console;
console.console_out = con_out;
UefiWriter.UEFI_WRITER_VTABLE = .{
.drain = UefiWriter.drain,
};
return console;
}
pub const UefiWriter = struct {
console: *UefiConsole,
interface: std.Io.Writer,
var UEFI_WRITER_VTABLE: std.io.Writer.VTable = .{
.drain = undefined,
};
pub fn drain(ptr: *std.Io.Writer, buf: []const []const u8, splat: usize) !usize {
_ = splat;
const self: *UefiWriter = @fieldParentPtr("interface", ptr);
if (self.console.console_out) |out| {
var written: usize = 0;
for (buf) |b| {
var start: usize = 0;
var ucs2_buf = [_]u16{0} ** 65;
while (start < buf.len) {
const len = unicode.utf8ToUtf16Le(ucs2_buf[0..64], b[start..@min(start + 64, b.len)]) catch {
return error.WriteFailed;
};
ucs2_buf[len] = 0;
_ = out.outputString(@ptrCast(&ucs2_buf)) catch {
return error.WriteFailed;
};
start += len;
}
written += b.len;
}
return written;
} else {
return 0;
}
}
};
pub fn writer(self: *UefiConsole) UefiWriter {
const w = UefiWriter{
.console = self,
.interface = .{
.vtable = @call(.never_inline, getVtable, .{}),
.buffer = &[0]u8{},
.end = 0
},
};
return w;
}
fn getVtable() *const std.Io.Writer.VTable {
return &UefiWriter.UEFI_WRITER_VTABLE;
}
};
pub var uc: UefiConsole = undefined;
pub fn initUefiConsole(system_table: *uefi.tables.SystemTable) void {
uc = UefiConsole.init(system_table);
}
pub fn info(comptime fmt: []const u8, args: anytype) void {
var w = uc.writer();
w.interface.print(fmt, args) catch {};
}