# uboot 命令

# 命令支持

当不清楚 uboot 支持什么命令时, 可输入 help? 可查看 uboot 支持的命令列表;当需要具体使用哪个命令时,可使用 help [命令]? [命令] 的方式查看具体命令的使用说明,eg: help printenv

具体可以使用什么命令,实际跟 uboot 中的 CONFIG_CMD_xxx 宏的使能有关,因此,如果无法使用某些命令,可能是因为把特定的 CONFIG_CMD_xxx 宏去掉了;而对于这些命令的开关,可以在 configs/xxx_defconfig 中定义,或者使用 make menuconfig 选择使能相应命令的支持。

# 常用命令行命令

A、环境变量操作

  1. printenv

    功能:打印环境变量。

    用法: printenv <name> ,其中 name 为相应的环境变量名,不填则打印所有环境变量配置。

  2. setenv

    功能:设置环境变量。

    用法: setenv <key> <value> ,其中 key 是变量名,value 是变量值。如果 value 为空,则表示删除对应的环境变量。

  3. saveenv

    功能:保存环境变量修改,使用 setenv 设置环境变量后不会掉电保存,需要保存后才不会丢失。

    用法: saveenv

  4. run

    功能:执行指定的环境变量里的语句。

    用法: run <var> ,其中 key 是指定的环境变量。

B、存储介质操作

  1. mmc & SD

    功能:对 mmc 存储介质进行操作,包括 EMMC 和 SD 卡。

    用法:

    • mmc list ,用于查看板子上 mmc 设备。
    • mmc dev <dev> <part> ,用于切换当前 mmc 设备,其中 dev 用来设置要切换的 mmc 设备号,part 是分区号(可以不写,默认为分区 0)。
    • mmc info ,查看当前 mmc 设备信息。
    • mmc part ,查看当前 mmc 设备分区。
    • mmc read / write <addr> <blk#> <cnt> ,读取 / 写入当前 mmc 设备数据,其中 addr 是数据写入 / 读取到 DRAM 中的地址 (十六进制), blk# 是要读取 / 写入到 emmc 的块起始地址 (十六进制),一个块是 512 字节,这里的块和扇区是一个意思,在 mmc 设备中我们通常说扇区, cnt 是要读取 / 写入的块数量 (十六进制)。
    • mmc erase <blk#> <cnt> ,擦除当前 mmc 设备数据,其中 blk# 为要擦除的起始块 (十六进制), cnt 是要擦除的数量 (十六进制)。
    • mmc rescan ,令用于扫描设备上所有的 mmc 设备,包括 EMMC 和 SD 卡。
  2. nand

    功能:对 nand flash 存储介质进行操作。

    用法:

    • nand info ,查看当前 nand flash 信息。
    • nand dev <dev> <part> ,用于切换当前 nand flash 设备,其中 dev 用来设置要切换的 nand 设备号,part 是分区号(可以不写,默认为分区 0)。
    • nand read / write <addr> <off> <size> ,读取 / 写入当前 nand flash 设备数据,其中 addr 是数据写入 / 读取到 DRAM 中的地址 (十六进制), off 是要读取 / 写入 nand flash 的起始地址 (十六进制),size 是要读取 / 写入的数据大小 (十六进制)。
    • mmc erase <addr> <size> ,擦除当前 nand flash 设备数据,其中 addr 为要擦除的起始地址 (十六进制), size 是要擦除的数据大小 (十六进制)。

C、网络操作

  1. ping

    功能:发送 ICMP_ECHO 请求到网络主机。

    用法: ping <hostaddr> ,其中 hostaddr 是目标发送请求主机 IP。

  2. dhcp

    功能:获取 ip 地址及通过 tftp 下载到内存。

    用法:

    • dhcp ,单纯用于自动获取 ip 地址。
    • dhcp <loadaddr> <[hostIPaddr:]filename> ,其中 loadaddr 是加载内存地址,hostIPaddr 是获取链接的主机 IP,filename 是要下载的文件名。
  3. nfs

    功能:通过 nfs (Network File System) 下载到内存。

    用法: nfs <loadaddr> <[hostIPaddr:]filename> ,其中 loadaddr 是加载内存地址,hostIPaddr 是获取链接的主机 ip,filename 是要下载的文件名。

  4. tftp / tftpboot

    功能:通过 tftp 下载到内存。

    用法: tftp / tftpboot <loadaddr> <[hostIPaddr:]filename> ,其中 loadaddr 是加载内存地址,hostIPaddr 是获取链接的主机 ip,filename 是要下载的文件名。

D、文件系统操作

  1. fatinfo

    功能:查询指定 mmc 设置指定分区的文件系统信息。

    用法: fatinfo <interface> <dev>:<part> ,其中 interface 表示接口(mmc 等),dev 是查询的设备号, part 是要查询的分区。

  2. fatls / ext4ls

    功能:查询 FAT /ext4 格式设备的目录和文件信息。

    用法: fatls / ext4ls <interface> <dev>:<part> <directory> ,其中 interface 表示接口(mmc 等),dev 是查询的设备号, part 是要查询的分区,directory 是要查询的目录(默认为根目录 / )。

  3. fatload / ext4load

    功能:查询 FAT /ext4 格式设备的目录和文件信息。

    用法: fatload / ext4load <interface> <dev>:<part> <addr> <filename> <bytes> <pos> ,其中 interface 表示接口(mmc 等),dev 是查询的设备号, part 是要查询的分区,addr 是保存在 DRAM 中的起始地址, filename 是要读取的文件名字,bytes 表示读取多少字节的数据(0 或者省略表示读取整个文件),pos 是要读的文件相对于文件首地址的偏移(0 或者省略表示从文件首地址开始读取)。

E、内存操作

  1. md

    功能:用于显示内存值。

    用法: md[.b, .w, .l] address [# of objects] ,其中,[.b, .w, .l] 对应 byte、word 和 long,也就是分别以 1 个字节、2 个字节、4 个字节来显示内存值。address 就是要查看的内存起始地址,[# of objects] 表示要查看的数据长度,这个数据长度单位不是字节,而是跟你所选择的显示格式有关;其数值皆为十六进制。

  2. nm

    功能:用于修改指定地址的内存值。

    用法: mw [.b, .w, .l] address value [count] ,同样以 [.b, .w, .l] 对应 byte、word 和 long,也就是分别以 1 个字节、2 个字节、4 个字节来指定操作格式,ddress 表示要填充的内存起始地址,value 为要填充的数据,count 是填充的长度(与选择的操作格式有关);其数值皆为十六进制。

  3. cp

    功能:用于将数据从一段内存拷贝到另一段内存中。

    用法: cp [.b, .w, .l] source target count ,[.b, .w, .l] 对应 byte、word 和 long 来指定操作格式,source 为源地址,target 为目的地址,count 为拷贝的长度(与选择的操作格式有关);其数值皆为十六进制。

  4. cmp

    功能:用于将数据从一段内存拷贝到另一段内存中。

    用法: cmp [.b, .w, .l] addr1 addr2 count ,[.b, .w, .l] 对应 byte、word 和 long 来指定操作格式,addr1 为第一段内存首地址,addr2 为第二段内存首地址,count 为要比较的长度(与选择的操作格式有关);其数值皆为十六进制。

F、启动内核

  1. bootz

    功能:从指定内存位置加载启动 zImage 镜像文件

    用法: bootm <zImageaddr> - <fdtaddr> ,其中,kerneladdr 是 zImage 镜像地址,fdtaddr 是设备树文件地址。

  2. bootm

    功能:从指定内存位置加载启动 uImage 镜像文件

    用法: bootm <uImageaddr> <- arg...> ,其中,kerneladdr 是 uImage 镜像地址,arg 是为可选子命令,具体可看 ? bootm

  3. boot

    功能:通过读取环境变量 bootcmd 来启动 linux 系统。

    用法: boot

G、other

  1. reset

    功能:重启 uboot。

  2. env default -a

    功能:获取默认 env 环境变量,即 include/env_default.hdefault_environment 数组中的变量。

  3. ls

    功能:查看当前 mmc 介质里的文件。eg: ls mmc 1:1 可以获取到设备 1 的分区 1 中存放着内核和设备树; ls mmc 1:2 可以获取到系统中的文件系统根目录所存在的文件及文件夹;如果 ls mmc 1:0 ,你会发现提示文件系统未知或错误,这是因为分区 0 存放的是 uboot,并且分区 0 没有格式化,所以文件系统格式未知。

# 环境变量

需要注意的是,环境变量的名字并不是统一的,除部分重要变量名外,主要是由芯片厂商或开发者自行协定的。

# 默认环境变量

默认环境变量可以在 include/configs/ 文件夹中找到对应的芯片配置头文件及在 include/env_default.h 文件中查看定义。一般其主要环境变量参数整体被定义在 CONFIG_EXTRA_ENV_SETTINGS 宏参数中,在 README 文件中可找到说明:

README
- Default Environment:
		CONFIG_EXTRA_ENV_SETTINGS
		Define this to contain any number of null terminated
		strings (variable = value pairs) that will be part of
		the default environment compiled into the boot image.
		For example, place something like this in your
		board's config file:
		#define CONFIG_EXTRA_ENV_SETTINGS \
			"myvar1=value1\0" \
			"myvar2=value2\0"
		Warning: This method is based on knowledge about the
		internal format how the environment is stored by the
		U-Boot code. This is NOT an official, exported
		interface! Although it is unlikely that this format
		will change soon, there is no guarantee either.
		You better know what you are doing here.
		Note: overly (ab)use of the default environment is
		discouraged. Make sure to check other ways to preset
		the environment like the "source" command or the
		boot command first.
		CONFIG_DELAY_ENVIRONMENT
		Normally the environment is loaded when the board is
		initialised so that it is available to U-Boot. This inhibits
		that so that the environment is not available until
		explicitly loaded later by U-Boot code. With CONFIG_OF_CONTROL
		this is instead controlled by the value of
		/config/load-environment.

# 常用环境变量

include/env_default.h 文件定义的环境变量,可通过读取宏来配置相应值,及从 CONFIG_EXTRA_ENV_SETTINGS 宏参数追加自定义环境变量,其中有几个变量是比较重要,这里结合 NXP 厂商的定义进行如下参考分析:

1、console 变量(固有)

功能:表示控制台输出设备。

2、baudrate 变量(固有)

功能:指定 linux 系统启动过程中串口控制台打印的波特率。

3、bootdelay 变量(固有)

功能:设置 uboot 启动时等待用户输入的延时,单位是秒。

4、fdt_addr 变量(私人)

功能:设备树加载启动的地址。

5、fdt_file 变量(私人)

功能:设备树加载显示的名称,如果 uboot 中配置的名称对应不上获取的设备树文件,将显示 undefined。

6、image 变量(私人)

功能:内核加载启动读取的文件名。

7、loadaddr 变量(固有)

功能:内核加载启动的地址。

8、ipaddr/serverip/gatewayip/netmask 变量(固有)

功能:用于设置网络信息,分别对应开发板 ip、服务器 ip、网关、子网掩码;设置完成后可用 ping 命令测试网络连通性。

9、bootcmd 变量(固有)

功能: bootcmd 变量是用来存储启动命令的环境变量,它定义了 uboot 启动 linux 系统的具体步骤。当 uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 linux 内核。

也可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值。

应用: bootcmd 变量的内容通常是一系列 uboot 命令和参数的组合,例如:

bootcmd=run load_kernel; run load_dtb; bootz ${kernel_addr_r} - ${fdt_addr_r}

上述 bootcmd 变量定义了两个命令: load_kernelload_dtb ,并最后执行了 bootz 命令来启动 linux 内核。这里的 run 命令表示执行一个之前定义好的环境变量,例如:

load_kernel=mmc dev ${mmc_dev}; fatload mmc ${mmc_dev}:${mmc_part} ${kernel_addr} zImage
load_dtb=fatload mmc ${mmc_dev}:${mmc_part} ${fdt_addr} devicetree.dtb

在上述命令中, load_kernelload_dtb 分别使用 fatload 命令从 mmc 设备 ${mmc_dev}${mmc_part} 分区( mmc ${mmc_dev}:${mmc_part} )中加载内核和设备树; ${kernel_addr}${fdt_addr} 是在 uboot 中预定义的环境变量,分别表示内核和设备树在内存中的地址。

在实际应用中, bootcmd 变量的内容需要根据硬件平台和具体应用场景来设置,以确保系统能够正确启动。可以使用 printenv bootcmd 命令来查看当前的 bootcmd 命令,使用 setenv bootcmd <cmd> 命令来手动设置 bootcmd 变量,例如,把上述命令定义并保存到 bootcmd 变量中:

setenv bootcmd 'run load_kernel; run load_dtb; run load_rootfs; bootm'
saveenv

10、bootargs 变量(固有)

功能: bootargs 变量是用来存储内核启动参数的环境变量,它在启动 linux 内核时会被传递给内核。bootargs 变量可以在 uboot 命令行中手动设置,也可以通过脚本自动设置。下面是一些常见的 bootargs 参数:

  • console:指定内核输出信息的终端设备,可以是串口、LCD 显示屏等。

  • root:指定根文件系统所在的设备和分区。

  • rootfstype:指定根文件系统的文件系统类型,例如 ext4jffs2nfs 等。

  • ip:指定 IP 地址和网络参数,用于网络启动。

  • mem:指定系统可用内存的大小,用于系统启动时内存的自适应分配。

  • quiet:设置内核启动时不显示冗长的信息。

  • debug:开启内核调试模式,用于调试内核代码。

应用:在设置 bootargs 变量时,需要根据硬件平台和具体应用场景来选择合适的参数,并确保参数的正确性。例如, console 参数需要根据硬件平台的串口地址和波特率来设置, root 参数需要根据具体的文件系统类型和分区来设置。例如:

setenv bootargs console=${console},${baudrate} root=${mmc_root}
saveenv

# 环境变量设置

环境变量的设置有两种方法,一种方法是通过修改静态配置,即通过修改 uboot 的文件中相关环境变量的配置。不过此类方法在实际中显然非常不实际,每次需要修改一次环境变量都需要重新编译整个 uboot。

另一种方法是利用 uboot 提供的 setenv 动态修改环境变量的设置,当设置完成后再通过 saveenv 把相应的环境变量设置保存到 Flash 等非易失性存储设备上。

在更改多次环境变量后,如果想恢复成 uboot 的文件中默认环境变量的配置,可以通过 env default -a 重新读取,最后通过 saveenv 保存。

uboot 的环境参数,在 uboot 启动过程中,会去校验 CRC 存放环境变量的一段空间,若 CRC 有效则使用该空间里的环境变量,无效则用默认的环境变量;因此在初次移植烧录 uboot 的时候,由于没有使用 saveenv 存储过,所以读不出 CRC 校验,而使用的默认环境变量(可通过 printenv 输出对比文件里环境变量的配置),同样的在信息打印中也会输出 *** Warning - bad CRC, using default environment

# 启动方式

uboot 有两种启动 linux 内核和 rootfs 的方法,一种是直接从 flash (nand 或 emmc) 启动,一种是从网络启动。这里面用到了两个非常重要的环境变量 bootcmdbootargs

# 从 EMMC 启动

从 EMMC 启动也就是将编译出来的 linux 镜像文件 zImage 和设备树文件保存在 EMMC 中, uboot 从 EMMC 中读取这两个文件并启动。

以 NXP 的 imx-6ull 为例:

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' # 设置控制台输出设备为 ttymxc0、波特率为 115200;指明根文件系统存放在 mmcblk1 设备的分区 2 中,EMMC 版本的核心板启动 linux 以后会存在 /dev/mmcblk0、/dev/mmcblk1、 /dev/mmcblk0p1、/dev/mmcblk0p2、 /dev/mmcblk1p1 和 /dev/mmcblk1p2 这样的文件,其中 /dev/mmcblkx (x=0~ n) 表示 mmc 设备,而 /dev/mmcblkxpy (x=0~ n,y=1~ n) 表示 mmc 设备 x 的分区 y;rootwait 表示等待 mmc 设备初始化完成以后再挂载,否则的话 mmc 设备还没初始化完成就挂载根文件系统会出错的,rw 表示根文件系统是可以读写的,不加 rw 的话可能无法在根文件系统中进行写操作,只能进行读操作。
mmc dev 1 # 切换到 EMMC
fatload mmc 1:1 0x80800000 zImage # 读取 zImage 到 0x80800000 处
fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb # 读取设备树到 0x83000000 处
bootz 0x80800000 - 0x83000000 # 启动内核

# 从网络启动

从网络启动最主要的是用来调试,试想,假设你更改了部分 linux kernel 驱动或 rootfs,如果是使用 EMMC 进行烧录下载,那么就得每次都对其镜像或文件系统烧写到 EMMC 中,这样就太麻烦,因此我们可以使用网络对其进行烧写替换。其前提条件是必须配置好网络设备及 uboot 设备树,能正常连通,否者一切都是扯淡。

以 NXP 的 imx-6ull 为例:

setenv ethaddr 8e:14:c8:bc:02:49
setenv ipaddr 192.168.1.2
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.100
setenv nfsroot /home/user/nfs_rootfs
setenv netargs setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=${serverip}:${nfsroot},proto=tcp rw ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}::eth0:off'
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000

note:网络获取设备树及镜像需要 tftp 服务的支持,网络挂载文件系统需要 nfs 服务的支持。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

夏沫の浅雨 微信支付

微信支付

夏沫の浅雨 支付宝

支付宝