U-boot 启动流程分析 3

「设备树」dtb给内核的两种工作模式 以前没有使用设备树时,需要bootloader传一个machine id给内核,内核启动的时候会根据这个machine_id来比较内核machine_desc(机器描述结构体)中的.nr,如果相等,就选中了对应的machine_desc(机器描述结构体)),然后调用machine_desc(机器描述结构体)中的.init(初始化函数)。当使用CONFIG_OF_EMBED方式时,也就是dtb集成在uboot中的时候,relocate uboot过程中也会把dtb一起relocate,所以这里就不需要处理。 阅读详情

下面详细介绍board_init_f函数的调用流程

board_init_f主要做一些运行环境的初始化,如:
获取uboot 的长度,获取fdt的地址,并进行合法化检查,初始化trace,初始化mem malloc,配置console buffer,cpu 架构的初始化,环境变量的初始化,串口的初始化,打印板子的一些信息,然后对内存进行reserve划分,初始化gd里面的变量,重定位fdt,最后重定位uboot自己,不在返回。

1、board_init_f函数很简单,关键就是遍历执行数组init_sequence_f里面的函数

void board_init_f(ulong boot_flags)
{
	gd->flags = boot_flags;
	gd->have_console = 0;

	if (initcall_run_list(init_sequence_f))
		hang();

#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
		!defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \
		!defined(CONFIG_ARC)
	/* NOTREACHED - jump_to_copy() does not return */
	hang();      /* 除了上面的core, 其他的应该在initcall_run_list 就不再返回了,否则就是出错了 */
#endif
}

2、init_sequence_f 数组内容,也就是board_init_f调用的回调函数。


