Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 194 of 9363. Microcontroller Fundamentals and Bare-Metal CFree lesson

Automating Vector Table Placement with Linker Scripts

Students will define specific memory sections in a linker script to ensure the vector table resides at the exact address expected by hardware.

In this lesson, you will learn how to use linker scripts to guarantee that your microcontroller’s vector table is anchored at the specific hardware-expected memory address.

Why Placement Matters

When a microcontroller powers up or triggers an interrupt, the hardware doesn't look for a function named main(). Instead, it looks at a fixed memory address (usually at the very beginning of Flash) to find the Vector Table. This table is a list of memory addresses pointing to your Reset Handler and various interrupt service routines. If your code isn't placed exactly where the hardware expects, the processor will fetch garbage data, causing a hard fault or a system freeze.

Using the Linker Script to Anchor the Table

To ensure the table stays at the start of your memory map, we define a specific input section in our linker script. We use a custom section name (often called .isr_vector) to group these entries together.

In your linker script, you define the output location like this:

SECTIONS
{
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Keep the vector table even if unused */
        . = ALIGN(4);
    } > FLASH
}

How It Works

  1. The Section Name: By wrapping the vector table entries in an attribute (e.g., __attribute__((section(".isr_vector")))) in your C code, the linker knows to collect those specific symbols into this named segment.
  2. The KEEP Command: The linker is usually "smart" and likes to remove unused code to save space. Since the hardware accesses the vector table directly—not through a function call—the linker might mistakenly think it's unused. The KEEP keyword tells the linker: "Do not optimize this away, no matter what."
  3. Alignment: We use ALIGN(4) because ARM Cortex-M processors require the vector table to be aligned to 256 bytes or 4-byte boundaries, depending on the architecture. This guarantees the hardware’s internal pointers always land on valid instruction addresses.

By offloading this task to the linker script, you eliminate the risk of manually placing code or guessing addresses, letting the build system ensure your application boots reliably every time.

Key Takeaway: Using the linker script to force the .isr_vector section to the start of Flash ensures the hardware can always find your interrupt pointers upon startup.