Limine-zig
Jump to navigation
Jump to search
Limine is a modern boot protocol developed with the Limine bootloader, this page covers how to take advantage of that protocol in a zig-based kernel. This does not cover making an ISO, just the code required, in the future this will change, but this is it for now.
Code
This code should work as long as you have zig 0.11.0 installed. As of writing this it is untested, but if you do test it out, and it works, remove this sentence, if it doesn't work please message me (veloya) on the discord server with the error message.
src/main.zig
const limine = @import("./limine.zig");
pub export var FRAMEBUF: limine.FramebufferRequest = .{};
export fn _start() void {
// Get an array of framebuffer pointers
const framebuffers = FRAMEBUF.response.?.framebuffers();
// Get the first framebuffer provided
const framebuffer = framebuffers[0];
// Height is in pixels, convert it to bytes
const byte_height = framebuffer.height * 4;
// Get total byte size by multiplying the height by the stride (or pitch)
const size = byte_height * framebuffer.pitch;
// Fill the framebuffer with white
for (0..size) |index| {
framebuffer.address[index] = 0xff;
}
while (true) {}
}
src/limine.zig
The limine.zig file can be found here
config/linker.ld
TODO: Write a better linker script
ENTRY(_start)
SECTIONS
{
. = 0xffffffff80000000;
.text : ALIGN(4096) { *(.text .text.*) }
.rodata : ALIGN(4096) { *(.rodata .rodata.*) }
.data : ALIGN(4096) { *(.data .data.*) }
.dynamic : ALIGN(4096) { *(.dynamic) }
.bss : ALIGN(4096) {
*(.bss .bss.*)
*(COMMON)
}
}
config/limine.cfg
boot "test-kern" {
protocol = "limine";
kernel-path = "boot:///boot/test-kern";
}
build.zig
A build.zig file is required to properly customize the target.
const std = @import("std");
const Target = @import("std").Target;
const CrossTarget = @import("std").zig.CrossTarget;
const Feature = @import("std").Target.Cpu.Feature;
pub fn build(b: *std.Build) !void {
var stdout = std.io.getStdOut();
const target = CrossTarget{
.cpu_arch = Target.Cpu.Arch.x86_64,
.os_tag = Target.Os.Tag.freestanding,
.abi = Target.Abi.none,
};
const optimize = b.standardOptimizeOption(.{});
const kernel = b.addExecutable(.{
.name = "test-kern",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
kernel.setLinkerScriptPath(.{ .path = "config/linker.ld" });
kernel.code_model = .medium;
kernel.rdynamic = true;
kernel.pie = true;
_ = try stdout.write("Building kernel\n");
b.installArtifact(kernel);
}