static const init_fnc_t init_sequence_f[] = {
	setup_mon_len, //设置 gd 的 mon_len 成员变量,此处为 __bss_end - _start,即整个代码的长度
#ifdef CONFIG_OF_CONTROL
	/*
	 * 对dtb进行合法性验证: 
	 * 1.获取fdt的地址. 
	 * 2.通过fdtdec_prepare_fdt来对fdt进行合法性检查,判断dtb是否存在,以及是否有四个字节对齐。
	 * 3.然后再调用fdt_check_header看看头部是否正常,fdt_check_header主要是检查dtb的magic是否正确
	 */
	fdtdec_setup, 
#endif
#ifdef CONFIG_TRACE_EARLY
	trace_early_init,//用于初始化trace,以便u-boot进行trace debug
#endif
	initf_malloc, //初始化 gd 中跟 malloc 有关的成员变量,比如 malloc_limit,表示 malloc 内存池大小
	//初始化list gd->log_head,把能输出log的device-driver加入到list里面
	log_init,
	initf_bootstage,	/* uses its own timer, so does not need DM, 在gd->bootstage里面找一个地方,记录board_init_f()的启动状态 */
#ifdef CONFIG_BLOBLIST
	bloblist_init,
#endif
	setup_spl_handoff, /* CONFIG_HANDOFF未配置,因此该函数仅返回0 */
	initf_console_record,/*申请gd->console_out和gd->console_in,用于启动控制台的记录buffer*/
#if defined(CONFIG_HAVE_FSP)
	arch_fsp_init,/* only for intel platform */
#endif
	/*
	 * 用于基于特定架构下的cpu初始化操作。该函数是一个弱函数,如果特定架构下的代码没有重新实现这个函数功能,那么这个函数将什么也不做
	 * risc-v 架构没看到实现
	 */
	arch_cpu_init,		/* basic arch cpu dependent setup */
	/*
	 * 与arch_cpu_init函数类似,该函数是一个弱函数,SoC/平台相关的CPU设置
	 */
	mach_cpu_init,		/* SoC/machine dependent CPU setup */
	/*
	 * dm:驱动模型,类似于kernel的driver的通用框架,使用probe进行初始化驱动
	 * 使用 initf_dm创建一个dm_root并将其绑定到"root driver”(driver),
	 * 然device_probe 来激活这个设备。第二步使用dm_scan来绑定设备树中的设备和驱动到dm_root下面。
	 */
	initf_dm, 
	/* 做cpu的一些初始化 */
	arch_cpu_init_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
// 这个函数由移植者提供,通常定义在开发板目录下,做一些板级的初始化。
// 提供这个函数的同时还需要定义配置宏CONFIG_BOARD_EARLY_INIT_F,这样才能将该函数真正编译进去
	board_early_init_f,
#endif

#if defined(CONFIG_PPC) || defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
	/* get CPU and bus clocks according to the environment variable */
	get_clocks,		/* get CPU and bus clocks (etc.),获取时钟参信息,并填到gd里面 */
#endif

#if !defined(CONFIG_M68K)
	//与具体体系结构和处理器芯片相关,初始化定时器,通过这个定时器来为u-boot提供时间参数
	timer_init,		/* initialize timer */
#endif

#if defined(CONFIG_BOARD_POSTCLK_INIT)
	board_postclk_init,
#endif

	/*
	 * 该函数用于存储环境变量的环境初始化。
	 * 该函数的实现本质是:设置gd的成员变量env_addr,也就是环境变量的保存地址。
	 */
	env_init,		/* initialize environment */

	//初始化波特率,根据CONFIG_BAUDRATE来初始化gd->baudrate
	init_baud_rate,		/* initialze baudrate settings */

	//初始化串口,通过default_serial_console获取当前的串口驱动,
	//根据自己的板子上的串口类型,实现串口驱动.
	serial_init,		/* serial communications setup */

	//控制台初始化
	console_init_f,		/* stage 1 init of console */

	//输出一些关于u-boot的一些信息,如版本,编译时间等等
	display_options,	/* say that we are here */

	//输出text,bss段的信息
	display_text_info,	/* show debugging info if required */

	//打印出cpu相关的信息,根据不同架构或者芯片来实现该函数
	checkcpu,
#if defined(CONFIG_SYSRESET)
	print_resetinfo,
#endif
#if defined(CONFIG_DISPLAY_CPUINFO)
	print_cpuinfo,		/* display cpu info (and speed),根据框架实现,基本上都是打印cpu的一些信息*/
#endif
#if defined(CONFIG_DTB_RESELECT)
	embedded_dtb_select,
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
	show_board_info, //打印板子的信息
#endif
	INIT_FUNC_WATCHDOG_INIT //看门狗的初始化
#if defined(CONFIG_MISC_INIT_F)
	misc_init_f,  //misc设备的初始化
#endif
	INIT_FUNC_WATCHDOG_RESET   //看门狗reset,避免watchdog触发板子的启动
#if defined(CONFIG_SYS_I2C)
	init_func_i2c, //初始化iic
#endif
#if defined(CONFIG_VID) && !defined(CONFIG_SPL)
	init_func_vid,
#endif
	announce_dram_init, //only 打印 DRAM:  
	dram_init,		/* configure available RAM banks,不是初始化DRAM,只是设置gd->sram_sized的值,并打印dram的信息 */
#ifdef CONFIG_POST
	post_init_f,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_SYS_DRAM_TEST)
	testdram, //测试dram,板级代码
#endif /* CONFIG_SYS_DRAM_TEST */
	INIT_FUNC_WATCHDOG_RESET

#ifdef CONFIG_POST
	init_post,
#endif
	INIT_FUNC_WATCHDOG_RESET
	/*
	 * Now that we have DRAM mapped and working, we can
	 * relocate the code and continue running from DRAM.
	 *
	 * Reserve memory at end of RAM for (top down in that order):
	 *  - area that won't get touched by U-Boot and Linux (optional)
	 *  - kernel log buffer
	 *  - protected RAM
	 *  - LCD framebuffer
	 *  - monitor code
	 *  - board info struct
	 */
	setup_dest_addr, //打印各种地址信息
