Gcc 什么';这两个链接器脚本部分之间的区别是什么?
我有一个STM32项目,涉及到一个.firmware_头部分,它覆盖了我的应用程序映像的末尾。我正在尝试重新定位.data部分,以便它出现在.firmware_头部分之前,但由于某些原因,我在这样做时遇到了很多困难 下面的代码可以工作,但是破坏了我用来为图像签名的脚本,因为它不知道需要在校验和计算中包含.data部分(LMA在RAM中) 这是行不通的。即使所有地址(sidata、sdata、edata)都正确并且映像启动,初始化的数据也有问题,映像在开始运行后通常会由于明显的原因硬失败。为什么它无法启动?要加载到内存中的数据的位置与前面的链接器脚本snippit中的位置相同,闪存中存储的数据的位置也相同Gcc 什么';这两个链接器脚本部分之间的区别是什么?,gcc,linker,embedded,stm32,Gcc,Linker,Embedded,Stm32,我有一个STM32项目,涉及到一个.firmware_头部分,它覆盖了我的应用程序映像的末尾。我正在尝试重新定位.data部分,以便它出现在.firmware_头部分之前,但由于某些原因,我在这样做时遇到了很多困难 下面的代码可以工作,但是破坏了我用来为图像签名的脚本,因为它不知道需要在校验和计算中包含.data部分(LMA在RAM中) 这是行不通的。即使所有地址(sidata、sdata、edata)都正确并且映像启动,初始化的数据也有问题,映像在开始运行后通常会由于明显的原因硬失败。为什么它
.data_flash :
{
. = ALIGN(4);
_sidata = .;
*(.data*)
. = ALIGN(4);
} > FLASH
.firmware_header :
{
. = ALIGN(4);
KEEP(*(.firmware_header))
. = ALIGN(4);
} > FLASH
.data_ram (NOLOAD) :
{
. = ALIGN(4);
_sdata = .;
. = . + SIZEOF(.data_flash);
_edata = .;
. = ALIGN(4);
} > SRAM
这就是我如何将数据从reset_handler()中的闪存加载到内存中的方法:
我错过了什么?它们的功能不应该完全相同吗 第一个脚本将所有
.data
段的字节放入闪存中的节中,但解析RAM中运行时位置的所有地址;这是您的程序所需要的。要初始化变量,您需要将内容从闪存复制到RAM,这就是您要做的
第二个脚本在flash中解析加载时间位置的.data
段的所有地址(如果我可以这么说的话);这无法工作,因为程序在运行时无法写入这些位置。NOLOAD
部分只是增加RAM中的位置指针,而不解析初始化变量的地址
请查看交叉引用中的一些初始化变量(值不等于零)。使用第一个脚本,它将正确地定位在RAM中的某个地址,使用第二个脚本,它将错误地定位在flash中的某个地址。第一个脚本将所有
段的字节放入flash中的节中,但解析它们在RAM中运行时位置的所有地址;这是您的程序所需要的。要初始化变量,您需要将内容从闪存复制到RAM,这就是您要做的
第二个脚本在flash中解析加载时间位置的.data
段的所有地址(如果我可以这么说的话);这无法工作,因为程序在运行时无法写入这些位置。NOLOAD
部分只是增加RAM中的位置指针,而不解析初始化变量的地址
请查看交叉引用中的一些初始化变量(值不等于零)。使用第一个脚本,它将正确地位于RAM中的某个地址,使用第二个脚本,它将错误地位于flash中的某个地址。不清楚为什么您的脚本不能与第一个解决方案一起工作。第一个解决方案是正确的方向。可能缺少的是数据部分指定>SRAM AT>FLASH来告诉链接器此部分位于FLASH中,但为ram链接。你可以试试这个。不清楚为什么你的脚本不能使用第一个解决方案。第一个解决方案是正确的方向。可能缺少的是数据部分指定>SRAM AT>FLASH来告诉链接器此部分位于FLASH中,但为ram链接。你可以试试这个。
.data_flash :
{
. = ALIGN(4);
_sidata = .;
*(.data*)
. = ALIGN(4);
} > FLASH
.firmware_header :
{
. = ALIGN(4);
KEEP(*(.firmware_header))
. = ALIGN(4);
} > FLASH
.data_ram (NOLOAD) :
{
. = ALIGN(4);
_sdata = .;
. = . + SIZEOF(.data_flash);
_edata = .;
. = ALIGN(4);
} > SRAM
void **pSource, **pDest;
for (pSource = &_sidata, pDest = &_sdata; pDest != &_edata; pSource++, pDest++)
*pDest = *pSource;