使用 ld 链接文件以输出二进制文件在 OS 开发中出现错误

Linking a file using ld to output a binary file gives error in OS development

我正在学习操作系统教程。我创建了 2 个文件。

  1. boot.asm
  2. kernel.c

kernel.c如下:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}

内核用于向文本模式视频显示区写入一个字符。内核是使用 Windows 版本的 GCC 编译的,其中:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o

I link 内核对象到二进制文件使用 LD:

ld -Ttext 0x10000 --oformat binary -o kernel.bin kernel.o

我得到的错误是:

ld : cannot link the file which is not PE executable type

谁能解决这个错误?

这意味着 ld 本身在编译时未配置为支持 PEPortable Executable 以外的输出格式 - 本机 Windows 可执行文件格式。

找到支持的或者自己搭建。

您的 Windows 版本的 LD 可能只支持 windows PE 类型。解决此问题的一种方法是输出到 PE,然后使用 objcopy 将 PE 文件转换为二进制文件。

为此,您必须将 main 重命名为 _main。使用 -ffreestanding GCC 将发出一个对象 而没有 Windows 在非静态函数前添加前导下划线的 ABI 约定.我们将使用您的 LD 首先输出一个 Windows PE 文件,它会抱怨 __main 入口点未定义。为了解决这个问题,您将 main 重命名为 _main 这样链接器就不会抱怨了。

使用这些指令生成内核二进制文件:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin

LD 命令输出到名为 kernel.pe 的文件。 objcopykernel.pe 转换为二进制 -O binary 输出到 kernel.bin