繁体   English   中英

如何通过将各自的部分放在不同的位置来链接两个目标文件?

[英]How to link two object files by placing their respective sections at different locations?

我有一个bootloader程序“boot.asm”,它必须包含一个特殊字,从一开始就有510字节的偏移量。 我有一个用C“kernel.c”编写的内核源代码。

我的计划是通过从引导加载程序加载第二个硬盘扇区并将其放在内存中的0x8000位置来调用内核(它将位于高清的第二个扇区)。

现在我将两个源文件编译成ELF目标文件(单独)到“boot.o”和“kernel.o”,然后通过链接器链接它们并输出原始二进制文件“kernel.bin”。

我想把我的bootloader代码从0x7c00开始,然后在0x7dfe位置我必须把特殊字放入。 然后在0x8000我必须放置我的内核代码。 即我想将两个目标文件的各个部分放在不同的位置。

这是我失败的尝试。

ENTRY(boot)
OUTPUT_FORMAT("binary")

SECTIONS{
  . = 0x7c00;
  .text :
  {
    *(.boot)
  }

  .sig : AT(0x7dfe){
     SHORT(0xaa55);
  }

  . = 0x8000;

  .text :
  {
    kernel.o(.text)
  }

  .rodata :
  {
    kernel.o(.rodata)
  }

  .data :
  {
    kernel.o(.data)
  }

  .bss :
  {
    kernel.o(.bss)
  }

}

我所理解的是,可执行文件不能有多个部分。

我对低级编程知之甚少。

我该如何解决这个问题。 谢谢。

您需要修复两件事,不要拆分.text输出部分,并使用AT()将内核紧跟在输出二进制文件中的引导扇区之后,同时保持其地址为0x8000。 例如,像这样的链接器脚本应该工作:

ENTRY(boot)
OUTPUT_FORMAT("binary")

SECTIONS {
  . = 0x7c00;
  .boot :
  {
    *(.boot)
  }

  . = 0x7dfe;
  .sig : {
     SHORT(0xaa55);
  }

  . = 0x8000;
  .kernel : AT(0x7e00)  /* place immediately after the boot sector */
  {
    *(.text)
    *(.rodata)
    *(.data)
    _bss_start = .;
    *(.bss)
    *(COMMON)
    _bss_end = .;
  }
  kernel_sectors = (SIZEOF(.kernel) + 511) / 512;

  /DISCARD/ : {
        *(.eh_frame)
  }
}

我添加了一些东西来处理你在GCC编译的目标文件中看到的部分。 _bss_start_bss_end符号可用于将.bss部分清零,并且根据Michael Petch的建议, kernel_sector符号设置为512字节扇区中的内核长度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM