如何通过GNU链接脚本在固件二进制末尾添加魔术字节标记?
问题原因
你当前的操作逻辑存在两处关键问题:
- C代码里的
end_of_code数组被放在.endc.end_of_code子段,而链接脚本中.endc段的执行顺序是先将所有.endc开头的段(包括这个数组)全部放入,再执行对齐和符号定义。这导致数组被放在.endc段的起始位置,而非整个固件的末尾。 - 链接脚本里的
.end_of_code = .;仅定义了一个指向当前地址的符号,并未将C数组关联到该地址,反而因为C数组早被加载进段中,符号指向的是数组之后的对齐地址。
解决方案
方案一:直接在链接脚本中写入魔术字节(最可靠,无需C代码)
通过链接脚本的内置指令直接写入4字节魔术值,确保它们位于FLASH区域的最后位置:
.endc : { . = ALIGN(4); // 先确保地址按4字节对齐 LONG(0x04030201); // 注意字节序:小端架构下需反向写数值,对应实际存储的0x01 0x02 0x03 0x04 _end_code_mark = .; // 标记魔术字节后的地址 } >FLASH
若目标架构为大端,直接写
LONG(0x01020304)即可。
方案二:调整C代码与链接脚本的段加载顺序
如果必须用C代码定义魔术字节,需确保它是.endc段中最后加载的内容:
- 修改C代码,将数组放在独立的子段:
const uint8_t end_of_code[] __attribute__((section(".endc.magic"))) = {0x01, 0x02, 0x03, 0x04};
- 修改链接脚本,明确指定段的加载顺序:
.endc : { KEEP(*(.endc)); // 加载原有.endc段内容(若存在) . = ALIGN(4); KEEP(*(.endc.magic)); // 最后加载魔术字节数组 _end_code_mark = .; } >FLASH
内容的提问来源于stack exchange,提问作者kokopelli
相关产品推荐
相关产品推荐

