目录
[二,TLBs和BP array和DSB和ISB](#二,TLBs和BP array和DSB和ISB)
[2.BP array](#2.BP array)
[3.DSB & ISB](#3.DSB & ISB)
[三,GENERATED_GBL_DATA_SIZE 和 GD_SIZE的区别](#三,GENERATED_GBL_DATA_SIZE 和 GD_SIZE的区别)
一,SCTLR寄存器和VBAR寄存器
SCTLR的bit13 为 V 位,此位是向量表控制位,当为 0 的时候向量表基地址
为 0X00000000 ,软件可以重定位向量表。为 1 的时候向量表基地址为 0XFFFF0000 ,软件不能
重定位向量表。
VBAR 寄存器用于设置向量表重定位的,受SCTLR的bit13 为 V 位影响。
二,TLBs和BP array和DSB和ISB
1.TLB
TLB 的基本作用
缓存地址转换:当 CPU 访问内存时,MMU(内存管理单元)需要将虚拟地址转换为物理地址。这个转换过程通常需要查表(页表),而 TLB 就是这些页表项的硬件缓存。
加速访问:如果转换信息在 TLB 中(TLB hit,命中),CPU 可以直接获得物理地址,速度极快。如果不在(TLB miss,未命中),CPU 必须从内存中的页表重新加载,速度较慢。
为什么需要 "invalidate"(使无效)?
虽然 U-Boot 通常运行在物理地址空间(或平坦映射),但在许多现代 ARM、RISC-V、PowerPC 等架构的处理器中,U-Boot 也会启用 MMU 和缓存(Cache)以提高执行速度(例如从 NAND 或网络加载内核时)。TLB 会缓存这些地址映射关系。当发生以下情况时,TLB 中的缓存条目会变得过时(Stale)或不一致。
2.BP array
什么是 BP array?
全称:BP array 指的是 Branch Predictor storage array,即存储分支预测信息的硬件结构。
功能:在现代高性能处理器(如 ARM Cortex-A 系列)的流水线设计中,BP(Branch Predictor,分支预测器)用于猜测指令流向。当 CPU 遇到条件分支指令(如循环、if-else)时,它会在结果出来前猜测哪条路径更可能被执行,并提前加载后续指令,从而避免流水线停顿,提高执行效率。
invalidate(使无效)的作用是什么?
执行 mcr p15, 0, r0, c7, c5, 6 这条指令,就是告诉分支预测单元:"之前记录的所有预测模式和历史状态全部作废,清空缓存。"
这意味着 CPU 不能再依赖过去的执行历史来做预测,必须重新观察当前代码的执行模式并建立新的预测表。
为什么 U-Boot 在启动初期必须这样做?
结合搜索结果和 ARM 架构的启动惯例,这主要是为了确保启动的绝对可靠性和一致性。
3.DSB & ISB
DSB(数据同步屏障)和 ISB(指令同步屏障)都是ARM架构中用于控制指令和内存访问顺序的屏障指令,但它们的作用范围和严格程度不同。简单来说:
DSB:确保之前的所有内存访问(读/写)和系统维护操作(如TLB、Cache维护)彻底完成后,才执行后续的任何指令(无论是指令访问还是数据访问)。它主要作用于内存系统。
ISB:清空(冲刷)CPU的流水线,确保所有在它之后的指令都重新从内存或缓存中预取和译码。它主要作用于指令执行流本身。
三,GENERATED_GBL_DATA_SIZE 和 GD_SIZE的区别
GENERATED_GBL_DATA_SIZE:是给汇编语言看的,用于在编译时精确计算内存布局。
GD_SIZE:是给C语言看的,用于在运行时获取结构体大小,以便进行内存操作。
为什么U-Boot需要两个看起来很像的东西?这源于一个技术限制:汇编语言无法直接使用C语言的 sizeof 运算符。
GENERATED_GBL_DATA_SIZE 的由来:在早期的U-Boot中,开发者需要在板级配置文件中手动定义一个宏(如 CONFIG_SYS_GBL_DATA_SIZE)来告诉汇编代码 global_data 结构体有多大。但这种方法容易出错,且当结构体更新时,很难保证各处手动定义的宏能同步更新。为了解决这个问题,U-Boot引入了一个智能工具(asm-offsets),它在编译时会自动计算 struct global_data 的实际大小,并生成 GENERATED_GBL_DATA_SIZE 这个宏,供汇编代码使用。这相当于在编译器和汇编器之间架起了一座自动化的桥梁。
这正是 GENERATED_GBL_DATA_SIZE 的典型应用------在C环境尚未完全准备好时,精确地分配内存。而在C代码中,开发者则可以直接使用 GD_SIZE(或直接写 sizeof(struct global_data)),它更直观、更符合C语言的编程习惯。
总结一下,GENERATED_GBL_DATA_SIZE 是专门为解决汇编代码无法使用 sizeof 的难题而生的自动化方案,而 GD_SIZE 则是C语言环境下的常规操作。 理解这两个宏的区别,能帮你更清晰地看懂U-Boot如何巧妙地衔接汇编启动阶段和C语言运行阶段。