2. Uboot的介绍

2.1. uboot简介

uboot是从FADSROM、8xxROM、PPCBOOT逐步发展演化而来的。uboot发展至今,已经可以实现非常多的功能, 在操作系统方面,它不仅支持嵌入式Linux系统的引导,还支持NetBSD,VxWorks, QNX, RTEMS, ARTOS, LynxOS, Android等嵌入式操作系统的引导。在CPU架构方面, uboot支持PowerPC、MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。

一般来说BootLoader必须提供系统上电时的初始化代码,在系统上电时初始化相关环境后, BootLoader需要引导完整的操作系统,然后将控制器交给操作系统。 简单来说BootLoader是一段小程序,它在系统上电时执行,通过这段小程序可以将硬件 设备进行初始化,如CPU、SDRAM、Flash、串口、网络等,初始化完毕后调用操作系统内核。

2.2. 启动uboot

以野火imx6ull buildroot系统的2020.10版本uboot为例,介绍uboot的使用, 在开发板上电uboot启动kernel之前快速按下键盘的空格或回车键, 进入uboot的命令模式。如下所示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
U-Boot 2020.10-g3d21e4d4 (Feb 25 2025 - 03:46:41 +0000)

CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 36C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth1: ethernet@20b4000 [PRIME]Could not get PHY for FEC0: addr 2

Hit any key to stop autoboot:  0
=>

可以看出uboot打印出了板子的一些基本信息,包括CPU、内存等信息。

2.3. uboot命令

当不清楚uboot支持什么命令时, 可输入 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
=> help

  ?         - alias for 'help'
  base      - print or set address offset
  bdinfo    - print Board Info structure
  blkcache  - block cache diagnostics and control
  bmode     - sd1|sd2|qspi1|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4
  bmode - getprisec
  boot      - boot default, i.e., run 'bootcmd'
  bootd     - boot default, i.e., run 'bootcmd'
  bootefi   - Boots an EFI payload from memory
  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
  bootz     - boot Linux zImage image from memory
  clocks    - display clocks
  cmp       - memory compare
  coninfo   - print console devices and information
  cp        - memory copy
  crc32     - checksum calculation
  dcache    - enable or disable data cache
  dhcp      - boot image via network using DHCP/TFTP protocol
  dm        - Driver model low level access
  dtfile    - dtoverlay utility commands
  echo      - echo args to console
  editenv   - edit environment variable
  env       - environment handling commands
  erase     - erase FLASH memory
  exit      - exit script
  ext2load  - load binary file from a Ext2 filesystem
  ext2ls    - list files in a directory (default /)
  ext4load  - load binary file from a Ext4 filesystem
  ext4ls    - list files in a directory (default /)
  ext4size  - determine a file's size
  ext4write - create a file in the root directory
  false     - do nothing, unsuccessfully
  fatinfo   - print information about filesystem
  fatload   - load binary file from a dos filesystem
  fatls     - list files in a directory (default /)
  fatmkdir  - create a directory
  fatrm     - delete a file
  fatsize   - determine a file's size
  fatwrite  - write file into a dos filesystem
  fdt       - flattened device tree utility commands
  flinfo    - print FLASH memory information
  fstype    - Look up a filesystem type
  fstypes   - List supported filesystem types
  fuse      - Fuse sub-system
  go        - start application at address 'addr'
  gpio      - query and control gpio pins
  help      - print command description/usage
  i2c       - I2C sub-system
  icache    - enable or disable instruction cache
  iminfo    - print header information for application image
  imxtract  - extract a part of a multi-image
  itest     - return true/false on integer compare
  ln        - Create a symbolic link
  load      - load binary file from a filesystem
  loadb     - load binary file over serial line (kermit mode)
  loads     - load S-Record file over serial line
  loadx     - load binary file over serial line (xmodem mode)
  loady     - load binary file over serial line (ymodem mode)
  loop      - infinite loop on address range
  ls        - list files in a directory (default /)
  md        - memory display
  mm        - memory modify (auto-incrementing address)
  mmc       - MMC sub system
  mmcinfo   - display MMC info
  mtest     - simple RAM read/write test
  mw        - memory write (fill)
  nfs       - boot image via network using NFS protocol
  nm        - memory modify (constant address)
  panic     - Panic with optional message
  ping      - send ICMP ECHO_REQUEST to network host
  pinmux    - show pin-controller muxing
  printenv  - print environment variables
  protect   - enable or disable FLASH write protection
  random    - fill memory with random pattern
  reset     - Perform RESET of the CPU
  run       - run commands in an environment variable
  save      - save file to a filesystem
  saveenv   - save environment variables to persistent storage
  setenv    - set environment variables
  setexpr   - set environment variable as the result of eval expression
  sf        - SPI flash sub-system
  showvar   - print local hushshell variables
  size      - determine a file's size
  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

