uboot移植(四)——uboot启动第一阶段

1:BL0 BL1 BL2分别是什么

(1)BL0:s5pv210的iROM中固化的代码

作用:初始化系统时钟,设置看门狗,初始化栈,加载BL1

(2)BL1:从外部启动介质(nand/SD卡)中加载的uboot.bin的前16K代码

作用:初始化RAM,关闭Cache,初始化DDR,设置栈,加载BL2

(3)BL2:是指在代码完成重定位后在DDR中运行的完整的uboot代码

作用:初始化其他外设,加载OS内核

三者的关系:开机上电自动运行BL0的代码,然后加载BL1到SDRAM中,接着通过重定位将BL2加载到DDR中,最终uboot启动完成,加载内核到DDR中

2:uboot的启动过程

下图是三星公司推荐210的启动过程

三星推荐的启动过程也是开机上电自动加载BL1,然后运行BL2,引导有、内核的启动,需要注意的三星推荐的启动过程中BL1和BL2都是放在SDRAM(96K)中的,但是随着uboot的发展uboot的大小已经超过了96K,所以BL2不能再放在SDRAM中,而是通过BL1重定位到DDR中

3:uboot启动时第一阶段做了哪些事情

uboot启动的入口函数是start.S,所以根据start.S这个文件中的代码去分析uboot启动的第一阶段。

(1)通过#include加载相应的头文件

(2)通过汇编伪指令.word定义4个4字节的变量,作用是为后面的计算校验和填充占位,确保image的头部有16字节的头信息,如果没有,则uboot会打印出 SD  checksun Error

(3)构建异常向量表,但是由于uboot的启动时间很短,异常发生的较少,所以并没有很细致地处理各种异常,当异常发生时重启即可

(4)通过操作CPSR程序状态寄存器设置SoC为SVC模式

(5)通过读取0xE0000004寄存器的值来判断启动介质,0xE0000004寄存器的值会根据OM0-OM5这6 个引脚的电平高低自动设置,通过读取这个寄存器的值就可以得到uboot从哪里启动

(6)设置栈,此时运行的代码是BL1,是在SDRAM中运行的,还有一点需要注意的是ARM都是满减栈,也就是入栈时是向下延伸的

(7)调用lowlevel_init函数,这个函数里面主要是 检查复位状态(热启动 冷启动 睡眠唤醒),复位后IO口的保存和恢复,关看门狗,开发板供电锁存,初始化时钟,初始化DDR,并在返回start.S之前打印字符‘OK‘,需要注意的是,lowlevel_init函数中有一段代码用来判断当前运行位置是在DDR还是SDRAM,其原理是通过比较运行地址和链接地址是否相同,而且它判断的是运行地址和链接地址的第12位开始的12位是否相同

ldr    r0, =0xff000fff

bic    r1, pc, r0        /* r0 <- current base addr of code */

ldr    r2, _TEXT_BASE        /* r1 <- original base addr in ram */

bic    r2, r2, r0        /* r0 <- current base addr of code */

cmp     r1, r2                  /* compare r0, r1

beq     1f            /* r0 == r1 then skip sdram init   */

bic    r1, pc, r0 的意思就是把pc中和r0对应的1改为0,0改为1,并存入寄存器r1中,也就是将r0取反在和pc相与  r1 = pc & (~(r0)) 如果相等则说明当前运行在DDR中,那么就不需要进行时钟和DDR的初始化,如果不相等则说明当前运行在SDRAM中,就需要进行时钟和DDR的初始化。

打印出来的字符‘OK‘,是一种调试信息,如果启动ubooot看到Ok 则说明是调用lowlevel_init后面的错误,如果没有看到OK则说明是在调用这个函数之前。在进行移植的时候也可以使用类似的方法在函数调用之间通过打印相应的字符来判断错误发的位置。

(8)再次设置开发板供电锁存,没实际意义

(9)在DDR中设置栈,原因是在lowlevel_init函数中已经对DDR进行了初始化,这时候的DDR是可用的

(10)再次判断当前运行位置是在SDRAM还是DDR,其方法还是一样,其目的是为了判断是否需要进行重定位

(11)虚拟地址映射

(12)第三次设置栈,这次设置栈的为了充分合理地使用内存(安全,紧凑不浪费内存)

(13)清bss段

(14)uboot第一阶段的最后一句: ldr  pc, _start_armboot指针指向_start_armboot这个函数,也就是uboot启动的第二阶段的入口函数。

时间: 2024-08-03 03:11:16

uboot移植(四)——uboot启动第一阶段的相关文章

U-Boot之启动第一阶段

