0

There are a lot of logs and other stuff below, so to skip to the punchline: I have a linker script and am setting variables within it, and using these variables to set up memory sections. But it seems like these variables are always being set to 0 no matter what I set them to in the script.

I am writing a linker script, trying to add two new memory sections to my output elf for an embedded systems application. I am trying to chop off the first bit of the preexisting RAM memory section, change the size of RAM accordingly, and place my new sections there.

Previously, using the nrf52840 development board and this library, I can modify the linker script for one of the example applications as so:

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
}
...

And this works perfectly. Recently, I have needed to port to the nrf9160 using the Zephyr RTOS, so I began using the NordicPlayground nrf library built on top of Zephyr at 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, I did a similar thing with the Zephyr linker script, modifying it as before. The build process somehow takes what I have done and generates the file build/spm/zephyr/linker.cmd in the build output folder:

__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
}
...

However, although I thought these two scripts should behave the same, trying to compile and link with the nrf9160 version with the Zephyr RTOS throws this error:

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

This is really strange for me, because this ouptut makes it seem like NEWSECTION1 and NEWSECTION2 have 0 length and both start at address 0x0, but this definitely should not be the case looking at the used linker script. To further make this confusing, if I replace __NewSection1Length with 0x500, or something like that, then the memory section will be 0x500B long, meaning that it seems like the error is that using variables in this linker script are being ignored or set to 0? Any help would be very much appreciated.

riley lyman
  • 317
  • 1
  • 11
  • I suspect your issue may have to do with the way some sample apps build different portions of the system (e.g. bootloader, spm, or application) on different virtual board definitions. One named "nrf9160_pxa10090ns" and one named "nrf9160_pca10090". Each may use slightly different board definitions and linker maps. The differentiation is because register maps move around when running in secure or non-secure mode. Next time I'm sitting at my PC I'll take a closer look. – JustinB Dec 20 '19 at 01:09

1 Answers1

0

Some of the more complicated features of Zephyr like bootloaders and SPM (secure partition manager) actually build using independent board definitions, linker scripts, and project configurations. Even though they all happen from one call to west build or ninja or make or whatever build tool you are configured with, they can sometimes end up mismatched.

You can see this if you go into the build output directory and notice that there will be multiple sub-directories with names like spm and mcuboot and zephyr. Each of these sub-directories will contain their own object files, map files, linker scripts, etc. The zephyr directory is the top level one that contains the build/link work for your final application and will merge in the pre-compiled binaries from the others. What I think is happening is that the prj.conf changes you made to create the custom sections in your application are only affecting one of these sub-builds. You likely need to find the prj.conf files for the other ones and modify them similarly.

JustinB
  • 320
  • 1
  • 5