LV09-02-uboot-02-命令简介

本文主要是uboot——命令的基本使用的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
SecureCRT Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日
Linux开发板 华清远见 底板: FS4412_DEV_V5 核心板: FS4412 V2
u-boot 2013.01
点击查看本文参考资料
参考方向 参考原文
------
点击查看相关文件下载

一、几个常用命令

1. help

我们在SecureCRT终端输入help,便会打印出当前uboot所支持的所有命令。

点击查看相关命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
?       - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
dhcp - boot image via network using DHCP/TFTP protocol
echo - echo args to console
editenv - edit environment variable
emmc - Open/Close eMMC boot Partition
env - environment handling commands
erase - erase FLASH memory
exit - exit script
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fdisk - fdisk - fdisk for sd/mmc.

fdt - flattened device tree utility commands
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mmc - MMC sub system
mmcinfo - display MMC info
movi - movi - sd/mmc r/w sub system for SMDK board

mtest - simple RAM read/write test
mw - memory write (fill)
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
showvar - print local hushshell variables
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true - do nothing, successfully
version - print monitor, compiler and linker version

2. reset

reset命令可以用于重启开发板,我们直接在命令行输入reset即可:

1
2
fs4412 # reset   
resetting ...

3. loadb

loadb命令通过串口进行数据的传输,我们一般使用该命令进行二进制文件的传输,它使用的是kermit protocol传输协议,一般使用格式如下:

1
loadb [ off ] [ baud ]
  • off:其实就是数据要加载到内存中的起始地址,例如在fs4412开发板中,我们经常使用loadb 40008000来启动kermit的传输。
  • baud:传输的波特率,可以不写,默认为115200

例如,

1
fs4412 # loadb 40008000

然后按下enter按键便会等待数据的传输,我们可以直接将文件拖拽到SecureCRT终端界面中,然后选择发送Kermmit即可开启文件传输,将会有以下提示:

1
2
3
4
5
6
7
8
## Ready for binary (kermit) download to 0x40008000 at 115200 bps...

kermit trl+C ȡ
正在传输 interface.bin...
100% 104 104 /0:00:01 0

## Total Size = 0x00000068 = 104 Bytes
## Start Addr = 0x40008000

4. go

go命令用于跳到指定的地址处执行应用,命令格式如下:

1
go addr [arg ...]
  • addr:是应用在DRAM中的首地址

我们上一步使用loadb命令将interface.bin文件下载到了0X40008000,现在我们使用go命令启动interface.bin这个应用,命令如下:

1
2
fs4412 # go 40008000
## Starting application at 0x40008000 ...

5. run

run命令用于运行环境变量中定义的命令,比如可以通过run bootcmd来运行 bootcmd中的启动命令,但是run命令最大的作用在于运行我们自定义的环境变量。在后面调试Linux系统的时候可能常常要在网络启动和EMMC/NAND启动之间来回切换,而bootcmd只能保存一种启动方式,如果要换另外一种启动方式的话就得重写bootcmd,会很麻烦。这里我们就可以通过自定义环境变量来实现不同的启动方式,比如定义环境变量mybootemmc表示从emmc启动,定义mybootnet表示从网络启动,定义mybootnand表示从NAND启动。如果要切换启动方式的话只需要运行run mybootxxx(xxxemmcnetnand)即可。一般命令格式如下:

1
run var [...]
  • var:表示需要运行的定义了命令的环境变量名。

6. mtest

mtest命令是一个简单的内存读写测试命令,可以用来测试自己开发板上的DDR,一般命令格式如下:

1
mtest [start [end [pattern [iterations]]]]
  • start:要测试的DRAM开始地址。
  • end:是结束地址。

【注意】如果要结束测试就按下键盘上的Ctrl + C键。

二、信息查询

1. printenv

该命令主要用于打印出所有的环境变量信息,我们在SecureCRT终端中直接执行下边的命令,便可以得到该命令的使用格式:

