bootz启动 Linux内核涉及do_bootm_linux 函数

一.  bootz启动Linux

uboot 启动Linux内核使用bootz命令。当然还有其它的启动命令,例如,bootm命令等等。

本文只分析 bootz命令启动 Linux内核的过程中涉及的几个重要函数。具体分析  do_bootm_linux函数执行过程。

本文继上一篇文章,地址如下:

bootz启动 Linux内核涉及 bootm_os_get_boot_func 函数-CSDN博客

二.   bootz 启动 Linux 内核涉及函数

2.  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 函数:

第13行,如果参数flag等于BOOTM_STATE_OS_GO或者BOOTM_STATE_OS_FAKE_GO ,就行 boot_jump_linux 函数。

boot_selected_os 函数在调用 do_bootm_linux 时,会将 flag 设置为 BOOTM_STATE_OS_GO。


第 14 行,执行函数 boot_jump_linux,此函数定义在文件 arch/arm/lib/bootm.c 中,函数内容如下:

static void boot_jump_linux(bootm_headers_t *images, int flag)
{
#ifdef CONFIG_ARM64
..........
#elseunsigned long machid = gd->bd->bi_arch_number;char *s;void (*kernel_entry)(int zero, int arch, uint params);unsigned long r2;int fake = (flag & BOOTM_STATE_OS_FAKE_GO);kernel_entry = (void (*)(int, int, uint))images->ep;s = getenv("machid");if (s) {if (strict_strtoul(s, 16, &machid) < 0) {debug("strict_strtoul failed!\n");return;}printf("Using machid 0x%lx from environment\n", machid);}debug("## Transferring control to Linux (at address %08lx)" \"...\n", (ulong) kernel_entry);bootstage_mark(BOOTSTAGE_ID_RUN_OS);announce_and_cleanup(fake);if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)r2 = (unsigned long)images->ft_addr;elser2 = gd->bd->bi_boot_params;.............kernel_entry(0, machid, r2);}
#endif
}

3~5 行之间的代码,是 64 ARM 芯片对应的代码, Cortex-A7 32 位芯片,因此用不到。

6 行,变量 machid 保存机器 ID

如果不使用设备树,这个机器 ID 会被传递给 Linux 内核,Linux 内核会在自己的机器 ID 列表里面查找是否存在与 uboot 传递进来的 machid 匹配的项目,如果存在就说明 Linux 内核支持这个机器,则 Linux 就会启动!

如果使用设备树的话,这个 machid 就无效了,设备树文件中存有一个“兼容性”这个属性,Linux 内核会比较“兼容性”属性的值(字符串)来查看是否支持这个机器。

第 8 行, kernel_entry 函数,名字“内核_ 进入”,说明此函数是进入 Linux 内核的,也 就是最终的大 boos !!
此函数有三个参数: zero arch params
第一个参数 zero 同样为 0
二个参数为机器 ID
第三个参数 ATAGS 或者设备树 (DTB) 首地址, ATAGS 是传统的方法,用 于传递一些命令行信息,如果使用设备树的话就要传递设备树 (DTB)
12 行,获取 kernel_entry 函数,函数 kernel_entry 并不是 uboot 定义的,而是 Linux 核定义的。
Linux 内核镜像文件的第一行代码就是函数 kernel_entry ,而 images->ep 保存着 Linux 内核镜像的起始地址,起始地址保存的正是 Linux 内核第一行代码!
26 行,调用 announce_and_cleanup函数, 来打印一些信息并做一些清理工作,此函数定 义在文件 arch/arm/lib/bootm.c 中,函数内容如下:
static void announce_and_cleanup(int fake)
{printf("\nStarting kernel ...%s\n\n", fake ?"(fake run for tracing)" : "");bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
.............cleanup_before_linux();
}

3 行,在启动 Linux 之前输出 “ Starting kernel ... ” 信息,所打印信息如下:

7 行,调用 cleanup_before_linux 函数做一些清理工作。