#ifdef CONFIG_OF_BOARD_FIXUP
	fix_fdt,
#endif

	//	下面reserve_开头的函数都是预留一些地址,填充gd里面的信息,方便后续使用
#ifdef CONFIG_PRAM
	reserve_pram,
#endif
	reserve_round_4k,
	arch_reserve_mmu,
	reserve_video,
	reserve_trace,
	reserve_uboot,
	reserve_malloc,
	reserve_board,
	setup_machine,
	reserve_global_data,
	reserve_fdt,
	reserve_bootstage,
	reserve_bloblist,
	reserve_arch,
	reserve_stacks,
	dram_init_banksize,
	show_dram_config,  // 打印出dram的配置信息
	INIT_FUNC_WATCHDOG_RESET
	setup_bdinfo,//设置board相关的信息,即设置gd中的bd结构下的变量
	display_new_sp, //打印新的堆栈信息
	INIT_FUNC_WATCHDOG_RESET

	//重定位下面的地址
	reloc_fdt,
	reloc_bootstage,//用于重定位已经存在的启动阶段中的记录
	reloc_bloblist, //重定位bloblist
	setup_reloc,//启动重定位标志来进行启动重定位, 重定位gd地址
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
	copy_uboot_to_ram,
	do_elf_reloc_fixups,
#endif
	clear_bss,//清bss段
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
		!CONFIG_IS_ENABLED(X86_64)
	jump_to_copy, //riscv会走到这里,会在这里进行重定位,arm的会在后门进行重定位,都少不了的
				//	 最终会调用relocate_code,位于start.S,进行重定位,不会返回了,接着往下走
#endif
	NULL,
};

uboot启动流程(5)之board_init_f 函数详解 board_init_f 函数详解 _main 中会调用 board_init_f 函数,board_init_f 函数主要有两个工作: ①、初始化一系列外设,比如串口、定时器,或者打印一些消息等。 ②、初始化 gd 的各个成员变量,uboot 会将自己重定位到 DRAM 最后面的地址区域,也就是将自己拷贝到 DRAM 最后面的内存区域中。这么做的目的是给 Linux 腾出空间,防止 Linuxk... 阅读详情

相关推荐

uboot启动流程-涉及board_init_f 函数

uboot启动流程-涉及board_init_f汇编函数

wojiaxiaohuang2014的博客 1199

Linux设备树详解(三)u-boot设备树的传递

以前没有使用设备树时,需要bootloader传一个machine id给内核,内核启动的时候会根据这个machine_id来比较内核machine_desc(机器描述结构体)中的.nr,如果相等,就选中了对应的machine_desc(机器描述结构体)),然后调用machine_desc(机器描述结构体)中的.init(初始化函数)。// 1. 当使用CONFIG_OF_EMBED的方式时,也就是dtb集成到uboot的bin文件中时,通过__dtb_dt_begin符号来获取dtb地址。

生活需要深度 2941

RK3399平台开发系列讲解(其他篇)1.3、U-boot启动流程分析

Platform: RK3399 OS: Android 7.1 Kernel: 4.4 UBOOT-VERSION = 2014 文章目录工具一、Makefile 与 lds二、汇编部分 start.S三、系统资源初始化四、核心数据结构与系统分析五、命令行解析与引导操作系统总结 工具 Source Insight 阅读源码工具 通过编译时产生的 System.sym 查看 通过反汇编生成...

内核笔记 5173

[uboot] (番外篇)uboot之fdt介绍

介绍uboot中的device tree的配置以及使用。简单流程介绍等等

ooonebook的博客 2万+

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】003 - u-boot-2024.07-rc3 源码目录结构分析

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】003 - u-boot-2024.07-rc3 源码目录结构分析

|~~~热爱生活、努力学习的小伙汁~~~| 592

u-boot的board_init_f和board_init_r阶段执行任务的对比

u-boot的board_init_f和board_init_r阶段执行任务的对比

14.3 U-Boot启动流程分析

