-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Armclang / armlink support in Zephyr - Zephyr CMake linker functions #36140
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some of these commits we could pull out and merge sooner:
- cmake: removed stray space in readelf outfile flag
- linker: removing unused _DATA_IN_ROM
- linker: align __data_ram/rom_start/end linker symbol names
etc.
cmake/extensions.cmake
Outdated
@@ -2245,3 +2279,379 @@ function(target_byproducts) | |||
COMMENT "Logical command for additional byproducts on target: ${TB_TARGET}" | |||
) | |||
endfunction() | |||
|
|||
######################################################## |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should put these in their own file (cmake/linker.cmake) and think about removing the zephyr_
prefix as I think this could be used by other projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@galak, not sure if linker.cmake
is best choice directly at the <zephyr>/cmake/
level as it may not be obvious to people that this particular file contains CMake extension functions / macros, and we also uses linker.cmake
elsewhere in this PR, meaning less obvious to people browsing the repo that cmake/linker.make
contains extension functions.
Maybe we should refactor and the create:
<zephyr>/cmake/extensions <-- folder
<zephyr>/cmake/extensions/zephyr.cmake <-- Very Zephyr specific extensions, functions prefixed with `zephyr_` (taken from extensions.cmake)
<zephyr>/cmake/extensions/generic.cmake <-- More generic CMake extensions (taken from extensions.cmake)
<zephyr>/cmake/extensions/linker.cmake <-- Linker specific CMake extensions, functions prefixed with `linker_` )
thoughts ?
I completely agree, and this is also my intention, but I wanted to create this PR first so people could se the reasoning for such independent cleanup. |
60f211d
to
0dd656f
Compare
/* | ||
* Tell armclang that stack alignment are ensured. | ||
*/ | ||
.eabi_attribute Tag_ABI_align_preserved, 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since 8-byte stack alignment currently is/must always be ensured, it would be better to make this part of _ASM_FILE_PROLOGUE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very good point, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we are almost out of time, a reminder to myself to refactor this in the future. @stephanosio
# r: Read-only region | ||
# w: Read-write region | ||
# x: Executable region | ||
# The flags r and x, or w and x may be combined like: rx, wx. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not an expert, but are there other flags that might be necessary here besides just these on some linkers? If so, should this be moved into multi_value_keywords instead of single_args? That would let you say FLAGS r x
while potentially leaving this a bit more future proof.
Or maybe a comma-separated list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
For a start I will leave it a bit open, to allow some more thoughts on best approach here.
@TTornblom would there be something to consider for IAR in this regard ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tejlmand I will check this out, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will check this out, thanks.
@TTornblom ping
8b44d5c
to
3191ee9
Compare
Addresses #33435 |
I wonder if this might tie in with #37123 (macos native_posix support). The major issue with macos is that the Mach-O binary file format only supports section names 1 <= n <= 16 chars in length, and we generate a number of linker-defined sections that exceed that size. One possible solution for that would be some kind of mapping for section names. I'll be looking at other solutions as well. Currently macos support is very brute force. |
7c35509
to
125e14a
Compare
@nashif @carlescufi There are two failures:
Besides that CI is green. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For an experimental feature, looks good enough to me.
Any nits/refinements/refactorings can be done later.
This commit introduces zephyr_linker CMake functions for creation of linker scripts. The linker functions supports the following features: - Configuration of memory sections - Configuration of memory groups - Creation of output sections - Configuration of input section the should go into output section and how those should be treated, such as sorting, keep, priority. - Defining linker symbols - Specifying Kernel VMA to support virtual linking on x86 Overview of functions and macros introduce with this commit: - pow2round - zephyr_linker - zephyr_linker_memory - zephyr_linker_memory_ifdef - zephyr_linker_group - zephyr_linker_section - zephyr_linker_section_ifdef - zephyr_iterable_section - zephyr_linker_section_obj_level - zephyr_linker_section_configure - zephyr_linker_symbol - zephyr_linker_property_append Signed-off-by: Torsten Rasmussen <[email protected]>
This commit introduces zephyr_linker_dts CMake functions for creation of linker scripts based on devicetree nodes. The linker devicetree functions supports the following features: - Configuration of memory sections based on devicetree nodes Overview of functions introduced with this commit: - zephyr_linker_dts_memory Signed-off-by: Torsten Rasmussen <[email protected]>
Converted existing ld script templates into CMake files. This commit takes the common-ram.ld, common-rom.ld, debug-sections.ld, and thread-local-storage.ld and creates corresponding CMake files for the linker script generator. The CMake files uses the new Zephyr CMake functions: - zephyr_linker_section() - zephyr_linker_section_configure() - zephyr_linker_section_obj_level() to generate the same linker result as the existing C preprocessor based scheme. Signed-off-by: Torsten Rasmussen <[email protected]>
This commit specifies the intList section in the IDT_LIST region in the arch/common CMakeLists.txt file. It uses zephyr_linker_section to setup the intList section for first pass linker file and configures the section to hold irq_info and intList input section. For second pass linker file, the irq_info and intList input sections are placed in the /DISCARD/ section. Signed-off-by: Torsten Rasmussen <[email protected]>
This is the initial version of a Zephyr CMake linker file for the arm architecture. This file defines memory regions, groups, linker sections and symbols for the arm architecture. It also sources the common common-ram.cmake, common-rom.cmake, debug-sections,cmake, and thread-local-storage.cmake. It configure sections for SoC families using zephyr_linker_sources() functions: - nxp_imx Signed-off-by: Torsten Rasmussen <[email protected]>
This commit add devicetree memory regions added to arm/linker.cmake. The following memory regions are now added to the generated linker script and scatter file if they exists in the devicetree. - chosen: zephyr,itcm - chosen: zephyr,dtcm - nodelabel: ti_ccfg_partition - nodelabel: sram1 - nodelabel: sram2 - nodelabel: sram3 - nodelabel: sram4 - nodelabel: sdram1 - nodelabel: sdram2 - nodelabel: backup_sram Also support for the itcm and dtcm section and their placement in corresponding memory regions has been added. Signed-off-by: Torsten Rasmussen <[email protected]>
Adding intial version of linker_script_common.cmake. This script parses memory regions, groups, sections, settings, and symbols defined in the Zephyr CMake build system. The linker script creates objects for each type above and groups sections, symbols, and groups together based on their configuration. This creates a hierarchy which the `<linker>_script.cmake` implementations can then use during linker script generation. linker_script_common.cmake also provides stubs for <type>_to_string() functions which are used when generating the output script. Each specific `<linker>_script.cmake` must implement those to_string() functions to create the final linker script. Signed-off-by: Torsten Rasmussen <[email protected]>
Adding intial version of ld_script.cmake. This script can generate ld linker script from the Zephyr CMake linker functions. This script is called by the build system and all linker settings, such as memory regions, groups, output sections, linker symbols defined with Zephyr CMake linker functions are passed to this script in order to generate an ld linker script. Signed-off-by: Torsten Rasmussen <[email protected]>
A "Linker script" choice group has been added to the linker options menu. The existing HAVE_CUSTOM_LINKER_SCRIPT config has been relocated inside the linker script menu. Two new entries has been created: - LD template, for using the old ld template files together with the C pre-processor to create the final linker script. - CMake linker generator, used for ARMClang / armlink toolchain. The CMake linker generator is also supported for LD linker scripts for the ARM architecture. In CMake, the file cmake/linker/ld/target.cmake has been updated to support the CMake LD linker generator. Signed-off-by: Torsten Rasmussen <[email protected]>
The armclang.h includes the toolchain/llvm.h header. Also it redifines the __GENERIC_SECTION and Z_GENERIC_SECTION so that they includes the `used` attribute which is needed by armlink. Signed-off-by: Torsten Rasmussen <[email protected]>
Initial bintools support for elfconvert - hex, srec, bin conversion - strip - gap fill Initial bintools support for readelf Initial bintools support for disaasembly Signed-off-by: Torsten Rasmussen <[email protected]>
This is the initial support for the armclang compiler together with the armlink linker. Introduced in this commit: - armclang compiler support - armlink linker support - armlink scatter file generator for scatter loading - dual pass linker script generation Signed-off-by: Torsten Rasmussen <[email protected]>
When using ARMClang linker and scatter files (armlink) then all libraries are linked as object libraries using `$<TARGET_OBJECTS:lib>`. CMake version 3.20 only has limited support for such linking: > Referencing $<TARGET_OBJECTS> in target_link_libraries calls worked > in versions of CMake prior to 3.21 for some cases, but was not fully > supported. One of those cases that do not work is Unix Makefiles generators. As only Ninja is currently verified to work, this commit will check the CMake version in use and the generator, and if CMake version <=3.21 is used with non-Ninja generator then an error is raised informing user to either use Ninja generator or update CMake. As the Ninja generator has been confirmed to work as expected, then that generator is accepted with CMake 3.20 and older. Signed-off-by: Torsten Rasmussen <[email protected]>
The default armlink signature uses `--list=<TARGET_BASE>.map`, but in Zephyr we uses a different name for the map file, therefore we need to specify a custom link executable signature. This is done in the linker specific flags file: cmake/linker/armlink/linker_flags.cmake Signed-off-by: Torsten Rasmussen <[email protected]>
This commit introduces armlink steering file. A steering file in armlink allows Zephyr to keep using existing linker symbols defined in ld scripts and used throughout the code tree. The steering file is generated at build time in order to resolve Zephyr linker symbols to their corresponding armlink symbols. As example, Zephyr defines __ramfunc_start which corresponds to the armlink auto defined Image$$ramfunc$$Base symbol. Or __init_PRE_KERNEL_1_start which corresponds to Image$$init_0$$Base. Signed-off-by: Torsten Rasmussen <[email protected]>
Support for ARM Compiler C library. This commit add support for the ARM Compiler C libary in: - Kconfig - libc/armstdc A new Kconfig symbol is added to allow a toolchain to specify if they support linking with the minimal C library. Also the CMake variable `TOOLCHAIN_HAS_NEWLIB` is exported to Kconfig so that CONFIG_NEWLIB_LIBS can only be enabled if the toolchain has newlib. The armclang toolchain selects the CMake scatter file generator and disables support for the LD linker template which is not supported by armlink. For the ARM Compiler C library, a corresponding lib/libc/armstc/ folder with a minimal implementation to work with the ARM Compiler C library is added. Signed-off-by: Torsten Rasmussen <[email protected]>
The stub file threading_weak.c has been added containing weak stub implementation of threading related kernel functions. The file is needed for armlink. When linking with armlink the linker will resolve undefined symbols for all undefined functions even if those functions the reference the undefined symbol is never actually called. This file provides weak stub implementations that are compiled when CONFIG_MULTITHREADING=n to ensure proper linking. Signed-off-by: Torsten Rasmussen <[email protected]>
This commit adds an additional test case for several kernel test suites to ensure that the linker script generator is working correctly for a subset of the Zephyr test suites. The ensures that the basic functionality of the linker script generator is working while still keep the performance impact on CI at a minimal level. Using the kernel tests is a trade-off between testing coverage of the linker script generator and the time it takes to complete CI. The kernel tests is considered to have the broadest coverage of various features important for the generated linker script. Signed-off-by: Torsten Rasmussen <[email protected]>
This is the initial support for Zephyr CMake linker functions.
Using CMake for linker script generations allows us to specify memory regions, linker sections, linker symbols in a common way using CMake functions, and then generate toolchain specific linker scripts / scatter files.
This allows users to only write things once and avoid linker scripts to get out of sync when only a single script (for example ld script) is updated, but not other linker scripts.
Besides a unifies Linker script language, another advantage of using CMake is that users can add new sections in their application CMakeLists.txt file.
Using CMake, a user can now write:
and this can even be done in the app CMakeLists.txt file, like:
This will create a memory region named
FOO
, with a sectionbar
where the input sectionbaz
will be placed with the KEEP flag.Also it is possible to describe a new section in CMake together with the library as:
With this PR, the arm architecture has been ported to the new Zephyr CMake linker generator.
When building with armclang, the new linker generator is always used.
When building with
zephyr
orgnuarmemb
, the old system will be used, and the new linker generator must be manually selected using:-DCONFIG_CMAKE_LINKER_GENERATOR=y
(or by using menuconfig).To build using
armclang
set the toolchain to armclang and the path to the toolchain.Building
hello_world
forqemu_cortex_m3
using armclang / armlink:and for
nrf52840dk_nrf52840
:Open minicom and see the console output:
Building with Zephyr toolchain using new linker generator:
ToDo:
Additional notes:
Issues seen when usingCMake 3.21 with make is supported. Older CMake with make will issue a error message, see: d72ec88make
, so for time being, please useninja
The cleanup commit series can be found here as independent PR:
#37938
Fixes #33435