嵌入式Linux -- uboot启动之第一阶段分析总结

​ 在uboot启动阶段开始之前,先理清uboot整体启动过程原理,uboot大小假定为200KB。启动过程首先是开机上电后,板载的BL0开始运行,BL0会判断外部接入的启动设备(Flash)的类型并加载外部启动设备中的uboot的前16KB(BL1)到SRAM中去运行,BL1运行时会初始化DDR,初始化时钟等等一系列操作,最后把整个uboot读取到DDR中,然后用一句长跳转(从SRAM跳转到DDR)指令从SRAM中直接跳转到DDR中继续执行uboot直到uboot完全启动,uboot启动后在uboot命令行中去启动OS,结束uboot运行。

starts.S解析

1.1、u-boot.lds中的开始入口_start

​ uboot的链接脚本中开始几行代码先选择了输出字体,CPU架构类型,然后用ENTRY(_ start)进入start.S中开始运行。

2.1、包含头文件
#include <config.h>
#include <version.h>
#if defined(CONFIG_ENABLE_MMU)
#include <asm/proc/domain.h>
#endif
#include <regs.h>

#ifndef CONFIG_ENABLE_MMU
#ifndef CFG_PHY_UBOOT_BASE
#define CFG_PHY_UBOOT_BASE	CFG_UBOOT_BASE
#endif
#endif

​ 分别包含了uboot/include文件夹中config.h、version.h、asm/proc/domain.h、regs.h,下面的条件没有满足,所以不进行下面的宏定义。

​ 对于include文件夹下的config.h,它是配置过程中产生的文件(详情看此文章第六部分第七节:https://blog.csdn.net/jn_statham/article/details/106440133),内容是一个宏定义,我使用的配置生成的宏定义的内容为#include <configs/x210_sd.h> 。

​ 对于include文件夹下的version.h,里面的内容为

#ifndef __VERSION_H__
#define __VERSION_H__

#ifndef DO_DEPS_ONLY
#include "version_autogenerated.h"
#endif

#endif

​ 包含了version_autogenerated.h,而此头文件是配置编译时自动生成的uboot版本信息,对应原理在uboot的主Makefile中开始部分。

​ 对于include文件夹下asm/proc/domain.h,实际asm和proc是在mkconfig中条件编译生成的两个指向相应文件夹的链接文件,本次使用的配置实际文件地址为uboot/include/asm-arm/proc-armv/domain.h,用来配置相应的域。

​ 对于include文件夹下的regs.h,此文件夹是在mkconfig中条件编译生成的一个链接文件,我们配置的这个链接文件指向的是&6.h,也就是include文件夹下的s5pc110.h,对应的是一堆寄存器的宏定义。

3.1、启动代码的16字节头部

​ 本开发板启动时需要16字节的校验头,在start.S中使用下方代码进行填充

#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
	.word 0x2000
	.word 0x0
	.word 0x0
	.word 0x0
#endif
4.1、构建异常向量表
.globl _start
_start: b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq

_undefined_instruction:
	.word undefined_instruction
_software_interrupt:
	.word software_interrupt
_prefetch_abort:
	.word prefetch_abort
_data_abort:
	.word data_abort
_not_used:
	.word not_used
_irq:
	.word irq
_fiq:
	.word fiq
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

​ 首先跳转到reset将IRQ和FIQ关掉,设置SVC栈,然后进行异常向量表的搭建。下面创建了一个字符对齐的内容,填充deadbeef进行十六字节对齐

_end_vect:
	.balignl 16,0xdeadbeef
5.1、TEXT_BASE、CFG_PHY_UBOOT_BASE
_TEXT_BASE:
	.word	TEXT_BASE

​ 这是Makefile中配置时设置的一个数,我们使用的配置是sd_x210_config,也就是在这个配置中设置的,对应的TEXT_BASE = 0xc3e00000。

_TEXT_PHY_BASE:
	.word	CFG_PHY_UBOOT_BASE

​ 这是uboot在DDR中的物理地址,它的值对应为CFG_PHY_UBOOT_BASE = 33e00000

6.1、对CPU进行相应初始化1
cpu_init_crit:

#ifndef CONFIG_EVT1
#if 0	
	bl	v7_flush_dcache_all
#else
	bl	disable_l2cache

	mov	r0, #0x0	@ 
	mov	r1, #0x0	@ i	
	mov	r3, #0x0
	mov	r4, #0x0
lp1:
	mov	r2, #0x0	@ j
lp2:	
	mov	r3, r1, LSL #29		@ r3 = r1(i) <<29
	mov	r4, r2, LSL #6		@ r4 = r2(j) <<6
	orr	r4, r4, #0x2		@ r3 = (i<<29)|(j<<6)|(1<<1)
	orr	r3, r3, r4
	mov	r0, r3			@ r0 = r3
	bl	CoInvalidateDCacheIndex
	add	r2, #0x1		@ r2(j)++
	cmp	r2, #1024		@ r2 < 1024
	bne	lp2			@ jump to lp2
	add	r1, #0x1		@ r1(i)++
	cmp	r1, #8			@ r1(i) < 8
	bne	lp1			@ jump to lp1

	bl	set_l2cache_auxctrl
	bl	enable_l2cache
#endif
#endif
	
	bl	disable_l2cache
	bl	set_l2cache_auxctrl_cycle
	bl	enable_l2cache

​ 因为我们定义了CONFIG_EVT1的值,所以这个条件不成立,执行后面的代码bl disable_l2cache、
bl set_l2cache_auxctrl_cycle和bl enable_l2cache,下面对disable_l2cache、set_l2cache_auxctrl_cycle以及enable_l2cache进行相应解析。

6.1.1、解析disable_l2cache

​ 它在start.S中,内容如下

.global disable_l2cache
disable_l2cache:
	mrc     p15, 0, r0, c1, c0, 1
	bic     r0, r0, #(1<<1)
	mcr     p15, 0, r0, c1, c0, 1
	mov	pc, lr

​ 对应操作协处理器CP15中的C1寄存器,用来禁止L2 cache。

6.1.2、解析set_l2cache_auxctrl_cycle

​ 它在start.S中,内容如下

       .align  5
.global set_l2cache_auxctrl_cycle
set_l2cache_auxctrl_cycle:
	mrc 	p15, 1, r0, c9, c0, 2
	bic 	r0, r0, #(0x1<<29)
	bic 	r0, r0, #(0x1<<21)
	bic 	r0, r0, #(0x7<<6)
	bic 	r0, r0, #(0x7<<0)
	mcr 	p15, 1, r0, c9, c0, 2
	mov     pc,lr

​ 在协处理器CP15的C9寄存器中进行操作,用来完成L2 cache的初始化。

6.1.3、解析enable_l2cache

​ 它在start.S中,内容如下

       .align  5
.global enable_l2cache
enable_l2cache:
	mrc     p15, 0, r0, c1, c0, 1
	orr     r0, r0, #(1<<1)
	mcr     p15, 0, r0, c1, c0, 1
	mov     pc, lr

​ 在协处理器CP15的C1寄存器中进行操作,用来使能L2 cache。

6.2、对CPU进行相应初始化2
6.2.1、对L1 cache进行操作
mov	r0, #0                  @ set up for MCR
        mcr	p15, 0, r0, c8, c7, 0   @ invalidate TLBs
        mcr	p15, 0, r0, c7, c5, 0   @ invalidate icache

​ 操作CP15协处理器使TLBs和icache无效。

6.2.2、关闭MMU
       /*
        * disable MMU stuff and caches
        */
        mrc	p15, 0, r0, c1, c0, 0
        bic	r0, r0, #0x00002000     @ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值