链接器脚本总是将变量解释为零?



下面有很多日志和其他东西,所以跳到重点:我有一个链接器脚本,正在其中设置变量,并使用这些变量来设置内存部分。但似乎无论我在脚本中将它们设置为什么,这些变量总是设置为 0。

我正在编写一个链接器脚本,尝试为嵌入式系统应用程序的输出 elf 添加两个新的内存部分。我正在尝试切断预先存在的 RAM 内存部分的第一部分,相应地更改 RAM 的大小,并将我的新部分放在那里。

以前,使用 nrf52840 开发板和此库,我可以修改其中一个示例应用程序的链接器脚本,如下所示:

SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
__NewSection1Start  = 0x20000000;
__TotalLength = 0x1000;
__NewSection2Length = __TotalLength / 2;
__NewSection1Length = __TotalLength / 2;
__NewSection2Start = __NewSection1Start + __NewSection1Length;
MEMORY
{
FLASH (rx)           : ORIGIN = 0x0,         LENGTH = 0xff000
NEWSECTION1 (rwx) : ORIGIN = __NewSection1Start, LENGTH = __NewSection1Length
NEWSECTION2 (rwx) : ORIGIN = __NewSection2Start, LENGTH = __NewSection2Length
RAM (rwx)            : ORIGIN = 0x20000000 + __TotalLength, LENGTH = 0x40000 
}
FLASH_PAGE_SIZE       = 4096;
FLASH_DATA_PAGES_USED = 4;
SECTIONS
{
.newsection1 :
{
KEEP (*(.newsection1));
} > NEWSECTION1
.newsection2 :
{
KEEP (*(.newsection2));
} > NEWSECTION2
}
...

这非常有效。最近,我需要使用 Zephyr RTOS 移植到 nrf9160,所以我开始在此链接中使用构建在 Zephyr 之上的 NordicPlayground nrf 库,修改其中一个示例应用程序。在尝试为该板和环境重写程序时,使用与此类似的技术,我对 Zephyr 链接器脚本做了类似的事情,像以前一样修改它。构建过程以某种方式采用我所做的并在构建输出文件夹中生成文件build/spm/zephyr/linker.cmd

__TotalLength = 0x1000;
__NewSection1Start = 0x20000000;
__NewSection2Length = __TotalLength / 2;
__NewSection1Length = __TotalLength / 2;
__NewSection2Start = __NewSection1Start + __NewSection1Length;
MEMORY
{
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0xc000
SRAM (wx) : ORIGIN = 0x20000000 + __TotalLength, LENGTH = (64 * 1K) - __TotalLength
NEWSECTION1 (rwx) : ORIGIN = __NewSection1Start, LENGTH = __NewSection1Length
NEWSECTION2 (rwx) : ORIGIN = __NewSection2Start, LENGTH = __NewSection2Length
IDT_LIST (wx) : ORIGIN = (0x20000000 + (64 * 1K)), LENGTH = 2K
}
ENTRY("__start")
SECTIONS
{
.newsection1 :
{
KEEP (*(.newsection1));
} > NEWSECTION1
.newsection2 :
{
KEEP (*(.newsection2));
} > NEWSECTION2
}
...

但是,尽管我认为这两个脚本的行为应该相同,但尝试使用 Zephyr RTOS 编译并与 nrf9160 版本链接会引发此错误:

