GHS MULTI链接脚本填充.srec内存间隙及FILL()用法咨询
GHS MULTI链接脚本SREC内存间隙填充解决方案
无效写法的核心原因
GHS链接器的FILL语义与GNU ld存在差异,尝试的写法不生效主要有三个原因:
- FILL()/=fill的位置不符合GHS语法要求
- 段与段之间的地址间隙无法通过单个段的填充属性覆盖,必须显式定义填充段
- 生成SREC时默认会过滤无有效内容的间隙区域,需额外开启填充参数
正确填充方案
1. 段内间隙填充语法
段内因对齐产生的间隙可通过FILL()或=fill属性填充,正确语法顺序为:段名 [其他属性] : [FILL(填充值) | =填充值] { 段内容 } > 内存区域
正确写法示例:
/* FILL()写法 */ .text : FILL(0xFF) { *(.text*) *(.rodata*) } > ROM /* =填充值简写写法 */ .data : =0x00 { *(.data*) } > RAM AT> ROM
2. 段间间隙填充语法
段与段之间的地址间隙需要定义独立的填充段覆盖,通用模板如下:
/* 填充当前地址到目标地址target_addr的间隙,填充值为0xFF */ .fill_gap : { FILL(0xFF); . += (target_addr - .); } > 内存区域
3. SREC输出参数配置
GHS默认生成SREC时会跳过无内容的间隙区域,需要在链接命令行或工程配置中添加参数:-srec-fill-gaps
请勿同时添加-srec-omit-empty参数,否则填充内容会被过滤。
完整可运行示例
/* 内存区域定义,根据你的硬件调整 */ MEMORY { ROM (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K } SECTIONS { /* 中断向量表,段内填充0xFF */ .isr_vector : FILL(0xFF) { KEEP(*(.isr_vector)) } > ROM /* 代码段,段内填充0xFF */ .text : FILL(0xFF) { *(.text*) *(.glue_7t) } > ROM /* 填充.text段结束到0x08008000的段间间隙 */ .text_rodata_gap : { FILL(0xFF); . += (0x08008000 - .); } > ROM /* 常量段,固定起始地址0x08008000,段内填充0xFF */ .rodata 0x08008000 : FILL(0xFF) { *(.rodata*) } > ROM /* 填充所有剩余ROM空间 */ .rom_remain : { FILL(0xFF); . += (ORIGIN(ROM) + LENGTH(ROM) - .); } > ROM /* RAM段定义 */ .data : { *(.data*) } > RAM AT> ROM .bss (NOLOAD) : { *(.bss*) *(COMMON) } > RAM }
CLEAR属性碎片化问题解决
遇到的使用CLEAR属性后SREC行碎片化问题,是因为CLEAR标记的段内容默认不会完整输出到SREC,添加-srec-fill-gaps参数即可解决;也可以直接放弃CLEAR属性,改用FILL(0x00)显式定义填充段,避免输出碎片化。
内容的提问来源于stack exchange,提问作者Lokesh Kakarla
相关产品推荐
相关产品推荐

