uboot启动流程-涉及board_init_f 函数

news2024/11/26 2:39:13

一.   uboot启动流程


_main 函数中会调用 board_init_f 函数,本文简单分析一下 board_init_f 函数。

二.   board_init_f 函数

board_init_f 函数主要有两个工作:

(1)   初始化一系列外设,比如串口、定时器,或者打印一些消息等。
(2)   初始化 gd 的各个成员变量,uboot 会将自己重定位到 DRAM 最后面的地址区域,也就
是将自己拷贝到 DRAM 最后面的内存区域中。
这么做的目的是给 Linux 腾出空间,防止 Linux kernel 覆盖掉 uboot ,将 DRAM 前面的区域完整的空出来。
在拷贝之前肯定要给 uboot 各部分 分配好内存位置和大小,比如 gd 应该存放到哪个位置, malloc 内存池应该存放到哪个位置等 等。这些信息都保存在 gd 的成员变量中,因此要对 gd 的这些成员变量做初始化。最终形成一 个完整的内存“分配图”,在后面重定位 uboot 的时候就会用到这个内存“分配图”。

下面简单分析一下 board_init_f 函数。 board_init_f 函数定义在文件 common/board_f.c 中定义,代码如下:
1035 void board_init_f(ulong boot_flags)
1036 {
1037 #ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
1038 /*
1039 * For some archtectures, global data is initialized and used 
1040 * before calling this function. The data should be preserved. 
1041 * For others, CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined 
1042 * and use the stack here to host global data until relocation.
1043 */
1044 gd_t data;
1045
1046 gd = &data;
1047
1048 /*
1049 * Clear global data before it is accessed at debug print
1050 * in initcall_run_list. Otherwise the debug print probably
1051 * get the wrong vaule of gd->have_console.
1052 */
1053 zero_global_data();
1054 #endif
1055
1056 gd->flags = boot_flags;
1057 gd->have_console = 0;
1058
1059 if (initcall_run_list(init_sequence_f))
1060 hang();
1061
1062 #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
1063 !defined(CONFIG_EFI_APP)
1064 /* NOTREACHED - jump_to_copy() does not return */
1065 hang();
1066 #endif
1067 }

1037~1054行代码无效,因为没有定义 CONFIG_SYS_GENERIC_GLOBAL_DATA
1056 行,初始化 gd->flags=boot_flags=0
1057 行,设置 gd->have_console=0
重点在第 1059 行! 通过 initcall_run_list 函数 来运行初始化序列 init_sequence_f 里面的一些
列函数,init_sequence_f 里面包含了一系列的初始化函数。 
init_sequence_f 也是定义在文件 common/board_f.c 中,由于 init_sequence_f 的内容比较长,里面有大量的条件编译代码,这里 为了缩小篇幅,将条件编译部分删除掉了
去掉条件编译以后的 init_sequence_f 函数 前半部分代码 如下:
(因为 init_sequence_f 函数后半部分是内存分配,下一篇文章再分析)
/*****************去掉条件编译语句后的 init_sequence_f***************/
1 static init_fnc_t init_sequence_f[] = {
2 setup_mon_len, 
3 initf_malloc, 
4 initf_console_record, 
5 arch_cpu_init, /* basic arch cpu dependent setup */ 
6 initf_dm, 
7 arch_cpu_init_dm, 
8 mark_bootstage, /* need timer, go after init dm */ 
9 board_early_init_f, 
10 timer_init, /* initialize timer */ 
11 board_postclk_init, 
12 get_clocks, 
13 env_init, /* initialize environment */ 
14 init_baud_rate, /* initialze baudrate settings */ 
15 serial_init, /* serial communications setup */ 
16 console_init_f, /* stage 1 init of console */ 
17 display_options, /* say that we are here */ 
18 display_text_info, /* show debugging info if required */ 
19 print_cpuinfo, /* display cpu info (and speed) */ 
20 show_board_info, 
21 INIT_FUNC_WATCHDOG_INIT 
22 INIT_FUNC_WATCHDOG_RESET 
23 init_func_i2c, 
24 announce_dram_init, 
25 /* TODO: unify all these dram functions? */
26 dram_init, /* configure available RAM banks */ 
27 post_init_f, 
28 INIT_FUNC_WATCHDOG_RESET
29 testdram, 
30 INIT_FUNC_WATCHDOG_RESET
31 INIT_FUNC_WATCHDOG_RESET
......
62 NULL,
63 };