回到 boot_jump_linux函数:
28~31 行是设置寄存器 r2 的值?
为什么要设置 r2 的值呢?Linux 内核一开始是汇编代码,因此, kernel_entry函数就是个汇编函 数。向汇编函数传递参数要使用 r0 r1 r2( 参数数量不超过 3 个的时候 ) ,所以 r2 寄存器就是 kernel_entry 函数的第三个参数。

28 行,如果使用设备树的话,r2 应该是设备树的起始地址,而设备树地址保存在 images

ftd_addr 成员变量中。

30 行,如果不使用设备树的话, r2 应该是 uboot 传递给 Linux 的参数起始地址,也就 是环境变量 bootargs 的值。

34 行,调用 kernel_entry 函数进入 Linux 内核,此行将一去不复返, uboot 的使命也就 完成了。

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

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

相关文章

[netty-websocket-boot-starter] 基于Netty的轻量级、高性能的WebSocket框架

简介 这是一个轻量级、高性能的基于 Netty 的 WebSocket 框架&#xff0c;提升你的 WebSocket 开发体验&#xff0c;为 Spring Boot 带来全新的 WebSocket 功能。 该项目使你可以轻松集成 WebSocket 到你的 Spring Boot 项目中&#xff0c;提供了 Tomcat WebSocket 的简单性&a…

windows flask 多进程高并发

最近在做的一个项目&#xff0c;需要将十几个python函数封装程flask服务供外界调用&#xff0c;每个函数之间没有什么关系&#xff0c;相互独立。虽然感觉不是很难&#xff0c;但因为用的windows系统&#xff0c;遇到的坑比较多&#xff0c;在此一一总结一下。 flask偶尔出现卡…

多线程并发篇---第十二篇

系列文章目录 文章目录 系列文章目录一、说说ThreadLocal原理?二、线程池原理知道吗?以及核心参数三、线程池的拒绝策略有哪些?一、说说ThreadLocal原理? hreadLocal可以理解为线程本地变量,他会在每个线程都创建一个副本,那么在线程之间访问内部 副本变量就行了,做到了…

服务供应商安全管理制度

1、总则 1.1、目的 为了规范XXXXX单位信息系统建设和运行过程中服务商的选择&#xff0c;按照信息安全等级保护要求进行服务商管理&#xff0c;特制定本管理规范。 1.2、范围 本办法适用于XXXXX单位在信息化建设和运行过程中服务商选择的安全管理。 1.3、职责 较小项目由…

燃气管网监测系统,让城市生命线更安全

万宾科技燃气管网监测系统&#xff0c;让城市生命线更安全 城市是现代社会的中心&#xff0c;拥有庞大的人口和各种基础设施&#xff0c;以满足人们的生活需求。城市基础设施包括供热&#xff0c;供水&#xff0c;管廊&#xff0c;河湖&#xff0c;建筑&#xff0c;排水&#x…

JavaScript class和function的区别

待整理&#xff1a; 一 二 Class 组件和 Function 组件是 React 中创建组件的两种主要方式。他们在语法和功能上有一些不同。以下分点是 Class 组件和 Function 组件在不同方面的对比&#xff1a; 1. 语法结构 Class 组件&#xff1a; import React, { Component } from …

php代码优化---本人的例子

直接上货&#xff1a; 1&#xff1a;数据统计 店铺数量、提现金额、收益金额、用户数量 旧&#xff1a; // //店铺// $storey db( store )->whereTime( addtime, yesterday )->count();//昨天// $stored db( store )->whereTime( addtime, d )->count();//今天…

leetcode:210. 课程表 II

课程表 II 提示 中等 889 相关企业 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示在选修课程 ai 前 必须 先选修 bi 。 例如&#xff0c;想要学习课程…

【计算机网络】网络编程接口 Socket API 解读(10)

