uboot移植(六)——uboot启动第二阶段(init_sequence)

简介:
1
2
3
4
5
     for  (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
         if  ((*init_fnc_ptr)() != 0) {
             hang ();
         }
     }

通过前面的定义init_fnc_t **init_fnc_ptr;可以知道init_fnc_ptr是一个二重指针,而init_sequence是一个函数指针数组里面存放的都是函数的函数名,这些函数都是板级初始化函数,*init_fnc_ptr解引用得到的就是一个函数指针,这个for循环的作用就是去遍历这个函数指针数组,而遍历的目的就是去执行这个函数指针数组里面的函数,从而对开发板的部分外设进行初始化。当遍历到最后一个元素NULL的时候跳出这个for循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
init_fnc_t *init_sequence[] = {
     cpu_init,         /* basic cpu dependent setup */
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
     reloc_init,         /* Set the relocation done flag, must
                    do this AFTER cpu_init(), but as soon
                    as possible */
#endif
     board_init,         /* basic board dependent setup */
     interrupt_init,         /* set up exceptions */
     env_init,         /* initialize environment */
     init_baudrate,         /* initialze baudrate settings */
     serial_init,         /* serial communications setup */
     console_init_f,         /* stage 1 init of console */
     display_banner,         /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
     print_cpuinfo,         /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
     checkboard,         /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
     init_func_i2c,
#endif
     dram_init,         /* configure available RAM banks */
     display_dram_config,
     NULL,
};

(1)cpu_init:cpu内部初始化,实际这个函数是个空函数

(2)board_init:初始化网卡和DDR

(3)interrupt_init:初始化定时器4(用来计时比如bootdelay),这里设置的10ms计时一次

(4)env_init:环境变量设置

(5)init_baudrate:初始化波特率

(6)serial_init:串口初始化(串口在uboot启动的第一阶段已经完成了),这里实际啥也没干

(6)console_init_f控制台初始化的第一阶段(实际上我们没有用到控制台)

(7)display_banner:打印uboot的版本信息

(8)print_cpuinf:初始化时钟

(9)checkboard:打印时钟信息

(10)init_func_i2c:这里没有用到I2C的设备,所以无实际作用

(11)dram_init:gd->bd中关于DDR配置部分全局变量的赋值(大小 起始地址 等)

(12)display_dram_config:打印DDR的配置信息

(13)NULL:用于跳出for循环。


以上是uboot在第二阶段做的主要事情

env_relocate (); 

环境变量的重定位,将SD卡中的环境变量读取到DDR中

需要注意的是SD卡中一开始是没有环境变量的,uboot第一次启动时环境变量是使用uboot中的配置头文件(如x210sd.h)中硬编码的一套默认的环境变量,当我启动uboot后使用saveen命令才会把环境变量写到SD卡的raw分区。以后使用的也是SD卡中的这一份环境变量。


uboot启动第二阶段的最后是进入一个死循环,输入命令  解析命令

1
2
3
for  (;;) {  
         main_loop ();
     }

main_loop函数执行一次代表了一次命令的输入 解析  和执行。内核启动阶段也是从这个函数开始的。




本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1834542

相关文章
|
4月前
|
安全 数据安全/隐私保护 Android开发
AVB源码学习(二):Uboot阶段AVB2.0校验流程
AVB源码学习(二):Uboot阶段AVB2.0校验流程
127 0
|
4月前
|
安全 Android开发
AVB源码学习(三):AVB2.0 Init阶段安全启动流程
AVB源码学习(三):AVB2.0 Init阶段安全启动流程
117 0
|
编译器
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
889 0
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
|
Linux
linux网络驱动初始化module_init函数跟踪
module_init函数对做驱动开发的同学是在太熟悉了,但是关于底层的知识可能大家有些不愿去了解,而其中知识对于网络初始化也直接相关,所以先将此分享。 在驱动程序中有module_init函数,该函数定义在文件 include/linux/module.h中(以前好像在include/linux/init.h中),如下。
2294 0