uboot启动内核的相关命令详解——boot、bootm

2023-11-08

1、boot和bootm命令的联系

当我们进入uboot的命令终端后,可以利用boot和bootm来启动内核,但是命令的使用方式有区别:
直接输入boot命令就可以启动内核,如果使用bootm命令,后面还需要传入内核在DDR中的地址。
(1)boot命令:完成内核的重定位,将内核从外存加载到内存,然后启动内核;
(2)bootm命令:调用时一般要传入内核在内存中的地址,然后去该地址处启动内核;如果不传入内核在内存中的地址,bootm会用默认地址去启动内核,这样不保证能正确启动内核。
(3)bootm命令可以算作是boot命令的子命令,因为boot命令最终也是调用bootm去启动内核
补充:uboot命令体系和环境变量是理解下面源码实现的基础,不清楚的可以看博客:《uboot的命令体系详解》《uboot中环境变量的实现》

2、boot命令实现源码

	#define CONFIG_BOOTCOMMAND	"movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm 30008000 30B00000"
	
	int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
	{
		int rcode = 0;
		
		//run_command是uboot中执行命令的函数,第一个参数就是要执行的命令
		#ifndef CFG_HUSH_PARSER
		//环境变量bootcmd的值默认就是CONFIG_BOOTCOMMAND
		if (run_command (getenv ("bootcmd"), flag) < 0)
				rcode = 1;
		#else
			if (parse_string_outer (getenv ("bootcmd"),
					FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
				rcode = 1;
		#endif
		
		return rcode;
	}

//利用U_BOOT_CMD宏注册命令
	U_BOOT_CMD(
		boot,	1,	1,	do_bootd,
		"boot    - boot default, i.e., run 'bootcmd'\n",
		NULL
	);

boot是启动内核的命令,boot命令的内容保存在环境变量bootcmd中,bootcmd的默认值来自于配置文件的CONFIG_BOOTCOMMAND宏定义。在main_loop函数中如果bootdelay时间内没有按下按键就会自动启动内核,可以把boot命令拆分成几个命令,其中包含重定位内核和启动内核。
(1)movi read kernel 30008000:用movi命令将外存的kernel分区读取到内存的0x30008000;
(2)movi read rootfs 30B00000 300000:用movi命令将外存的rootfs读取到内存的0x30B00000,读取长度0x300000
(3)bootm 30008000 30B00000:bootm是直接启动内核的指令,0x30008000是告诉bootm命令内核此时在内存的0x30008000地址处;

3、bootm命令实现源码

	int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
	{
		image_header_t	*hdr;
		ulong		addr;
		ulong		iflag;
		const char	*type_name;
		uint		unc_len = CFG_BOOTM_LEN;
		uint8_t		comp, type, os;

		void		*os_hdr;
		ulong		os_data, os_len;
		ulong		image_start, image_end;
		ulong		load_start, load_end;

	//判断内核是否是zImage
	#ifdef CONFIG_ZIMAGE_BOOT
	#define LINUX_ZIMAGE_MAGIC	0x016f2818 //这是一个魔术,用来判断是否是zImage
		/* find out kernel image address */
		if (argc < 2) {
			addr = load_addr;
			debug ("*  kernel: default image load address = 0x%08lx\n",
					load_addr);
		} else {
			 //argv[1]就是调用bootm命令时指定的内核所在地址
			addr = simple_strtoul(argv[1], NULL, 16);
			debug ("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
		}
		 //判断镜像头的第37-40字节处是否存放的是LINUX_ZIMAGE_MAGIC
		 //这是zImage类型内核的特征
		if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {
			printf("Boot with zImage\n");
			addr = virt_to_phys(addr);//得到内核的物理地址,因为uboot可能开启了虚拟地址映射
			hdr = (image_header_t *)addr;//得到内核的头信息
			hdr->ih_os = IH_OS_LINUX;//指明该内核是Linux
			hdr->ih_ep = ntohl(addr);//得到内核的入口

			memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t));

			/* save pointer to image header */
			images.legacy_hdr_os = hdr;

			images.legacy_hdr_valid = 1; //标志位,如果不为1是用设备树的方式启动内核

			goto after_header_check;
		}
	#endif

	#if defined(CONFIG_ZIMAGE_BOOT)
	after_header_check:
		os = hdr->ih_os;
	#endif
	
		//根据操作类型判断调用不同的内核启动函数
		switch (os) {
		default:			/* handled by (original) Linux case */
		case IH_OS_LINUX:
	#ifdef CONFIG_SILENT_CONSOLE
		fixup_silent_linux();
	#endif
		do_bootm_linux (cmdtp, flag, argc, argv, &images); //启动linux内核
		break;

	case IH_OS_NETBSD:
		do_bootm_netbsd (cmdtp, flag, argc, argv, &images);
		break;
		}

		show_boot_progress (-9);

		if (iflag)
			enable_interrupts();

		return 1;
	}

摘抄自uboot的do_bootm函数中zImage内核启动部分的代码,为了便于理解内核启动的过程,其余关于uImage和设备树的代码都已经删除了。bootm函数的主要作用就是解析内核的头信息,区分出内核的类型和调用相应内核的启动函数。do_bootm 函数主要功能:
(1)识别出当前的启动方式:zImage、uImage或者设备树;
(2)根据不同的启动方式去初始化images全局变量和内核头信息;
(3)根据操作系统类型,调用不同的内核启动函数;
补充:常见的linux系统启动函数是do_bootm_linux (),细节请看博客:《do_bootm_linux函数解析》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uboot启动内核的相关命令详解——boot、bootm 的相关文章

  • chown:不允许操作

    我有问题 我需要通过 php 脚本为系统中的不同用户设置文件所有者权限 所以我通过以下命令执行此操作 其中 1002 是系统的用户 ID file put contents filename content system chown 100
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • nslookup 报告“无法解析 '(null)': 名称无法解析”,尽管它成功解析了 DNS 名称

    我在 ubuntu 上 并且正在运行 docker 默认桥接网络 我有 Zookeeper kafka 的容器化版本 以及我编写的与 kafka 对话的应用程序 I do a docker exec it
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何将目录及其子目录中的所有 PDF 文件复制到一个位置?

    如何全部复制PDF文件从目录及其子目录到单个目录 实际上还有更多的文件 并且深度有些任意 假设四个目录的最大深度是公平的 我想这些文件需要重命名 如果a pdf例如 位于多个目录中 因为我会adding https ebooks stack
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • jpegtran 优化而不更改文件名

    我需要优化一些图像 但不更改它们的名称 jpegtran copy none optimize image jpg gt image jpg 但是 这似乎创建了 0 的文件大小 当我对不同的文件名执行此操作时 大小仍然完全相同 怎么样 jp
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • 为什么我可以直接从 bash 执行 JAR?

    我是一个长期从事 Java 工作的人 并且知道运行带有主类的 JAR 的方法MANIFEST MFJar 中的文件很简单 java jar theJar jar 我用它来启动 Fabric3 服务器 包含在bin server jar在其标
  • 为arm构建WebRTC

    我想为我的带有arm926ej s处理器的小机器构建webrtc 安装 depot tools 后 我执行了以下步骤 gclient config http webrtc googlecode com svn trunk gclient s
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • 当 grep "\\" XXFile 我得到“尾随反斜杠”

    现在我想查找是否有包含 字符的行 我试过grep XXFile但它暗示 尾随反斜杠 但当我尝试时grep XXFile没关系 谁能解释一下为什么第一个案例无法运行 谢谢 区别在于 shell 处理反斜杠的方式 当你写的时候 在双引号中 sh
  • Linux:如何设置进程的时区?

    我需要设置在 Linux 机器上启动的各个进程的时区 我尝试设置TZ变量 在本地上下文中 但它不起作用 有没有一种方法可以使用与系统日期不同的系统日期从命令行运行应用程序 这可能听起来很愚蠢 但我需要一种sandbox系统日期将被更改的地方
  • 使用 Grep 查找两个短语之间的文本块(包括短语)

    是否可以使用 grep 来高亮所有以以下内容开头的文本 mutablePath CGPathCreateMutable 并以以下内容结尾 CGPathAddPath skinMutablePath NULL mutablePath 这两个短
  • 监视目录的更改

    很像一个类似的问题 https stackoverflow com questions 112276 directory modification monitoring 我正在尝试监视 Linux 机器上的目录以添加新文件 并希望在这些新文
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost

随机推荐

  • xpath下载安装

    xpath是我们提取网页内容的常用的一款Chrome插件 反正就是很好用 下面是提供xpath安装的方式 1 找到Chrome插件官网地址下载xpath http chromecj com web development 2018 01 8
  • IDEA -gradle项目构建报错:Could not resolve all artifacts for configuration :classpath

    问题出现 加新依赖 刷新导入时报错 build gradle设置镜像 即在下面中加入 maven url http maven aliyun com nexus content groups public buildscript repos
  • 计算机组成原理:了解计算机三种编址方式(按位编址、字节编址、字编址)

    目录 一 首先简单了解一下字节 Byte 和位 b 二 B KB MB GB之间的转换关系 三 目前计算机有三种编址方式 1 按位编址 1b 2 字节编址 1 Byte 8b 3 字编址 机器字长word 32b 64b 四 例题来加深理解
  • matlab 从航空激光雷达数据中提取森林度量和单棵树属性

    目录 一 功能概述 1 算法概述 2 加载和可视化数据 3 分割提取地面点和非地面点 4 高程归一化 5 提取森林指标 6 冠层高度模型 7 检测树顶 8 单树分割 9 提取树属性 二 完整代码 三 结果展示
  • 借据与电子借据

    借据 借据是个人或单位借用个人或公家的现金 财物时所写的凭证性的一种应用文 借据 条 是人们在日常工作和生活中经常使用的一种应用文 借据从发文的角度看可以分为两类 一类是个人在借他人或单位的钱物时向对方所写的借据或借条 另一类是单位向个人或
  • 【银行转账-功能测试分析】

    转账功能分析 通过选择付款账号 填写转账金额 输入收款账户 含收款账号 收款人姓名 开户行 以及其他附加信息 手机号 备注等 填写好之后 进入安全认证页面选择安全工具 填写安全密码 最后提交转账 测试分析与设计思路 1 正常流程类设计 确保
  • elementui-slider 滑动时会重置为0的问题解决

    文章目录 问题描述 问题排查 问题解决 总结 问题描述 首次打开有 elementui slider的页面 不管滑动哪个滑块 滑动时都会自动归0 划得动 但是会自动回到最左侧0的位置 但是他确实触发了change函数 问题排查 尝试了很多方
  • Sentinel限流算法详解(硬啃)

    文章目录 常见四种限流算法 固定窗口计数器 滑动窗口计数器 漏桶 也有称漏斗 Leaky bucket 令牌桶 Token bucket Sentinel源码举例 滑动窗口 漏桶 令牌桶 常见四种限流算法 固定窗口计数器 固定窗口 相比其他
  • 如何进入安全模式? windows系统使用小技巧

    一 Windows95环境下进入安全模式 1 开启计算机 如果正在运行Windows 请重启计算机 2 在计算机开启时 请留意观察屏幕 当出现Starting Windows 95的时候 按住F5键 这样就能进入安全模式 3 或者 在计算机
  • easyexcel poi 一个模板导出excel包含多个sheet

    easy poi 一个模板导出excel包含多个sheet 1 简述 2 导出代码实例 3 导出模板 4 导出效果 5 项目实战案例 1 简述 通过调用ExcelExportUtil exportExcelClone map params
  • mybatis原理(含图)

    上面中流程就是MyBatis内部核心流程 每一步流程的详细说明如下文所述 1 读取MyBatis的配置文件 mybatis config xml为MyBatis的全局配置文件 用于配置数据库连接信息 2 加载映射文件 映射文件即SQL映射文
  • 字符的点阵显示(模拟户外广告显示屏)

    字符的点阵显示 电子科技大学软件学03级02班 周银辉一 效果二 关于C 读取字符点阵的代码 原理就不再阐述了 到Baidu里面搜一下 很多 不过一般都是C C 的 说明 对于一个字符 GetWordLattics函数返回的bool 表示一
  • Windows 10

    前言 Windows作为工作机 对于计算机系的同学来说 主要是在于利用图形化的界面直观的创建虚拟机 典型的有代表性的是virtualbox和VMware这两家公司的桌面级虚拟化软件 尤其是小白这样的初学者 更高层次的虚拟机技术才是kvm x
  • 信息安全技术 网络安全漏洞分类分级指南

    声明 本文是学习GB T 30279 2020 信息安全技术 网络安全漏洞分类分级指南 而整理的学习笔记 分享出来希望更多人受益 如果存在侵权请及时联系我们 网络安全漏洞分级 概述 网络安全漏洞分级根据漏洞分级的场景不同 分为技术分级和综合
  • 这里是哪里错显示[Error] ‘else‘ without a previous ‘if‘?

    include
  • (c语言 )输入10个学生5门课的成绩,分别用函数求:每个学生平均分;每门课的平均分;

    c语言 输入10个学生5门课的成绩 分别用函数求 每个学生平均分 每门课的平均分 include
  • 新版Spring Boot(9)- Spring Boot 整合 Web 开发(5)

    1 路径映射 不需要每个Controller都加路径映射 Configuration public class WebMvcConfig implements WebMvcConfigurer 页面只是简单的返回 不需要返回数据 param
  • WPF Image 旋转图片方法

    WPF在对图片进行旋转时 可以使用Image RenderTransform 设置它的初始旋转角度Angle 默认是0 在旋转照片图像时 还需要设置图片的旋转中心 CenterX CenterY 一般都设置它的宽度一半 高度一半 先看一下效
  • php按钮添加post请求,PHP发送POST请求的常用方式

    PHP发送POST请求我们使用的是curl来操作了 下面来看看一些常用的post数据的例子 具体的一起和111cn小编来看看吧 在PHP开发的过程中经常需要发送POST请求 POST相比GET要安全很多 而且传输的数据量也较大 下面PHP程
  • uboot启动内核的相关命令详解——boot、bootm

    1 boot和bootm命令的联系 当我们进入uboot的命令终端后 可以利用boot和bootm来启动内核 但是命令的使用方式有区别 直接输入boot命令就可以启动内核 如果使用bootm命令 后面还需要传入内核在DDR中的地址 1 bo