参考:
嵌入式Linux移植和Uboot
http://nano.lichee.pro/get_started/first_eye.html
Boot loader与Uboot
BIOS,Bootloader和U-boot的区别
嵌入式linux开发uboot启动过程源码分析
写的很好 嵌入式linux之Uboot和系统移植–基础
1、启动引导程序——bootloader:
boot程序:引导程序。
在设计单片机的程序时,不论是否嵌入了嵌入式操作系统还是裸机运行程序,在MCU硬件部分都已经固化好了启动引导程序。有时候为了用户升级程序,还会设计用户级别的启动引导程序。
启动引导程序是在正式的程序运行之前运行的程序,在一般的系统中主要用来加载程序和初始化硬件的。在单片机中Bootloader是基于特定硬件平台来实现的,它会初始化硬件设备,可以将程序的起始指针跳转到该执行代码的区域。
对于Bootloader可总结以下四点:
- Bootloader是硬件启动时执行的引导程序,是运行操作系统的前提;
- Bootloader是在操作系统内核或用户应用程序运行之前运行的一段代码;
- 在嵌入式系统中,整个系统的初始化和加载任务一般由Bootloader来完成;
- 对硬件进行相应的初始化和设定,最终为操作系统准备好环境。
2、Uboot和bootloader
uboot属于bootloader的一种。其他的bootloader还有:
bootloader | 描述 | |
---|
armboot | 支持arm平台,支持多种网络协议 | | blob | 适用Linux | | Redboot | 完善的嵌入式系统bootloader。支持Y-modem协议 | |
3、Uboot都做了什么
在uboot的源码内,程序会最先从一个start.s汇编文件启动。
与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段。BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现;BL2阶段主要是对外部设备如网卡、Flash等的初始化以及uboot命令集等的自身实现,通常用C语言来实现。
整个程序最先启动的start.s文件首先确定了:
可知start.S的流程为:异常向量——上电复位后进入复位异常向量——跳到启动代码处——设置处理器进入管理模式——关闭看门狗——关闭中断——设置时钟分频——关闭MMU和CACHE——进入lowlever_init.S——检查当前代码所处的位置,如果在FLASH中就将代码搬移到RAM中
1、BL1阶段
uboot的BL1阶段代码通常放在start.s文件中,用汇编语言实现,其主要代码功能如下:
(1) 指定uboot的入口。在链接脚本uboot.lds中指定uboot的入口为start.S中的_start。
(2)设置异常向量(exception vector)
(3)关闭IRQ、FIQ,设置SVC模式
(4)关闭L1 cache、设置L2 cache、关闭MMU
(5)根据OM引脚确定启动方式
(6)在SoC内部SRAM中设置栈
(7)lowlevel_init(主要初始化系统时钟、SDRAM初始化、串口初始化等)
(8)设置开发板供电锁存
(9)设置SDRAM中的栈
(10)将uboot从SD卡拷贝到SDRAM中
(11)设置并开启MMU
(12)通过对SDRAM整体使用规划,在SDRAM中合适的地方设置栈
(13)清除bss段,远跳转到start_armboot执行,BL1阶段执行完
*2、*BL2阶段
start_armboot函数位于lib_arm/board.c中,是C语言开始的函数,也是BL2阶段代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,BL2阶段的主要功能如下:
(1)规划uboot的内存使用
(2)遍历调用函数指针数组init_sequence中的初始化函数
(3)初始化uboot的堆管理器mem_malloc_init
(4)初始化SMDKV210开发板的SD/MMC控制器mmc_initialize
(5)环境变量重定位env_relocate
(6)将环境变量中网卡地址赋值给全局变量的开发板变量
(7)开发板硬件设备的初始化devices_init
(8)跳转表jumptable_init
(9)控制台初始化console_init_r
(10)网卡芯片初始化eth_initialize
(11)uboot进入主循环main_loop
总结:一切都是为了启动内核
|