uboot启动流程-涉及board_init_f 函数

一.   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.mzph.cn/news/92894.shtml

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

相关文章

动态规划算法(2)--最大子段和与最长公共子序列

目录 一、最大子段和 1、什么是最大子段和 2、暴力枚举 3、分治法 4、动态规划 二、最长公共子序列 1、什么是最长公共子序列 2、暴力枚举法 3、动态规划法 4、完整代码 一、最大子段和 1、什么是最大子段和 子段和就是数组中任意连续的一段序列的和,而…

阿里云服务器方升架构、自研硬件、AliFlash技术创新

阿里云服务器技术创新:服务器方升架构及自研硬件、自研存储硬件AliFlash和阿里云异构计算加速平台,阿里云百科分享阿里云服务器有哪些技术创新: 目录 服务器技术创新 服务器方升架构及自研硬件 自研存储硬件AliFlash 阿里云异构计算加速…

【Excel】快速提取某个符号前面的数据内容

【问题描述】 在使用excel整理数据过程中,经常与需要调整数据后,进行使用。 例如凭证导出后,科目列是包含科目编码和科目名称的。 但由于要将数据复制到其他的导入模板上使用,对应的模板只需要科目编码,不需要科目名称…

常说的I2C协议是干啥的(电子硬件)

I2C(Inter-Integrated circuit)协议是电子传输信号中常用的一种协议。 它是一种两线式串行双向总线,用于连接微控制器和外部设备,也因为它所需的引脚数只需要两条(CLK和DATA),硬件实现简单&…

Acwing 906. 区间分组

Acwing 906. 区间分组 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 这段代码是用来维护一个最小堆,以确保右边界不相交的区间被正确地保留在堆中。让我详细解释这段代码: heap.empty():这个条件检查最小堆 heap 是否为…

【牛客网】JZ39 数组中出现次数超过一半的数字

题目 思路 思路1 将数组排序,再保证有结果的情况下,此时数组中间的数字就是想要的结果 思路2 在保证有结果的情况下,此时数组的的众数是数组长度的一半以上 所以我们可以通过抵消的做法来找到最终的结果 我们可以从头遍历这个数组,如果两个数不相同,则消去这两个数,最坏的…

Bug:elementUI样式不起作用、Vue引入组件报错not found等(Vue+ElementUI问题汇总)

前端问题合集:VueElementUI 1. Vue引用Element-UI时,组件无效果解决方案 前提: 已经安装好elementUI依赖 //安装依赖 npm install element-ui //main.js中导入依赖并在全局中使用 import ElementUI from element-ui Vue.use(ElementUI)如果此…

C++笔记之环形队列

C笔记之环形队列 code review! 文章目录 C笔记之环形队列1.概念I——摘自 https://mp.weixin.qq.com/s/HUn9TF09RZ-UJKYPR5ZXhA2.概念II——摘自 http://t.csdnimg.cn/72bng3.概念III—— 摘自https://mp.weixin.qq.com/s/9Ga502p1DLcc6o75JBQlDg4.概念IV—— 摘自https://mp…

基于SSM的网上药品售卖系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Django之模板

一)模板(T) 什么时候会使用模板呢? 仅对于Django这个框架来说,因为其是默认前后端不分离的框架(前后端不分离值开发时前后端的代码在一起,不通过接口的方式连接,通过模板渲染的方式…

Ubuntu 20.04 安装部署 TiDB DM v7.3.0 集群【全网独家】

文章目录 测试环境说明TiDB 单机环境部署DM 集群部署1. 免密设置2. 组件下载3. DM 配置文件模板获取4.DM 配置文件设置5.部署与启动 DM 集群 前言: 放眼全网,我找不出一篇在 Ubuntu 里面搭建 DM 集群的文章,虽然 TiDB 官方推荐使用 CentOS 系…

多线程 - 阻塞式队列

阻塞队列 阻塞队列,也是一个队列 ~~ 先进先出 实际上有一些特殊的队列,不一定非得遵守先进先出的 ~~ 优先级队列(PriorityQueue) 阻塞队列,也是特殊的队列,虽然也是先进先出的,但是带有特殊的功能: 阻塞 如果队列为空,执行出队列操作,就会阻塞.阻塞到另一个线程往队列里添加元…

gitee 远程仓库操作基础(二)

(1)clone远端仓库,本地建立分支推送 (基于远程仓库版本库 本地建立分支开发新功能) git clone gitgitee.com:xxxxx/alsa_test.git git remote add origin gitgitee.com:xxxxx/alsa_test.git进入clone过后路径代码,查看本地分支,发现该项目远程仓库有很多分支 基于…

分布式文件存储系统Minio实战

分布式文件系统应用场景 互联网海量非结构化数据的存储需求电商网站:海量商品图片视频网站:海量视频文件网盘 : 海量文件社交网站:海量图片 1. Minio介绍 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存…

【JVM】第四篇 垃圾收集器ParNewCMS底层三色标记算法详解

导航 一. 垃圾收集算法详解1. 分代收集算法2. 标记-复制算法3. 标记-清除算法4. 标记-整理算法二. 垃圾收集器详解1. Serial收集器2. Parallel Scavenge收集器3. ParNew收集器4. CMS收集器三. 垃圾收集底层三色标记算法实现原理1. 垃圾收集底层使用三色标记算法的原因?2. 垃圾…

[Linux 基础] 一篇带你了解linux权限问题

文章目录 1、Linux下的两种用户2、文件类型和访问权限(事物属性)2.1 Linux下的文件类型2.2 基本权限2.3 文件权限值的表示方法(1)字符表示方法(2)8进制数值表示方法 2.4 文件访问权限的相关设置方法(1) chm…

javaee SpringMVC中json的使用

jsp <%--Created by IntelliJ IDEA.User: 呆萌老师:QQ:2398779723Date: 2019/12/6Time: 15:55To change this template use File | Settings | File Templates. --%> <% page contentType"text/html;charsetUTF-8" language"java" %> <%St…

json能够存储图片吗?

JSON 本身并不适合存储图片&#xff0c;因为它是一种轻量级的数据交换格式&#xff0c;易于阅读和编写&#xff0c;同时也易于机器解析和生成。JSON 数据格式简单&#xff0c;只包含键值对&#xff0c;因此它主要用于存储和传输文本数据。 然而&#xff0c;你可以将图片转换为 …

《数据结构、算法与应用C++语言描述》-栈的应用-列车车厢重排问题

列车车厢重排问题 一列货运列车有 n 节车厢&#xff0c;每节车厢要停靠在不同的车站。假设 n个车站从 1 到n 编号&#xff0c;而且货运列车按照从n到1的顺序经过车站。车厢的编号与它们要停靠的车站编号相同。为了便于从列车上卸掉相应的车厢&#xff0c;必须按照从前至后、从…

【吞噬星空】连播两集,尼赫鲁对徐欣动手,罗峰修分身强势复仇

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析吞噬星空资讯。 吞噬星空动画第四季定档之后&#xff0c;官方真的是太宠粉了&#xff0c;每天都会公布全新预告情报&#xff0c;无论是外星人物角色&#xff0c;亦或者宇宙星球建模&#xff0c;那都是相当的炸裂。如今更…