当前位置: 首页 > news >正文

Uboot源码超详细分析(2)

目录

一.bootz启动linux内核过程

1.images全局变量

2.bootz函数

        3.bootz_start 函数

        4.do_bootm_states函数

                5.bootm_os_get_boot_func 函数

                6.do_bootm_linux 函数


一.bootz启动linux内核过程

1.images全局变量

        不管是 bootz 还是 bootm 命令,在启动 Linux 内核的时候都会用到一个重要的全局变量:images,images 在文件 cmd/bootm.c 中有如下定义:

bootm_headers_t images;

        bootm_headers_t结构体中的相关变量有:

image_info_t os; /* OS 镜像信息 */
ulong /* OS 入口点 */
ulong rd_start, rd_end; /* ramdisk 开始和结束位置 */
char *ft_addr; /* 设备树地址 */
ulong ft_len; /* 设备树长度 */
ulong initrd_start; /* initrd 开始位置 */
ulong initrd_end; /* initrd 结束位置 */
ulong cmdline_start; /* cmdline 开始位置 */
ulong cmdline_end;
bd_t *kbd; /* cmdline 结束位置 *///宏定义表示 BOOT 的不同阶段
#define BOOTM_STATE_START (0x00000001)
#define BOOTM_STATE_FINDOS (0x00000002)
#define BOOTM_STATE_FINDOTHER (0x00000004)
#define BOOTM_STATE_LOADOS (0x00000008)
#define BOOTM_STATE_RAMDISK (0x00000010)
#define BOOTM_STATE_FDT (0x00000020)
#define BOOTM_STATE_OS_CMDLINE (0x00000040)
#define BOOTM_STATE_OS_BD_T (0x00000080)
#define BOOTM_STATE_OS_PREP (0x00000100)
#define BOOTM_STATE_OS_FAKE_GO (0x00000200)/*'Almost' run the OS*/
#define BOOTM_STATE_OS_GO (0x00000400)

        其中os 成员变量是image_info_t类型的,为系统镜像信息。image_info_t定义如下:

typedef struct image_info {ulong		start, end;		/* start/end of blob */ulong		image_start, image_len; /* start of image within blob, len of image */ulong		load;			/* load addr for the image */uint8_t		comp, type, os;		/* compression, type of image, os type */uint8_t		arch;			/* CPU architecture */
} image_info_t;

2.bootz函数

        bootz 命令的执行函数为 do_bootz,在文件 cmd/bootm.c 中有如下定义:

int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{int ret;/* Consume 'bootz' */argc--; argv++;if (bootz_start(cmdtp, flag, argc, argv, &images))return 1;/** We are doing the BOOTM_STATE_LOADOS state ourselves, so must* disable interrupts ourselves*/bootm_disable_interrupts();images.os.os = IH_OS_LINUX;ret = do_bootm_states(cmdtp, flag, argc, argv,BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |BOOTM_STATE_OS_GO,&images, 1);return ret;
}

        调用 bootz_start 函数,调用函数 bootm_disable_interrupts 关闭中断。设置 images.os.os 为 IH_OS_LINUX,也就是设置系统镜像为 Linux。调用函数 do_bootm_states 来执行不同的 BOOT 阶段,这里要执行的 BOOT 阶段有: BOOTM_STATE_OS_PREP 、 BOOTM_STATE_OS_FAKE_GO 和 BOOTM_STATE_OS_GO。

        3.bootz_start 函数

        bootz_srart 函数也定义在文件 cmd/bootm.c 中,bootz_start 主要用于初始化 images 的相关成员变量,函数内容如下:

static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,char * const argv[], bootm_headers_t *images)
{int ret;ulong zi_start, zi_end;//调用函数 do_bootm_states,执行 BOOTM_STATE_START 阶段。ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,images, 1);/* Setup Linux kernel zImage entry point *///设置 images 的 ep 成员变量,也就是系统镜像的入口点if (!argc) {images->ep = load_addr;debug("*  kernel: default image load address = 0x%08lx\n",load_addr);} else {images->ep = simple_strtoul(argv[0], NULL, 16);debug("*  kernel: cmdline image address = 0x%08lx\n",images->ep);}//调用 bootz_setup 函数,判断当前的系统镜像文件是否为Linux的镜像文件ret = bootz_setup(images->ep, &zi_start, &zi_end);if (ret != 0)return 1;lmb_reserve(&images->lmb, images->ep, zi_end - zi_start);//查找 ramdisk 和设备树(dtb)文件if (bootm_find_images(flag, argc, argv))return 1;#ifdef CONFIG_SECURE_BOOTextern uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size);if (authenticate_image(images->ep, zi_end - zi_start) == 0) {printf("Authenticate zImage Fail, Please check\n");return 1;}
#endifreturn 0;
}

        4.do_bootm_states函数

        do_bootz 最 后 调 用 的 就 是 函 数 do_bootm_states , 而 且 在 bootz_start 中 也 调 用 了
do_bootm_states 函 数 ,此 函 数 定 义 在 文 件common/bootm.c 中。

        函数 do_bootm_states 根据不同的 BOOT 状态执行不同的代码段,通过如下代码来判断
