系统篇: uboot 启动流程

bootloader是系统上电后最初加载运行的代码。它提供了处理器上电复位后最开始需要执行的初始化代码。在PC机上引导程序一般由BIOS开始执行,然后读取硬盘中位于MBR(Main Boot Record,主引导记录)中的Bootloader(例如LILO或GRUB),并进一步引导操作系统的启动。然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动就完全由bootloader来完成。它主要的功能是加载与引导内核映像 。

一、u-boot的作用

初始化CPU,初始化内存、串口、时钟等硬件资源,加载内核、引导内核,为操作系统的运行提供环境准备

在这里插入图片描述

二、u-boot的启动流程

1、第一阶段依赖于cpu体系结构的代码,从存储介质中读取小部分程序到cpu中,这部分程序要完成引导linux所用的硬件的初始化以及加载uboot其余程序到RAM中

  • 初始化CPU(中断向量表、时钟、内存等资源)
  • 禁止IRQ和FIQ
  • 拷贝u-boot第二阶段的代码到内存
  • 为第二阶段C程序的运行建立堆栈空间
  • 跳转到第二阶段的入口处执行

2、继续初始化必备硬件,加载linux镜像到RAM中,把执行权限交给linux

  • 本阶段所需的硬件资源的初始化,为引导linux kernel做准备
  • 将内核镜像从flash读取到内存中
  • 微内核设置启动参数
  • 引导内核
三、源码分析

目录结构:

  • board中存放于开发板相关的配置文件,每一个开发板都以子文件夹的形式出现。
  • commom文件夹实现u-boot行下支持的命令,每一个命令对应一个文件。
  • cpu中存放特定cpu架构相关的目录,每一款cpu架构都对应了一个子目录。
  • Drivers中是u-boot支持的各种设备的驱动程序。
  • Include文件夹是u-boot使用的头文件,还有各种硬件平台支持的汇编文件,系统配置文件和文件系统支持的文件。

启动流程代码分析:

.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		//切换CPU模式为SVC模式,关闭中断,以便访问更多硬件资源
	 */
	mrs	r0, cpsr
	bic	r0, r0, #0x1f
	orr	r0, r0, #0xd3
	msr	cpsr,r0

	/*
	 * disable MMU stuff and caches		//关闭MMU与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, r0, #0x00000800	@ set bit 11 (Z---) BTB
	mcr	p15, 0, r0, c1, c0, 0


after_ziju:
	/* init PLL/DDRC/pin mux/... */			//初始化时钟、内存、IO
	ldr	r0, _blank_zone_start
	ldr	r1, _TEXT_BASE
	sub	r0, r0, r1
	cmp 	r3, r2
	beq	pcie_slave_addr
	ldr	r1, =RAM_START_ADRS
	ldr	sp, =STACK_TRAINING
	b	ziju_ddr_init
pcie_slave_addr:
	ldr	r1, =0x0
	ldr	sp, =PCIE_SLV_STACK
	ldr	r4, =SYS_CTRL_REG_BASE
	str	r2, [r4, #HI3531D_SYSBOOT10]
ziju_ddr_init:
	add	r0, r0, r1
	mov	r1, #0x0		/* flags: 0->normal 1->pm */
	bl	init_registers		/* init PLL/DDRC/... */


copy_loop:				@ copy 32 bytes at a time					//循环拷贝u-boot到内存
	ldmia	r0!, {
   r3 - r10}		@ copy from source address [r0]
	stmia	r1!, {
   r3 - r10}		@ copy to target address [r1]
	cmp	r0, r2			@ until source end addreee [r2]
	ble	copy_loop

/* Set up the stack */		//设置堆栈
stack_setup:
	ldr	r0, _TEXT_BASE		@ upper 128 KiB: relocated uboot
	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
#ifdef CONFIG_USE_IRQ
	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
#endif
	sub	sp, r0, #12		@ leave 3 words for abort-stack
	and	sp, sp, #~7		@ 8 byte alinged for (ldr/str)d

	ldr	pc, _start_armboot	@ jump to C code		//跳转到start_armboot函数执行
_start_armboot: .word start_armboot
void start_armboot (void)
/* Pointer is writable since we allocated a register for it */
	gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t))
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值