为什么ld链接器在编译elf_i386代码时失败

问题描述 投票:0回答:3

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

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
3个回答
1
投票

运行

ld --help
并查找以
supported 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
投票

尝试运行此命令:

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

几乎在所有情况下,您永远都不想手动调用

ld
请改用
gcc

这是因为

gcc
不是编译器。
gcc
是一个驱动程序,它调用子进程,如编译器本身(
cc1
用于C,
cc1plus
用于C++,
lto1
用于LTO字节码),汇编器(
as
)和链接器(
collect2
)和
ld
)取决于命令行选项。

例如,如果该过程包括像 with 这样的链接

gcc main.c -o main.exe

gcc
最终将使用您不想手动添加的many选项和库来调用链接器。要查看 triver 正在调用的命令,请将
-v -Wl,-v
添加到
gcc
选项。更具体地说,在您的情况下,您想通过类似的方式进行链接

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

然后根据需要使用

objcopy
从ELF转换为其他格式。 (当时从
gcc
请求非默认输出格式存在问题,因此最好采取单独的步骤。

此外,您可能想要添加更多选项,例如

-nostdlib
-nostartfiles
nodefaultlibs
、设置入口点或任何您可能需要的内容。

我不熟悉您正在使用的确切工具链。您是否正在尝试进行某种交叉编译? IE。托管

gcc
的机器/操作系统与运行可执行文件的机器/操作系统不同。如果是这种情况,您需要一个合适的交叉编译器,而
-m32
还不够。


-1
投票

问题解决了吗?我也有同样的问题...

© www.soinside.com 2019 - 2024. All rights reserved.