可看到uboot支持很多的命令,功能十分强大,与linux类似,在执行某条uboot命令时, 可使用 tab 自动补全命令,在没有命令名冲突的情况下可以使用命令的前几个字母作为命令的输入, 例如想要执行 reset 命令,输入 resre 即可。

当需要具体使用哪个命令时,可使用 “help 命令”“? 命令” 的方式查看具体命令的使用说明。以 “help printenv” 为例,

1
2
3
4
5
6
7
8
=> help printenv
printenv - print environment variables

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

可以看到printenv命令的说明以及使用方法。

关于uboot命令的使用可参考uboot官方链接: http://www.denx.de/wiki/DULG/Manual 5.9. uboot Command Line Interface 部分。

2.3.1. uboot常见命令

uboot命令众多,下面介绍常用的uboot命令,详细的uboot命令使用方式请使用 help [命令] 查看。

常见命令

命令

说明

举例

help

列出当前uboot所有支持的命令

help [命令]

查看指定命令的帮助

help printenv

reset

重启uboot

printenv

打印所有环境参数的值

printenv [环境参数名]

查看指定的环境参数值

printenv bootdelay

setenv

设置/修改/删除环境参数的值

setenv bootdelay 3

saveenv

保存环境参数

ping

检测网络是否连通

ping 192.168.0.1

md

查看内存地址上的值

md.b 0x80000000 10

以字节查看0x80000000后0x10个数据

mw

用于修改内存地址上的值

mw.b 0x80000000 ff 10

以字节修改0x80000000后0x10个数据为ff

echo

打印信息,与linux下的echo类似

run

在执行某条环境参数命令

run bootcmd,执行bootcmd

bootz

在内存中引导内核启动

ls

查看文件系统中目录下的文件

load

从文件系统中加载二进制文件到内存

以上为用户较为常用使用的部分命令,具体的使用方式可使用 help [命令] 查看。

2.3.2. mmc命令

mmc命令能够对如sd卡以及emmc类的存储介质进行操作,以下进行简单说明, 对于mmc命令不熟悉可使用 help mmc 查看相关命令的帮助,常用功能如下所示

mmc命令功能

命令

说明

mmc list

查看板子上mmc设备

mmc dev

查看/切换当前默认mmc设备

mmc info

查看当前mmc设备信息

mmc part

查看当前mmc设备分区

mmc read

读取当前mmc设备数据

mmc write

写入当前mmc设备数据

mmc erase

擦除当前mmc设备数据

2.3.2.1. 查看mmc设备

使用 mmc list 查看板子上相关设备,此处使用的是emmc版本的开发板,并插入了sd卡, 可看到打印信息如下。

1
2
3
=> mmc list
FSL_SDHC: 0 (SD)
FSL_SDHC: 1

SD为设备0,eMMC为设备1,可以使用 mmc dev 切换的mmc设备,打印信息如下。

1
2
3
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device

使用 mmc info 查看当前使用的eMMC设备的信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
=> mmc info
Device: FSL_SDHC
Manufacturer ID: 15
OEM: 100
Name: 8GTF4
Bus Speed: 52000000
Mode: MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 7.3 GiB
Bus Width: 4-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.3 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 512 KiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected

2.3.2.2. 查看分区信息

使用 mmc part 列出当前mmc设备分区

