学习目标

  • 理解链接脚本的作用
  • 掌握链接脚本语法
  • 学会编写自定义链接脚本

3.1 什么是链接脚本

链接脚本(Linker Script)告诉链接器:

  • 各段放在哪里
  • 程序入口在哪里
  • 内存如何布局

3.2 基本语法

OUTPUT_ARCH(riscv)      /* 目标架构 */
ENTRY(_start)           /* 入口符号 */

MEMORY {
    RAM : ORIGIN = 0x80000000, LENGTH = 128M
}

SECTIONS {
    .text : {
        *(.text*)
    } > RAM
}

3.3 完整示例

OUTPUT_ARCH(riscv)
ENTRY(_start)

MEMORY {
    RAM : ORIGIN = 0x80000000, LENGTH = 128M
}

SECTIONS {
    . = 0x80000000;

    .text : {
        *(.text.init)   /* 启动代码 */
        *(.text*)       /* 其他代码 */
    } > RAM

    .rodata : {
        *(.rodata*)     /* 只读数据 */
    } > RAM

    .data : {
        *(.data*)       /* 已初始化数据 */
    } > RAM

    .bss : {
        _bss_start = .;
        *(.bss*)        /* 未初始化数据 */
        _bss_end = .;
    } > RAM

    . = ALIGN(16);
    _stack_top = . + 0x10000;  /* 64KB 栈 */
}

3.4 关键概念

位置计数器 .

当前地址,可以赋值和读取。

段合并

*(.text*) 表示所有 .text 开头的段。

符号定义

_bss_start = .;

定义符号供程序使用。

下一步

Bootloader 原理

更新时间: