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

时间:2016-05-20 10:40:54

标签: assembly kernel ld x86-16 osdev

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

  1. boot.asm
  2. kernel.c
  3. 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
    

    我使用 LD

    将内核对象链接到二进制文件
    ld -Ttext 0x10000 --oformat binary -o kernel.bin kernel.o
    

    我得到的错误是:

      

    ld:无法链接不是PE可执行类型的文件

    有人能解决这个错误吗?

    • 使用的操作系统:windows
    • 编译器:GCC
    • 链接器:ld

2 个答案:

答案 0 :(得分:4)

您的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

答案 1 :(得分:1)

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

找一个支持或自己构建它的人。