1
2
3
4
5
6
7
=> mmc part

Partition Map for MMC device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     8192            81920           40ea9836-01     0c
  2     90112           15179776        40ea9836-02     83

以上可以看到有两个分区,第一个分区为存放内核和设备树的boot分区,第二个分区为存放根文件系统的rootfs分区。

2.3.2.3. mmc操作

可使用以下指令对mmc存储介质以block为操作单位进行读、写、擦除操作,根据上面sd的信息可知, 一个block为512字节。

1
2
3
 mmc read addr blk# cnt    #读
 mmc write addr blk# cnt   #写
 mmc erase blk# cnt        #擦除

简单实例:将mmc设备的的前10个block读取到0x80000000地址处: mmc read 0x80000000 0 10

2.3.3. 文件系统操作命令

uboot能够对ext2/3/4以及fat文件系统设备进行访问, 可使用fstype命令判断存储介质分区使用的是什么类型的文件系统。 以mmc1介质为例,判断eMMC的两个分区的文件系统类型

1
2
3
4
5
6
7
#查看mmc1(eMMC)的第一个分区类型
=> fstype mmc 1:1
fat

#查看mmc1(eMMC)的第二个分区类型
=> fstype mmc 1:2
ext4

知道了文件系统的类型即可使用相对应的命令对分区内容进行操作了。

2.3.3.1. FAT格式文件系统

uboot提供了能够对于FAT格式文件系统操作的各个指令, 如下所示,详细可通过 help [命令] 查看

FAT格式文件系统命令

命令

说明

fatinfo

打印关于文件系统的信息

fatls

查看存储设备的fat分区里的内容

fatload

从fat分区里读出文件到指定的内存地址

fatwrite

把内存上的数据存储到fat分区的一个文件里

fatmkdir

创建文件夹

fatrm

删除文件

2.3.3.1.1. 查看文件系统信息

使用fatinfo查看文件系统信息,打印信息如下

1
2
3
4
5
6
=> fatinfo mmc 1:1
Interface:  MMC
  Device 1: Vendor: Man 000015 Snr fd7b58ce Rev: 0.6 Prod: 8GTF4R
            Type: Removable Hard Disk
            Capacity: 7456.0 MB = 7.2 GB (15269888 x 512)
Filesystem: FAT32 "NO NAME    "
2.3.3.1.2. 查看分区下的文件目录

使用fatls查看分区下的文件目录,打印信息如下

1
2
3
4
5
=> fatls mmc 1:1
  7863120   zImage
    38733   imx6ull-mmc-npi-lite.dtb

2 file(s), 0 dir(s)
  • zImage :内核

  • imx6ull-mmc-npi-lite.dtb :设备树

通过加载第一个分区的内核和设备树即可进行启动。

2.3.3.1.3. 读取文件内容

使用fatload将FAT文件系统的文件加载到内存中,如下所示

1
2
=> fatload mmc 1:1 0x80800000 /zImage
7863120 bytes read in 412 ms (18.2 MiB/s)
2.3.3.1.4. FAT文件系统其他操作

uboot还提供了FAT文件系统的其他操作命令,可用于创建目录、写入、删除等操作, 通常情况下在uboot中需要使用这类命令的场景很少,简单介绍如下:

  • fatmkdir:创建目录

  • fatrm:删除文件

  • fatwrite:把内存上的数据存储到FAT分区的一个文件里

2.3.3.2. ext4格式文件系统

ext4文件系统的命令使用方式和FAT使用方式相似,仅命令名不同, uboot提供的ext文件系统命令如下

ext4格式文件系统命令

命令

说明

ext4ls

查看存储设备的ext4分区里的内容

ext4load

从ext4分区里读出文件到指定的内存地址

ext4write

把内存上的数据存储到ext4分区的一个文件里

2.3.3.2.1. ext4文件系统操作

下面以将/etc/os-release的内容读取到内存实例,简单说明uboot对ext4文件系统操作。

