Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Linker Script

Did you try to build the project again? Yup, it no longer compiles. So, what happened?

The problem is: the linker does not know how to lay out your program in memory. Embedded systems like the ESP32 don't have an operating system to handle memory, so we must tell the linker exactly where code, data, and stack should go.

To fix this, we provide a linker script. This is a simple text file that tells the linker things like:

  • Where to place code in memory

  • Where the stack starts

  • How big each memory region is

The linker script we will use is called linkall.x. This script is provided by the esp-hal. It contains memory layout settings suitable for ESP32.

Cargo config

We can update the ".cargo/config.toml" file with the following lines to fix the issue. However, we will not use this approach. Instead, we will use the build.rs file.

[target.xtensa-esp32-none-elf]
rustflags = ["-C", "link-arg=-Tlinkall.x"]

⚠️ Don't add the linker argument in both .cargo/config.toml and build.rs. It will cause a conflict and result in a build error. Use only one method.

Build.rs file

The esp-generate tool adds this line to the build.rs file. It also does a few more things along with it, which we are not covering here. To match that structure, we will also add the linker argument using a build.rs file.

Now create a new file named build.rs in the root of your project directory (not inside the src/ folder), and add the following code:

fn main() {
    // make sure linkall.x is the last linker script (otherwise might cause problems with flip-link)
    println!("cargo:rustc-link-arg=-Tlinkall.x");
}

With this, you should now be able to compile your project:

cargo build