ARM uboot 源码分析7 - uboot的命令体系
一、uboot 命令体系基础
1、使用 uboot 命令
(1) uboot 启动后进入命令行环境下,在此输入命令按回车结束,uboot 会收取这个命令然后解析,然后执行。
2、uboot 命令体系实现代码在哪里
(1) uboot 命令体系的实现代码在 uboot/common/cmd_xxx.c 中。有若干个 .c 文件和命令体系有关。(还有 command.c main.c 也是和命令有关的)

3、每个命令对应一个函数
(1) 每一个 uboot 的命令背后都对应一个函数。这就是 uboot 实现命令体系的一种思路和方法。
(2) 我们要找到每一个命令背后所对应的那个函数,而且要分析这个函数和这个命令是怎样对应起来的。
4、命令参数以 argc & argv 传给函数
(1) 有些 uboot 的命令还支持传递参数。也就是说命令背后对应的函数接收的参数列表中有 argc 和 argv,然后命令体系会把我们执行命令时的命令+参数(md 30000000 10)以 argc(3)和 argv(argv[0]=md, argv[1]=30000000 argv[2]=10)的方式传递给执行命令的函数。
举例分析,以 help 命令为例:
help 命令背后对应的函数名叫:do_help。在 uboot/common/command.c 的236行。int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])

二、uboot 命令解析和执行过程分析
1、从 main_loop 说起
(1) uboot 启动的第二阶段,在初始化了所有该初始化的东西后,进入了一个死循环,死循环的循环体就是 main_loop。
(2) main_loop 函数执行一遍,就是一个获取命令、解析命令、执行命令的过程。
(3) run_command 函数就是用来执行命令的函数。

2、run_command 函数关键点分析
(1) 控制台命令获取;
(2) 命令解析。parse_line 函数把 “md 30000000 10” 解析成 argv[0]=md, argv[1]=30000000 argv[2]=10;

(3) 在命令集中去查找命令。find_cmd(argv[0]) 函数去 uboot 的命令集合当中搜索有没有 argv[0] 这个命令。

(4) 执行命令。最后用函数指针的方式调用执行了对应函数。

思考:关键点就在于 find_cmd 函数如何查找到这个命令是不是 uboot 的合法支持的命令?这取决于 uboot 的命令体系机制(uboot 是如何完成命令的这一套设计的,命令如何去注册、存储、管理、索引。)。
三、uboot如何处理命令集1
1、可能的管理方式
(1) 数组。结构体数组,数组中每一个结构体成员就是一个命令的所有信息。
(2) 链表。链表的每个节点 data 段就是一个命令结构体,所有的命令都放在一条链表上。这样就解决了数组方式的不灵活。坏处是需要额外的内存开销,然后各种算法(遍历、插入、删除等)需要一定复杂度的代码执行。
(3) 有第三种吗?uboot 没有使用数组或者链表,而是使用了一种新的方式来实现这个功能。
2、命令结构体 cmd_tbl_t


(1) name:命令名称,字符串格式。
(2) maxargs:命令最多可以接收多少个参数。
(3) repeatable:指示这个命令是否可重复执行。重复执行是 uboot 命令行的一种工作机制,就是直接按回车则执行上一条执行的命令。
(4) cmd:函数指针,命令对应的函数的函数指针,将来执行这个命令的函数时,使用这个函数指针来调用。
(5) usage:命令的短帮助信息。对命令的简单描述。
(6) help:命令的长帮助信息。细节的帮助信息。
(7) complete:函数指针,指向这个命令的自动补全的函数。
总结:uboot 的命令体系在工作时,一个命令对应一个 cmd_tbl_t 结构体的一个实例,然后 uboot 支持多少个命令,就需要多少个结构体实例。uboot 的命令体系把这些结构体实例管理起来,当用户输入了一个命令时,uboot 会去这些结构体实例中查找(查找方法和存储管理的方法有关)。如果找到则执行命令,如果未找到则提示命令未知。
3、uboot 实现命令管理的思路


(1) 填充 1 个结构体实例构成一个命令
(2) 给命令结构体实例附加特定段属性(用户自定义段),链接时将带有该段属性的内容链接在一起排列(挨着的,不会夹杂其他东西,也不会丢掉一个带有这种段属性的,但是顺序是乱序的)。
(3) uboot 重定位时,将该段整体加载到 DDR 中。加载到 DDR 中的 uboot 镜像中,带有特定段属性的这一段,其实就是命令结构体的集合,有点像一个命令结构体数组。
(4) 段起始地址和结束地址(链接地址、定义在 u-boot.lds 中)决定了这些命令集的开始和结束地址。


