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

Linker Script Always Interprets Variables as Zero?

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

我正在编写一个 linker 脚本,试图将两个新的内存部分添加到我的嵌入式系统应用程序的输出精灵中。我试图砍掉预先存在的 RAM 内存部分的第一位,相应地更改 RAM 的大小,并将我的新部分放在那里。

以前,使用 nrf52840 开发板和 this 库,我可以修改示例应用程序之一的 linker 脚本,如下所示:

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,所以我开始使用在 this link, modifying one of the sample apps in there. In trying to rewrite the program for that board and environment, using a technique similar to this Zephyr 之上构建的 NordicPlayground nrf 库,我用 Zephyr linker 脚本做了类似的事情,像以前一样修改它。构建过程以某种方式采用我所做的并在构建输出文件夹中生成文件 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 版本编译和 link 会抛出此错误:

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

这对我来说真的很奇怪,因为这个输出让 NEWSECTION1NEWSECTION2 的长度看起来像是 0,并且都从地址 0x0 开始,但这绝对不应该查看使用过的 linker 脚本的案例。为了进一步混淆,如果我将 __NewSection1Length 替换为 0x500 或类似的东西,那么内存部分将是 0x500B 长,这意味着错误似乎是使用变量在这个 linker 脚本中被忽略或设置为 0?非常感谢任何帮助。

Zephyr 的一些更复杂的功能,如引导加载程序和 SPM(安全分区管理器),实际上是使用独立的板定义、链接描述文件和项目配置构建的。尽管它们都是通过调用 west buildninjamake 或您配置的任何构建工具而发生的,但有时它们最终可能会不匹配。

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