1.查看/etc/目录中的文件内容,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
=> ext4ls mmc 1:2 /etc/
<DIR>       4096 .
<DIR>       4096 ..
<DIR>       4096 cron
            334 fstab
            341 group
              10 hostname
              40 hosts
<DIR>       4096 init.d
            1281 inittab
              21 issue
<SYM>         19 mtab
<DIR>       4096 network
            230 nsswitch.conf
<SYM>         21 os-release
            340 passwd
            299 profile
<DIR>       4096 profile.d
            2744 protocols
<SYM>         18 resolv.conf
          10873 services
            135 shadow
              17 shells
<DIR>       4096 udev

2.将/etc/os-release 文件读取到内存地址0x8000 0000处

1
2
=> ext4load mmc 1:2  0x80000000  /etc/os-release
101 bytes read in 27 ms (2.9 KiB/s)

3.查看内存0x8000 0000的部分数据内存

1
2
3
4
5
6
7
8
9
=> md.b 0x80000000 0x80
80000000: 4e 41 4d 45 3d 42 75 69 6c 64 72 6f 6f 74 0a 56    NAME=Buildroot.V
80000010: 45 52 53 49 4f 4e 3d 2d 67 61 37 34 37 64 39 39    ERSION=-ga747d99
80000020: 0a 49 44 3d 62 75 69 6c 64 72 6f 6f 74 0a 56 45    .ID=buildroot.VE
80000030: 52 53 49 4f 4e 5f 49 44 3d 32 30 32 31 2e 30 32    RSION_ID=2021.02
80000040: 2e 33 0a 50 52 45 54 54 59 5f 4e 41 4d 45 3d 22    .3.PRETTY_NAME="
80000050: 42 75 69 6c 64 72 6f 6f 74 20 32 30 32 31 2e 30    Buildroot 2021.0
80000060: 32 2e 33 22 0a 00 ff ff ff ff ff ff ff ff ff ff    2.3"............
80000070: ff ff ff ff ff ff ff ff ff ff 08 00 40 00 fe ff    ............@...

可以看到/etc/os-release的内容,此处使用的buildroot版本为2021.02.3。

2.3.4. nand命令

nand命令能够对如nand类的存储介质进行操作,以下进行简单说明, 对于nand命令不熟悉可使用 help nand 查看相关命令的帮助,常用功能如下所示

nand命令功能

命令

说明

nand info

查看nand信息

nand erase

擦除nand块

nand read

读取nand数据到内存

nand write

将内存数据写入nand

nand markbad off

标记坏块

nand bad

检查坏块

nand dump

转储nand数据

nand erase.chip

擦除整个nand

2.3.4.1. 查看nand设备

1
2
3
4
5
6
7
8
9
=> nand info

Device 0: nand0, sector size 256 KiB
  Page size       4096 b
  OOB size         256 b
  Erase size    262144 b
  subpagesize     4096 b
  options     0x40004200
  bbt options 0x00000000
  • Device 0:表示系统中有一个NAND设备,编号为0,设备名称为nand0

  • Page size:表示NAND设备的页大小为4096字节,也即4kb

  • OOB size:表示每页的OOB区域大小为256字节。OOB区域通常用于存储ECC(错误校正码)或元数据。

  • Erase size:表示NAND设备的擦除块大小为262144字节,也即256kb,擦除块是NAND闪存的最小擦除单元。

  • subpagesize:表示子页大小为4096字节。子页是NAND设备支持的更小读写单元。

  • options:表示NAND设备的选项标志,通常用于描述设备的特性或配置。

  • bbt options:表示坏块表的选项标志,0x00000000即没有坏块。

2.3.4.2. 读取nand数据到内存

设备树存放在nand的0x400000区域,大小为,0x100000(1M),可通过nand read进行读取。

1
2
3
4
=> nand read 0x83000000 0x400000 0x100000

  NAND read: device 0 offset 0x400000, size 0x100000
  1048576 bytes read: OK

读取nand起始地址0x400000,大小0x100000内容,到内存0x83000000位置。

内核存放在nand的0x500000区域,大小为,0xa00000(10M),可通过nand read进行读取。

