uboot源码分析2-启动第二阶段
一、背景知识
1、uboot第二阶段应该做什么?
- 概括来讲uboot第一阶段主要就是初始化了SoC内部的一些部件(譬如看门狗、时钟),然后初始化DDR并且完成重定位。
- 由宏观分析来讲,uboot的第二阶段就是要初始化剩下的还没被初始化的硬件。主要是SoC外部硬件(譬如iNand、网卡芯片····)、uboot本身的一些东西(uboot的命令、环境变量等····)。然后最终初始化完必要的东西后进入uboot的命令行准备接受命令。
2、uboot中经常出现一种情况就是根据一个宏是否定义了来条件编译决定是否调用一个函数内部的代码。uboot中有2种解决方案来处理这种情况:方案一:在调用函数处使用条件编译,然后函数体实际完全提供代码。方案二:在调用函数处直接调用,然后在函数体处提供2个函数体,一个是有实体的一个是空壳子,用宏定义条件编译来决定实际编译时编译哪个函数进去。
二、函数执行流程
1、定义变量,gd,然后实例化
2、给gd->bd赋值,内存间隔 为了防止高版本的gcc的优化造成错误
3、执行init_sequence函数,都是board级别的各种硬件初始化
- cpu_init():cpu内部的初始化,但在start.S初始化过,所以这里是空的。
- board_init():网卡的GPIO和端口的配置、定义开发板的机器码、定义uboot给linux kernel启动时的传参的内存地址gd->bd->bi_boot_params=0x30000100
注意:board_init中除了网卡的初始化之外,剩下的2行用来初始化DDR。这里的初始化DDR和汇编阶段lowlevel_init中初始化DDR是不同的。当时是硬件的初始化,目的是让DDR可以开始工作。现在是软件结构中一些DDR相关的属性配置、地址设置的初始化,是纯软件层面的。
- interrupt_init():初始化定时器,将timer4设置为定时10ms
- env_init():环境变量有关的初始化
注:这个函数只是对内存里维护的那一份uboot的env做了基本的初始化或者说是判定(判定里面有没有能用的环境变量)。当前因为我们还没进行环境变量从SD卡到DDR中的relocate,因此当前环境变量是不能用的。
- init_baudrate():初始化串口通信的波特率的
- serial_init():初始化串口的,其实什么都没做
- console_init_f():事情都没做
注:f表示是第一阶段初始化,_r表示第二阶段初始化
- display_banner():用来串口输出显示uboot的logo

- print_cpuinfo():输出CPU的一些信息,比如:时钟频率

- checkboard():检查当前开发板是哪个开发板并且打印出开发板的名字。
- dram_init():关于DDR软件的初始化,关于DDR配置部分的全局变量赋值
- display_dram_config():打印显示dram的配置信息

4、NorFlash的初始化,打印的也是NorFlash的配置信息(491-492)[和此开发板无关]
5、初始化uboot的堆管理器,DDR内存中给堆预留了896KB的内存
6、开发板独有初始化:mmc初始化;初始化SoC内部的SD/MMC控制器的

7、环境变量的重定位,完成从SD卡中将环境变量读取到DDR中的任务。
8、IP地址、MAC地址的确定
9、开发板上的硬件设备(818)
10、跳转表,通过函数指针就可以执行具体的函数
11、console的纯软件架构方面的初始化,去给console相关的数据结构中填充相应的值
12、使能CPSR中总中断标志位
13、loadaddr、bootfile这两个环境变量都是内核启动有关的
14、网卡相关的初始化(于X210(DM9000)来说,这个函数是空的)
15、x210开发板在启动起来之前的一些初始化,以及LCD屏幕上的logo显示(887)

