cortex-m-rt: Linking with custom linkerfile
IsaacDynamo opened this issue · 5 comments
What is the recommended way to link with a custom linkerfile? This is not mentioned in Advanced usage.
Copying the link.x from target/thumbv7m-none-eabi/debug/build/cortex-m-rt-.../out and dropping it in the root of the crate seem to work, but I don't really get why. Does the linker have some search path order or is there some build.rs magic going on in the background?
The file link.x is loaded because the .cargo/config file adds -Tlink.x as a linker argument.
The linker will look in pwd as part of its search path. It's better to get build.rs to
copy the linker script to $OUT_DIR, and then tell cargo to put $OUT_DIR in the linker search path. That way your crate will still build if you happen to start in a different directory (e.g. you are using a cargo workspace).
OK I think I understand.
In the normal case the user adds something like "-C", "link-arg=-Tlink.x" to the rust flags.
And the cortex-m-rt crate uses its build.rs to generate a link.x from a template, places it in its $OUT_DIR and adds the $OUT_DIR to the search path with cargo:rustc-link-search.
The linker will search the -L paths in order until it finds a link.x.
When a link.x is placed into the root of the project, the linker will try and find -Tlink.x as a relative path, before looking in any of the -L paths. Therefor it will prefer the script in the root.
But instead of relying on this, one should use a build.rs script similar to cortex-m-rt to place the linkerscript in $OUT_DIR.
Do you known of any projects that use custom linkerfiles that I can reference as an example?
https://github.com/rp-rs/flash-algo uses a custom linker script.
The flash-algo project doesn't depend on cortex-m-rt, and the used build.rs and link.x can therefore be pretty straight forward.
Some background: I'm playing around with the Cortex MPU, but it requires more control over the memory layout. So I need a custom linkerfile, but I still want to use the init code provided by cortex-m-rt if possible.
I get the feeling that the best way to use a custom linker file and also use the rt, is to copy build.rs and link.x.in from cortex-m-rt, and modify the copied link.x.in till desired. Or perhaps even fork the project if more control is needed.
Do you have any alternative suggestions for this use-case?
If you want to use the cortex-m-rt start-up code, you'll need a linker script that exports the symbols that the start-up code requires - they're all documented in the linker script. If you want to copy the cortex-m-rt one and add stuff, you can do that. Or can add sections to your local memory.x like how the RP2040 HAL needs to insert a special boot code block before the standard Arm vector table.