为何ld将代码加载到0x1000而非0x0?如何让代码从0x0开始?
汇编代码在二进制文件中从0x1000起始的原因及解决方法
问题背景
我拥有以下文件:
boot.s
.section code_section code: jmp code .section boot_magic_section boot_magic: .word 0xaa55
linker_script.ld
SECTIONS { beginning : { boot.o(code_section) . += 510; boot.o(boot_magic_section) } = 0 .bss : { *(COMMON) } rest : { *(.note.gnu.property) } }
执行编译链接命令:
as -o boot.o boot.s ld -T linker_script.ld -o boot.bin boot.o && objdump -D boot.bin
反汇编结果显示code段位于虚拟地址0x0;但执行hexdump boot.bin -x时,发现代码实际在文件的0x1000偏移位置开始。
请问为何代码会从0x1000而非0x0开始?如何让汇编代码从0x0起始?
原因分析
你用ld直接输出的boot.bin本质是ELF格式的可执行文件,不是纯二进制镜像:
objdump -D解析的是ELF文件的虚拟内存地址(VMA),链接脚本里你把beginning段的VMA设为0,所以反汇编显示代码在0x0。hexdump查看的是文件的实际字节偏移,ELF文件的段默认会按4KB(0x1000)的页大小对齐,所以代码段被放到了文件中0x1000的偏移位置,这是ELF文件格式的默认对齐规则导致的。
解决方法
要生成代码从0x0起始的纯二进制镜像,需要用objcopy将ELF文件转换为纯二进制格式,步骤如下:
先用
ld生成ELF格式的中间文件:ld -T linker_script.ld -o boot.elf boot.o使用
objcopy提取纯二进制内容:objcopy -O binary boot.elf boot.bin
此时再执行hexdump boot.bin -x,就能看到代码从文件的0x0偏移位置开始,最后511-512字节是0xaa55,完全符合MBR的格式要求。
内容的提问来源于stack exchange,提问作者TornaxO7
相关产品推荐
相关产品推荐

