diff --git a/build.zig b/build.zig index 24cff05..95a2ce2 100644 --- a/build.zig +++ b/build.zig @@ -20,17 +20,79 @@ pub fn build(b: *std.Build) void { }; const optimize = b.standardOptimizeOption(.{}); - const kernel = b.addExecutable(.{ + const kernel_elf = b.addExecutable(.{ .name = "kernel.elf", .root_source_file = b.path("src/main.zig"), .target = b.resolveTargetQuery(target_query), .optimize = optimize, .code_model = .kernel, }); + kernel_elf.setLinkerScript(b.path("src/linker.ld")); - kernel.setLinkerScript(b.path("src/linker.ld")); - b.installArtifact(kernel); + const kernel_elf_artifact = b.addInstallArtifact(kernel_elf, .{}); - const kernel_step = b.step("kernel", "Build the kernel"); - kernel_step.dependOn(&kernel.step); + const kernel_bin = b.addObjCopy(kernel_elf.getEmittedBin(), .{ + .format = .bin, + .only_section = ".blob", + }); + kernel_bin.step.dependOn(&kernel_elf_artifact.step); + + const kernel_bin_copy = b.addInstallBinFile( + kernel_bin.getOutput(), + "kernel.bin", + ); + kernel_bin_copy.step.dependOn(&kernel_bin.step); + + const kernel_step_elf = b.step("elf", "Build the kernel ELF"); + kernel_step_elf.dependOn(&kernel_elf.step); + + const kernel_step_bin = b.step("bin", "Build the kernel BIN (with objcopy)"); + kernel_step_bin.dependOn(&kernel_bin_copy.step); + + const iso_dir_path = b.fmt("{s}/iso_dir", .{b.cache_root.path.?}); + const iso_dir_boot_path = b.fmt("{s}/boot", .{iso_dir_path}); + const grub_dir_path = b.fmt("{s}/{s}", .{ iso_dir_boot_path, "grub" }); + + const iso_make_dir = b.addSystemCommand(&[_][]const u8{ + "mkdir", + "-p", + grub_dir_path, + }); + + const iso_copy_kernel = b.addSystemCommand(&[_][]const u8{ + "cp", + b.fmt("{s}/bin/{s}", .{ b.install_path, "kernel.elf" }), + iso_dir_boot_path, + }); + iso_copy_kernel.step.dependOn(&iso_make_dir.step); + iso_copy_kernel.step.dependOn(kernel_step_elf); + + const iso_copy_grubcfg = b.addSystemCommand(&[_][]const u8{ + "cp", + "src/grub.cfg", + grub_dir_path, + }); + iso_copy_grubcfg.step.dependOn(&iso_make_dir.step); + + const iso_make_iso = b.addSystemCommand(&[_][]const u8{ + "grub2-mkrescue", + "-o", + b.fmt("{s}/{s}", .{ b.install_path, "kernel.iso" }), + iso_dir_path, + }); + iso_make_iso.step.dependOn(&iso_copy_grubcfg.step); + iso_make_iso.step.dependOn(&iso_copy_kernel.step); + + const iso_step = b.step("iso", "Create bootable iso using GRUB2"); + iso_step.dependOn(&iso_make_iso.step); + + const run_qemu = b.addSystemCommand(&[_][]const u8{ + "qemu-system-i386", + "-cdrom", + b.fmt("{s}/{s}", .{ b.install_path, "kernel.iso" }), + }); + run_qemu.step.dependOn(&iso_make_iso.step); + + const run_qemu_step = b.step("run", "Run in qemu"); + run_qemu_step.dependOn(&run_qemu.step); } diff --git a/src/grub.cfg b/src/grub.cfg index 2164e64..7904bf7 100644 --- a/src/grub.cfg +++ b/src/grub.cfg @@ -1,3 +1,3 @@ menuentry "Zig Bare Bones" { multiboot /boot/kernel.elf -} \ No newline at end of file +} diff --git a/src/linker.ld b/src/linker.ld index ec475c8..b96f361 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -1,13 +1,10 @@ ENTRY(_start) SECTIONS { - . = 1M; - - .multiboot { - KEEP(*(.multiboot)) - } + . = 2M; .text : ALIGN(4K) { + *(.multiboot) *(.text) } @@ -23,4 +20,8 @@ SECTIONS { *(COMMON) *(.bss) } -} + + /DISCARD/ : { + *(.note .note.*) + } +} \ No newline at end of file diff --git a/src/main.zig b/src/main.zig index aa00104..11f024d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -9,6 +9,7 @@ const MultibootHeader = packed struct { magic: i32 = MAGIC, flags: i32, checksum: i32, + padding: u32 = 0, }; export var multiboot align(4) linksection(".multiboot") = MultibootHeader{ @@ -20,13 +21,17 @@ 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(.auto, kmain, .{}); - //kmain(); - + asm volatile ( + \\ movl %[stk], %esp + \\ movl %esp, %ebp + \\ call kmain + : + : [stk] "{ecx}" (@intFromPtr(&stack_bytes_slice) + @sizeOf(@TypeOf(stack_bytes_slice))), + ); while (true) {} } -fn kmain() void { +export fn kmain() void { console.initialize(); console.puts("Hello world!"); }