BOOT 状态:  

states & BOOTM_STATE_XXX

        通过函数 bootm_os_get_boot_func 来查找系统启动函数,参数 images->os.os 是系统类型,根据这个系统类型选择对应的启动函数,在 do_bootz 中设置images.os.os=IH_OS_LINUX。函数返回值就是找到的系统启动函数,这里找到的 Linux 系统启动函数为 do_bootm_linux,因此 boot_fn=do_bootm_linux,后面执行 boot_fn函数的地方实际上是执行的 do_bootm_linux 函数。

        调用函数 boot_selected_os 启动 Linux 内核,此函数第 4 个参数为 Linux 系统镜
像头,第 5 个参数就是 Linux 系统启动函数 do_bootm_linux。

                5.bootm_os_get_boot_func 函数

                查找对应系统的启动函数,此函数定义在文件 common/bootm_os.c 中。

                6.do_bootm_linux 函数

                do_bootm_linux 就是最终启动 Linux 内核的函数,此函数定义在文件 arch/arm/lib/bootm.c,函数内容如下:

int do_bootm_linux(int flag, int argc, char * const argv[],bootm_headers_t *images)
{/* No need for those on ARM */if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)return -1;if (flag & BOOTM_STATE_OS_PREP) {boot_prep_linux(images);return 0;}if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {boot_jump_linux(images, flag);return 0;}boot_prep_linux(images);boot_jump_linux(images, flag);return 0;
}

                        在do_bootm_linux函数中调用boot_prep_linux函数,此函数的作用是在启动linux之前做一些其他处理,比如在设备树的chosen节点下添加子结点bootargs,bootargs子结点存放bootargs环境变量。

                        在boot_jump_linux函数中调用announce_and_cleanup函数输出starting kernel ...并且做一些清理工作,调用kernel_entry函数启动linux内核。

二.总结


文章转载自:
http://anba.hnsdj.cn
http://alinement.hnsdj.cn
http://anguiped.hnsdj.cn
http://beefwood.hnsdj.cn
http://calciferous.hnsdj.cn
http://afforce.hnsdj.cn
http://ameliorable.hnsdj.cn
http://belongingness.hnsdj.cn
http://brahmin.hnsdj.cn
http://capitalize.hnsdj.cn
http://cadaverous.hnsdj.cn
http://appentice.hnsdj.cn
http://chophouse.hnsdj.cn
http://beadsman.hnsdj.cn
http://bullyboy.hnsdj.cn
http://chaffer.hnsdj.cn
http://barbacan.hnsdj.cn
http://aeroengine.hnsdj.cn
http://cautionry.hnsdj.cn
http://afterwit.hnsdj.cn
http://brazen.hnsdj.cn
http://arytenoidectomy.hnsdj.cn
http://cecity.hnsdj.cn
http://cao.hnsdj.cn
http://caressingly.hnsdj.cn
http://careerman.hnsdj.cn
http://chloramine.hnsdj.cn
http://basification.hnsdj.cn
http://bathinette.hnsdj.cn
http://ascendancy.hnsdj.cn
http://www.dtcms.com/a/280051.html

相关文章:

  • 力扣25.7.15每日一题——有效单词
  • 对于编写PID过程中的问题
  • TCP可靠性设计的核心机制与底层逻辑
  • TDengine GREATEST 和 LEAST 函数用户手册
  • 26.将 Python 列表拆分为多个小块
  • SSM框架学习DI入门——day2
  • 跨平台移动开发技术深度分析:uni-app、React Native与Flutter的迁移成本、性能、场景与前景
  • IOS 18下openURL 失效问题
  • Flutter瀑布流布局深度实践:打造高性能动态图片墙
  • LVS(Linux Virtual Server)详细笔记(理论篇)
  • JavaScript进阶篇——第三章 箭头函数核心
  • 【问题排查流程总结】tmd2635模块开发中断异常,排查心得
  • python技巧:使用pyvisa控制仪器;安装NI-VISA等visa库;导入pyvisa并创建资源管理器;打开和使用仪器
  • 【 Cache 写策略学习笔记】
  • 编程项目选择思考点以及项目包装的关键点
  • linux系统------LVS+KeepAlived+Nginx高可用方案
  • 优雅的Java:01.数据更新如何更优雅
  • Rocky Linux 9 源码包安装php8
  • 基于按键开源MultiButton框架深入理解代码框架(一)(指针的深入理解与应用)
  • 开源AI Agent开发平台Dify源码剖析系列(二)
  • HTTP 协议
  • 微信小程序进度条cavans
  • 【电脑】显卡(GPU)的基础知识
  • Golang Channel与协程的完美配合指南
  • CAU数据挖掘 第五章 聚类问题
  • vscode里面怎么配置ssh步骤
  • Python+Selenium自动化爬取携程动态加载游记
  • python实现自动化sql布尔盲注(二分查找)
  • js最简单的解密分析
  • 分支战略论:Git版本森林中的生存法则