为什么 lw t0, (a0) 能直接从 Flash 读

在 RISC-V 这种典型的嵌入式系统里,“flash 能不能像内存一样 lw 读取?”这是一个很多人刚开始都会迷糊的问题。其实答案非常简单:

可以,前提是 flash 被 CPU 通过总线映射到地址空间(Memory-Mapped I/O)中。

下面给你掰开揉碎讲清楚——实话实说,硬件上就是这么干的。


⭐ 为什么 lw t0, (a0) 能直接从 Flash 读?

因为在 MCU / SoC 里:

Flash 不是通过 SPI 或外设读出来的(那要命慢)。

Flash 是直接挂在系统总线上,被“映射(mapped)到某个固定地址区间”。

换句话说:

Flash 就像 ROM 一样,CPU 把其中内容当成内存一样读即可。


⭐ Memory-Mapped 的本质

比如系统里的地址空间可能是这样分布的(随便举例):

地址范围设备
0x0000_0000 – 0x0003_FFFFFlash(ROM)
0x2000_0000 – 0x2000_FFFFSRAM
0x4000_0000 – …外设寄存器

启动代码里 _data_lma 通常指向 flash 里的 .data 段实际位置:

_data_lma = 0x00008000   # 位于 Flash
_data_vma = 0x20000000   # data 在 RAM 里的最终位置

CPU 执行:

lw t0, (a0)

a0 = 0x00008000 时,实际上是在从 flash 的某个物理地址读取。

Flash 控制器会在背后完成访问时序,比如:

  • address latch

  • read cycle

  • wait state(flash 慢所以要等)

  • 返回数据

对 CPU 来说就是一个普通的 load 指令。


⭐ 为什么能这样设计?

因为这样有几个硬优点:

🟦 1. 启动速度快

CPU reset 后 PC=flash 的入口地址,直接执行,不需要“先从 Flash 读一段代码再搬到 RAM 再执行”。

🟦 2. 访问简单

软件不需要管理 flash 控制器复杂的读时序。

🟦 3. 芯片内置 flash 本来就和 CPU 紧耦合

绝大多数 MCU(STM32、GD32、Nuclei、Kendryte、ESP32)内部都是:

CPU —— AHB —— Flash 控制器 —— Embedded Flash array

CPU load/store 就能读。


⭐ 你在写的 startup code 是 “XIP 模式”

XIP = eXecute In Place
意思是:在 flash 里直接执行指令,不需要 preload 到 RAM

  • 指令直接从 flash 读

  • 数据段要搬到 RAM 用(你代码里就是在复制 .data)

  • .bss 清零


⭐ 一个生活中的比喻

很像一本存放在书架(flash)上的字典:

  • 查字(load):你直接翻书查,不需要把整本书搬到桌子上

  • 写字(store):你不能直接写(flash 不能随便写)

  • 你要做笔记(data 段):你会把必要内容抄到草稿纸(RAM)

代码里做的正是:

  • 从“书架”(flash)把 data 抄到“草稿纸”(RAM)

  • 然后程序运行全用 RAM 中的可写数据


⭐ 再回答你的核心一句话

为什么 lw 能直接操作 flash?

因为 flash(只读存储器)通过总线映射在 CPU 地址空间里,CPU load 指令自动走 flash 控制器读取数据。


如果你要,我还能给你画一张 RISC-V SoC 内部 bus + Flash 映射结构图,让你一眼就看懂整个访问流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值