title: U-Boot命令与使用 tags: [uboot, bootloader, embedded-linux, imx6ull, system-boot] created: 2026-09-17 updated: 2026-09-17
U-Boot(Universal Boot Loader)是一款遵循GPL协议的开源bootloader程序,广泛应用于嵌入式Linux系统启动。它本质上是一个裸机综合例程,可以看作是一个功能强大的裸机程序。
U-Boot的官网为 http://www.denx.de/wiki/U-Boot/,源码可通过FTP服务器下载。
Linux系统启动必须依赖bootloader程序。芯片上电后首先运行bootloader,其主要工作包括:
bootloader与Linux内核的关系类似PC上的BIOS与Windows的关系。
| 种类 | 描述 |
|---|---|
| 官方uboot | 由uboot官方维护开发,版本更新快,支持常用芯片 |
| 半导体厂商uboot | 半导体厂商维护,专门针对自家芯片,支持更全面 |
| 开发板厂商uboot | 开发板厂商在半导体厂商基础上加入自家开发板支持 |
实际使用中通常选择半导体厂商或开发板厂商的uboot。NXP维护的版本为2016.03,正点原子在其基础上进行了适配。
U-Boot 官方源码当前最新版本为2019.04,但一般不会直接使用官方源码。NXP(半导体厂商)维护的版本为2016.03,正点原子在此基础上适配了 I.MX6U-ALPHA 开发板(出厂系统由 NXP 官方编译器arm-poky-linux-gnueabi-gcc编译,本教程统一使用arm-linux-gnueabihf-gcc)。版本号可通过version命令查看:
U-Boot 2016.03-gd3f0479 (Aug 07 2020 - 20:47:37 +0800)
进入U-Boot命令行后,输入help或?可查看所有支持的命令。使用help 命令名查看具体用法。
# 查看所有命令
help
?
# 查看特定命令用法
help bootz
? bootz
bdinfo
输出包括:
# 查看所有环境变量
printenv
print
U-Boot支持TAB键自动补全功能,输入print后按TAB即可自动补全(直接输入print也可以)。
version
输出U-Boot版本号和编译时间。
# 修改环境变量
setenv bootdelay 5
saveenv
# 新建环境变量
setenv author zuozhongkai
saveenv
# 删除环境变量(赋空值)
setenv author
saveenv
# 修改包含空格的值(用单引号括起来)
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
setenv修改的是DRAM中的环境变量,修改后必须使用saveenv保存到Flash中,否则重启后会恢复原值。
保存时会显示存储设备信息:
内存命令直接对DRAM进行读写操作,所有数字均为十六进制。
md[.b, .w, .l] address [# of objects]
.b:字节显示.w:字(2字节)显示.l:长字(4字节)显示
# 以字节格式查看0x80000000开始的0x10个数据(16字节)
md.b 80000000 10
# 以字格式查看(16*2=32字节)
md.w 80000000 10
# 以长字格式查看(16*4=64字节)
md.l 80000000 10
注意:uboot命令中的数字都是十六进制的!十进制20应写为
14。
nm [.b, .w, .l] address
# 示例:修改0x80000000地址数据为0x12345678
nm.l 80000000
# 输入: 12345678
# 输入q退出
与nm类似,但修改后地址会自动递增。
# 以 .l 格式修改 0x80000000 起连续 3 个内存块(3*4=12 字节)
mm.l 80000000
# 输入05050505
# 输入05050505
# 输入05050505
# 输入q退出
mw [.b, .w, .l] address value [count]
# 以长字格式填充0x80000000开始的0x10个内存块为0x0A0A0A0A
mw.l 80000000 0A0A0A0A 10
cp [.b, .w, .l] source target count
# 将0x80000000处0x10个内存块拷贝到0x80000100
cp.l 80000000 80000100 10
cmp [.b, .w, .l] addr1 addr2 count
# 比较0x80000000和0x80000100处的0x10个内存块
cmp.l 80000000 80000100 10
使用网络命令前需设置网络环境变量:
setenv ipaddr 192.168.1.50
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.253
saveenv
ping 192.168.1.253
重要:只能在U-Boot中ping其他机器,其他机器不能ping U-Boot。
dhcp
DHCP会同时通过TFTP尝试启动Linux内核。
nfs [loadAddress] [[hostIPaddr:]bootfilename]
# 示例:下载zImage到0x80800000
nfs 80800000 192.168.1.253:/home/user/linux/nfs/zImage
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
# 示例:下载zImage(只需文件名,无需完整路径)
tftp 80800000 zImage
TFTP比NFS更简洁,不需要输入完整路径。
mmc info
# 或
mmcinfo
mmc list
mmc dev [dev] [part]
# 切换到SD卡
mmc dev 0
# 切换到EMMC分区0
mmc dev 1 0
# 切换到EMMC分区2
mmc dev 1 2
mmc read addr blk# cnt
# 从EMMC第0x600块读取0x10个块到0x80800000
mmc read 80800000 600 10
mmc write addr blk# cnt
# 将0x80800000处数据写入SD卡第2块开始的位置
mmc write 80800000 2 2E6
警告:千万不要写SD卡或EMMC的前两个块(扇区),里面保存着分区表!
mmc part
mmc rescan
mmc erase blk# cnt
警告:没事不要使用
mmc erase擦除 MMC 设备!
| 命令 | 描述 |
|---|---|
mmc hwpartition |
设置 MMC 设备的分区 |
mmc bootbus |
设置指定 MMC 设备的 BOOT_BUS_WIDTH 域的值 |
mmc bootpart |
设置指定 MMC 设备的 boot 和 RPMB 分区的大小 |
mmc partconf |
设置指定 MMC 设备的 PARTITION_CONFIG 域的值 |
mmc rst |
复位 MMC 设备 |
mmc setdsr |
设置 DSR 寄存器的值 |
SD 卡(742 块,即 0x2E6):
mmc dev 0 0 # 切换到 SD 卡分区 0
mmc write 80800000 2 2E6 # 从第 2 个扇区开始写 0x2E6 个块
EMMC(需要额外做分区配置):
mmc dev 1 0 # 切换到 EMMC 分区 0
tftp 80800000 u-boot.imx # 下载 u-boot.imx 到 DRAM
mmc write 80800000 2 32E # 烧写 u-boot.imx 到 EMMC 中
mmc partconf 1 1 0 0 # 分区配置,EMMC 需要这一步!
相关命令有fatinfo、fatls、fstype、fatload和fatwrite,仅支持FAT格式文件系统。
# fatinfo <interface> [<dev[:part]>] 查询文件系统信息
fatinfo mmc 1:1
# fatls <interface> [<dev[:part]>] [directory] 列出目录/文件
fatls mmc 1:1
# fstype <interface> <dev>:<part> 查看分区文件系统格式
fstype mmc 1:0
fstype mmc 1:1
fstype mmc 1:2
# fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
# bytes 为 0 或省略表示读整个文件,pos 为文件内偏移
fatload mmc 1:1 80800000 zImage
# fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>
# 需在板级配置头文件中使能 CONFIG_FAT_WRITE
fatwrite mmc 1:1 80800000 zImage 6788f8
U-Boot 支持ext2和ext4两种格式,常用命令有ext2load、ext2ls、ext4load、ext4ls和ext4write,含义和用法与 FAT 系列一致。EMMC 分区 2 为 ext4 格式,用于存放根文件系统(rootfs)。
# 列出 EMMC 分区 2(ext4)中的文件和目录
ext4ls mmc 1:2
# 读取文件到 DRAM(用法同 fatload)
ext4load mmc 1:2 <addr> <filename>
# 写入(用法同 fatwrite)
ext4write mmc 1:2 <addr> <filename> <bytes>
前提是使用 NAND 版本核心板并编译对应的 U-Boot。常用命令有nand info、nand device、nand erase、nand write、nand read,以及查看/操作设备树的fdt命令。
# 打印 NAND 信息(页大小、OOB、擦除大小等)
nand info
# nand erase[.spread] [clean] off size 从 off 开始擦除 size 区域
nand erase.part [clean] partition 擦除指定分区
nand erase.chip [clean] 全片擦除
# nand write addr off size 向 NAND 指定地址写数据
# nand read addr off size 从 NAND 指定地址读数据到 DRAM
I.MX6U-ALPHA 出厂系统 NAND 分区(共 6 个分区):
| 分区 | 地址范围 | 大小 | 内容 |
|---|---|---|---|
| boot | 0x000000~0x3FFFFF | 4MB | uboot |
| env | 0x400000~0x41FFFF | 128KB | 环境变量 |
| logo | 0x420000~0x51FFFF | 1MB | 启动图标 |
| dtb | 0x520000~0x61FFFF | 1MB | 设备树 |
| kernel | 0x620000~0xE1FFFF | 8MB | Linux 内核 |
| rootfs | 0xE20000~0x20000000 | 剩余 | 根文件系统 |
烧写 kernel 与 dtb 示例:
tftp 0x87800000 zImage
nand erase 0x620000 0x800000
nand write 0x87800000 0x620000 0x800000
tftp 0x87800000 imx6ull-14x14-emmc-7-1024x600-c.dtb
nand erase 0x520000 0x100000
nand write 0x87800000 0x520000 0x100000
注意:I.MX6ULL 要求 NAND 版 U-Boot 额外包含 BCB 和 DBBT,直接编译出的
u-boot.imx不能烧写到 NAND(需 mfgtool 用kogs-ng工具添加)。rootfs 太大,也不在 U-Boot 中更新,改用 Mfgtool 烧写。
读取设备树并用fdt查看:
nand read 0x83000000 0x520000 0x19000
fdt addr 83000000
fdt header
fdt print
bootz [addr [initrd[:size]] [fdt]]
# 示例:从网络启动
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
bootz 80800000 - 83000000
# 示例:从 EMMC 分区 1 启动
fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
bootz 80800000 - 83000000
bootm [addr [initrd[:size]] [fdt]]
读取bootcmd环境变量中的命令自动启动:
boot
# 复位重启
reset
# 跳转到指定地址执行(arg 为可选参数)
go addr [arg ...]
# 例:tftp 87800000 printf.bin; go 87800000(裸机程序链接首地址为 0x87800000)
tftp 87800000 printf.bin
go 87800000
# 运行环境变量中的命令
run bootcmd
# 内存读写测试
mtest [start [end [pattern [iterations]]]]
mtest 80000000 80001000
bootargs保存Linux内核启动参数,是最关键的环境变量之一:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
常用参数:
console=ttymxc0,115200:串口控制台配置root=/dev/mmcblk1p2:根文件系统设备rootwait:等待根设备就绪rw:以读写方式挂载若不设置
bootargs,启动内核时会报错:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0),原因是内核找不到根文件系统。
bootcmd保存自动启动时执行的命令集合:
# 从网络启动
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
saveenv
# 从EMMC启动
setenv bootcmd 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
saveenv
| 变量 | 说明 |
|---|---|
ipaddr |
开发板IP地址 |
ethaddr |
MAC地址(必须设置,且唯一) |
gatewayip |
网关地址 |
netmask |
子网掩码 |
serverip |
服务器IP(Ubuntu主机) |
# 定义不同启动方式
setenv mybootemmc 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
setenv mybootnand 'nand read 80800000 4000000 800000; nand read 83000000 6000000 100000; bootz 80800000 - 83000000'
setenv mybootnet 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
saveenv
# 使用run命令切换启动方式
run mybootemmc
run mybootnand
run mybootnet
控制启动倒计时时间,默认为3秒。修改方法:
setenv bootdelay 5
saveenv
在Ubuntu上安装TFTP服务:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
创建TFTP目录并设置权限:
mkdir ~/linux/tftpboot
chmod 777 ~/linux/tftpboot
配置/etc/xinetd.d/tftp:
server tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /home/user/linux/tftpboot/
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
配置/etc/default/tftpd-hpa:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/user/linux/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"
启动服务:
sudo service tftpd-hpa start
sudo service tftpd-hpa restart
NFS目录创建和权限设置:
mkdir ~/linux/nfs
chmod 777 ~/linux/nfs
完整网络启动流程:
# 设置网络环境变量
setenv ipaddr 192.168.1.50
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.253
saveenv
# 测试网络
ping 192.168.1.253
# 下载内核和设备树
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
# 启动
bootz 80800000 - 83000000
出现TFTP error: 'Permission denied'错误时:
chmod 777 /home/user/linux/tftpbootchmod 777 zImagesudo apt-get install libncurses5-devU-Boot 源码解压到 ~/linux/uboot/alientek_uboot:
tar -vxjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2
512MB(DDR3)+8GB(EMMC)核心板:
# 清理工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
# 配置(EMMC版本)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
# 编译
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
也可写成脚本 mx6ull_alientek_emmc.sh:
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
256MB(DDR3)+512MB(NAND)核心板配置文件为 mx6ull_14x14_ddr256_nand_defconfig,脚本名 mx6ull_alientek_nand.sh。
编译产物:u-boot.bin(二进制)和u-boot.imx(加头部后的最终镜像)。U-Boot 是裸机程序,需在前面加上 IVT、DCD 等头部才能在 I.MX6U 上执行,u-boot.imx 就是添加头部后的镜像,也是最终烧写的文件。
chmod 777 imxdownload
./imxdownload u-boot.bin /dev/sdd
注意:不能烧写到
/dev/sda或sda1!
Hit any key to stop autoboot:倒计时内按回车进入命令行U-Boot 2016.03-gd3f0479 (Aug 07 2020 - 20:47:37 +0800)
CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 51C
Reset cause: POR
Board: I.MX6U ALPHA|MINI
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Display: ATK-LCD-7-1024x600 (1024x600)
Video: 1024x600x24
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc1(part 0) is current device
Net: FEC1
Error: FEC1 address not set.
Normal Boot
Hit any key to stop autoboot: 0
=>
要点:CPU 为飞思卡尔 i.MX6ULL,主频 792MHz(此时运行在 396MHz),工业级结温 -40°C~105°C;FSL_SDHC:0 接 SD(TF) 卡,FSL_SDHC:1 接 EMMC;EMMC 版本默认以 EMMC 为存储器,故显示 switch to partitions #0 与 mmc1(part 0);FEC1 address not set 提示网卡 MAC 未设置。NAND 版本无 EMMC/SD 信息,显示 NAND 容量。
# 测试信息查询
bdinfo
printenv
version
# 测试内存操作
md.b 80800000 10
mw.l 80800000 0A0A0A0A 10
# 测试网络
ping 192.168.1.253
tftp 80800000 zImage
# 测试启动
bootz 80800000 - 83000000
⚠️ 来源说明:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。
| 特性 | IMX6ULL | STM32MP1 | RK3568 |
|---|---|---|---|
| 启动方式 | SD/EMMC/NAND | SD/MMC/NOR | SD/EMMC/NAND/SPI |
| 默认串口 | ttymxc0 | uart4 | ... |
| 内存地址 | 0x80000000 | 0xC0000000 | 0x00000000 |
| 内核加载地址 | 0x80800000 | 0xC2000000 | 0x00208000 |
| 设备树加载地址 | 0x83000000 | 0xC4000000 | 0x00F80000 |
| U-Boot版本 | 2016.03 | 2021.10 | 2017.09 |
| 交叉编译器 | arm-linux-gnueabihf | arm-ostl-linux-gnueabi | arm-linux-gnueabihf |
不同平台的U-Boot命令基本一致,但配置文件和默认环境变量有所不同:
mx6ull_*_defconfigstm32mp1_*_defconfigrk3568_*_defconfig⚠️ 来源说明:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识(答案基于书中事实整理)。
答:U-Boot是嵌入式系统的bootloader,主要作用是初始化硬件(DDR、串口等)、加载内核到内存并启动Linux。与PC BIOS的区别:
答:setenv修改的是DRAM中的环境变量,断电后丢失。saveenv将DRAM中的环境变量写入Flash(EMMC/SD/NAND),确保重启后仍然有效。正确流程是先setenv再saveenv。
答:因为U-Boot只实现了ping的发送功能,没有实现ICMP应答功能。U-Boot可以发送echo request,但不会响应其他机器的echo request,所以其他机器ping不通U-Boot。
答:
bootcmd:保存自动启动时执行的命令序列,如加载内核、设备树并启动bootargs:传递给Linux内核的启动参数,如控制台设备、根文件系统路径、挂载方式等答:通过mmc write命令实现:
tftp 80800000 u-boot.imx — 下载新U-Boot到DRAMmmc dev 0 0 — 切换到目标设备mmc write 80800000 2 2E6 — 写入(742 块,跳过前2个扇区的分区表;EMMC 用 mmc write 80800000 2 32E,还需 mmc partconf 1 1 0 0)内容来源: 《I.MX6U嵌入式Linux驱动开发指南》第30章 U-Boot使用实验