-
Notifications
You must be signed in to change notification settings - Fork 934
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
rp2_common/pico_standard_link: implement customizable linker script #1547
base: develop
Are you sure you want to change the base?
Conversation
…sing C preprocessor Background: For cases where modifications to the linker script are required, pico-sdk only provides the option to provide an entire linker script using pico_set_linker_script. This patch adds a function pico_customize_linker_script to create a linker script in the build process, based on a template provided by pico-sdk and local settings provided by the user. Use cases for linker script modification include: - using the linker script as a rudimentary file system for binary blobs - sharing WiFi firmware blobs between bootloader and application (picowota) - reducing the number of code duplication in linker scripts (e.g. memmap_blocked_ram.ld which differs in only one line from the default) In such cases, deriving the linker script from a template may/should lead to code that is easier to maintain. Implementation: The template is memmap.ld.in, the user input is provided by specifying a customization file to be included, and the linker script is generated by the C preprocessor. The template exposes a few settings by #defining them before including the customization file, and provides a few hooks to add elements to the template. Examples and hints for use, based on a working example where cyw43 firmware lives in a separate region in flash: in CMakeLists.txt: pico_customize_linker_script(my_target tweaks.h) tweaks.h: #undef MAIN_FLASH_LENGTH #define MAIN_FLASH_LENGTH 256k #undef ADDITIONAL_FLASH_REGIONS #define ADDITIONAL_FLASH_REGIONS \ FLASH_CYWFW(rx): ORIGIN = 0x10040000, LENGTH = 256k #undef ADDITIONAL_SECTIONS #define ADDITIONAL_SECTIONS \ .fw_cyw43 : { \\ . = ALIGN(4k); \\ KEEP(*(.fw_cyw43.meta)) \\ . = ALIGN(512); \\ *(.fw_cyw43.blob) \\ } > FLASH_CYWFW Details: - The linker script will be a build product named ${TARGET}.ld - When using \\ at the end of lines, newlines are inserted in the resulting linker script in a postprocessing step. This is done to improve readability of the resulting linker script. - Lines starting with # need to be removed from the output; they are now turned into /*comments*/ - Values that are to be overridden need to be #undeffed before redefining them, which is a bit awkward; another option is to use #ifdef for each and every variable in the template; yet another option (for integers) is to use linker variables (i.e. simply setting MAIN_FLASH_LENGTH=256k).
I know nothing about linker scripts, but replying to just your comment about |
I have thought about that, but it hides the default values (they come later, and only |
Fixes #398
Background:
For cases where modifications to the linker script are required, pico-sdk only provides the option to provide an entire linker script using
pico_set_linker_script
. This patch adds a functionpico_customize_linker_script
to create a linker script in the build process, based on a template provided by pico-sdk and local settings provided by the user.The tool of choice is the C preprocessor, but I am open to suggestions for an alternative.
Use cases for linker script modification include:
memmap_blocked_ram.ld
which differs in only one line from the default)In such cases, deriving the linker script from a template may/should lead to code that is easier to maintain.
Implementation:
The template is
memmap.ld.in
, the user input is provided by specifying a customization file to be included, and the linker script is generated by the C preprocessor. This of course is just one of many template solutions, but this one only requires a C compiler, which is available by definition.The template exposes a few settings by #defining them before including the customization file, and provides a few hooks to add elements to the template.
Examples and hints for use, based on a working example where cyw43 firmware lives in a separate region in flash:
in CMakeLists.txt:
tweaks.h:
Details:
${TARGET}.ld
\\
at the end of lines, newlines are inserted in the resulting linker script in a postprocessing step. This is done to improve readability of the resulting linker script.#
need to be removed from the output; they are now turned into/*comments*/
#undef
fed before redefining them, which is a bit awkward; another option is to use#ifdef
for each and every variable in the template; yet another option (for integers) is to use linker variables (i.e. simply settingMAIN_FLASH_LENGTH=256k
).TODO:
This was only tested on OS X with makefile builds, so broader testing is probably needed (although this new feature doesn't change/break anything existing).
As mentioned above, at least
memmap_blocked_ram.ld
(andmemmap_default.ld
) could easily be derived at runtime from the template. Maybe the other linker scripts can also derive from the template with the right tweaks.