四、uboot 如何处理命令集2
1、uboot 命令定义具体实现分析
(1) U_BOOT_CMD 宏基本分析

这个宏定义在 uboot/include/command.h 中。
U_BOOT_CMD(
version, 1, 1, do_version,
“version - print monitor version\n”,
NULL
);
这个宏替换后变成:
cmd_tbl_t __u_boot_cmd_version attribute ((unused,section (“.u_boot_cmd”))) = {#name, maxargs, rep, cmd, usage, help}

总结:这个 U_BOOT_CMD 宏的理解,关键在于结构体变量的名字和段属性。名字使用 ## 作为连字符,附加了用户自定义段属性,以保证链接时将这些数据结构链接在一起排布。
(2) 链接脚本。
2、find_cmd 函数详解

(1) find_cmd 函数的任务,是从当前 uboot 的命令集中查找是否有某个命令。如果找到则返回这个命令结构体的指针,如果未找到返回 NULL。
(2) 函数的实现思路很简单,如果不考虑命令带点的情况(md.b md.w 这种)就更简单了。查找命令的思路其实就是 for 循环遍历数组的思路,不同的是数组的起始地址和结束地址是用地址值来给定的,数组中的元素个数是结构体变量类型。

3、U_BOOT_CMD 宏详解
(1) 这个宏其实就是定义了一个命令对应的结构体变量,这个变量名和宏的第一个参数有关;因此只要宏调用时,传参的第一个参数不同,则定义的结构体变量不会重名。
4、命令举例:version 命令

五、uboot 中增加自定义命令
1、在已有的 c 文件中直接添加命令
(1) 在uboot/common/command.c中添加一个命令,叫:mycmd。
(2) 在已有的.c文件中添加命令比较简单,直接使用U_BOOT_CMD宏即可添加命令,给命令提供一个do_xxx的对应的函数这个命令就齐活了。
(3) 添加完成后要重新编译工程(make distclean; make x210_sd_config; make),然后烧录新的uboot去运行即可体验新命令。
(4)还可以在函数中使用argc和argv来验证传参。
2、自建一个 c 文件并添加命令
(1) 在uboot/common目录下新建一个命令文件,叫cmd_aston.c(对应的命令名就叫aston,对应的函数就叫do_aston函数),然后在c文件中添加命令对应的U_BOOT_CMD宏和函数。注意头文件包含不要漏掉。
(2) 在uboot/common/Makefile中添加上aston.o,目的是让Make在编译时能否把cmd_aston.c编译链接进去。
(3) 重新编译烧录。重新编译步骤是:make distclean; make x210_sd_config; make
3、体会:uboot 命令体系的优点
(1) uboot的命令体系本身稍微复杂,但是他写好之后就不用动了。我们后面在移植uboot时也不会去动uboot的命令体系。我们最多就是向uboot中去添加命令,就像本节课所做的这样。
(2) 向uboot中添加命令非常简单。
源自朱友鹏老师.
相关文章:
ARM uboot 源码分析7 - uboot的命令体系
一、uboot 命令体系基础 1、使用 uboot 命令 (1) uboot 启动后进入命令行环境下,在此输入命令按回车结束,uboot 会收取这个命令然后解析,然后执行。 2、uboot 命令体系实现代码在哪里 (1) uboot 命令体系的实现代码在 uboot/common/cmd_xx…...
物理服务器与云服务器备份相同吗?
自从云计算兴起以来,服务器备份已经从两阶段的模拟操作演变为由云服务器备份软件执行的复杂的多个过程。但是支持物理服务器和虚拟服务器之间的备份相同吗?主要区别是什么?我们接下来将详细讨论这个问题。 物理服务器与云服务器备份的区别 如果您不熟悉虚拟服务器…...
【Linux】system V共享内存 | 消息队列 | 信号量
🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉system V共…...
FSC的宣传许可 答疑
【FSC的宣传许可 答疑】问:已经采购了认证产品但没有贴FSC标签,是否可以申请宣传许可?答:不可以。要宣传您采用了FSC认证产品的前提条件之一是产品必须是认证且贴有标签的。如果产品没有贴标,则不可申请宣传许可。您的…...
Leetcode力扣秋招刷题路-0100
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 100. 相同的树 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是…...
协作对象死锁及其解决方案
协作对象死锁及其解决方案 1.前言 在遇到转账等的需要保证线程安全的情况时,我们通常会使用加锁的方式来保证线程安全,但如果无法合理的使用锁,很可能导致死锁。或者有时我们使用线程池来进行资源的使用,如调用数据库࿰…...
良许也成为砖家啦~
大家好,我是良许。 没错,良许成为砖家啦,绝不是口嗨,有图有真相! 有人会说,咦,这明明是严宇啊,跟你良许有啥关系? 额。。老读者应该知道良许的来历—— 鄙人真名严宇&a…...
Java中的编程细节
前言: 学习过程中有不少时候遇到一些看似简单,做起来事倍功半的问题。我也想自己是个聪明人,学东西一听就懂,一学就会,马上就能灵活应用。但这种事不能强求,要么自己要看个十遍二十遍最后理清逻辑…...
Yolov8从pytorch到caffe (一) 环境搭建
Yolov8从pytorch到caffe (一) 环境搭建 1. 创建虚拟环境2. 安装pytorch与v8相关库3. 测试安装是否成功4. 测试推理图像在windows上配置YOLOv8的环境,训练自己的数据集并转换到caffemodel1. 创建虚拟环境 利用conda创建虚拟环境 conda create -n yolo python=3.8 -y 并进入ac…...
2023年CDGA考试-第16章-数据管理组织与角色期望(含答案)
2023年CDGA考试-第16章-数据管理组织与角色期望(含答案) 单选题 1.在定义任何新组织或尝试改进现有组织之前了解当前组织的哪些方面非常重要? A.企业文化、运营模式和人员 B.业务战略、技术战略、数据战略 C.工具、方法和流程 D.事业环境因素、组织过程资产,行动路线图 …...
Stream——集合数据按照某一字段排序
文章目录前言假设业务场景排序前的准备正序排序1、数据集合的判空 Optional.isPresent()2、使用sort排序3、将排序后的数据流转换为list你以为这样就完了?倒序排序前言 之前,针对Stream链式编程中的几个方法做了大致的说明。详情可以参考: J…...
ubuntu:20.04编译arrow
1)拉取代码 git clone https://github.com/apache/arrow.git 2)切换分支 git checkout apache-arrow-11.0.0 3)拉入测试数据并设置环境变量 pushd arrow git submodule update --init export PARQUET_TEST_DATA"${PWD}/cpp/submodules/parquet-testing/da…...
2023如果纯做业务测试的话,在测试行业有出路吗?
直接抛出我的结论:手工做业务类测试,没有前途。 个人建议赶紧从业务测试跳出来,立即学习代码,走自动化测试方向。目前趋势,业务测试需要用自动化做。 为了让大家能够信服我的观点,本文将从以下方面进行阐…...
golang grpc ssl
无CA场景 在不考虑CA的场景下呢,client有client.key和client.crt,server有server.key和server.crt,生成方式可以如下: $ openssl genrsa -out server.key 2048 $ openssl req -new -x509 -days 3650 \-subj "/CGB/LChina/Og…...
华为服务器驱动下载及安装
1.服务器技术支持网站 https://support.xfusion.com/support/#/zh/home 2.选择软件下载 3.选择服务器型号 4.选择驱动 5.根据需求选择驱动 例如红帽7.4系统 6.安装驱动 自动安装驱动步骤: 1)使用BMC虚拟光驱挂载onboard_driver_xxx.iso: 2)mount /dev/sr0 /mnt …...
【Shell】常用命令合集
常用命令: 文件和目录: cd /home 进入 ‘/home’ 目录 cd … 返回上一级目录 cd …/… 返回上两级目录 cd - 返回上次所在目录 cp file1 file2 将file1复制为file2 cp -a dir1 dir2 复制一个目录 cp -a /tmp/dir1 . 复制一个目录到当前工作目录(.代表当前目录…...
15- 答题卡识别及分数判定项目 (OpenCV系列) (项目十五)
项目要点 图片读取 : img cv2.imread(./images/test_01.png)灰度图: gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)高斯模糊: blurred cv2.GaussianBlur(gray, (5, 5), 0) # 去噪点边缘检测: edged cv2.Canny(blurred, 75, 200)检测轮廓: cnts cv2.findContours(e…...
LeetCode 热题 C++ 146. LRU 缓存
力扣146 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否…...
Java线程池使用与原理解析(线程池优点、使用方法、参数含义及线程池运转机制)
为什么要使用线程池? JDK1.5后JUC包添加了线程池相关接口,在Java诞生之初并没有线程池这个概念。刚开始Java程序都是自行创建线程去处理任务。随着应用使用的线程越来越多,JDK开发者们发现有必要使用一个统一的类来管理这些线程,…...
mybatis入门配置
mybatis mybatis是一款持久层框架,用于简化JDBC开发 持久层:负责将数据保存到数据库的那一层代码JavaEE的三层架构:表现层、业务层、持久层、,就相当与mvc设计模式过程中的Controller、service、dao 1.创建一个maven模块&#…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
