如何阻止链接器添加填充字节?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
相关产品推荐
相关产品推荐