14.3  U-Boot启动流程分析U-Boot支持许多的处理器和开发板,主要是该软件有良好的架构,本节以使用ARM处理器的smdk2410开发板为例分析U-Boot的启动流程,在其他的处理器架构上,U-Boot也执行类似的启动流程。图14-3是U-Boot在ARM处理器的启动步骤。图14-3  U-Boot在ARM处理器的启动步骤图14-3列出了U-Boot在ARM处理器启动

Linux/UNIX典藏大系 2620

使用STC15F104W产生PWM脉冲

最近的小项目中使用到了STC15F104W产生PWM脉冲

yeats1989的专栏 1万+

U-boot启动流程分析(基于三星S3C2440)

U-boot启动流程分析

m0_62055248的博客 402

JDK8升级JDK17过程中遇到的那些坑

JDK8虽然非常好,但是JDK版本已经发布到JDK20了,且JDK8后的版本升级了很多新的特性,如模块化、ZGC以及虚拟线程、结构性并发等,也是非常有吸引力的,所以决定将基于JDK8的项目升级到最近的LTS版本JDK17。

BASK2312的博客 6685

EFR32BG22 Thunderboard开发板 使用SPI 读取加速度计

Simplicity Studio v5 创建Silicon Labs蓝牙SoC EFR32BG22 Thunderboard模块的加速度计工程,模块上有一个ICM-20648 6轴运动跟踪设备,集成3轴加速度计和3轴陀螺仪功能,使用SPI接口跟EFR32BG22芯片连接。 我尽量以图片的形式展示(少打字): 将EFR32BG22的Thunderboard模块通过USB线插入到电脑,打开Simplicity Studio v5软件。 下面看重点: 点击搜索到的IO Stream: USART,点击Ins

qq_25727979的博客 1494

3.3【U-boot分析】内核启动流程分析

内核的最终目的:运用应用程序 一、内核编译 一)解压缩:tar xjf linux-linux-2.6.22.6.tar.bz2 一)打补丁: 用 patch 命令, -p 是指需要忽略的目录层数。如果打补丁,在源代码里有显示。 --- 是指源文件。 +++ 是指修改过的文件。 ...

百无禁忌想,脚踏实地干 436

〖进阶篇1〗YAML参数解析:从nav2_params.yaml看机器人导航调优

本文深入解析了ROS2 Nav2导航系统中关键的nav2_params.yaml文件,提供了从定位、行为树、运动控制到环境感知等核心模块的参数调优实战指南。文章通过具体场景案例,如狭窄走廊、动态仓库和高精度对接,详细阐述了如何调整AMCL粒子数、控制器权重、代价地图膨胀半径等参数,以解决机器人导航中的犹豫、碰撞和精度问题,帮助开发者实现从“能用”到“好用”的进阶。

m9n0o的博客 417

Atmel SAMA5D3 U-Boot 启动流程简单分析

处理器              ATSAMA5D3x 硬件平台          SAMA5D3x-EK u-boot 版本     u-boot-2012.10 先阅读链接脚本 arch/arm/cpu/u-boot.lds 文件:  OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm") ; 指

mxl_mxl的专栏 4268

群晖Hyper Backup还原实战:加密与非加密备份的完整操作指南

本文详细介绍了群晖Hyper Backup在加密与非加密备份场景下的完整还原操作指南。通过实战案例和高级技巧,帮助用户应对硬盘故障或系统崩溃时的数据恢复挑战,特别是加密备份恢复中的关键节点和常见陷阱。

weixin_29323365的博客 440

calibration的“前世今生”——从simulink开发到CANape的XCP标定

