为什么 ld linker 在编译 elf_i386 代码时失败

why does ld linker fail when compiling elf_i386 code

提问人:Jack Thomson 提问时间:1/15/2023 最后编辑:Michael PetchJack Thomson 更新时间:8/15/2023 访问量:341

问:

我正在尝试制作一个简单的操作系统,但似乎无法让链接器工作。 我尝试使用命令:

ld -m elf_i386 -o kernel.bin -Ttext 0x1000 kernel-entry.o kernel.o --oformat binary

但它只是回应:

unrecognised emulation mode: elf_i386

我目前正在尝试使用 MinGW 在 Windows 上运行它并且 我不想使用 WSL(适用于 Linux 的 Windows 子系统),因为这也行不通。

为了尝试运行它,我运行了:

gcc -m32 -ffreestanding -c kernel.c -o kernel.o
nasm assembly/kernel-entry.asm -f elf -o kernel-entry.o
ld -m elf_i386 -o kernel.bin -Ttext 0x1000 kernel-entry.o kernel.o --oformat binary
nasm assembly/mbr.asm -f bin -o mbr.bin
cat mbr.bin kernel.bin > os-image.bin
qemu-system-i386 -fda os-image.bin
x86 mingw linker-errors ld osdev

评论

2赞 Michael Petch 1/15/2023
因为你的MIngW编译器和实用程序不理解文件格式。我建议安装 i386 或 i686 ELF 交叉编译器。在 WSL/WSL2 中使用 Linux 会更容易进行操作系统开发。另一种选择是与 nasm(而不是 )和 LD(而不是 )一起使用。使用 Windows 工具链进行操作系统开发可能会有问题,并且为内核生成正确的二进制文件时会出现问题。gccldELF-f win32-f elf32-mi386pe-melf_i386

答:

1赞 Brecht Sanders 2/10/2023 #1

运行并查找以 开头的行。ld --helpsupported emulations:

它将列出您正在使用的仿真中支持的仿真。ld

由于 MinGW/MinGW-w64 面向使用 COFF/PE 格式而不是 ELF 的 Windows,因此您的 gcc+binutils 很有可能不支持您尝试面向的平台。

解决方案是获得支持您的仿真/目标平台的 gcc+binutils,要么自己构建它,要么以某种方式找到一个有效的预构建版本。

或者你可以尝试从 Linux 进行交叉编译。在我的 Debian Linux 上,我看到返回:ld --help

supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu elf_l1om elf_k1om i386pep i386p
0赞 emacs drives me nuts 2/10/2023 #2

要尝试运行此 ran:

gcc -m32 [...]
[...]
ld [...]

在几乎所有情况下,您都不想手动拨打 ld请改用。gcc

这是 bacause 不是编译器。 是一个驱动程序,它根据命令行选项调用编译器(对于 C,对于 C++,对于 LTO 字节码)、汇编程序 () 和链接器 ( 和 ) 等子进程。gccgcccc1cc1pluslto1ascollect2ld

例如,如果该过程包括链接 like with

gcc main.c -o main.exe

gcc最终将调用链接器,其中包含许多您不想手动添加的选项和库。要查看 triver 正在调用的命令,请添加到选项中。更具体地说,在您的情况下,您希望通过类似-v -Wl,-vgcc

gcc -m32 -o kernel.elf -Ttext 0x1000 kernel-entry.o kernel.o

然后根据需要使用 ELF 转换为其他格式。(请求非默认输出格式在当时有问题,所以最好在一个单独的步骤中。objcopygcc

此外,您可能希望添加更多选项,例如 、 、 、 设置入口点或您可能需要的任何内容。-nostdlib-nostartfilesnodefaultlibs

我对您正在使用的确切工具链并不熟悉。您是否正在尝试进行某种交叉编译?即托管的机器/操作系统与运行可执行文件的机器/操作系统不同。如果是这样的话,你需要一个合适的交叉编译器,这还不够。gcc-m32