底层移植之RBL, UBL, Uboot的关系
首先RBL=ROM Bootloader,UBL=user Bootloader。 RBL为TI固化在芯片ROM中的bootloader,OMAP上电启动过后首先将运行RBL,然后通过RBL加载UBL,再通过UBL加载uboot,而uboot就是用来加载Linux内核的。如果在具体应用过程中不需要使用到Linux(实际上一般都会用到的),uboot甚至是UBL都可以省去。
首先RBL = ROM Bootloader,UBL= user Bootloader UBOOT = Universal Boot Loader。
RBL为TI固化在芯片ROM中的bootloader,OMAP上电启动过后首先将运行RBL,然后通过RBL加载UBL,再通过UBL加载uboot,而uboot就是用来加载Linux内核的。如果在具体应用过程中不需要使用到Linux(实际上一般都会用到的),uboot甚至是UBL都可以省去。
UBL为一级Bootloader,uboot为二级Bootloader,一级Bootloader的大小是有限制的(应该是64KB以下,没查到具体数值),这也是为什么会有二级Bootloader的原因。如果一个应用程序小于这个大小,那么我们可以不需要烧写UBL,而只用烧写该应用程序相应的bin文件(下面第3点将阐述如何得到这个文件)就行了。
UBL的程序设计,相对UBOOT、KERNEL、ROOTFS、设备驱动、DSP开发来说,还是比较简单。我们先从DAVINCI的启动说起,了解UBL在DAVIN系统中的位置和作用。对于固件程序烧写在NAND FLASH 的Davinci dm644x嵌入式系统,上电启动的过程如下:
1. RBL阶段:
系统复位后,保存在片内ROM的RBL程序开始运行,RBL程序根据BTSEL[0-3]管脚的电平来判断相应的启动方式。[00]表明是NAND启动方式,RBL程序便从外接nand flash中读取UBL的数据到内部RAM中(UBL最大可达14K),然后转至UBL代码运行;[01]表明是EMIFA启动方式,RBL则直接转至EMIFA EM_CS2 memory space(0x02000000)处开始运行,EMIFA的数据和地址总线宽度分别由EM_WIDTH和AEAW[4:0]引脚决定;[10]表明是HPI启动方式,RBL通过HPI传输代码获得UBL,然后转至UBL代码处运行;[11]表明是UART启动方式,RBL通过UART0传输代码获得UBL,然后转至UBL代码处运行。第一、三、四种方式都是RBL将UBL下载到ARM RAM0和ARM RAM1(0x0-0x3fff,共16K)中,然后转至UBL运行。DSP的是自引导还是由ARM引导由DSP_BT引脚电平决定,如果为高则自引导,如果为低则由ARM引导。
2. UBL阶段,也就是u-boot阶段:
ti官方提供的是u-boot,所以这里阐述的是u-boot的启动过程。在u-boot中最初阶段主要完成系统时钟、DDR频率的初始化,准备好加载C程序运行的环境,这时候程序运行在ARM RAM中或nor flash中,由启动方式决定。然后拷贝u-boot代码到DDR中,并跳转到C程序的start_armboot处运行(在DDR2中)。
u-boot的具体设置过程如下:
(1)U-boot代码中首先设置最基本的系统硬件环境,包括系统PLL及DDR2的初始化、PSC的配置及使能UART0、AEMIF等硬件模块;
(2)配置系统的内存(通过ATAG_ MEM块和mem=)NAND Flash和DDR2;
(3)在flash中或通过tftp加载内核到指定的存储地址;
(4)初始化传递到内核的引导参数(EMAC地址,串口,控制台,视频格式等)
(5)获得ARM Linux机类型值(DVEVM为#901);
(6)设置kernel tagged list;
(7)用初始值设置ARM的寄存器;
(8)调用linux内核;
针对DM644X的设置有:
(1)关中断和MMU。
(2)使能DSP电源域(PTCMD),把DSP置为复位状态。
(3)初始化PLL,使能DDR2,软复位DDR2并且重新使能DDR2,使其脱离复位状态。
(4)初始化系统PLL。
(5)配置AEMIF引脚为NOR Flash接口。
(6)VTP校准。
3. Linux内核启动阶段:
(1)内核中的boot/compressed/
head.s代码开始运行,保存从u-boot中传入的参数,然后会执行一段处理器相关的代码,中间再做些判断和处理,最后
对压缩的内核进行解压。
(2)内核中的kernel/
head.s代码开始运行,初始化页表,cache和MMU等。
(3)start_kernel()运行,根据从U-boot中得到参数及其他初始化设置(在board-evm.c中),进行一系列的内核初始化,比如io地址映射、定时器和串口初始化、内存页表重新映射等。
(4)Linux的第一个进程init()运行,该进程根据系统中的配置初始化系统。根据从U-boot中得到参数,从flash中或nfs中启动文件系统;
(5)shell启动。
更多推荐
所有评论(0)