1
2
3
4
=> nand read 0x80800000 0x500000 0xa00000

  NAND read: device 0 offset 0x500000, size 0xa00000
  10485760 bytes read: OK

读取nand起始地址0x500000,大小0xa00000内容,到内存0x80800000位置。

2.3.5. ubi命令

nand使用的是ubifs文件系统,可以使用ubi相关命令查看信息或读写。

ubi命令功能

命令

说明

ubi part

显示当前UBI分区信息

ubi info

显示UBI设备或卷的详细信息

ubifsload

从UBIFS文件系统中加载文件到内存

ubifsls

列出UBIFS文件系统中的目录内容

ubifsmount

挂载UBIFS文件系统

ubifsumount

卸载已挂载的UBIFS文件系统

2.3.5.1. 显示UBI文件系统分区信息

 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
=> ubi part rootfs
ubi0: attaching mtd4  //分区位于mtd4
ubi0: scanning is finished
ubi0: attached mtd4 (name "rootfs", size 497 MiB) //名称和大小
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 1988, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 1/0, WL threshold: 4096, image sequence number: 115871333
ubi0: available PEBs: 36, total reserved PEBs: 1952, PEBs reserved for bad PEB handling: 40
=> ubi info
UBI: MTD device name:            "rootfs"   //MTD设备名称
UBI: MTD device size:            497 MiB    //MTD 设备大小
UBI: physical eraseblock size:   262144 bytes (256 KiB)
UBI: logical eraseblock size:    253952 bytes
UBI: number of good PEBs:        1988
UBI: number of bad PEBs:         0
UBI: smallest flash I/O unit:    4096
UBI: VID header offset:          4096 (aligned 4096)
UBI: data offset:                8192
UBI: max. allowed volumes:       128
UBI: wear-leveling threshold:    4096
UBI: number of internal volumes: 1
UBI: number of user volumes:     1
UBI: available PEBs:             36
UBI: total number of reserved PEBs: 1952
UBI: number of PEBs reserved for bad PEB handling: 40
UBI: max/mean erase counter: 1/0

2.3.5.2. 显示UBI文件系统分区内容

需要先通过ubifsmount挂载文件系统:

1
2
=> ubi part rootfs
=> ubifsmount ubi0

然后使用ubifsls查看文件系统内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
=> ubifsls /
<DIR>        5024  Thu Jan 01 00:01:07 1970  bin
<DIR>         608  Thu Jan 01 00:01:07 1970  dev
<DIR>        1432  Thu Jan 01 00:01:07 1970  etc
<DIR>        1040  Thu Jan 01 00:01:07 1970  lib
<DIR>         160  Sat Jun 12 14:58:31 2021  mnt
<DIR>         160  Sat Jun 12 14:58:31 2021  opt
<DIR>         224  Thu Jan 01 00:03:02 1970  run
<DIR>         160  Sat Jun 12 14:58:31 2021  tmp
<DIR>         160  Sat Jun 12 14:58:31 2021  sys
<DIR>         672  Thu Jan 01 00:01:07 1970  var
<DIR>         480  Thu Jan 01 00:01:07 1970  usr
<DIR>         160  Sat Jun 12 14:58:31 2021  proc
<DIR>        3808  Thu Jan 01 00:01:07 1970  sbin
<DIR>         160  Sat Jun 12 14:58:31 2021  root
<LNK>          11  Thu Jan 01 00:01:07 1970  linuxrc
<LNK>           3  Thu Jan 01 00:01:07 1970  lib32
<DIR>         160  Sat Jun 12 14:58:31 2021  media

2.3.5.3. 读取UBI文件系统分区内容

下面以将/etc/issue的内容读取到内存实例,简单说明uboot对ubifs文件系统操作。

  1. 挂载ubifs文件系统并查看/etc/目录中的文件内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