1
2
3
4
5
6
7
8
fs4412 # ? printenv
printenv - print environment variables

Usage:
printenv [-a]
- print [all] values of all environment variables
printenv name ...
- print value of environment variable 'name

该命令使用方式很简单,我们直接在命令行输入:

1
fs4412 # printenv

然后我们会得到以下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
baudrate=115200
baudrate=115200
bootargs=root=/dev/nfs nfsroot=192.168.10.101:/home/hk/4nfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.10.102
bootcmd=tftp 0x41000000 /fs4412/uImage;tftp 0x42000000 /fs4412/exynos4412-fs4412.dtb;bootm 0x41000000 - 0x42000000
bootdelay=3
ethact=dm9000
ethaddr=11:22:33:44:55:66
fileaddr=41000000
filesize=26D213
gatewayip=192.168.10.1
ipaddr=192.168.10.102
netmask=255.255.252.0
serverip=192.168.10.101
stderr=serial
stdin=serial
stdout=serial

Environment size: 498/16380 bytes

2. bdinfo

bdinfo命令,此命令用于查看板子信息,直接输入bdinfo即可,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fs4412 # bdinfo
arch_number = 0x00000D7F
boot_params = 0x40000100
DRAM bank = 0x00000000
-> start = 0x40000000
-> size = 0x10000000
DRAM bank = 0x00000001
-> start = 0x50000000
-> size = 0x10000000
DRAM bank = 0x00000002
-> start = 0x60000000
-> size = 0x10000000
DRAM bank = 0x00000003
-> start = 0x70000000
-> size = 0x10000000
ethaddr = 11:22:33:44:55:66
ip_addr = 192.168.10.102
baudrate = 115200 bps
TLB addr = 0x7FFF0000
relocaddr = 0x7FE8A000
reloc off = 0x3C08A000
irq_sp = 0x7FD81F48
sp start = 0x7FD81F38
FB base = 0x00000000

3. version

version用于查看 uboot的版本号,直接输入version即可:

1
2
3
4
5
fs4412 # version

U-Boot 2013.01 (Apr 11 2020 - 04:15:49) for fs4412
arm-none-linux-gnueabi-gcc (crosstool-NG hg+default-2685dfa9de14 - tc0002) 4.6.4
GNU ld (crosstool-NG hg+default-2685dfa9de14 - tc0002) 2.23.1

三、环境变量

上边我们通过printenv打印出来的信息中有很多的环境变量,比如 baudratebootcmd等等。uboot中的环境变量都是字符串,既然叫做环境变量,那么它的作用就和变量一样。比如bootdelay这个环境变量就表示 uboot 启动延时时间,默认 bootdelay=3,也就默认延时 3 秒。前面说的 3 秒倒计时就是由 bootdelay 定 义的,如果将 bootdelay 改为5的话就会倒计时 5s了。 。

1. setenv

该命令主要用于操作环境变量,我们在SecureCRT中查看一下该命令使用格式:

1
2
3
4
5
6
7
8
fs4412 # ? setenv
setenv - set environment variables

Usage:
setenv [-f] name value ...
- [forcibly] set environment variable 'name' to 'value ...'
setenv [-f] name
- [forcibly] delete environment variable 'name'

【注意】此命令修改完后,开发板若重启,那么所有环境变量将会复原。

1.1 修改环境变量

环境变量是可以修改的,例如我们想修改一下uboot启动linux倒计时,这个时间是由bootdelay环境变量来控制的,我们上边是5秒,我们可以通过以下命令更改秒数,例如,

1
fs4412 # setenv bootdelay 3

这样便可以将bootdelay修改为3秒。

1.2 创建环境变量

我们也可以通过该命令创建新的环境变量:

1
fs4412 # setenv name value

例如,

1
2
3
fs4412 # setenv aaa ccc
fs4412 # print aaa
aaa=ccc

1.3 删除环境变量

