2

https://wiki.osdev.org/Bare_Bones上的 OS 开发 wiki包含使用程序集文件和 C 文件的组合编写非常基本的“Hello World”x86 内核的示例。

https://github.com/andrewrk/HellOS展示了一个类似的项目,但使用 Zig 语言编写在一个文件中。

有没有办法用 C 做同样的事情?Zig 中使用的选项似乎在 gcc 中有一些类似物,例如:

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),
};

似乎可以翻译成:

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)
};

和汇编代码的 Zig 等价物:

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

好像可以变成

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

但是我无法让这个被接受,即使我使用的 ld 文件与 Zig 示例使用的相同。

这是可行的事情还是我完全在错误的树上吠叫?

(注意:输出内核只需要由 引导qemu --kernel,而不是 GRUB 或任何东西。)

4

0 回答 0