Help with setting up an OS

Hi, I need help setting up my OS in Zig with Limine. I know the project is, to put it mildly, small and objectively not very good, but this is my first project in Zig and my first kernel. Also, I’m only 13 for now.

If you want to improve or fix my bad code, please leave comments so I can better understand what you changed. If anyone helps, thank you — I’ve already been struggling with this for 3 hours, and I don’t even know why the problem is happening at all. my os: [edit] I set the kernel to a higher-half address, but I still get the error:

“lower half PHDRs are not allowed”

2 Likes

Welcome to Ziggit !
I’ll have a quick look at your code ! I literally built a lightweight OS using limine a month ago lol

I’m wondering, did you use xorriso to make your iso ? If not what other tools ? Do you run it with Qemu ?

If so can you provide the cli command that you use to build it / run it ?

Thanks !

3 Likes

Heya !
This was a quick fix, you simply forgot to specify and use the limine_requests phdrs. Here’s your updated linker script

ENTRY(_start)

PHDRS
{
    limine_requests PT_LOAD;
    text PT_LOAD;
    rodata PT_LOAD;
    data PT_LOAD;
}

SECTIONS
{
    . = 0xffffffff80000000;

    .limine_requests : {
        KEEP(*(.limine_requests_start))
        KEEP(*(.limine_requests))
        KEEP(*(.limine_requests_end))
    } :limine_requests

    . = ALIGN(CONSTANT(MAXPAGESIZE));

    .text : {
        *(.text .text.*)
    } :text

    . = ALIGN(CONSTANT(MAXPAGESIZE));

    .rodata : {
        *(.rodata .rodata.*)
    } :rodata

    . = ALIGN(CONSTANT(MAXPAGESIZE));

    .data : {
        *(.data .data.*)
    } :data

    .bss : {
        *(.bss .bss.*)
        *(COMMON)
    } :data

    /DISCARD/ : {
        *(.eh_frame*)
        *(.note .note.*)
    }
}

And the orca_kernel.zig file becomes :

const std = @import("std");
const orc = @import("orca_stdlibs");

pub const MagicAndRevision = extern struct {
    magic: [2]u64 = .{ 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc },
    revision: u64 = 3,
};

export var start_marker linksection(".limine_requests_start") = [4]u64{
    0xf6b8f4b39de7d1ae,
    0xfab91a6940fcb9cf,
    0x785c6ed015d3e316,
    0x181e920a7852b9d9,
};

export var magic_and_revision: MagicAndRevision linksection(".limine_requests") = .{};
export var end_marker linksection(".limine_requests_end") = [2]u64{
    0xadc0e0531bb10d03,
    0x9572709f31764c62,
};

pub export fn _start() callconv(.c) noreturn {
    orc.uart_print("hello orca!");

    while (true) {
        asm volatile ("hlt");
    }
}

Note the added linksection(".limine_*") which tells the linker where to put these variables, which was absent from your original codebase.

Happy coding !

9 Likes

​Hey!
​Yes, I am using xorriso to generate the ISO image, and I run it inside Qemu.
​Here is the exact CLI command I use to launch it

qemu-system-x86_64 -cdrom orca.iso -serial stdio -d int -no-reboot -no-shutdown