我们创建了不想要的环境变量怎么办呢?有创建肯定有删除,该命令同样也可以删除环境变量,去掉后边的值,就可以将一个已经存在的环境变量删除:

1
fs4412 # setenv name

例如,

1
2
3
fs4412 # setenv aaa    
fs4412 # print aaa
## Error: "aaa" not defined

删除后,我们打印一个不存在测环境变量便会出错。

2. saveenv

前边的环境变量我们修改后,只在此次使用有效,当开发板关机时,修改过的环境变量全部会失效,那如何保存下来,让这些修改过的环境变量后边也依然可以生效呢?我们可以使用saveenv命令。

1
2
3
fs4412 # saveenv
Saving Environment to MMC...
Writing to MMC(0)... .done

这样我们修改过的环境变量就会被保存到eMMC,下一次开发板重新启动,环境变量还会是我们修改后的值。

四、内存操作

1. md

md命令用于显示内存值,格式如下:

1
md[.b, .w, .l] address [# of objects]
  • [.b .w .l]:对应 bytewordlong,也就是分别以 1个字节 、 2个字节、 4个字节。
  • address:要查看的内存起始地址。
  • [# of objects]:表示要查看的数据长度,这个数据长度单位不是字节,而是跟我们所选择的显示格式有关。比如我们设置要查看的内存长度 为20(十六进制为 0x14),如果显示格式为 .b 的话那就表示20个字节;如果显示格式为.w的话就表示 20word,也就是 20*2=40个字节;如果显示格式为 .l的话就表示 20long,也就是20*4=80个字节。

【注意】uboot命令中的数字都是十六进制的,不是十进制的!命令里面的数字都是十六进制的,所以可以不用写0x前缀,十进制
20其十六进制为 0x14,所以命令 md后面的个数应该是 14,如果写成 20的话就表示查看32(十六进制为 0x20)个字节的数据。

2. nm

nm命令用于修改指定地址的内存值,命令格式如下:

1
nm[.b, .w, .l] address

nm命令同样可以以 .b .w.l来指定操作格式。例如,我们现在要以.l格式修改0x40008000地址处数据为12345678,我们输入以下命令:

1
2
fs4412 # nm.l 40008000 
40008000: e8bd84f0 ?

其中40008000表示现在要修改的内存地址, e8bd84f0表示地址40008000现在的数据,?后面就可以输入要修改后的数据0x12345678,输入完成以后按下回车:

1
2
40008000: e8bd84f0 ? 12345678
40008000: 12345678 ?

这样我们便修改了相应的数据,然后输入q再按下回车就可以退出了

1
40008000: 12345678 ? q

3. mm

mm命令也是修改指定地址内存值的,使用 mm修改内存值的时候地址会自增,而使用命令nm的话地址不会自增。使用格式如下:

1
mm[.b, .w, .l] address

使用方式与nm一致,只不过它的地址会自己增加,例如

1
2
3
4
5
6
7
8
9
fs4412 # mm.l 40008000
40008000: 12345678 ? 11111111
40008004: e92d41f0 ? 22222222
40008008: e1a04000 ? 33333333
4000800c: e1a05001 ? q
fs4412 # nm.l 40008000
40008000: 11111111 ? 44444444
40008000: 44444444 ? 55555555
40008000: 55555555 ? q

4. mw

mw用于使用一个指定的数据填充一段内存,命令格式如下:

1
mw[.b, .w, .l] address value [count]
  • [.b .w .l]:对应 bytewordlong,也就是分别以 1个字节 、 2个字节、 4个字节。
  • address:要查看的内存起始地址。
  • value:为要填充的数据。
  • count:填充的长度。

例如,

1
2
3
fs4412 # mw.l 40008000 12345678 4
fs4412 # md.l 40008000 4
40008000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4.

5. cp

cp是数据拷贝命令,用于将 DRAM中的数据从一段内存拷贝到另一段内存中,或者把 Nor Flash中的数据拷贝到 DRAM中。命令格式如下:

1
cp[.b, .w, .l] source target count
  • [.b .w .l]:对应 bytewordlong,也就是分别以 1个字节 、 2个字节、 4个字节。
  • source:源地址。
  • target:目的地址。
  • count:为拷贝的长度。

例如,

1
2
3
4
5
6
7
fs4412 # cp.l 40008000 41000000 5
fs4412 # md.l 41000000 5
41000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4.
41000010: e1a07002 .p..
fs4412 # md.l 40008000 5
40008000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4.
40008010: e1a07002 .p..

6. cmp

cmp是比较命令,用于比较两段内存的数据是否相等,命令格式如下:

1
cmp[.b, .w, .l] addr1 addr2 count
  • [.b .w .l]:对应 bytewordlong,也就是分别以 1个字节 、 2个字节、 4个字节。
  • addr1:第一段内存首地址。
  • addr1:第二段内存首地址。
  • count:为要比较的长度。

五、存储器访问

关于存储器的访问主要是mmc命令,我们使用help mmc来查看它的帮助信息:

1
2
3
4
5
6
7
8
9
10
mmc - MMC sub system

Usage:
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] [bootable]- show or set current mmc device [partition] [bootable]
mmc list - lists available devices

但是还有一个mmcinfo的命令,在目前使用的这个版本uboot中似乎并不被列在mmc的命令中。

1. mmcinfo

mmcinfo命令用于查看当前设备的mmc信息,直接输入命令即可,例如:

1
2
3
4
5
6
7
8
9
10
11
12
fs4412 # mmcinfo
FAIL: waiting for status update.
Device: S5P_MSHC4
Manufacturer ID: 15
OEM: 100
Name: 8GTF4
Tran Speed: 0
Rd Block Len: 512
MMC version 4.0
High Capacity: Yes
Capacity: 14.6 MiB
Bus Width: 2-bit

2. mmc rescan

mmc rescan命令用于扫描当前开发板上所有的 MMC设备,包括 EMMCSD卡,直接输入mmc rescan即可。

3. mmc list

mmc list命令用于来查看当前开发板一共有几个MMC设备,直接输入mmc list即可,例如:

1
2
fs4412 # mmc list
S5P_MSHC4_dev0

4. mmc dev

mmc dev命令用于切换当前MMC设备,一般使用格式如下:

1
mmc dev [dev] [part]
  • dev:设置要切换的 MMC设备号。
  • part:分区号,如果不写分区号的话默认为分区 0

5. mmc part

有时候 SD卡或者 EMMC会有多个分区,可以使用命令mmc part来查看其分区,直接输入命令即可:

1
mmc part

6. mmc read

mmc read命令用于将MMC中指定扇区中的内容读取到内存中指定的地址,命令格式如下:

1
mmc read <dev_num> addr blk# cnt
  • dev_nummmc的设备号,可以通过mmc list查询到,这个参数可以不写,不写的话默认为当前mmc设备。
  • addr:数据读取到内存中的起始地址。
  • blk#:要读取的块起始地址 (十六进制 ),一个块是 512字节,这里的块和扇区是一个意思,在 MMC设备中我们通常说扇区。
  • cnt:要读取的块数量 (十六进制 )。

例如,

1
mmc read 0 0x40008000 0x600 0x10

这个命令的含义就是,把第0mmc设备块偏移为0x600处开始,长度为16x512大小的数据,读出到内存0x40008000处。

7. mmc write

mmc write命令用于将数据写到MMC设备里面。我们可以使用命令mmc write来 升级 uboot,也就是在 uboot中更新 uboot。这里会要用到nfs或者 tftp命令,通过nfs或者tftp命令将新的 u-boot.bin下载到开发板的DRAM中,然后再使用命令mmc write将其写入到MMC设备中。一般使用格式如下:

1
mmc write <dev_num> addr blk# cnt
  • dev_nummmc的设备号,可以通过mmc list查询到,这个参数可以不写,不写的话默认为当前mmc设备。
  • addr:数据将要写入到内存中的起始地址。
  • blk#:要写入的块起始地址 (十六进制 ),一个块是 512字节,这里的块和扇区是一个意思,在 MMC设备中我们通常说扇区。
  • cnt:要写入的块数量 (十六进制 )。

【注意】千万不要写 SD卡或者EMMC的前两个块 (扇区 ),里面保存着分区表。

例如,

1
mmc write 0 0x40008000 0x600 0x10

这个命令的含义就是,把内存0x40008000开始,长度为16x512大小的数据,写入到第0mmc设备块偏移位置为0x600处。

8. mmc erase

mmc erase命令用于擦除MMC设备的指定块,一般使用格式如下:

1
mmc erase blk# cnt
  • blk#:要擦除的起始块。
  • cnt:要擦除的数量。

【注意】一般不要用 mmc erase来擦除 MMC设备。

六、网络操作

uboot中,至少支持的外设就是串口和网口,因为我们需要通过这两个外设进行文件的传输,下边我们先来学习一下网络操作相关命令吧。

1. 网络环境变量

要使用网络的话,还是需要先设置一下网络的相关环境变量。相关的环境变量如下:

环境变量描述
ipaddr开发板 IP 地址,可以不设置,使用 dhcp 命令来从路由器获取 IP 地址。
ethaddr开发板的 MAC 地址,一定要设置。
gatewayip网关地址。
netmask子网掩码。
serverip服务器IP地址,也就是 Ubuntu主机 IP 地址,用于调试代码。

要注意,开发板的IP一定要与Ubuntu主机的IP处于网段,这样才能实现网络通信。我的一般设置如下:

1
2
3
4
5
6
7
8
9
fs4412 # setenv ipaddr 192.168.10.102
fs4412 # setenv ethaddr 11:22:33:44:55:66
fs4412 # setenv gatewayip 192.168.10.1
fs4412 # setenv netmask 255.255.255.0
fs4412 # setenv serverip 192.168.10.101

# 最后再保存一下环境变量到 mmc
fs4412 # saveenv

2. ping

我们的开发板的网络能否使用,是否可以和服务器 (Ubuntu主机 )进行通信,可以通过ping命令验证,直接ping服务器的IP地址即可,比如我的服务器IP地址为 192.168.10.101,那么命令格式如下:

1
fs4412 # ping 192.168.10.101

如果连接成功的话,会有以下信息提示:

1
2
3
4
5
6
dm9000 i/o: 0x5000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 11:22:33:44:55:66
operating at 100M full duplex mode
Using dm9000 device
host 192.168.10.101 is alive

如果连接不成功(服务器没开启或者说IP不在同一网段的话),可能会有以下提示:

1
2
3
4
5
6
dm9000 i/o: 0x5000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 11:22:33:44:55:66
operating at 100M full duplex mode
Using dm9000 device
ping failed; host 192.168.10.101 is not alive

【注意】只能在 ubootping其他的机器,其他机器不能 ping uboot,因为 uboot没有对 ping命令做处理,如果用其他的机器 ping uboot的话会失败!

3. dhcp

dhcp用于从路由器获取IP地址,前提得开发板连接到路由器上的,如果开发板是和电脑直连的,那么dhcp命令就会失效。直接输入dhcp命令即可通过路由器获取到IP地址。

4. tftp

tftp命令用于通过网络下载数据到指定的内存地址中,tftp命令使用的是TFTP协议,Ubuntu主机作为TFTP服务器。因此需要在 Ubuntu上搭建TFTP服务器,之前的时候我们已经搭建并本地验证过了,在uboot中使用的格式如下:

1
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
  • tftpboot:命令的全称,但是其实我们输入一个tftp就足够了。
  • loadAddress:是文件在内存中的存放地址。
  • hostIPaddr:服务器的IP地址,实际就是Ubuntu主机的IP地址,如果说前边我们设置了serverip环境变量的话,这里是可以省略的。
  • bootfilename:是要从Ubuntu中下载的文件这个文件是以服务器中tftp目录为根目录的。

例如,我们前边设置的tftp目录为/home/hk/3tftp,然后我们需要下载这个文件:

1
/home/hk/3tftp/fs4412/interface.bin

这个时候我们使用的命令如下:

1
2
3
4
5
fs4412 # tftp 40008000 /fs4412/interface.bin

# 或者

fs4412 # tftp 40008000 192.168.10.101:/fs4412/interface.bin

按下enter按键之后,我们会得到以下提示:

1
2
3
4
5
6
7
8
9
10
11
12
dm9000 i/o: 0x5000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 11:22:33:44:55:66
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.10.101; our IP address is 192.168.10.102
Filename '/fs4412/interface.bin'.
Load address: 0x40008000
Loading: T #
0 Bytes/s
done
Bytes transferred = 104 (68 hex)

这个时候我们可以使用go命令运行一下程序,来看看测试程序是否确实下载到了0x40008000处:

1
go 40008000

然后我们会看到开发板的led灯开始闪烁,这就说明我们已经成功下载了我们的应用程序到内存中。

七、文件系统操作

1. FAT格式文件系统

1.1 fatinfo

fatinfo命令用于查询指定MMC设备分区的文件系统信息,格式如下:

1
fatinfo <interface> [<dev[:part]>]
  • interface:表示接口,比如mmc
  • dev:查询的设备号。
  • part:要查询的分区。

例如,我们要查询设备0MMC分区1的文件系统信息,命令如下:

1
fatinfo mmc 0:1

1.2 fatls

fatls命令用于查询FAT格式设备的目录和文件信息,格式如下:

1
fatls <interface> [<dev[:part]>] [directory]
  • interface:表示接口,比如mmc
  • dev:查询的设备号。
  • part:要查询的分区。
  • directory:是要查询的目录。

例如,我们要查询设备0MMC分区1的所有目录和文件,命令如下:

1
fatls mmc 0:1

1.3 fatload

fatload命令用于将指定的文件读取到内存中,命令格式如下:,格式如下:

1
fatload <interface> [<dev[:part]>]  <addr> <filename> [bytes [pos]]
  • interface:表示接口,比如mmc
  • dev:设备号。
  • part:分区。
  • addr:要保存到内存中的起始地址。
  • filename:要读取的文件名字。
  • bytes:表示读取多少字节的数据,如果bytes0或者省略的话表示读取整个文件。
  • pos:是要读的文件相对于文件首地址的偏移,如果为0或者省略的话表示从文件首地址开始读取。

例如,我们将设备0的分区1中的zImage文件读取到内存中的0X40008000地址处,命令如下:

1
fatload mmc 0:1 40008000 zImage

2. EXT格式文件系统

由于这里使用的是uboot 2013版本的,这里的一些命令似乎并不怎么支持,后边用的也很少,这里就不写了,后边用到了再补充。

八、boot操作

1. 两个环境变量

1.1 boodcmd

bootcmd环境变量中保存着uboot的默认命令,该环境变量其实也叫做自启动环境变量。在我们重启开发板的时候,会有这么一个提示信息:

1
Hit any key to stop autoboot : 3

这里就是uboot倒计时,这里的这个时间由环境变量bootdelay控制,当倒计时结束之前按下任意按键,就会进入uboot的一个命令行的模式,着大盖就类似于我们重装windows系统时的BIOS系统一样。

当我们在倒计时期间没有按下任何按键的话,倒计时结束以后就会执行bootcmd中的命令。这些命令一般用来启动linu内核,比如读取EMMC或者NAND Flash中的linux内核镜像文件和设备树文件到DRAM中,然后启动linux内核。可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值,板子第一次运行 uboot 的时候都会使用默认值来设置 bootcmd 环境变量。

需要注意的是该环境变量中可以有多条命令,多条命令之间用\;分隔开,修改完后我们需要将环境变量进行保存,否则下次重启,我们设置的环境变量就会失效,另外,我们可以通过run命令来运行这个环境变量中的命令。例如,

1
2
3
fs4412 # setenv bootcmd tftp 40008000 interface.bin\;go 40008000
fs4412 # saveenv
fs4412 # run bootcmd

1.2 bootargs

bootargs 保存着 uboot 传递给 Linux 内核的参数,也被叫做自启动参数,uboot不需要使用。例如,

1
setenv bootargs root=/dev/nfs nfsroot=<server_ip>:<server_nfs_dir_path> rw console=ttySAC2,115200 init=/linuxrc ip=linux_ip
  • console
    console 用来设置 linux 终端(或者叫控制台),也就是开发板安装好linux后,我们通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕?如果是串口的话串口号是多少等。这里设置 consolettySAC2ttySAC2 后面有个,115200,这是设置串口的波特率,console=ttySAC2,115200 综合起来就是设置 ttySAC2作为 Linux 的终端,并且串口波特率设置为 115200
  • root
    root用来设置根文件系统的位置,例如
1
root=/dev/mmcblk[dev_num]p[cnt]

这就表示 mmc 设备 dev_num (从0开始)的分区 cnt(从0开始)。我们有时候也会使用上边例子中的方式:

1
root=/dev/nfs nfsroot=<server_ip>:<server_nfs_dir_path>

这指明了根文件系统类型(nfs),后边的nfsroot表示网络文件系统路径,可以挂载一个ubuntu服务器的nfs共享文件夹。

【注意】在root参数中,还会有一个rw,这就表示根文件系统是可以读写的,不加 rw 的话可能无法在根文件系统中进行写操作,只能进行读操作。

  • init

init用来指定init进程的程序路径,一般init=/linuxrc, 或者init=/etc/preinitpreinit的内容一般是创建consolenull设备节点,运行init程序,挂载一些文件系统等操作。我们可能以为init=/linuxrc是固定写法,其实不然,/linuxrc指的是/目录下面的linuxrc脚本,一般指向busybox

  • ip

这就表示linux启动后自身的IP地址。

2. bootm

要启动Linux,需要先将Linux镜像文件拷贝到DRAM中,如果使用到设备树的话,也需要将设备树拷贝到DRAM中。可以从 EMMC或者NAND等存储设备中将Linux镜像和设备树文件拷贝到DRAM,也可以通过nfs或者tftpLinux镜像文件和设备树文件下载到DRAM中。
不管用那种方法,只要能将Linux镜像和设备树文件存到DRAM中就行,然后使用boom命令来启动,boom命令用于启动linux镜像文件, boom命令格式如下:

1
bootm [addr [arg ...]]
  • addrlinux镜像在DRAM中的首地址。
  • arg:可以是一个initrd映像的地址,当引导一个需要设备树的Linux内核时,需要第三个参数,它是设备树的地址。要在不使用initrd镜像的情况下引导内核,我们需要使用-作为第二个参数。

其实有的资料中,该命令格式是这样的,我感觉更加详细一点:

1
bootm [addr [initrd[:size]] [fdt]]
  • addr:是 Linux镜像文件在DRAM中的位置,
  • initrd:是 initrd文件在DRAM中的地址,如果不使用 initrd的话使用-代替即可 。
  • fdt:就是设备树文件在 DRAM 中的地址。

或者直接这样写可能更清晰一点:

1
bootm kernel-addr ramdisk-addr dtb-addr
  • kernel-addr: 内核的下载地址 。
  • ramdisk-addr: 根文件系统的下载地址。
  • dtb-addr: 设备树的下载地址。

【注意】若不使用相应的地址,对应的位置写-