16、自动更新的功能
- 我们可以将要升级的镜像放到SD卡的固定目录中,然后开机时在uboot启动的最后阶段检查升级标志(是一个按键。按键中标志为"LEFT"的那个按键,这个按键如果按下则表示update mode,如果启动时未按下则表示boot mode)。如果进入update mode则uboot会自动从SD卡中读取镜像文件然后烧录到iNand中;如果进入boot mode则uboot不执行update,直接启动正常运行。
三、总结
(1)第一阶段为汇编阶段、第二阶段为C阶段
(2)第一阶段在SRAM中、第二阶段在DRAM中
(3)第一阶段注重SoC内部、第二阶段注重SoC外部Board内部
uboot源码分析2-启动第二阶段的更多相关文章
- u-boot 源码分析(1) 启动过程分析
u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...
- u-boot源码分析之C语言段
题外话: 最近一直在学习u-boot的源代码,从代码量到代码风格,都让我认识到什么才是真正的程序.以往我所学到的C语言知识和u-boot的源代码相比,实在不值一提.说到底,机器都是0和1控制的.感觉这 ...
- u-boot源码分析
Uboot源码分析 源码以u-boot-1.3.4为基准,主芯片采用at91sam9260,主要介绍uboot执行流程. uboot官网:http://www.denx.de/wiki/U-Boot/ ...
- v87.01 鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main () | 百篇博客分析 OpenHarmony 源码
本篇关键词:内核重定位.MMU.SVC栈.热启动.内核映射表 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 v75.03 鸿蒙内核源码分析(汇编基础) | ...
- Appium Server 源码分析之启动运行Express http服务器
通过上一个系列Appium Android Bootstrap源码分析我们了解到了appium在安卓目标机器上是如何通过bootstrap这个服务来接收appium从pc端发送过来的命令,并最终使用u ...
- Appium Android Bootstrap源码分析之启动运行
通过前面的两篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>和<Appium Android Bootstrap源码分析之命令解析 ...
- Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7)
http://blog.chinaunix.net/uid-20543672-id-3157283.html Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3 ...
- Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7)【转】
原文地址:Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://bl ...
- Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】
原文地址:Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.c ...
随机推荐
- 操作系统OS - 重装Windows7卡在completing installation
1. shift + f10 2. cd oobe 3. Msoobe
- 关于定时执行任务:Crontab的20个例子
关于定时执行任务:Crontab的20个例子 LeeLom 关注 2016.09.28 19:53* 字数 713 阅读 9186评论 6喜欢 15 简介 Linux crontab和Windows ...
- Mysql 分组查询出现'this is incompatible with sql_mode=only_full_group_by'的解决办法
由于Mysql自动开启了 only_full_group_by,所以若查询的字段不在group by里面,则分组报错. 解决办法其一:mysql配置,关闭only_full_group_by,这种办法 ...
- @implementer,抽象类,接口
@implementer,抽象类,接口 1. implementer 在看twisted源码时,经常出现@implementer(IReactorFDSet) 它来自zope.interfa ...
- Solr搜索引擎服务器学习笔记
Solr简介 采用Java5开发,基于Lucene的全文搜索服务器.同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置.可扩展并对查询性能进行了优化,并且提供了一个完善的功能 ...
- Lucene学习笔记一
Lucene课件 1.全文检索 1.1常见的全文检索 在window系统中,可以指定磁盘中的某一个位置来搜索你想要得到的东西.这个功能是windows比较常用的功能.在这个界面中能搜索的内容有*.*, ...
- GO 面向对象-方法
package main import ( "fmt" ) /* 定义结构体 */ type Circle struct { radius float64 } func main( ...
- 2019 深信服 下棋(DFS+回溯)
链接:https://www.nowcoder.com/questionTerminal/a0feb0696e2043a5b3b0779fa861b64a?f=discussion来源:牛客网 8x8 ...
- Windows驱动开发-DPC定时器
DCP是一种使用更加灵活的定时器,可以对任意间隔时间进行定时.DPC定时器的内部使用了一个定时器对象KTIMER,当你设定了定时器之后,从设定开始起经过这个时间之后操作系统会将一个DPC定时器的例程插 ...
- LeetCode 725. Split Linked List in Parts(分隔链表)
题意:将原链表分隔成k个链表,要求所有分隔的链表长度差异至多为1,且前面的链表长度必须大于等于后面的链表长度. 分析: (1)首先计算链表总长len (2)根据len得到分隔的链表长度要么为size, ...