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 或任何东西。)