=> ubi part rootfs
=> ubifsmount ubi0
=> ubifsls /etc/
<LNK>          19  Thu Jan 01 00:01:07 1970  mtab
<DIR>         584  Thu Jan 01 00:01:07 1970  network
<LNK>          21  Thu Jan 01 00:01:07 1970  os-release
<DIR>         712  Thu Jan 01 00:01:07 1970  init.d
              10  Thu Feb 20 13:51:38 2025  hostname
              340  Sat Jun 12 14:58:31 2021  passwd
              334  Sat Jun 12 14:58:31 2021  fstab
              306  Sat Jun 12 14:58:31 2021  group
              40  Thu Feb 20 13:51:38 2025  hosts
              21  Thu Feb 20 13:51:38 2025  issue
            1240  Thu Feb 20 13:51:38 2025  inittab
              135  Thu Feb 20 13:51:38 2025  shadow
              17  Thu Feb 20 13:51:38 2025  shells
              947  Thu Feb 20 13:49:54 2025  mdev.conf
            2744  Sat Jun 12 14:58:31 2021  protocols
<LNK>          18  Thu Jan 01 00:01:07 1970  resolv.conf
              299  Thu Feb 20 13:08:13 2025  profile
<DIR>         232  Thu Jan 01 00:01:07 1970  profile.d
            10873  Sat Jun 12 14:58:31 2021  services
  1. 将/etc/issue文件读取到内存地址0x8000 0000处

1
=> ubifsload 0x80000000 /etc/issue
  1. 查看内存0x8000 0000的部分数据内存

1
2
3
4
5
6
7
8
9
=> md.b 0x80000000 0x80
80000000: 57 65 6c 63 6f 6d 65 20 74 6f 20 42 75 69 6c 64    Welcome to Build
80000010: 72 6f 6f 74 0a ef bf 7f ff ff ff ff 7f fd ff d9    root............
80000020: f7 f7 ff ff fe ff bf b9 cf f1 ee ff df ef fd bb    ................
80000030: ff ff ff df ff fe df ef ff ff ff ff bf ff fc aa    ................
80000040: ff e5 f5 ff df fe fe aa ff ff ff ff 7f bf ff 9b    ................
80000050: ff bf ff ff fe bf ff fa df fe ff ff 7f fe fe fe    ................
80000060: ff ff f6 ff ff ae ff bf ef 7f ff ff bd ff 7f ef    ................
80000070: df 57 ff ff be bf 7c af ff fd ff 7f fd bf fd ff    .W....|.........

可以看到/etc/issue文件内容为Welcome to Buildroot

2.4. uboot启动内核过程

bootcmd与bootargs可以说是uboot最重要的两个环境参数, uboot执行完毕之后,如果没有按下回车,则会自动执行bootcmd命环境参数里的内容, 而bootargs则是传递给内核的启动参数。

2.4.1. 从eMMC或SD启动内核过程

使用 printenv bootcmd 可查看bootcmd的内容。

1
2
 => printenv bootcmd
 bootcmd=run distro_bootcmd

bootcmd执行了distro_bootcmd,同样可以使用 printenv distro_bootcmd 查看distro_bootcmd的内容如下

1
2
3
4
5
=> printenv distro_bootcmd
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done

#boot_targets的值如下
boot_targets=mmc0 mmc1

也就是说distro_bootcmd会执行 bootcmd_mmc0、bootcmd_mmc1 这两个环境参数, 在前面我们知道,mmc0表示的sd卡的存储设备,mmc1表示的emmc设备, 也就是说当sd卡插在板子时,若sd卡装有系统则会优先从sd卡内启动。

1
2
3
4
 => printenv bootcmd_mmc0
 bootcmd_mmc0=setenv devtype mmc; setenv mmcdev 0; setenv bootpart 0:1 ; setenv rootfpart 0:2 ; run boot
 => printenv bootcmd_mmc1
 bootcmd_mmc1=setenv devtype mmc; setenv mmcdev 1; setenv bootpart 1:1 ; setenv rootfpart 1:2 ; run boot

bootcmd_mmc0与bootcmd_mmc1均设置各自 devtype、mmcdev、bootpart、rootfpart 环境参数的值, 最后运行 boot 环境参数,boot内容如下

提示