2 行, setup_mon_len 函数设置 gd mon_len 成员变量,此处为 __bss_end -_start ,也就 是整个代码的长度,即 uboot的镜像大小
3 行, initf_malloc 函数初始化 gd 中跟 malloc 有关的成员变量,比如 malloc_limit ,此函 数会设置 gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN=0X400 malloc_limit 表示 malloc 内存池大小。
4 行 , initf_console_record 函数, 如 果 定 义 了 宏 CONFIG_CONSOLE_RECORD 和 宏
CONFIG_SYS_MALLOC_F_LEN ,则此函数就会调用函数 console_record_init ,但是 IMX6ULL
uboot 没有定义宏 CONFIG_CONSOLE_RECORD ,所以此函数直接返回 0
5 行, arch_cpu_init 函数,应该与架构相关的初始化。
6 行, initf_dm 函数,驱动模型的一些初始化。
7 行, arch_cpu_init_dm 函数未实现。
8 行, mark_bootstage 函数应该是和啥标记有关的
9 行, board_early_init_f 函数,板子相关的早期的一些初始化设置, I.MX6ULL 用来初始 化串口的 IO 配置 。
10 行, timer_init 函数,初始化定时器, Cortex-A7 内核有一个定时器,这里初始化的就 Cortex- A 内核的那个定时器。通过这个定时器来为 uboot 提供时间。就跟 Cortex-M 内核 Systick 定时 器一样。关于 Cortex-A 内部定时器的详细内容,请参考文档 ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf 的“ Chapter B8 The Generic Timer ”章节。
11 行, board_postclk_init 函数 ,对于 I.MX6ULL 来说是设置 VDDSOC 电压。
12 行, get_clocks 函数,用于获取一些时钟值, I.MX6ULL 获取的是 sdhc_clk 时钟,也就 SD 卡外设的时钟。
13 行, env_init 函数,是和环境变量有关的,设置 gd 的成员变量 env_addr ,也就是环境变 量的保存地址。
14 行, init_baud_rate 函数,用于初始化波特率,根据环境变量 baudrate 来初始化 gd->baudrate
15 行,serial_init 函数,初始化串口。
16 行,console_init_f 函数,设置 gd->have_console 1 ,表示有个控制台,此函数也将前面 暂存在缓冲区中的数据通过控制台打印出来。
17 行, display_options 函数 ,通过串口输出一些信息:
U-Boot 2016.03 (Jul 07 2023 - 17:11:27 +0800)
18 行, display_text_info ,打印一些文本信息,如果开启 UBOOT DEBUG 功能的话就
会输出 text_base bss_start bss_end ,形式如下:
debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",text_base, bss_start, bss_end);
开启 UBOOT 的 DEBUG 功能的方法:

include/configs下有不用开发板的配置头文件,IMX6ULL使用的是 mx6ullevk.h,可以在mx6ullevk.h文件中加:

#define   DEBUG

重新编译后的 uboot镜像文件,烧录到设备,就可以打印 uboot的debug信息。

Board: I.MX6U ALPHA|MINI

19 行, print_cpuinfo 函数,用于打印 CPU 信息,打印结果如下:
CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 35C
Reset cause: POR

20 行, show_board_info 函数,用于打印板子信息,会调用 checkboard 函数,打印如下:
21 行, INIT_FUNC_WATCHDOG_INIT ,初始化看门狗,对于 I.MX6ULL 来说是空函数
22 行, INIT_FUNC_WATCHDOG_RESET ,复位看门狗,对于 I.MX6ULL 来说是空函数
23 行, init_func_i2c 函数,用于初始化 I2C ,初始化完成以后会输出如下:、
I2C:   ready

