diff --git a/.gitignore b/.gitignore index 523ca7e..880cd5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -hellos -zig-cache +zig-out +.zig-cache diff --git a/README.md b/README.md index e085748..b6da19f 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ Bare bones "hello world" i386 kernel written in [Zig](https://ziglang.org/). ## Building ``` -zig build-exe hellos.zig -target i386-freestanding -T linker.ld +zig build --release=small ``` ## Testing with qemu ``` -qemu-system-i386 -kernel hellos +qemu-system-i386 -kernel zig-out/bin/HellOs ``` diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..5848585 --- /dev/null +++ b/build.zig @@ -0,0 +1,25 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{ .default_target = .{ .os_tag = .freestanding, .abi = .eabi, .ofmt = .elf, .cpu_arch = .x86 } }); + const optimize = b.standardOptimizeOption(.{}); + + const kernel = b.addExecutable(.{ + .name = "HellOS", + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + kernel.setLinkerScriptPath(b.path("linker.ld")); + + b.installArtifact(kernel); + + const unit_tests = b.addTest(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + const run_unit_tests = b.addRunArtifact(unit_tests); + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&run_unit_tests.step); +} diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..8613100 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,12 @@ +.{ + .name = "HellOS", + .version = "0.1.0", + .minimum_zig_version = "0.14.0", + .paths = .{ + "build.zig", + "build.zig.zon", + "linker.ld", + "src", + "README.md", + }, +} diff --git a/hellos.zig b/src/main.zig similarity index 78% rename from hellos.zig rename to src/main.zig index 1a300ba..5c0f022 100644 --- a/hellos.zig +++ b/src/main.zig @@ -1,6 +1,9 @@ +const std = @import("std"); const builtin = @import("builtin"); -const MultiBoot = packed struct { +const StackTrace = std.builtin.StackTrace; + +const MultiBoot = extern struct { magic: i32, flags: i32, checksum: i32, @@ -21,21 +24,28 @@ export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined; const stack_bytes_slice = stack_bytes[0..]; export fn _start() callconv(.Naked) noreturn { - @call(.{ .stack = stack_bytes_slice }, kmain, .{}); - + const stack = stack_bytes_slice; + asm volatile ( + \\ movl %[stk], %esp + \\ movl %esp, %ebp + \\ jmp kmain + : + : [stk] "{ecx}" (@intFromPtr(&stack) + @sizeOf(@TypeOf(stack))), + ); while (true) {} } -pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { - @setCold(true); +pub fn panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn { + @branchHint(.cold); + _ = error_return_trace; terminal.write("KERNEL PANIC: "); terminal.write(msg); while (true) {} } -fn kmain() void { +export fn kmain() callconv(.C) void { terminal.initialize(); - terminal.write("Hello, Kernel World from Zig 0.7.1!"); + terminal.write("Hello, Kernel World from Zig 0.14.0!"); } // Hardware text mode color constants @@ -62,7 +72,7 @@ fn vga_entry_color(fg: VgaColor, bg: VgaColor) u8 { } fn vga_entry(uc: u8, color: u8) u16 { - var c: u16 = color; + const c: u16 = color; return uc | (c << 8); } @@ -76,7 +86,7 @@ const terminal = struct { var color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - const buffer = @intToPtr([*]volatile u16, 0xB8000); + const buffer: [*]volatile u16 = @ptrFromInt(0xB8000); fn initialize() void { var y: usize = 0;