若从uboot中直接使用printenv查看boot的内容会显得格式很乱,推荐在uboot源码include/configs/mx6ullfire_lite.h 中查看。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
"args_mmc_old=setenv bootargs console=ttymxc0 " \
  "root=/dev/mmcblk${mmcdev}p2 rw " \
  "rootfstype=ext4 " \
  "rootwait ${cmdline} ${flashtype}\0" \
"boot=mmc check;${devtype} dev ${mmcdev};mmc rescan; " \   //检查、扫描MMC设备
  "run args_mmc_old;" \
  "echo loading zImage ...; "\
  "load ${devtype} ${bootpart} 0x80800000 /zImage;"\       //从MMC设备加载内核到内存
  "echo loading dtb ...; "\
  "load ${devtype} ${bootpart} 0x83000000 /imx6ull-mmc-npi-lite.dtb;"\  //从MMC设备加载设备树到内存
  "bootz 0x80800000 - 0x83000000;"    \        //启动内核
  " \0" \
  • devtype:设备类型,此处为mmc

  • bootpart:是boot分区,如果是SD卡则值为0:1,如果是eMMC则值为1:1

  • mmcdev:mmc设备号,如果是SD卡则值为0,如果是eMMC则值为1

  • 0x80800000:内核加载地址

  • 0x83000000:设备树加载地址

从以上可见,从eMMC或SD卡启动系统十分简单,仅需在uboot命令行执行以下命令即可手动引导系统启动。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#sd启动
run args_mmc_old
load mmc 0:1 0x80800000 zImage
load mmc 0:1 0x83000000 imx6ull-mmc-npi-lite.dtb
bootz 0x80800000 - 0x83000000

#emmc启动
run args_mmc_old
load mmc 1:1 0x80800000 zImage
load mmc 1:1 0x83000000 imx6ull-mmc-npi-lite.dtb
bootz 0x80800000 - 0x83000000

2.4.2. 从nand启动内核过程

使用 printenv bootcmd 可查看bootcmd的内容。

1
2
=> printenv bootcmd
bootcmd=nand read ${fdt_addr} 0x400000 0x100000;nand read ${loadaddr} 0x500000 0xA00000;bootz ${loadaddr} - ${fdt_addr}

提示

若从uboot中直接使用printenv查看boot的内容会显得格式很乱,推荐在uboot源码include/configs/mx6ullfire_lite.h 中查看。

1
2
3
4
5
6
"bootargs=console=ttymxc0,115200 ubi.mtd=3 "  \
  "root=ubi0:rootfs rw rootfstype=ubifs "                  \
  "mtdparts=gpmi-nand:4m(u-boot),1m(dtb),10M(kernel),-(rootfs)\0" \
"bootcmd=nand read ${fdt_addr} 0x400000 0x100000;"  \  //读取设备树
  "nand read ${loadaddr} 0x500000 0xa00000;"\     //读取内核
  "bootz ${loadaddr} - ${fdt_addr}\0"   //启动系统

从以上可见,从nand启动系统十分简单,仅需在uboot命令行执行以下命令即可手动引导系统启动。

1
2
3
nand read 0x83000000 0x400000 0x100000
nand read 0x80800000 0x500000 0xa00000
bootz 0x80800000 - 0x83000000

2.5. uboot环境参数介绍

uboot中环境参数为我们提供一种不修改uboot源码的情况下, 能够修改kernel启动倒计时、ip地址、以及向内核传递不同的参数等。

在板子上使用 printenv 可查看板子上所有的环境参数, 使用 setenv 添加/修改/删除环境参数,具体说明如下所示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#设置新的环境参数名为abc,值为100
=> setenv abc 100
=> echo $abc
= 100

#将值修改为200
=> setenv abc 200
=> echo $abc
200

#删除abc环境参数
=> setenv abc
=> echo $abc

=>

默认情况下使用setenv命令修改环境参数重启后就会消失, 若想要掉电保存需要执行 saveenv 将环境参数保存到存储介质。

uboot上有一些官方规定的环境变量,这些环境变量在uboot有着特殊的作用, 可通过以下链接查看: https://www.denx.de/wiki/view/DULG/UBootEnvVariables