物理基址定义
_TEXT_PHY_BASE:
.word CFG_PHY_UBOOT_BASE
start.s
中使用 _TEXT_PHY_BASE
存放物理基址。这个变量很重要,因为我们在 u-boot 中使用 MMU ,在 MMU 没有开启之前,需要这个变量来保证程序能在正确的地址运行
通过在 u-boot 源码中全局搜索可以发现, CFG_PHY_UBOOT_BASE
定义在 uboot/include/configs/x210_sd.h
中
#define MEMORY_BASE_ADDRESS 0x30000000
...
#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x3e00000
CFG_PHY_UBOOT_BASE
这个宏是在 MEMORY_BASE_ADDRESS
的位置上偏移了 0x3e00000 的空间
链接脚本需要的变量
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
_bss_start
_bss_end
这两个变量之前也在链接脚本中见过
BSS 段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域
BSS 段使用前需要清0,通过在这里提供 BSS 段的地址,方便链接时清0
复位
reset:
/*
* set the cpu to SVC32 mode and IRQ & FIQ disable
*/
@;mrs r0,cpsr
@;bic r0,r0,#0x1f
@;orr r0,r0,#0xd3
@;msr cpsr,r0
msr cpsr_c, #0xd3 @ I & F disable, Mode: 0x13 - SVC
到这里就是 u-boot 真正的复位代码了
MSR 指令用亍将操作数的内容传送到程序状态寄存器的特定域中
cpsr 是 ARM 架构的当前程序状态寄存器,而 cpsr_c 是程序状态寄存器的后8位,也就是控制位
cpsr 寄存器的描述如下
I 和 F 位对应的是 IRQ 和 FIQ 中断的标志位,置1为关闭
因为模式位是前5位控制的,所以 0xd3 相当于 0x13,对应的就是 SVC(管理)模式
再加上代码中的注释,我们就可以知道这段代码的作用就是让处理器进入 SVC 模式并关闭中断
cpu_init_crit
这里是为了初始化一些重要的寄存器和内存的时钟
cpu_init_crit 只会在重启的时候运行,当 u-boot 在 ram 中的时候不会运行
这部分做了这些事
- 重新初始化开启 L2 cache
- 刷新 L1 的数据和指令 cache
- 关闭 MMU
- 读取启动介质选择
## 读取启动信息
ldr r0, =PRO_ID_BASE @ PRO_ID_BASE=E000 0000
ldr r1, [r0,#OMR_OFFSET] @ OMR_OFFSET=0000 0004
bic r2, r1, #0xffffffc1
这段代码目的是从 E000 0004 这个寄存器读取电平信息,这个寄存器是 OM 引脚的地址。通过设置 OM 引脚的电平,就可以设置 u-boot 的启动介质
bic 的作用是为了清除无关的位,方便后面进行启动介质的判断
/* NAND BOOT */
cmp r2, #0x0 @ 512B 4-cycle
moveq r3, #BOOT_NAND
...
/* SD/MMC BOOT */
cmp r2, #0xc
moveq r3, #BOOT_MMCSD
/* NOR BOOT */
cmp r2, #0x14
moveq r3, #BOOT_NOR
通过判断前面存入 r2 的值,得到不同的启动介质的信息
lowlevel_init
ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */
sub sp, sp, #12 /* set stack */
mov fp, #0
bl lowlevel_init /* go setup pll,mux,memory */
从图中可以看出 0xd0036000 是 sram 的地址空间,此时 ddr 还没有初始化完成,只能使用不需要初始化的 sram
通过 sub 创建了一个 stack,再让 fp(栈帧指针)指向 stack 的开头(fp 用作栈的开头,sp 作为栈的当前位置,fp 和 sp 一起组成了一个栈帧)
设置 stack 是为了用来存储 LR 的值,因为当前是被调用的子函数中, LR 中存储着当前子函数的范围地址,如果直接使用 bl 调用子函数,就会丢失当前子函数的返回地址
所以在子函数中调用子函数时,需要先将当前的 LR 压栈
后记
关于 SP FP PC LR 寄存器有空会说说的,我也是在学习汇编才接触到这些寄存器,也是在看了些资料才稍微了解了些