24 行, announce_dram_init 函数 ,此函数很简单,就是输出字符串“ DRAM:
26 行, dram_init 函数,并非真正的初始化 DDR ,只是设置 gd->ram_size 的值,对于正点原 I.MX6ULL 开发板 EMMC 版本核心板来说就是 512MB
串口打印如下:

27 行, post_init_f 函数,此函数用来完成一些测试,初始化 gd->post_init_f_time
29 行, testdram 函数,测试 DRAM ,空函数。
以上是 board_init_f 函数的前半部分。
具体是初始化一系列外设,比如串口、定时器,或者打印一些消息等。
下一篇文章简单分析 board_init_f函数的后半部分代码,具体是内存分配的部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1056498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker Tutorial

什么是Docker 为每个应用提供完全隔离的运行环境 Dockerfile, Image,Container Image: 相当于虚拟机的快照(snapshot)里面包含了我们需要部署的应用程序以及替它所关联的所有库。通过image,我们可以创建很…

音乐创作软件:ToneLIB Jam v4.7.8 Crack

从强大的选项卡编辑器到 3D 模式 Tonelib Jam 是一款用于播放和创作音乐的综合软件应用程序。TL Jam专为初学者和经验丰富的吉他手而设计,可以提供一个完美的平台来掌握乐器,让您轻松学习自己喜欢的歌曲或设置高效的日常吉他练习程序。TL Jam 具有功能强…

目标检测|边框检测框转换,交并比计算 代码实现

