学习目标

  • 编写 Bootloader
  • 实现数据搬运
  • 跳转到 SRAM

5.1 链接脚本

OUTPUT_ARCH(riscv)
ENTRY(_start)

MEMORY {
    FLASH : ORIGIN = 0x80000000, LENGTH = 1M
    SRAM  : ORIGIN = 0x80100000, LENGTH = 128K
}

SECTIONS {
    /* Bootloader 在 Flash */
    .bootloader : {
        *(.text.boot)
    } > FLASH

    /* 应用程序镜像在 Flash */
    .text_flash : {
        _text_flash_start = .;
        *(.text*)
        _text_flash_end = .;
    } > FLASH

    /* 应用程序运行在 SRAM */
    .text : AT(_text_flash_start) {
        _text_start = .;
        *(.text*)
        _text_end = .;
    } > SRAM

    .data : AT(_text_flash_end) {
        _data_start = .;
        *(.data*)
        _data_end = .;
    } > SRAM

    .bss : {
        _bss_start = .;
        *(.bss*)
        _bss_end = .;
    } > SRAM

    . = ALIGN(16);
    _stack_top = . + 0x10000;
}

5.2 Bootloader 代码

.section .text.boot
.global _start

_start:
    # 拷贝 .text 段
    la t0, _text_flash_start
    la t1, _text_start
    la t2, _text_end
copy_text:
    beq t1, t2, copy_data
    lw t3, 0(t0)
    sw t3, 0(t1)
    addi t0, t0, 4
    addi t1, t1, 4
    j copy_text

copy_data:
    # 拷贝 .data 段
    la t0, _text_flash_end
    la t1, _data_start
    la t2, _data_end
copy_data_loop:
    beq t1, t2, clear_bss
    lw t3, 0(t0)
    sw t3, 0(t1)
    addi t0, t0, 4
    addi t1, t1, 4
    j copy_data_loop

clear_bss:
    # 清零 .bss
    la t0, _bss_start
    la t1, _bss_end
clear_bss_loop:
    beq t0, t1, jump_to_app
    sw zero, 0(t0)
    addi t0, t0, 4
    j clear_bss_loop

jump_to_app:
    # 设置栈指针
    la sp, _stack_top
    # 跳转到应用程序
    la t0, main
    jr t0

下一步

UART 串口协议

更新时间: