详细介绍uboot下run_command调用哪些命令函数进行执行
在 U-Boot 中,run_command()
是命令执行的核心函数,它负责解析命令字符串、查找对应的命令结构体,并调用命令的执行函数。其命令执行流程涉及多个关键函数和数据结构,以下是详细介绍:
一.命令介绍
1. 核心数据结构:struct cmd_tbl_s
U-Boot 中的所有命令都通过 struct cmd_tbl_s
(通常 typedef 为 cmd_tbl_t
)结构体定义,每个命令对应一个该结构体的实例。其关键成员包括:
运行
struct cmd_tbl_s {
const char *name; // 命令名称(如 "bootm"、"printenv")
int maxargs; // 最大参数数量
int repeatable; // 是否可重复执行(按回车重复上一条命令)
int (*cmd)(struct cmd_tbl_s *, int, int, char *const []); // 命令执行函数
const char *usage; // 简短帮助信息
const char *help; // 详细帮助信息
// 其他扩展字段(如命令分组、权限等)
};
命令的实际逻辑由 cmd
函数指针实现,run_command()
的最终目标就是找到这个函数并调用。
2. run_command()
的核心流程
run_command()
函数的主要作用是将输入的命令字符串(如 "bootm 0x80000000"
)解析为命令名和参数,查找对应的 cmd_tbl_t
结构体,并调用其 cmd
函数。其流程涉及以下关键函数:
(1)命令解析:parse_line()
- 作用:将原始命令字符串拆分为命令名和参数数组。
- 细节:处理空格分隔、引号包裹的参数(如
"setenv bootargs console=ttyS0,115200"
),返回参数数量和参数数组。
(2)命令查找:find_cmd()
- 作用:根据解析出的命令名,在命令列表中查找对应的
cmd_tbl_t
结构体。 - 实现:
- U-Boot 维护一个全局命令列表(通常通过链接脚本收集所有命令结构体)。
find_cmd()
遍历列表,通过字符串匹配找到与命令名对应的结构体。- 扩展:支持命令别名(如
boot
可能是bootm
的别名)和命令分组。
(3)权限检查(可选):cmd_permission_check()
- 作用:部分 U-Boot 版本支持命令权限控制(如安全启动场景),检查当前环境是否允许执行该命令。
(4)执行命令函数:cmd_tbl_t->cmd()
- 作用:调用命令结构体中定义的
cmd
函数,传入命令参数,执行实际逻辑。 - 示例:
bootm
命令对应do_bootm()
函数。printenv
命令对应do_printenv()
函数。- 函数原型为
int (*cmd)(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
,其中:cmdtp
:当前命令的结构体指针。flag
:执行标志(如后台执行、重定向等)。argc
:参数数量(含命令名)。argv
:参数数组。
(5)错误处理:cmd_process_error()
- 作用:处理命令执行返回的错误码(如参数错误、执行失败),输出对应的错误信息。
3. 关键辅助函数
run_command_list()
:批量执行多条命令(如脚本或环境变量中的命令序列,用分号分隔)。cmd_usage()
:当命令参数错误时,调用此函数打印命令的用法(usage
字段)。getenv()
/setenv()
:命令执行中可能涉及环境变量操作(如saveenv
命令调用saveenv()
)。
4. 示例流程:执行 printenv
命令
- 用户输入
printenv
,调用run_command("printenv", 0)
。 parse_line("printenv", argv, ARGC_MAX)
解析出argc=1
,argv[0]="printenv"
。find_cmd("printenv")
找到对应的cmd_tbl_t
结构体(name="printenv"
,cmd=do_printenv
)。- 调用
do_printenv(cmdtp, 0, 1, argv)
,执行打印环境变量的逻辑。 - 返回执行结果(0 表示成功,非 0 表示失败)。
总结
run_command()
是 U-Boot 命令系统的调度中心,其核心是通过 find_cmd()
关联命令名与执行函数,最终调用命令结构体中定义的 cmd
函数。整个流程涉及命令解析、查找、权限检查和执行,支撑了 U-Boot 中所有交互命令的运行。
一般有哪些命令需要执行呢
在 U-Boot 中,命令是与 bootloader 交互的主要方式,用于完成系统初始化、环境配置、启动引导等核心功能。根据功能分类,常用命令可分为以下几类:
二.常用命令
基础操作与信息查询命令
-
help
/?
- 功能:查看所有支持的命令或指定命令的帮助信息。
- 示例:
help bootm
显示bootm
命令的用法。
-
version
- 功能:打印 U-Boot 版本信息、编译时间、编译器版本等。
-
bdinfo
- 功能:显示板级信息(board info),如内存布局、CPU 型号、时钟频率等。
-
iminfo
- 功能:检查指定地址的镜像文件(如内核、设备树)是否有效,验证其头部信息和校验和。
- 示例:
iminfo 0x80000000
检查地址0x80000000
处的镜像。
环境变量操作命令
环境变量(environment variables)用于配置 U-Boot 行为(如启动参数、设备地址等),常用命令:
-
printenv
- 功能:打印所有环境变量或指定变量的值。
- 示例:
printenv bootargs
查看启动参数。
-
setenv
- 功能:设置或修改环境变量。
- 示例:
setenv bootargs console=ttyS0,115200
设置串口控制台参数。
-
saveenv
- 功能:将当前环境变量保存到持久化存储(如 Flash、EEPROM),避免重启后丢失。
-
env default -a
- 功能:恢复默认环境变量(清除自定义配置)。
内存操作命令
用于读写、测试内存(RAM),常用于调试或加载镜像:
-
md
(memory display)- 功能:从指定地址开始显示内存数据(十六进制和 ASCII 格式)。
- 示例:
md.b 0x80000000 100
以字节(b
)为单位显示0x80000000
开始的 256 字节(0x100
)。
-
mw
(memory write)- 功能:向指定内存地址写入数据。
- 示例:
mw.w 0x80000000 0x1234 10
以字(w
,2 字节)为单位,向0x80000000
写入 10 个0x1234
。
-
cp
(copy memory)- 功能:在内存地址间复制数据。
- 示例:
cp 0x80000000 0x81000000 0x1000
将0x80000000
开始的 4KB(0x1000
)数据复制到0x81000000
。
-
mtest
- 功能:内存测试,检测指定地址范围的 RAM 是否正常。
- 示例:
mtest 0x80000000 0x80100000
测试0x80000000
到0x80100000
之间的内存。
存储设备操作命令
用于访问 Flash、SD 卡、硬盘等存储设备,加载镜像或文件
-
mmc
- 功能:操作 MMC/SD 卡(如检测设备、分区、读写数据)。
- 子命令:
mmc list
(列出设备)、mmc read
(读数据到内存)、mmc write
(写内存数据到设备)。 - 示例:
mmc read 0x80000000 0x800 0x1000
从 MMC 设备 0 的扇区0x800
读取0x1000
个扇区到内存0x80000000
。
-
nand
- 功能:操作 NAND Flash(如擦除、读写、检测坏块)。
- 子命令:
nand erase
(擦除分区)、nand read
(读数据到内存)、nand write
(写数据到 Flash)。
-
fatload
/ext4load
- 功能:从 FAT/ext4 文件系统中加载文件到内存(需先识别存储设备)。
- 示例:
fatload mmc 0:1 0x80000000 uImage
从 MMC 设备 0 的第 1 个分区(FAT 格式)加载uImage
到内存0x80000000
。
-
sf
(SPI Flash)- 功能:操作 SPI Flash(如擦除、读写)。
- 示例:
sf read 0x80000000 0x100000 0x200000
从 SPI Flash 的0x100000
地址读取0x200000
字节到内存0x80000000
。
系统启动相关命令
用于引导内核或其他镜像启动,是 U-Boot 的核心功能:
-
bootm
(boot image)- 功能:启动内存中的多阶段镜像(如 uImage 格式的内核),支持传递设备树(DTB)。
- 示例:
bootm 0x80000000 - 0x81000000
从0x80000000
启动内核,使用0x81000000
地址的设备树。
-
bootz
(boot zImage)- 功能:启动压缩的 zImage 格式内核(无需解压,直接引导)。
-
bootefi
- 功能:启动 EFI(Extensible Firmware Interface)兼容的镜像(如 UEFI 应用、内核)。
-
bootcmd
- 功能:执行环境变量
bootcmd
中定义的启动脚本(通常是默认启动流程,如自动从存储设备加载并启动内核)。 - 示例:
run bootcmd
手动触发默认启动流程。
- 功能:执行环境变量
-
go
- 功能:直接跳转到指定内存地址执行代码(适用于裸机程序或无头部信息的镜像)。
- 示例:
go 0x80000000
从0x80000000
地址开始执行。
网络相关命令
用于通过网络下载镜像、调试或更新固件:
-
ping
- 功能:测试与目标 IP 的网络连通性。
- 示例:
ping 192.168.1.100
。
-
dhcp
- 功能:通过 DHCP 获取 IP 地址,并可自动加载指定镜像。
- 示例:
dhcp 0x80000000
从 DHCP 服务器获取 IP 并下载镜像到0x80000000
。
-
tftpboot
/ftpboot
- 功能:通过 TFTP/FTP 从服务器下载文件到内存。
- 示例:
tftpboot 0x80000000 192.168.1.100:uImage
从 TFTP 服务器下载uImage
到内存。
-
nfs
- 功能:通过 NFS(网络文件系统)挂载远程目录并加载文件。
其他常用命令
reset
:重启系统。poweroff
:关闭系统电源(需硬件支持)。fdt
:操作设备树(Device Tree),如修改节点属性(fdt set
)、查看节点(fdt get
)。loadb
/loads
:通过串口(kermit/xmodem 协议)接收文件到内存(常用于无网络 / 存储设备的调试场景)。
总结
U-Boot 命令覆盖了从基础配置到系统启动的全流程,核心目标是为内核启动准备环境(加载镜像、设置参数、初始化硬件)。实际使用中,最常用的命令包括环境变量操作(printenv
/setenv
)、存储设备读写(mmc
/fatload
)、内核启动(bootm
/bootz
)和网络下载(tftpboot
)。不同开发板可能会根据硬件特性扩展自定义命令(如特定外设控制)。