提问人:Jack Thomson 提问时间:1/15/2023 最后编辑:Michael PetchJack Thomson 更新时间:8/15/2023 访问量:341
为什么 ld linker 在编译 elf_i386 代码时失败
why does ld linker fail when compiling elf_i386 code
问:
我正在尝试制作一个简单的操作系统,但似乎无法让链接器工作。 我尝试使用命令:
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
答:
运行并查找以 开头的行。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
要尝试运行此 ran:
gcc -m32 [...] [...] ld [...]
在几乎所有情况下,您都不想手动拨打 ld
。请改用。gcc
这是 bacause 不是编译器。 是一个驱动程序,它根据命令行选项调用编译器(对于 C,对于 C++,对于 LTO 字节码)、汇编程序 () 和链接器 ( 和 ) 等子进程。gcc
gcc
cc1
cc1plus
lto1
as
collect2
ld
例如,如果该过程包括链接 like with
gcc main.c -o main.exe
gcc
最终将调用链接器,其中包含许多您不想手动添加的选项和库。要查看 triver 正在调用的命令,请添加到选项中。更具体地说,在您的情况下,您希望通过类似-v -Wl,-v
gcc
gcc -m32 -o kernel.elf -Ttext 0x1000 kernel-entry.o kernel.o
然后根据需要使用 ELF 转换为其他格式。(请求非默认输出格式在当时有问题,所以最好在一个单独的步骤中。objcopy
gcc
此外,您可能希望添加更多选项,例如 、 、 、 设置入口点或您可能需要的任何内容。-nostdlib
-nostartfiles
nodefaultlibs
我对您正在使用的确切工具链并不熟悉。您是否正在尝试进行某种交叉编译?即托管的机器/操作系统与运行可执行文件的机器/操作系统不同。如果是这样的话,你需要一个合适的交叉编译器,这还不够。gcc
-m32
上一个:Cmake 链接问题
评论
gcc
ld
ELF
-f win32
-f elf32
-mi386pe
-melf_i386