基于samsung的Exynos 4412 从链接脚本u-boot.lds中我们知道u-boot是从start.s这个汇编文件开始的,所以u-boot启动的第一阶段肯定也是从这里开始的,这个文件在cpu/arm_cortexa9/文件夹下,下面我们依照这个文件一步一步分析u-boot启动的第一阶段. #include <config.h> #include <version.h> #if defined(CONFIG_ENABLE_MMU) #include <asm/pro

uboot启动第一阶段--start.S

uboot分为两个阶段:start.S是uboot的第一阶段. 一:引入start.S u-boot.s找到start.S的入口 ①首先在C语言中整个项目的入口就是main函数(这是C语言规定的),所以如果要去了解C语言的项目,从main函数开始,这样才能分析,如果随便拿一个文件就开始看,最后看得一头雾水,对自己没有信心.怎么来找呢?可以使用souceinsight的搜索功能来查找. ②在uboot中因为有汇编阶段参与,因此不能直接找main.c.整个程序的入口取决于连接脚本中ENTRY声明的地

u-boot启动第一阶段

目标板:2440开发板 u-boot启动的第一阶段是在文件start.S中完成的,这个过程对不同硬件平台的设置是不同的.下面进入start.S _start: b reset //跳转到reset //设置CPU为SVC32安全管理模式 reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 //关闭看门狗 #if defined(CONFIG_S3C2400

OK6410 uboot移植之sd启动

1  uboot移植 1.1移植准备工作 1.1.1安装交叉编译工具链 版本:arm-linux-gcc 4.4.1 环境:ubuntu14.04.01LTS 1.1.2建立OK6410配置项 从官网下载u-boot-2012.10.tar.bz2,由于uboot支持的smdk6400单板与我们的板子OK6410最相似,所以修改是基于smdk6400进行的,初步修改uboot建立OK6410配置项. 详细修改过程如下: 进入u-boot-2012.10顶层目录,在board/Samsung目录下

uboot移植一uboot架构分析

开发环境: 1 .开发板mini2440 2. u-boot-2010.12 参考i资料:https://blog.csdn.net/androidbbc/article/details/50961163 http://www.cnblogs.com/kele-dad/p/8969174.html 一.下载u-boot- 2010.12,并且解压 二.分析u-boor-2010.12 api: 存放uboot提供的接口函数 config.mk: 根据不同开发板定制的代码,代码也不少 driver

uboot移植之uboot命令体系解析

1:回归到main_loop uboot启动第二阶段的最后,进入死循环main_loop()函数,命令行中没输出一次命令,就会执行一次main_loop函数,完成一次命令的获取.解析和执行. 2:uboot命令体系的实现原理 uboot中里面维护了很多命令,每个命令对应一个结构体变量,当我们在命令行输入一个命令时.这时就涉及如何去维护这些命令的问题,一般的方法有两种,数组或者链表,但是数组的缺陷在开始的时候需要确定数组的大小,链表的话效率比较低,所以uboot使用了另一种方式.uboot中一个命

uboot移植之uboot中的SD卡驱动解析

1:地址对硬件操作的影响 (1)操作系统(指的是linux)下MMU肯定是开启的,也就是说linux驱动中肯定都使用的是虚拟地址.而纯裸机程序中根本不会开MMU,全部使用的是物理地址.这是裸机下和驱动中操控硬件的一个重要区别. (2)uboot早期也是纯物理地址工作的,但是现在的uboot开启了MMU做了虚拟地址映射,这个东西驱动也必须考虑.查uboot中的虚拟地址映射表,发现210开发板里面,除了0x30000000-0x3FFFFFFF映射到了0xC0000000-0xCFFFFFFF之外,

uboot移植(五)——uboot启动的第二阶段(gd和bd)

之前uboot启动第一阶段的最后将指针指向了start_armboot这个函数,这里也 是uboot启动的第二阶段的开始并且uboot启动第二阶段大部分是在这个函数中完成 的. DECLARE_GLOBAL_DATA_PTR;这个宏在大部分中的文件中都有这个宏,这个宏的 实际定义是在include/asm-arm/Global_data.h #define DECLARE_GLOBAL_DATA_PTR   register volatile gd_t *gd asm ("r8") 这

U-BOOT 移植到友善之臂mini2440

U-BOOT 移植到友善之臂mini2440 开发环境:ubuntu 10.10 编译器:友善之臂mini2440光盘自带arm-linux-gcc 4.4.3 一. 在denx官网下载源码,我所用版本号为u-boot-2010.03. 二. 主机编译环境为友善之臂提供的arm-linux-gcc.所參考板子为smdk2410. 三. 启动第一阶段移植过程 1.首先測试编译环境,由于arm-linux-gcc,已经添?了PATH环境变量,在lib_arm文件夹下的config.mk 定义了CRP