A linker script is a configuration file written in the linker's command language that directs the linker on precisely how to combine multiple object files and libraries into a single executable or binary image. It explicitly defines the target hardware's memory layout, specifying the addresses and sizes of memory regions (like SRAM, DRAM, or NPU-local memory) and dictating where each section of code and data (.text, .data, .bss) must be placed. This control is essential for embedded systems and hardware accelerators where memory is constrained and specific addresses are mapped to physical hardware registers or fast on-chip memory.
Glossary
Linker Script

What is a Linker Script?
A linker script is a critical configuration file used in the final stage of compiling software for specialized hardware like NPUs.
For NPU acceleration, a linker script ensures that performance-critical kernels and weight tensors are placed in optimal memory regions to minimize latency and maximize bandwidth. It manages symbol resolution, assigning final addresses to functions and variables, and handles relocation adjustments. By defining entry points and stack/heap locations, it creates a runnable binary tailored to the exact memory map of the target System-on-Chip (SoC). This low-level control is a foundational step in vendor SDK workflows for generating efficient, deployable binaries for specialized accelerators.
Key Components of a Linker Script
A linker script is a configuration file that provides the linker with a precise blueprint for constructing the final executable or binary image from compiled object files and libraries. It is critical for NPU programming to define the exact memory layout, section placement, and symbol addresses required by the target accelerator hardware.
Memory Layout Definition
The core directive of a linker script is to define the memory map of the target system. This specifies the available memory regions, their start addresses, lengths, and access permissions (e.g., read, write, execute). For NPUs, this often involves mapping code to tightly coupled instruction memory (TCM) and data to high-bandwidth on-chip SRAM.
- MEMORY Command: Declares physical memory blocks (e.g.,
FLASH,SRAM,NPU_IMEM). - Example:
MEMORY { NPU_CMEM (rwx) : ORIGIN = 0x80000000, LENGTH = 256K }
Section Placement Directives
The SECTIONS command controls how input sections from object files (.text, .data, .bss, .rodata) are mapped into output sections and placed within the defined memory regions. This is essential for ensuring NPU kernels and their associated weights are located in optimal memory for performance.
- Output Sections: Define where specific types of code/data go (e.g.,
.npu.text). - Input Section Patterns: Use wildcards like
*(.text.vendor_kernel*)to collect specific functions. - Location Counter (.): The special variable that tracks the current output address.
Symbol Assignment and Resolution
Linker scripts can create, define, and assign values to symbols, which are addresses or absolute values accessible to the program. This is used to expose the start and end addresses of memory regions or sections to the runtime or bootloader.
- Assignment Operator (=):
_npustack_top = ORIGIN(NPU_CMEM) + LENGTH(NPU_CMEM); - PROVIDE: Ensures a symbol is only created if not already defined elsewhere, preventing conflicts.
- Symbols as Entry Points: The
ENTRY(symbol)command specifies the first instruction to execute.
Alignment and Region Constraints
NPU memory subsystems often have strict alignment requirements for data types and DMA transfers. Linker scripts enforce these using alignment directives and region fill/overflow checks.
- ALIGN(expression): Forces the location counter to the next specified boundary (e.g.,
ALIGN(128)for cache lines). - SUBALIGN: Controls alignment of input sections within an output section.
- FILL: Specifies a fill pattern for unused areas within a section.
- >region: The placement operator ensures a section is placed within a specific memory region.
KEEP and Garbage Collection
To prevent the linker's garbage collection (--gc-sections) from removing critical but unreferenced code—such as NPU kernel functions or interrupt vectors that are called via hardware, not software—the KEEP command is used.
- Syntax:
KEEP(*(.npu.vectors))ensures the interrupt vector table is preserved. - Application: Essential for vendor runtime initialization code and hardware-specific sections that are not explicitly called from the main application but are required for the NPU to function.
Overlays and Advanced Constructs
For complex systems, linker scripts support advanced constructs like overlays (where the same memory region is used for different code sections at different times) and conditional expressions. They can also include other script files and use built-in functions for calculations.
- OVERLAY: Manages memory overlays for systems with constrained RAM.
- INCLUDE: Incorporates another linker script file.
- Built-in Functions: Use
SIZEOF,ADDR,LOADADDRto query section properties programmatically within the script.
How Linker Scripts Work in NPU Acceleration
A linker script is a critical configuration file in the compilation toolchain that directs the final stages of binary creation for Neural Processing Unit (NPU) targets.
A linker script is a configuration file written in the linker's command language that explicitly directs the linker on how to combine sections from input object files and libraries into the final executable or binary image. For NPU acceleration, it precisely defines the memory map, specifying absolute addresses for code (.text), data (.data, .bss), and other sections within the NPU's distinct memory hierarchies (e.g., tightly coupled memory, global DRAM). This control is essential because NPUs often have non-uniform, specialized memory architectures where placement directly impacts performance and correctness.
The script manages symbol resolution and relocation, binding symbolic references to final addresses. It can also define symbols for the runtime to query, such as the start and end of a scratchpad memory region. By dictating section ordering and alignment, linker scripts enable hardware-aware optimizations, such as placing critical kernels or weight buffers in faster, lower-latency memory banks. This level of control is a foundational step in vendor SDK workflows for generating binaries that fully leverage the NPU's physical architecture, moving beyond generic compilation to hardware-specific deployment.
Common Use Cases for Linker Scripts
Linker scripts are essential for controlling the low-level layout of software, especially when targeting specialized hardware like NPUs. These cards detail their primary applications in embedded and accelerator programming.
Memory Map Definition for NPU Firmware
The core function of a linker script is to define the precise memory layout of the final executable. For NPU firmware, this involves:
- Mapping sections like
.text(code),.data(initialized variables), and.bss(uninitialized data) to specific address ranges in the NPU's internal SRAM or tightly coupled memory. - Placing vendor runtime libraries and hardware intrinsic implementations in performance-critical memory banks.
- Reserving memory-mapped I/O regions for registers that control the accelerator, ensuring code does not accidentally overwrite them.
- Example: Directing all vector computation kernels (
.text.vec) into a low-latency scratchpad memory for maximum throughput.
Section Placement for Hardware Intrinsics
Linker scripts enforce the correct placement of code that uses vendor-specific intrinsics or inline assembly.
- Vendor SDKs often provide pre-compiled object files containing optimized routines. The linker script must ensure these are placed in memory regions that align with the NPU's instruction cache architecture.
- It can group all functions using a particular tensor core ISA extension into a contiguous
.section.npu.tensorto improve cache locality. - This prevents the linker from scattering low-level hardware-accessing code throughout the binary, which could degrade performance or violate alignment constraints.
Managing Multiple Memory Banks
Modern NPUs feature heterogeneous memory hierarchies (e.g., global DDR, shared L2 cache, local SRAM). Linker scripts manage data placement across these banks.
- Performance-critical data (e.g., weights for the active layer) can be assigned to fast SRAM using a
>sramdirective in the section definition. - Less-frequently accessed data (e.g., model metadata) can be placed in slower, but larger, external DRAM (
>ddr). - This manual partitioning is crucial for meeting real-time latency requirements in edge AI deployments, as it minimizes costly data movement between memory levels.
Creating Custom Sections for Profiling
Developers use linker scripts to create custom ELF sections for instrumentation and performance profiling.
- A section like
.probe_datacan be defined to hold counters for kernel execution cycles. The script places it in a memory region accessible to both the NPU and a host CPU for analysis. - Auto-tuning frameworks may generate multiple kernel variants. The linker script can place each variant (
.kernel.variant1,.kernel.variant2) in separate address ranges, allowing the runtime to benchmark and select the fastest. - This enables evaluation-driven development by providing a structured way to embed telemetry directly into the binary layout.
Handling Static vs. Dynamic Linking
Linker scripts control how static libraries (.a files) and dynamic libraries (.so files) from a vendor SDK are incorporated.
- For static linking, the script pulls required object files from the vendor's
libnpu.aarchive and places them in the NPU's memory map. Unused functions are discarded to save space. - For dynamic linking on systems with an OS, the script can define the
INTERPsegment to point to a vendor runtime dynamic loader and set theDYNAMICsegment for symbol resolution. - This is key for deployment optimization, allowing a single driver binary to support multiple NPU generations through runtime library selection.
Defining Entry Points and Boot Sequences
In bare-metal or RTOS environments for NPUs, the linker script defines the system's entry point and bootstrapping code layout.
- It sets the initial Program Counter (PC) address by assigning the vector table or
_startsymbol to a specific ROM address. - It organizes the boot sequence: ROM code copies
.datafrom flash to RAM and zeroes out.bssbefore jumping to main. - For firmware updates, it can define a bootloader section in protected memory and an application section in upgradable memory, managing the symbols and jump tables between them. This supports secure over-the-air updates in embedded AI systems.
Frequently Asked Questions
A linker script is a critical configuration file that directs the final stages of software compilation for hardware accelerators like NPUs. It defines the memory map, section placement, and symbol resolution for the executable binary.
A linker script is a configuration file written in the linker's command language that provides explicit instructions to the linker (e.g., ld) on how to combine multiple object files and libraries into a single executable or shared library. It works by defining the memory layout of the target system, specifying where different sections of code and data (like .text, .data, .bss) should be placed in memory, and resolving symbolic references between object files. For NPU programming, it is essential for mapping kernels and tensor buffers to specific accelerator memory regions (e.g., NPU SRAM, global DDR).
Key directives include:
MEMORY: Declares the memory regions (address, size, attributes) of the target hardware.SECTIONS: Defines the output sections and rules for placing input sections from object files into them.- Symbol assignments (e.g.,
_stack_top = .;) to define critical addresses.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
A linker script operates within a broader ecosystem of low-level compilation and deployment tools. These related concepts define the interfaces, formats, and processes that interact with the linker to produce a final executable for hardware acceleration.
Application Binary Interface (ABI)
A low-level interface specification that defines the contract between separately compiled modules and the operating system. For NPU programming, the ABI dictates:
- Calling conventions for functions that pass data to accelerator kernels.
- Register usage and stack management rules.
- Data structure layout and alignment in memory. The linker uses the ABI rules to correctly resolve cross-module references and ensure binary compatibility between vendor libraries and user code.
ELF Sections
Contiguous segments within an Executable and Linkable Format (ELF) binary file that contain specific types of data. A linker script's primary job is to map input sections from object files to output sections in the final executable. Key sections for NPU workloads include:
.text: Contains executable machine code, including compiled kernels..data&.bss: Hold initialized and zero-initialized global/static variables..rodata: Stores read-only data like constants.- Vendor-specific sections (e.g.,
.weight,.instruction_buffer) for accelerator-specific data. The script controls the order, placement, and attributes (read, write, execute) of these sections in memory.
Relocation
The process performed by the linker of adjusting absolute addresses in object code to reflect the final memory locations where code and data are loaded. When compiling for an NPU with a specific memory map:
- The compiler generates code using temporary placeholder addresses.
- The linker script defines the final base addresses for memory regions (e.g.,
SRAM = 0x80000000). - The linker performs relocation, patching all references to symbols and sections with their final, absolute addresses based on the script's layout. This is critical for ensuring pointers and function calls in NPU kernels target the correct locations in tightly constrained on-chip memory.
Vendor Toolchain
A suite of vendor-specific software tools used to build applications for a particular hardware platform, like an NPU. The linker script is a key configuration file consumed by the linker within this toolchain. The full suite typically includes:
- Compiler (often a cross-compiler) that generates object files.
- Assembler for low-level code.
- Linker (
ld) that combines objects using the linker script. - Binary utilities (
objcopy,objdump) for manipulating the final executable. - Debugger for the target architecture. The linker script must be compatible with the vendor's linker, which may support proprietary section types or commands for accelerator memory hierarchies.
Cross-Compiler
A compiler that runs on one computer architecture (the host, e.g., x86) but generates executable code for a different architecture (the target, e.g., an NPU). The linker script is target-specific. Key interactions:
- The cross-compiler produces object files in the target's object format (e.g., ELF for the NPU).
- The accompanying cross-linker is invoked, which reads the target-specific linker script to understand the NPU's memory map (addressable SRAM, registers, etc.).
- The final linked binary is in a format (e.g., a raw binary blob or a specialized ELF) that can be loaded by the NPU's runtime or bootloader. This separation allows development on standard PCs while targeting specialized accelerator hardware.
Symbol Table
A data structure within object and executable files that stores metadata about symbols—the named identifiers for functions, global variables, and sections. The linker uses symbol tables to:
- Resolve references: When one object file calls an external function
kernel_launch(), the linker searches other objects' symbol tables to find its definition. - Define memory addresses: The linker script can assign addresses to symbols (e.g.,
_stack_top = . + 0x1000;). The final symbol table in the executable reflects these resolved, absolute addresses. - Provide debugging info: Symbol tables enable debuggers to map machine code addresses back to source code names, which is also crucial for profiling NPU kernel performance.

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us