我一直在尝试在stm32微控制器上实现引导加载程序+双插槽应用固件fota策略的固件中的位置独立代码。
如果引导加载程序正确地返回irq表并加载正确的.got节偏移量,那么即使我将固件上传到与链接器脚本应该到达的地址不同的地址,固件也会被w引导加载程序正确地启动。
然而,当固件试图访问. getTable部分的本地静态变量时,它会将它们加载到错误的地址,我发现这些变量不能通过. getTable访问,我认为这是主要问题。
.got部分中包含的所有全局变量都可以正确访问,但函数内部声明的静态变量的地址根本不存在于全局偏移表中,而是通过向程序计数器添加偏移量来访问(这破坏了固件的位置独立性)。
这些局部静态变量将属于. xml部分,而全局变量位于. xml中,可以很好地加载。
*是否有一种方法可以确保.got部分用于Map所有局部静态变量,就像全局数据一样,强制执行代码位置独立性?
我用的是GCC,
- -fpic用于位置独立性
- -msingle-pic-base
- -fno-jump-tables
我已经尝试按照另一个问题(见下文)中的建议添加-mpic-data-is-text-relative,但它没有解决这个问题。
此处的所有编译器标志
-mcpu=cortex-m33 -std=gnu11 -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -DSTM32H563xx -c -I../Core/Inc -I../Drivers/STM32H5xx_HAL_Driver/Inc -I../Drivers/STM32H5xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32H5xx/Include -I../Drivers/CMSIS/Include -I"C:\Repos\bootloader_test\BootloaderTest\Core\Shared" -O0 -ffunction-sections -fdata-sections -Wall -fno-jump-tables -fpic -msingle-pic-base -fstack-usage -fcyclomatic-complexity --specs=nano.specs -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb
在固件链接器中,.got表被创建为节
.got (APP_GOT_START):
{
. = ALIGN(4);
GOT_START = .;
KEEP(*(.got))
GOT_END = .;
. = ALIGN(4);
} >APP_GOT AT> APP_B_GOT
在同一个链接器中,. xml节被声明为
.bss (APP_RAM_START):
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss section */
_sbss = . ; /* define a global symbol at bss start */
__bss_start__ = _sbss ;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
这些问题或多或少都在处理同一个问题,
- unanswered, comments redirect to #2
- explains the problem but does not provide the solution, redirects to #3
1.已回答,但添加-mpic-data-is-text-relative似乎对我不起作用
1条答案
按热度按时间ny6fqffe1#
找到解决方案了!
对我来说,诀窍是添加**-mno-pic-data-is-text-relative**,这样它就强制编译器禁用选项pic-data-is-text-relative,即使没有指定(!).
这与所引用的问题中提出的建议强制启用所述选项的解决方案完全相反。
现在,局部静态变量被添加到全局偏移表中,并被正确访问。
来源:[https://gcc.gnu.org/legacy-ml/gcc-patches/2016-05/msg00630.html]