Can the Zig "HellOS" example be ported to C as a single file without a .s support file?

Viewed 136

The OS Development wiki at https://wiki.osdev.org/Bare_Bones contains a sample of writing a very basic "Hello World" x86 kernel using a combination of an assembly file and a C file.

https://github.com/andrewrk/HellOS shows a similar project, but written in a single file using the Zig language.

Is there a way to do the same using C? The options used in Zig seem to have some analogues in gcc, for example this:

const MultiBoot = packed struct {
    magic: i32,
    flags: i32,
    checksum: i32,
};

const ALIGN = 1 << 0;
const MEMINFO = 1 << 1;
const MAGIC = 0x1BADB002;
const FLAGS = ALIGN | MEMINFO;

export var multiboot align(4) linksection(".multiboot") = MultiBoot{
    .magic = MAGIC,
    .flags = FLAGS,
    .checksum = -(MAGIC + FLAGS),
};

Seems to be translatable to:

const int32_t ALIGN = 1 << 0;
const int32_t MEMINFO = 1 << 1;
const int32_t MAGIC = 0x1BADB002;
const int32_t FLAGS = ALIGN | MEMINFO;

const struct {
    int32_t magic;
    int32_t flags;
    int32_t checksum;
} multiboot __attribute__((used, aligned(4), section(".multiboot"))) = {
    .magic = MAGIC,
    .flags = FLAGS,
    .checksum = -(MAGIC + FLAGS)
};

And the Zig equivalent of the assembly code:

export fn _start() callconv(.Naked) noreturn {
    @call(.{ .stack = stack_bytes_slice }, kmain, .{});
    while (true) {}
}

Seems like it could become

void __attribute__((used, naked, noreturn)) start() {
    asm (
    "mov stack, %esp\n"
    "call kmain"
    );
    while(1);
}

But I haven't been able to get this to be accepted, even though I'm using the same ld file as the Zig example used.

Is this a viable thing to do or I am barking completely up the wrong tree?

(Note: the output kernel only needs to be bootable by qemu --kernel, not GRUB or anything.)

0 Answers
Related