uboot启动内核的相关命令详解——boot、bootm
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_BOOTCOMMANDif (run_command (getenv ("bootcmd"), flag) < 0)rcode = 1;#elseif (parse_string_outer (getenv ("bootcmd"),FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)rcode = 1;#endifreturn 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;//指明该内核是Linuxhdr->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_CONSOLEfixup_silent_linux();#endifdo_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函数解析》。
uboot启动内核的相关命令详解——boot、bootm相关推荐
- 20-Linux系统进程与计划任务相关命令详解整合
系统进程与计划任务相关命令详解整合 at at命令用于在指定时间执行命令.它能够接受在当天的hh:mm(小时:分钟)式的时间指定.假如该时间已过去,那么就放在第二天执行. 也能够使用midnight( ...
- 2022-08-14 SSH 相关命令详解
SSH 相关命令详解 ssh ssh-keygen ssh-copy-id ssh-agent 和 ssh-add ssh-keyscan sshd ssh ssh – OpenSSH 远端登陆客户端 ...
- Linux 中 3 个文件打包上传和下载相关命令详解
tar 命令 通过 SSH 访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar 命令就是必不可少的一个功能强大的工具.Linux 中最流行的tar是麻雀虽小,五脏俱全,功能强大. 使用t ...
- php redis命令大全,redis中key相关命令详解
一.概述: 本文将主要讲述与Key相关的Redis命令.学习这些命令对于学习Redis是非常重要的基础,也是能够充分挖掘Redis潜力的利器.(推荐:redis视频教程) 二.相关命令列表: 命令原型 ...
- linux 硬盘、RAID相关命令详解
本文主要介绍linux下查看各种硬盘信息的命令如何使用,如何快速的查到自己想要的硬盘相关信息,各种命令做一个汇总. Nvme-cli Q1:如何查看nvme写缓存打开否: [root@node83 p ...
- RPM 包相关命令详解
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_33656602/article/ ...
- RocketMQ实战系列-RocketMQ命令详解
导语 之前分析了关于RocketMQ源码的东西,接下来的阶段就是进入到实战的相关系列操作中,在这个系列中也会继续从源码的角度入手,深入的分析,在RocketMQ中的编程思想.下面就来介绍一下在Ro ...
- linux下bcd文件还原,BCDEDIT命令详解 | 数据恢复实验室 Data Recovery Laboratory
案例:bcdedit添加系统启动项 使用BCDEDIT命令,编辑启动项,方便.快捷,只需记住几条命令,必要时替换即可. 以下是一个案例: 标识符 {de329298-0dd8-11e0-90b6-8a ...
- BCDEDIT命令详解 【Z】
使用BCDEDIT命令,编辑启动项,方便.快捷,只需记住几条命令,必要时替换即可. 以下是一个案例: 标识符 {de329298-0dd8-11e0-90b6-8af61b7989dc} device ...
最新文章
- MySQL重置root用户密码的方法
- 基于Dijkstra算法的武汉地铁路径规划!
- linux中操作java进程
- 姚班大神陈立杰最新动向:MIT毕业后将进入诺奖摇篮,成为UC伯克利Miller研究员...
- oracle的那些事
- python 中的真值表
- pythonseleniumAPI
- linux内核定时唤醒,Linux内核时钟与定时器的实现
- Android-Universal-Image-Loader 框架使用
- 反积分饱和 程序_用抗积分饱和PID控制传递函数为G(s)的被控对象
- ViewState笔记
- elasticsearch查询操作(使用marvel插件)
- Gmail Labs各功能全球开放
- 6.13编一程序,将两个字符串连接起来,不要用strcat函数。
- Zabbix主页应用介绍
- wps页眉添加下划线
- css选中父元素下的第一个子元素
- Qt样式表使用总结3,我常用的选色方法
- 【面试准备之】HR面试时100个关键问题
- java线段绕原点旋转的方法,将点绕坐标原点顺时针旋转得到点的坐标为___________。-九年级数学-魔方格...