Socket 是网络协议栈暴露给编程人员的 API&#xff0c;相比复杂的计算机网络协议&#xff0c;API 对关键操作和配置数据进行了抽象&#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍&#xff0c;从而更好的理解 socket 编程。…

linux 服务器类型Apache配置https访问

一&#xff1a;查看服务器类型&#xff0c;下载相应的SSL证书 命令&#xff1a;netstat -anp | grep :80 httpd是Apache超文本传输协议(HTTP)服务器的主程序&#xff0c;所以下载Apache证书 二&#xff1a;将证书解压后复制到服务器上 三个文件&#xff1a;xxx.key xxx_publ…

C //例6.8 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。

C语言设计 &#xff08;第四版&#xff09; 谭浩强 例6.8 例6.8 输入一行字符&#xff0c;统计其中有多少个单词&#xff0c;单词之间用空格分隔开。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法1&#xff1a;使用gets函数 #include …

草莓病害图像数据集(YOLO使用,train为655张照片和val为487张照片)

前言&#xff1a;所有图像和标签是一一对应&#xff0c;没有标签缺失 写了两个程序来分别检查train文件夹的图像和val文件夹图像是否有缺失标签&#xff0c;如果有&#xff0c;会直接打印出缺失标签的图像名字。也方便以后用户自己添加自己收集的图像数据后&#xff0c;核对图…

Linux shell编程学习笔记12:布尔运算和逻辑运算

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、逻辑、字符串、文件测试等多种运算。前面几节我们陆续研究了 Linux shell编程 中的 字符串运算、算术运算和关系运算&#xff0c;今天我们来研究 Linux shell编程中的的布尔运算、逻辑运算。 一、…

React实现地图搜索

在现代的Web应用程序中&#xff0c;地图搜索功能对于许多应用来说是必不可少的。无论是为了查找特定位置、规划路线&#xff0c;还是为了展示附近的兴趣点&#xff0c;地图搜索都可以提供给用户很好的交互体验。 在本文中&#xff0c;我们将使用React框架来实现一个简单的地图…

纯文本邮件发送:java

1.打开jdk的conf下的security文件的.security,找到并删除&#xff0c;权限问题建议复制文件修改后替换 jdk.tls.disabledAlgorithmsSSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL 删除后的内容 然…

数据结构 - 4(栈和队列6000字详解)

一&#xff1a;栈 1.1 栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原…

php如何查找地图距离

要在PHP中使用高德地图、百度地图或腾讯地图获取位置信息&#xff0c;您可以使用它们的相应API服务。以下是获取位置信息的一般步骤&#xff1a; 思路: 获取API密钥&#xff1a;首先&#xff0c;您需要注册并获取相应地图服务提供商的API密钥。这将允许您访问他们的API以获取位…

Python学习基础笔记六十九——文本2

二进制&#xff08;字节&#xff09;模式&#xff1a; 文本文件&#xff0c;纯文本文件就是保存文本字符串的文件&#xff0c;跟word还不一样&#xff0c;word是富文本文件。 其实就文件存储的底层来说&#xff0c;不管什么类型的文件&#xff08;文本、视频、图片、word、Ex…

rsync 备份工具(附rsync+inotify 实时同步部署实例)

rsync 备份工具(附rsyncinotify 实时同步部署实例&#xff09; 1、rsync概述1.1关于rsync1.2rsync 的特点1.3工作原理 2、rsync相关命令2.1基本格式和常用选项2.2启动和关闭rsync服务2.3下行同步基本格式2.4上行同步基本格式2.5免交互2.5.1指定密码文件2.5.2rsync-daemon方式2.…

博弈论:gym104065j

https://vjudge.net/contest/587311#problem/J 我也不知道我在此题中学到了什么套路 结论&#xff1a;你选的数必须尽量接近 s u m 3 \frac {sum} 3 3sum​&#xff0c;然后这个就是解 因为另外两人选的是和你的数相比不可能更接近&#xff0c;所以必然一个大一个小 唯一的…