Linux驱动开发:uboot启动流程详解_uboot是怎么启动的

本文深入解析Linux驱动开发中的uboot启动流程,包括reset、cpsr和cp15设置、cpu初始化以及板级初始化阶段,阐述了各步骤的作用和原因,如关闭FIQ和IRQ、设置SVC模式、关闭MMU和Cache等,以确保uboot的稳定运行。
摘要由CSDN通过智能技术生成

2.2 reset

reset 函数存在于 arch/arm/cpu/armv7/start.s 文件中,而 reset 函数跳转到 save_boot_params 函数,save_boot_params 函数又跳转到 save_boot_params_ret中,具体如下:

//第一段:reset跳转到save_boot_params	
    .globl	reset
	.globl	save_boot_params_ret

reset:
	/* Allow the board to save important registers */
	b	save_boot_params
save_boot_params_ret:
	/*
	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
	 * except if in HYP mode already
	 */
	mrs	r0, cpsr
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
	msr	cpsr,r0

//第二段:save_boot_params跳转到save_boot_params_ret
    ENTRY(save_boot_params)
	    b	save_boot_params_ret		@ back to my caller
    ENDPROC(save_boot_params)
	    .weak	save_boot_params

2.3 cpsr和cp15 STCLR

reset 函数跳转到 save_boot_params_ret函数后,具体如下:

save_boot_params_ret:
	/*
	 * 关闭 FIQ 和 IRQ 中断,设置 CPU 处于 SVC 特权模式
	 * except if in HYP mode already(除非已经处于HYP特权模式,比SVC低一点的特权)
	 */
	mrs	r0, cpsr
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
	msr	cpsr,r0

    /*
     *★SCTLR寄存器bit13清零(bit13控制中断向量表地址,0:可以重定位;1:默认为0xFFFF0000)将_start 
     *的数值写入该寄存器,也就是中断向量表的起始地址为0x87800000
     */
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
	bic	r0, #CR_V		@ V = 0
	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTLR Register

	/* Set vector address in CP15 VBAR register */
	ldr	r0, =_start
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
#endif

	/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_cp15
	bl	cpu_init_crit
#endif

	bl	_main

从上述代码能看出,代码包含5个部分:cpsr,cp15,cpu_init_cp15,cpu_init_crit和**_main**。

2.3.1 cpsr
/*
 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
 * except if in HYP mode already
 */
mrs	r0, cpsr
and	r1, r0, #0x1f		@ mask mode bits
teq	r1, #0x1a		@ test for HYP mode
bicne	r0, r0, #0x1f		@ clear all mode bits
orrne	r0, r0, #0x13		@ set SVC mode
orr	r0, r0, #0xc0		@ disable FIQ and IRQ
msr	cpsr,r0

**cpsr:**给目标寄存器写入对应的数值(可以参考芯片手册),关闭 FIQ 和 IRQ,并且讲CPU设置为 SVC 特权模式。

为什么这样操作的原因:

**(1) 禁止 FIQ 和 IRQ:**uboot 作为芯片上电的第一道程序是至关重要的,而中断是很危险的,它的等级太高了,可以轻松打断程序的正常运行。所以,为了保证uboot的正常运行,需要关闭部分中断。

(2) 设置 SVC:uboot的运行避免不了对各类寄存器等操作,为了保证操作的正常,需要给CPU设置高特权模式。

2.3.2 cp15
/*
 * Setup vector:
 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
 * Continue to use ROM code vector only in OMAP4 spl)
 */
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
	bic	r0, #CR_V		@ V = 0
	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTLR Register

	/* Set vector address in CP15 VBAR register */
	ldr	r0, =_start
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
#endif

**cp15 SCTLR:**SCTLR寄存器bit13清零(bit13控制中断向量表地址,0:可以重定位;1:默认为0xFFFF0000)将_start的数值写入该寄存器,也就是中断向量表的起始地址为0x87800000

2.4 cpu_init_cp15

cpu_init_cp15 存在于 arch/arm/cpu/armv7/start.s 文件中:

/*************************************************************************
 *
 * cpu_init_cp15
 *
 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
 * CONFIG_SYS_ICACHE_OFF is defined.
 *
 *************************************************************************/
ENTRY(cpu_init_cp15)
	/*
	 * Invalidate L1 I/D
	 */
    mov	r0, #0			@ set up for MCR
	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs  /*禁止从TLB中取地址描述符,也就是禁止虚拟地址到物理地址的转换,因为刚开始操作的都是物理寄存器!*/
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache 	/*关闭指令cache*/
	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array	/*关闭分支预测*/
	mcr p15, 0, r0, c7, c10, 4	@ DSB	 /*多核cpu之间进行数据同步*/
	mcr p15, 0, r0, c7, c5, 4	@ ISB /*进行指令同步,放弃流水线中已经取到的指令,重新取指令*/


	/*
	 * disable MMU stuff and caches
	 */
	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, #0x00000002	@ set bit 1 (--A-) Align
	orr	r0, 
  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值