U-boot的执行流程

嵌入式技术

1330人已加入

描述

1.概述

本文主要讲述了U-boot的执行流程。

U-boot版本:2022.10;硬件平台架构:ARMv8;操作系统:Linux。

2.分析思路

根据U-Boot使用的链接器脚本文件,确定程序入口。从程序入口开始,通过静态代码分析,结合实际打印的log,梳理程序的调用关系和执行流程,一直分析到U-Boot执行的最后阶段,即命令交互界面。

本文分析的执行流程仅限于U-Boot proper(非SPL),分析ARMv8架构SOC的单核或多核中的主核执行流程。对U-Boot的主体流程进行分析,不追求细节,使读者对U-Boot工作流程达到整体轮廓的理解,更多细节后续专题讨论。

3.程序入口

U-boot的程序入口由链接器脚本文件指定,链接器脚本文件的扩展名为.lds。U-boot当前使用的链接器脚本文件可通过menuconfig配置界面查看。下面是ARMv8架构芯片使用的链接器脚本文件示例,为arch/arm/cpu/armv8/u-boot.lds。

脚本

查看u-boot.lds可知,U-boot的程序入口为_start,位于arch/arm/cpu/armv8/start.S。

脚本

4.执行流程

4.1复位向量

在arch/arm/cpu/armv8/start.S中,从程序入口_start开始,最先执行的程序为复位向量reset,截取的起始部分代码如下。

脚本

复位向量reset的主要工作是存储启动参数、初始化硬件、执行勘误程序、执行spin-table多核启动处理程序等。

复位向量reset最后跳转到主核程序标号master_cpu,然后跳转到_main程序执行。

脚本

4.2_main程序

_main程序位于arch/arm/lib/crt0_64.S。

_main的主要执行流程如下:

(1)为调用board_init_f()建立初始运行环境;

(2)调用board_init_f(),该函数为在系统RAM(如DRAM、DDR)中执行程序准备硬件环境;

(3)调用relocate_code(),搬运U-Boot代码到新的地址空间;

(4)为调用board_init_r()建立最终运行环境;

(5)跳转到board_init_r(),完成板级初始化,启动cli命令交互功能。

4.3board_init_r()流程

board_init_r()程序位于common/board_r.c。

脚本

board_init_r()的核心代码是815行的initcall_run_list(init_sequence_r),循环执行init_sequence_r[]函数数组的成员函数。init_sequence_r[]在common/board_r.c定义,截取的起始部分成员函数如下。

脚本

board_init_r()最后执行的代码即为init_sequence_r[]的最后一个成员函数run_main_loop。截取的init_sequence_r[]末尾部分成员函数如下。

脚本

4.4run_main_loop流程

run_main_loop()在common/board_r.c定义,循环执行main_loop()函数。

脚本

main_loop()函数在common/main.c定义,其主要功能包括:

(1)cli初始化。由cli_init()函数实现。

(2)boot倒计时处理。在自动运行bootcmd前等待设置的延时时长。由bootdelay_process()函数实现。

(3)执行autoboot命令。由void autoboot_command(const char *s)函数实现。该函数自动运行用户配置的bootcmd命令。例如:若通过SD卡启动Linux操作系统,将SD卡中镜像文件拷贝到内存,并通过boot命令启动Linux的工作就是由 autoboot_command函数完成的。

(4)cli命令交互功能。由cli_loop()函数实现。用户看到的U-boot命令交互界面就是该函数实现的。这是U-boot执行的最后阶段。

cli_loop()函数在common/cli.c定义。

脚本

4.5执行流程图

综上,U-boot的执行流程图如下。

脚本

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分