文章目录 1. 相互转换的函数2.交并比实现 在目标检测任务中,非常重要的一部分就是框出检测框 这就需要检测框的位置大小等一些信息 一般我们有如下两种方式标记一个检测的位置和大小 1 两点法 检测框左上角坐标(x1,y1),检测框右下角坐标(x2…

2023年最新云存储工具排行榜:找到适合你的云存储服务

随着数据规模的不断增长,传统的本地存储已经无法满足用户的需求。云存储工具通过提供灵活、安全和高效的数据存储服务,成为了现代化的数据管理方式。在众多云存储工具中,有一些在功能和性能方面表现出色,成为用户首选。下面是2023…

时间序列-AR模型与MA模型的原理与实现

文章目录 1 自回归模型AR Model1.1 自回归模型 vs 多元线性回归模型1.1.1 线性回归1.1.2 AR(1)模型1.1.3 AR(p)模型 1.2 AR建模问题 2 移动平均模型 MA Model2.1 MA模型的数学表示2.1.1 MA(1)模型2.2.2 MA(q)模型 2.2 MA建模问题 ARIMA模型是AR模型(自回归模型&…

计算机网络(二):物理层

参考引用 计算机网络微课堂-湖科大教书匠计算机网络(第7版)-谢希仁 1. 物理层的基本概念 物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流物理层为数据链路层屏蔽了各种传输媒体的差异,使数据链路层只需要考虑如何完成本…

levelDB引擎

一、背景 1.1、影响磁盘性能的因素: 主要受限于磁盘的寻道时间,优化磁盘数据访问的方法是尽量减少磁盘的IO次数。磁盘数据访问效率取决于磁盘IO次数,而磁盘IO次数又取决于数据在磁盘上的组织方式。磁盘数据存储大多采用B树类型数据结构&…

排序篇(三)----交换排序

排序篇(三)----交换排序 1.冒泡排序 基本思想: ​ 通过不断地比较相邻的元素,将较大的元素往后移动,从而实现排序的目的。 具体的步骤如下: 从待排序的数组中选择相邻的两个元素进行比较,如果前一个元素大于后一个元素&#…

Java编程技巧:swagger2、knif4j集成SpringBoot或者SpringCloud项目

目录 1、springbootswagger2knif4j2、springbootswagger3knif4j3、springcloudswagger2knif4j 1、springbootswagger2knif4j 2、springbootswagger3knif4j 3、springcloudswagger2knif4j 注意点: Api注解:Controller类上的Api注解需要添加tags属性&a…

在云服务器上打开ftp服务-踩坑及心得

我们产生这个需求的原因是因为打算搭建一个博客,选择了使用wordpress框架。然后,在安装插件的过程中,需要使用FTP服务进行操作。于是,我们决定搞清楚这个过程,并在其中遇到的困难进行记录。 一、安装vsftpd # 安装 s…

python生成中金所期权行权价

参考沪深300股指期权的合约表,写一个工具函数: 使用方法 def get_format_option_gap(value: float, deviation: int 0): # 根据中证1000指数获取点位"""根据标准的行权价,生成不同档位的期权列表,适合中金所:…

铁道货车通用技术条件

声明 本文是学习GB-T 5600-2018 铁道货车通用技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 90 mm90 mm。 B.2 制造要求 B.2.1 车体钢结构组成后: a) 敞车钢质侧、端板的平面度公差应小于或等于15 mm/m; 压型侧、端板的平面度…

S0003-Mac下iTerm2+zsh+ohmyzsh打造优雅美观终端

背景 优雅耐看的终端工具,必是每个程序员的追求。 本人也不例外,从业几年先后使用过: windows电脑:cmd、git bash、wsl zsh、terminal zshMac电脑: 自带terminal、iTerm2、terminal zsh 其中windows terminal zsh、mac ter…

数据结构——二叉树的基本概念及顺序存储(堆)

目录 一.前言 二.树概念及结构 2.1 树的概念 2.2 树的相关概念 2.3 树的表现 2.4 树在实际中的应用(表示文件系统的目录树结构) 三.二叉树的概念及结构 3.1 概念 3.2 特殊的二叉树 3.3 二叉树的性质 3.4 二叉树的存储结构 3.4.1 顺序存储 3…

Vitamin K

各位 比对 机制 --Mechanism of Action of Vitamin K Carboxylase (VKC).IV. Intermediates and Transition State-davis2007.pdf --Mechanism of Action of Vitamin K Carboxylase (VKC).IV. Intermediates and Transition State-davis2007.pdf -- 维生素K的作用机制-dow…

房子再小,也要有自己的装修设计!福州中宅装饰,福州装修

小空间 也要有好设计 小户型的房子现在越来越受欢迎了 但是面积不大的小户型 怎么装修才能更适合居住呢? 那么多的东西又应该如何收纳呢? 白色系装修 采用白色系为装修的主色调 白色在装修上能让视觉上显得更宽敞 让小面积的房子 变得更多简洁大…

91、Redis - 事务 与 订阅-发布 相关的命令 及 演示

★ 事务相关的命令 Redis事务保证事务内的多条命令会按顺序作为整体执行,其他客户端发出的请求绝不可能被插入到事务处理的中间, 这样可以保证事务内所有命令作为一个隔离操作被执行。 Redis事务同样具有原子性,事务内所有命令要么全部被执…

最新AI智能创作系统源码V2.6.2/AI绘画系统/支持GPT联网提问/支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图…

【C语言】IO流(文件操作)- scanf / printf没那么简单!

本篇文章目录 1. 为什么使用文件?2. 什么是文件?3. IO流的概念4. 操作文件的步骤文件指针4.1 打开文件和关闭文件4.2 读写文件(顺序读取)4.2.1 字符输入输出4.2.2 字符串(文本行)输入输出4.2.3 格式化输入输…

SSM - Springboot - MyBatis-Plus 全栈体系(十六)

第三章 MyBatis 三、MyBatis 多表映射 2. 对一映射 2.1 需求说明 根据 ID 查询订单,以及订单关联的用户的信息! 2.2 OrderMapper 接口 public interface OrderMapper {Order selectOrderWithCustomer(Integer orderId); }2.3 OrderMapper.xml 配置…