You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止链接器添加填充字节?x86裸机引导程序链接脚本优化问询

如何阻止链接器添加填充字节?x86裸机引导程序链接脚本优化问询

我完全懂你的困扰——那些链接器自动填充的零字节纯粹是浪费空间,毕竟你的第一阶段引导程序本来就要手动加载第二阶段,这些padding完全没必要。解决这个问题的核心,是搞清楚链接器的两个关键概念:虚拟内存地址(VMA)和加载内存地址(LMA)。

简单来说:

  • VMA是代码运行时所在的内存地址(就是你之前用. = 地址设置的内容)
  • LMA是代码在输出二进制文件里的偏移地址

你之前的脚本只设置了VMA,链接器默认会让LMA等于VMA,所以才会在.boot和.text32之间填充大量零来补全地址差。现在我们要把这两个地址分开配置,让文件里的段紧密排列,但运行时地址保持你需要的0x10000。

直接给你修改后的链接脚本:

OUTPUT_FORMAT("elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)

SECTIONS {
    /* 第一阶段引导扇区:运行地址0x7c00,文件从偏移0开始 */
    . = 0x7c00;
    .boot : AT(0) {
        boot.o (.boot);
    }

    /* 引导扇区魔术字:运行地址0x7c00+510,文件偏移510 */
    . = 0x7c00 + 510;
    .magic : AT(510) {
        SHORT(0xaa55);
    }

    /* 第二阶段32位代码:运行地址0x10000,文件从偏移512(0x200)开始 */
    . = 0x10000;
    .text32 : AT(0x200) {
        boot.o (.boot32);
        main32.o (.text);
    }
}

关键修改说明:

  • 每个段后面的AT(偏移)就是指定该段在输出文件里的LMA(加载偏移):
    • .boot用AT(0),让它从文件最开头(偏移0)开始,对应运行地址0x7c00
    • .magic用AT(510),确保魔术字刚好落在文件的第511字节(偏移从0算),符合引导扇区要求
    • .text32用AT(0x200)(也就是十进制512),让它紧跟在引导扇区(512字节)后面,文件里不会有多余的填充,同时运行时链接到0x10000地址

验证方法:

  • 用objdump -h 你的输出文件查看段信息,你会看到每个段的VMA是你需要的运行地址,LMA是我们设置的文件偏移,两者不再相等
  • 用hexdump -C 你的输出文件检查内容,512字节之后会直接出现第二阶段的代码,中间没有大片的零填充

最后提醒一句:你的第一阶段引导程序加载第二阶段时,一定要把文件中从偏移512开始的内容,准确加载到内存的0x10000地址,这样才能和链接时的VMA对应上,保证代码正常运行。

备注:内容来源于stack exchange,提问作者milck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 10:24:37