Skip to content

cmake: linker_script: arm: Cannot move .bss and .noinit LMA to RAM #59064

Closed as not planned
@57300

Description

@57300

Describe the bug

When building with CONFIG_CMAKE_LINKER_GENERATOR=y, the program headers show .bss and .noinit sections being loaded from flash, which is incorrect. These sections' VMA and LMA should be the same.

A fix was attempted in f5eada5, but it introduced another bug (#57590) on multiple platforms, because some sections should still be loaded from flash, such as .data.

A proper fix, which only moves select sections to the RAM region, is hindered by an apparent bug in the linker script generator.

To Reproduce

  1. git revert f5eada5553467c732e7e5bf283e72b66d7be71a9 -n
  2. west build -b mps2_an521 samples/philosophers -p -DCONFIG_CMAKE_LINKER_GENERATOR=y
  3. arm-zephyr-eabi-readelf -l build/zephyr/zephyr.elf
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x0060dc 0x10006028 0x10006028 0x00008 0x00008 R   0x4
  LOAD           0x0000b4 0x10000000 0x10000000 0x06030 0x06030 RWE 0x4
  LOAD           0x0060e8 0x38000000 0x10006030 0x000f0 0x03df0 RW  0x8
  LOAD           0x000000 0x38003df0 0x10006120 0x00000 0x006db RW  0x8

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx
   01     .rom_start .text init device_area sw_isr_table log_const_area device_handles .rodata .ARM.exidx
   02     .data device_states k_mutex_area .noinit
   03     .bss
  1. Observe that the PhysAddr for segments 02 and 03 (or whichever ones contain .bss and .noinit) do not match VirtAddr.
  2. Hotfix:
diff --git a/cmake/linker_script/arm/linker.cmake b/cmake/linker_script/arm/linker.cmake
index 9cad47539c..9e48a0ec29 100644
--- a/cmake/linker_script/arm/linker.cmake
+++ b/cmake/linker_script/arm/linker.cmake
@@ -122,14 +122,14 @@ include(${COMMON_ZEPHYR_LINKER_DIR}/common-ram.cmake)
 #include(kobject.ld)

 if(NOT CONFIG_USERSPACE)
-  zephyr_linker_section(NAME .bss VMA RAM LMA FLASH TYPE BSS)
+  zephyr_linker_section(NAME .bss VMA RAM LMA RAM TYPE BSS)
   zephyr_linker_section_configure(SECTION .bss INPUT COMMON)
   zephyr_linker_section_configure(SECTION .bss INPUT ".kernel_bss.*")
   # As memory is cleared in words only, it is simpler to ensure the BSS
   # section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
   zephyr_linker_section_configure(SECTION .bss ALIGN 4)

-  zephyr_linker_section(NAME .noinit GROUP RAM_REGION TYPE NOLOAD NOINIT)
+  zephyr_linker_section(NAME .noinit VMA RAM LMA RAM TYPE NOLOAD NOINIT)
   # This section is used for non-initialized objects that
   # will not be cleared during the boot process.
   zephyr_linker_section_configure(SECTION .noinit INPUT ".kernel_noinit.*")
  1. west build && arm-zephyr-eabi-readelf -l build/zephyr/zephyr.elf
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x0060fc 0x10006028 0x10006028 0x00008 0x00008 R   0x4
  LOAD           0x0000d4 0x10000000 0x10000000 0x06030 0x06030 RWE 0x4
  LOAD           0x006104 0x38000000 0x10006030 0x000f0 0x000f0 RW  0x4
  LOAD           0x000000 0x38000000 0x380000f0 0x00000 0x006db RW  0x8
  LOAD           0x000000 0x380006e0 0x380006e0 0x00000 0x03d00 RW  0x8

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx
   01     .rom_start .text init device_area sw_isr_table log_const_area device_handles .rodata .ARM.exidx
   02     .data device_states k_mutex_area
   03     .bss
   04     .noinit
  1. Observe that segments 02 and 03 start at the same VirtAddr and are now overlapping, presumably because the generated linker script in build/zephyr/linker.cmd is incorrect.
  2. Try west build -t run to confirm that samples/philosophers is not running properly.

Expected behavior

.bss should not overlap with .data.

The program headers should resemble the ones produced with CONFIG_CMAKE_LINKER_GENERATOR=n:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x004b54 0x10004a80 0x10004a80 0x00008 0x00008 R   0x4
  LOAD           0x0000d4 0x10000000 0x10000000 0x06070 0x06070 RWE 0x4
  LOAD           0x006144 0x38000000 0x10006070 0x000dc 0x000dc RW  0x4
  LOAD           0x006220 0x1000614c 0x1000614c 0x00004 0x00004 R   0x1
  LOAD           0x000000 0x380000e0 0x380000e0 0x00000 0x043e0 RW  0x8

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx
   01     rom_start text .ARM.exidx initlevel device_area sw_isr_table device_handles log_const_area zephyr_dbg_info rodata
   02     datas device_states
   03     .last_section
   04     bss noinit

Impact

Minor?

Environment

  • OS: Linux
  • Toolchain: Zephyr SDK 0.16.0
  • Commit SHA or Version used: v3.4.0-rc2

Additional context

Introduced in Zephyr v2.7.0.

Metadata

Metadata

Assignees

Labels

Stalearea: Linker Scriptsblock: HW TestTesting on hardware required before mergingbugThe issue is a bug, or the PR is fixing a bugpriority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions