1 写在开头
最近基于全志平台修修补补了其uboot代码,借此篇文章梳理下uboot的流程,方便日后温故。全文基于全志平台Uboot源码进行讲解。想要学习Uboot的同学不用担心是什么平台,正所谓大同小异、融会贯通、举一反三、知行合一、形神兼备、万佛。。。。。。
2 全志uboot特点
机器上电之后会执行固化在soc内部ROM里的引导程序,这个程序会遍历所有支持的启动介质,直到找到第一个支持的。目前 支持的启动介质是sd/mmc卡、nand和spinor。当程序初始化启动介质成功后,就从固定位置读入Bootloader的Boot0到SRAM,然后跳 到SRAM执行。全志的UBOOT分为两部分boot0和boot2,问题来了,为什么要分为两个部分?
答:因为在Bootloader阶段,使用的SRAM大小只有32KB,除去C运行环境需要的栈空间,可用的空间在24KB左右,这点不足以载入整个Uboot。所以需要将Uboot分成两个部分,将简易而必须的任务放在Boot0执行,将繁重的任务放在Boot1执行。Boot0主要负责初始化DRAM,将Boot1加载到DRAM中,并跳转到DRAM中执行Uboot1流程;Boot1自然就是我们熟悉的Uboot流程,负责初始化外设,引导加载内核等。
下面我们将用两个章节分别来介绍Boot0和Boot1,重点是在第四章的Boot1讲解
3 Boot0流程
3.1 入口函数_start
_start: b reset
reset:
mrs r0, cpsr
bic r0, r0, #ARMV7_MODE_MASK
orr r0, r0, #ARMV7_SVC_MODE
orr r0, r0, #( ARMV7_IRQ_MASK | ARMV7_FIQ_MASK ) @// After reset,ARM automaticly disables IRQ and FIQ, and runs in SVC mode.
bic r0, r0, #(1<<9) @// set little-endian
msr cpsr_c, r0
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
mcr p15, 0, r0, c1, c0, 0
ldr sp, =CONFIG_BOOT0_STACK_BOTTOM
bl clear_bss
bl cpu_init_s
bl main
clear_bss:
ldr r0, =__bss_start
ldr r1, =__bss_end
mov r2, #0 /* clear */
clbss_1:
stmia r0!, {r2}
cmp r0, r1
blt clbss_1
mov pc, lr
#ifdef CONFIG_SUNXI_MULITCORE_BOOT
.globl secendory_cpu_init
secendory_cpu_init:
mrs r0, cpsr
bic r0, r0, #ARMV7_MODE_MASK
orr r0, r0, #ARMV7_SVC_MODE
orr r0, r0, #( ARMV7_IRQ_MASK | ARMV7_FIQ_MASK ) @// After reset, ARM automaticly disables IRQ and FIQ, and runs in SVC mode.
bic r0, r0, #(1<<9) @// set little-endian
msr cpsr_c, r0
mrc p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARCH_SUN8IW10P1
orr r0, r0, #0x00002000 @ set bits 13 (--V-)
#else
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
#endif
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
mcr p15, 0, r0, c1, c0, 0
ldr sp, =CONFIG_BOOT0_CPU1_STACK_BOTTOM
bl secendory_main
#endif
第1行:跳转到reset函数执行
第3-8行:通过配置cpsr寄存器,将cpu配置为SVC模式,关闭中断,设置为小端模式
第9-14行:配置CP15的C1寄存器;bit13清0代表向量表基地址为0x00000000,目的是接下来软件可以重定位向量表;bit2清0;bit11置1;bit12清0;
第16行:将PC寄存器指向0xB3F0
第17行:跳转到clear_bss执行,作用是清零bss段
第18行:跳转到cpu_init_s执行,空函数,未做任何事情
第19行:跳转到main执行,下面重点介绍main