编译独立平展二进制文件导致输出体积过大问题排查
问题原因
你生成的二进制文件体积异常庞大,核心原因是使用--oformat binary时,GNU ld会将ELF文件中所有加载段从最低虚拟地址(VMA)到最高虚拟地址的完整范围写入二进制文件,中间的空隙会自动填充0x00。从你提供的objdump输出能看到:
- 存在VMA为0x0的加载段(对应
.comment等辅助段) .text段在0x1000,.eh_frame段在0x2000
这种分散的段布局导致链接器需要填充大量空隙,若环境默认链接脚本包含高地址预留区域,就会生成128MB级别的超大文件。
解决步骤
1. 修正汇编入口文件
更新kernel_entry.asm,显式声明全局入口点_start,确保链接器能正确识别程序起始位置:
[bits 32] [extern main] global _start _start: call main jmp $
2. 编译C文件时禁用冗余段
添加编译参数,禁止生成异常处理、 unwind表等不必要的段,减少冗余内容:
gcc -m32 -fno-pie -ffreestanding -c kernel.c -o kernel.o -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables
3. 使用自定义链接脚本
创建linker.ld脚本,统一管理段布局,确保所有必要段从0x1000开始连续排列,只保留核心段:
ENTRY(_start) OUTPUT_FORMAT("elf32-i386") OUTPUT_ARCH(i386) SECTIONS { . = 0x1000; .text : { *(.text) } .data : { *(.data) } .bss : { __bss_start = .; *(.bss) __bss_end = .; } _end = .; }
4. 重新链接生成二进制文件
使用自定义链接脚本执行链接命令,生成紧凑的内核二进制:
ld -m elf_i386 -o kernel.bin -T linker.ld kernel_entry.o kernel.o --oformat binary
内容的提问来源于stack exchange,提问作者Ahmed Fawzy
相关产品推荐
相关产品推荐