整体思路 备注: elf可简单的看作为hex和map的集合,其中包括可执行的程序、变量及其对应的地址(simulink生成代码是也可以勾选生成ASAP2的a2l文件,有变量但变量对应的地址为空,只有编译后才分配地址) 定义变量是观测值还是标定值需要在simulink中的数据字典定义变量存储类型,详见simulink系列。 1. 前期准备A2L的制作 安装完成CanApe软件 , 插上CanApe硬件( 如:vector 1640A)。打开A2L编辑软件 ASAP2 Editor(注意不是ASAP2 Vi

IHTY_NUI的博客 1万+

U-Boot v2026.07 移植实战:基于 i.MX6ULL 的 5 步启动流程分析与 3 个关键配置

本文详细解析了U-Boot v2026.07在i.MX6ULL处理器上的移植实战,重点介绍了5步启动流程和3个关键配置。内容涵盖BootROM与U-Boot的协同工作、DDR控制器配置、环境变量存储方案等核心内容,为开发者提供全面的移植指南和调试技巧。

weixin_33841503的博客 411

LDRA Testbed(TBrun)软件单元测试_操作指南

通过前面的几篇文章,使用Testbed进行软件静态分析的内容已经基本讲解完毕。从这篇文章开始,将继续讲解如何使用TBrun进行软件单元测试、软件集成测试。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 7771

Hi3556v200 u-boot+Liteos方案启动流程分析--3.通用uboot分析之board_init_f

1.前言 本文主要就Hi3556v200的U-boot+Liteos方案的启动流程做简要介绍, 前面主要分析了Hi3556v200下的start.S文件,在这之后它将解压通用uboot的代码执行,执行的入口位于通用uboot的start.S文件。 通过_main最终调用到board_init_f函数,board_init_f将遍历执行init_sequence_f函数数组。 U-boot版本:u-boot-2016.11 2.init_sequence_f函数数组 位于/u-boot-2016.11/com

HZero 783

手把手写深度学习(27):如果获得相机位姿态的plücker embedding?以RealEstate10K为例

用plücker embedding表示相机的位姿是一种非常常用的方法,这篇博客以RealEstate10K数据集为例子,详细讲解如何从相机的轨迹坐标中获得plücker embedding,用于下一步模型的学习。

沉迷单车的追风少年 2239

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

s3c6410 uboot代码分析

转自:http://hi.baidu.com/__eabi/blog/item/be67533797bc73f014cecb49.html 以下用以记录uboot代码的分析过程,目标是s3c6410,如有错误,欢迎指正。 强调,内容与三星原厂提供的uboot-1.1.6有更改的地方,因为外接外设的区别,特别是nand_flash、外接网卡芯片和LCD芯片 以下纯代码情景分析,请结

只有不想做的,没有做不到的 1659

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

u-boot 启动过程 —— 基于S3C2410

jun2ran的专栏 1021

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

u-boot分析1:Nandflash、Norflash启动

了解u-boot之前首先了解下Bootloader,简单说Bootloader就是一段小程序,它在系统上电时开始运行,初始化硬件设备,准备好软件环境,最后调用操作系统内核。u-boot全称:Universal Boot Loader,即通用Bootloader,遵循GPL条款,开放源码。支持多种嵌入式操作系统内核:Linux、NetBSD、VxWorks等支持多个处理器系列:如PowerPC、AR...

qq_31917863的博客 2151

U-BOOT中MAKEFILE详解【1】

kuangreng的专栏 3518

第一、二期衔接——5.3 u-boot分析与使用—源码分析

u-boot分析与使用—Makefile结构分析 硬件平台:韦东山嵌入式Linxu开发板(S3C2440.v3) 软件平台:运行于VMware Workstation 12 Player下UbuntuLTS16.04_x64 系统 参考资料:《嵌入式Linux应用开发手册》、《嵌入式Linux应用开发手册第2版》 开发环境:Linux 2.6.22.6 内核、arm-linux-gcc-3.4.5-glibc-2.3.6工具链、u-boot-1.1.6 目录u-boot分析与使用—Makefile结构分

weixin_42813232的博客 923
上一篇: U-boot 启动流程分析 2
下一篇: U-boot 启动流程分析 4
Runner_Linux
博客等级 码龄6年 17粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值