链接内核 - 输入文件的 i386 架构与 i386:x86_64 输出不兼容

Linking kernel - i386 architecture of input file is incompatible with i386:x86_64 output

我正在尝试从我的汇编文件内核阶段转移到我的 C 文件内核阶段(终于...)。但是,我在 link 将编译的 C 内核编译到编译的汇编内核入口程序的过程中遇到了一些麻烦。

这是我的 kernel_entry.asm 文件的代码。

[BITS 32]           ; Starting in 32 bit protected mode
[EXTERN main]           ; Extern to C file main function

call main           ; Invoke main in our C kernel

jmp $               ; Jump here - Infinite loop

这是我的 kernel.c 文件的代码。

void main() {
  char* video_memory = (char*) 0xB8000;
  *video_memory = 'X';
}

这是我用来编译它们的命令行。

nasm -f elf -o kernel_entry.o kernel_entry.asm
gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x0500 kernel_entry.o kernel.o --oformat binary

最后一个命令行给我这个错误。

ld: i386 architecture of input file `kernel_entry.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 0000000000000500

注意:我正在将我的内核加载到地址和偏移量 0x0000:0x0500,这就是我使用 -Ttext 0x0500 的原因,我不确定为什么会出现第二个 ld 警告,但目前看来并不重要(尽管如果如果您在这方面提供任何帮助,我们将不胜感激。

谁能告诉我为什么我不能 link 这些文件在一起?我也在 Ubuntu dekstop 64 位上运行。预先感谢您提供的任何帮助。

您似乎是在 64 位系统上编译此代码。因此,kernel.o 是 64 位二进制文​​件,不能与 32 位二进制文​​件链接 kernel_entry.o

由于您没有任何使系统进入长模式的代码,您可能希望将 "kernel" 编译为 32 位代码。使用 -m32 触发:

gcc -m32 -ffreestanding -c kernel.c -o kernel.o
    ^^^^