ARM GCC如何强制未使用的AES变量加载到Bootloader指定Flash地址?
问题:Cortex-M7 Bootloader中强制保留AES密钥到Flash指定地址
基于Cortex-M7的Bootloader项目使用ARM GCC 10.3.1编译器,需将一个仅主应用使用的AES密钥变量固定到Flash指定地址。已完成以下配置,但变量仍被编译器优化剔除:
- 链接脚本中定义专属内存区域与段,且添加
KEEP指令 - 变量标记
__attribute__((section(".aes_key_sect")))属性
仅在Bootloader的init函数中对变量做伪访问时,变量才会被纳入构建。添加const关键字无效果,寻求更优解决方案。
相关代码与现象
链接脚本内存定义
/* Specify the memory areas */ MEMORY { FLASH_FSBL (rx) : ORIGIN = 0x08000000, LENGTH = 126K FLASH_FSBL_AESKEY (rx) : ORIGIN = 0x0801F900, LENGTH = 256 }
自定义AES密钥段
/* Section for AES key */ .aes_key_sect : { PROVIDE(region_aes_key_start = .); KEEP (*(.aes_key_sect)) PROVIDE(region_aes_key_end = .); } >FLASH_FSBL_AESKEY
Boot代码变量定义
#define LOCATION_AES_KEY __attribute__((section(".aes_key_sect"))) LOCATION_AES_KEY static uint8_t aeskey_const[] = { #include "../../../aes256_key.txt" };
编译现象
- 未伪访问时:
FLASH_FSBL_AESKEY占用为0 - 添加伪访问代码后:
FLASH_FSBL_AESKEY占用32B(符合AES-256密钥长度)
解决方案
方案1:给变量添加used属性(推荐)
直接在变量属性中添加used,强制编译器保留该变量,避免编译阶段被优化剔除,后续链接器的KEEP指令即可正常将其放入指定区域:
#define LOCATION_AES_KEY __attribute__((section(".aes_key_sect"), used)) LOCATION_AES_KEY static uint8_t aeskey_const[] = { #include "../../../aes256_key.txt" };
方案2:链接脚本中直接引用变量符号
若不想修改C代码,可在链接脚本中直接指定变量符号,强制链接器包含该变量。注意:若变量用static修饰,需额外添加externally_visible属性让符号对外可见:
修改C代码
#define LOCATION_AES_KEY __attribute__((section(".aes_key_sect"), externally_visible)) LOCATION_AES_KEY static uint8_t aeskey_const[] = { #include "../../../aes256_key.txt" };
修改链接脚本
/* Section for AES key */ .aes_key_sect : { PROVIDE(region_aes_key_start = .); KEEP (*(.aes_key_sect)) /* 直接引用变量符号,强制链接器包含 */ KEEP(*(aeskey_const)) PROVIDE(region_aes_key_end = .); } >FLASH_FSBL_AESKEY
方案3:针对文件关闭未使用变量优化
在Makefile中给包含该变量的源文件添加编译选项-fno-unused-variable,禁止编译器优化该文件中的未使用变量:
# 假设变量在boot_key.c文件中 boot_key.o: CFLAGS += -fno-unused-variable
内容的提问来源于stack exchange,提问作者unalignedmemoryaccess
相关产品推荐
相关产品推荐

