使用链接描述文件制作ELF文件,而不在段之间使用零初始化块

时间:2017-05-13 03:00:20

标签: linker ld elf grub

我正在尝试将链接器命令脚本设计为可由旧版grub引导(使用多引导)。我在所需位置(在前8192字节内)获取多重引导标头时遇到困难。我的脚本看起来像:

SECTIONS
{
    .multiboot :
    {
        __multiboot_header = .;
        *(.multiboot)
    }

    .text 0x00100000 :
    {
        *(.text*)
        *(.rodata)
    }

    /* ... remainder of script ... */
}

总的来说,我的目标是在物理内存的第一个1MiB之后由引导加载程序加载我的自定义可执行文件;作为 .text 部分声明的一部分的地址似乎按照我的预期完成了。读取ELF标题将输入点指定为:

$ readelf -h kernel.elf | grep Entry
  Entry point address:               0x100000

然而,在这样做的过程中,我似乎也增加了这个文件。

$ ls -l file.elf
-rwxr-xr-x 1 user user 1049960 May 13 02:20 file.elf

ELF标题和 .text 部分之间的区域初始化为零。

$ hexdump -C file.elf
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  00 00 10 00 34 00 00 00  |............4...|
00000020  00 04 10 00 00 00 00 00  34 00 20 00 02 00 28 00  |........4. ...(.|
00000030  09 00 08 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 f8 00 10 00  f8 f0 4e 00 07 00 00 00  |..........N.....|
00000050  00 00 20 00 51 e5 74 64  00 00 00 00 00 00 00 00  |.. .Q.td........|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 07 00 00 00  |................|
00000070  10 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000  8b 25 f8 f0 4e 00 50 53  e8 66 00 00 00 fa f4 eb  |.%..N.PS.f......|
00100010  fc 55 89 e5 53 83 ec 10  c7 45 f8 00 00 00 00 eb  |.U..S....E......|
00100020  38 a1 f4 00 10 00 8b 55  f8 01 d2 01 d0 8b 15 f4  |8......U........|

此外,虽然readelf -s报告__multiboot_header的值为0x0( 应该是结构的地址,因为它是在同一点定义的在链接器文件中,对吗?):

$ readelf -s kernel.elf | grep multiboot
    22: 00000000     0 NOTYPE  GLOBAL DEFAULT    1 __multiboot_header

readelf -S的输出似乎有冲突:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 1] .multiboot        PROGBITS        00000000 1000f8 00000c 00      0   0  1
  [ 2] .text             PROGBITS        00100000 100000 000096 00  AX  0   0  1

这意味着 .multiboot 部分实际上位于 .text 部分中。

如果我通过0x1000f8偏移到文件中,那么我可以找到结构,但是,我不确定偏移来自何处。

TL;博士

1)如何确保特定数据结构在输出文件的前8192个字节内?

2)如何在不使用零初始化块的大间隙来扩充输出二进制数的情况下指定加载地址?

1 个答案:

答案 0 :(得分:1)

elf文件格式由其自己的规则生成,它如何存储信息不受链接器文件的直接影响(例如,存储的部分的偏移量必须与它们在存储器中的生命周期的位置不相关)。它是由链接器文件中的SECTIONS命令描述的内存布局,而elf文件格式描述此布局......您需要一个能够加载elf的加载器各个部分进入目标位置。

要获得可以1:1加载到内存中的平面二进制文件,请使用objcopy(例如objcopy -O binary myfile.elf myfile.bin之类的内容)。该文件的布局直接受链接描述文件的影响, .multiboot 部分的内容实际上应该偏移0