riley@riley-Blade:~<code_base>/nrf/samples/nrf9160/example_app$ west build -b nrf9160_pca10090ns
source directory: /home/riley<code_base>/nrf/samples/nrf9160/example_app
build directory: /home/riley<code_base>/nrf/samples/nrf9160/example_app/build
BOARD: nrf9160_pca10090ns (origin: CMakeCache.txt)
[6/17] Linking C executable spm/zephyr/spm_zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
FLASH:         32 KB        48 KB     66.67%
SRAM:       10000 B        60 KB     16.28%
NEWSECTION1:          0 GB         2 KB      0.00%
NEWSECTION2:          0 GB         2 KB      0.00%
IDT_LIST:          40 B         2 KB      1.95%
[12/17] Linking C executable zephyr/zephyr_prebuilt.elf
FAILED: zephyr/zephyr_prebuilt.elf 
: && ccache /home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gcc    zephyr/CMakeFiles/zephyr_prebuilt.dir/misc/empty_file.c.obj  -o zephyr/zephyr_prebuilt.elf  -Wl,-T zephyr/linker.cmd -Wl,-Map=/home/riley<code_base>/nrf/samples/nrf9160/example_app/build/zephyr/zephyr.map -u_OffsetAbsSyms -u_ConfigAbsSyms -Wl,--whole-archive app/libapp.a zephyr/libzephyr.a zephyr/arch/arm/core/libarch__arm__core.a zephyr/arch/arm/core/cortex_m/libarch__arm__core__cortex_m.a zephyr/arch/arm/core/cortex_m/mpu/libarch__arm__core__cortex_m__mpu.a zephyr/lib/libc/minimal/liblib__libc__minimal.a zephyr/subsys/net/libsubsys__net.a zephyr/subsys/net/ip/libsubsys__net__ip.a zephyr/drivers/gpio/libdrivers__gpio.a zephyr/drivers/serial/libdrivers__serial.a zephyr/modules/nrf/lib/bsdlib/lib..__nrf__lib__bsdlib.a zephyr/modules/nrf/lib/at_host/lib..__nrf__lib__at_host.a zephyr/modules/nrf/drivers/at_cmd/lib..__nrf__drivers__at_cmd.a /home/riley<code_base>/nrfxlib/bsdlib/lib/cortex-m33/hard-float/libbsd_nrf9160_xxaa.a -Wl,--no-whole-archive zephyr/kernel/libkernel.a zephyr/CMakeFiles/offsets.dir/arch/arm/core/offsets/offsets.c.obj -L"/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v8-m.main+fp/hard" -L/home/riley<code_base>/nrf/samples/nrf9160/example_app/build/zephyr -lgcc -Wl,--print-memory-usage /home/riley<code_base>/nrfxlib/crypto/nrf_oberon/lib/cortex-m33/hard-float/liboberon_3.0.0.a -lc -mthumb -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -Wl,--gc-sections -Wl,--build-id=none -Wl,--sort-common=descending -Wl,--sort-section=alignment -nostdlib -static -no-pie -Wl,-X -Wl,-N -Wl,--orphan-handling=warn -mabi=aapcs -march=armv8-m.main+dsp libspmsecureentries.a && :
Memory region         Used Size  Region Size  %age Used
FLASH:      110428 B       976 KB     11.05%
SRAM:       24608 B       124 KB     19.38%
NEWSECTION1:         264 B         0 GB       inf%
NEWSECTION2:           1 B         0 GB       inf%
IDT_LIST:         120 B         2 KB      5.86/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: zephyr/zephyr_prebuilt.elf section `.newsection1' will not fit in region `NEWSECTION1'
/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: zephyr/zephyr_prebuilt.elf section `.newsection2' will not fit in region `NEWSECTION2'
/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: section .newsection2 LMA [0000000000000000,0000000000000000] overlaps section .newsection1 LMA [0000000000000000,0000000000000107]
/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: region `NEWSECTION1' overflowed by 264 bytes
/home/riley/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: region `NEWSECTION2' overflowed by 1 byte
collect2: error: ld returned 1 exit status
%
ninja: build stopped: subcommand failed.
ERROR: command exited with status 1: /home/riley/.local/bin/cmake --build /home/riley<code_base>/nrf/samples/nrf9160/example_app/build

这对我来说真的很奇怪,因为这个 ouptut 使它看起来像NEWSECTION1NEWSECTION2的长度为 0,并且都从地址0x0开始,但绝对不应该是这种情况看着使用的链接器脚本。为了进一步混淆这一点,如果我用0x500或类似的东西替换__NewSection1Length,那么内存部分将0x500B长,这意味着似乎错误是在此链接器脚本中使用变量被忽略或设置为 0?任何帮助将不胜感激。

Zephyr的一些更复杂的功能,如引导加载程序和SPM(安全分区管理器(,实际上是使用独立的板定义,链接器脚本和项目配置构建的。即使它们都发生在对west buildninjamake或您配置的任何构建工具的一次调用中,它们有时最终会不匹配。

如果您进入构建输出目录并注意到将有多个子目录的名称为spmmcubootzephyr,您可以看到这一点。 这些子目录中的每一个都将包含自己的目标文件、映射文件、链接器脚本等。zephyr目录是包含最终应用程序的构建/链接工作的顶级目录,并将合并到其他目录的预编译二进制文件中。 我认为正在发生的事情是,您在应用程序中创建自定义部分所做的prj.conf更改仅影响这些子构建之一。 您可能需要查找其他文件的prj.conf文件并进行类似的修改。