目录
介绍
uboot 的本质工作是引导 Linux,所以 uboot 肯定有相关的 boot(引导)命令来启动 Linux。
常用的跟 boot 有关的命令有:
- bootz
- bootm
- boot。
1 、bootz 命令
要启动 Linux,需要先将 Linux 镜像文件拷贝到 DRAM 中,如果使用到设备树的话也需要将设备树拷贝到 DRAM 中。可以从 EMMC 或者 NAND 等存储设备中将 Linux 镜像和设备树文件拷贝到 DRAM,也可以通过 nfs 或者 tftp 将 Linux 镜像文件和设备树文件下载到 DRAM 中。
bootz启动Linux
不管用那种方法,只要能将 Linux 镜像和设备树文件存到 DRAM 中就行,然后使用 bootz 命令来启动,bootz 命令用于启动 zImage 镜像文件,bootz 命令格式如下:
bootz [addr [initrd[:size]] [fdt]]
命令 bootz 有三个参数:
- addr 是 Linux 镜像文件在 DRAM 中的位置
- initrd 是 initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可
- fdt 就是设备树文件在 DRAM 中的地址。
1、tft启动
现在使用网络和 EMMC 两种方法来启动 Linux 系统,首先将 I.MX6U-ALPHA 开发板的 Linux 镜像和设备树发送到 Ubuntu 主机中的 tftpboot 文件夹下。Linux 镜像文件前面已经放到了 tftpboot 文件夹中,现在把设备树文件放到 tftpboot 文件夹里面。以 EMMC 核心板为例,将开发板光盘->8、开发板系统镜像->imx6ull-alientek-emmc.dtb
文件发送到 Ubuntu 主机中的 tftpboot 文件夹里面,完成以后的 tftpboot 文件夹如下所示:
fyuan@ubuntu:~/linux/tftpboot$ ls
imx6ull_liefyuan_emmc.dtb u-boot.imx zImage
1、设置开发板网络设置
setenv ipaddr 192.168.0.121
setenv ethaddr de:b4:7c:de:dc:07
setenv gatewayip 192.168.0.1
setenv netmask 255.255.255.0
setenv serverip 192.168.0.120
saveenv
2、ping虚拟机(tft服务器)
ping 192.168.0.120
3、tft下载zImage
下载 Linux 镜像文件和设备树都准备好了,我们先学习如何通过网络启动 Linux,使用 tftp命令将 zImage 下载到 DRAM 的 0X80800000 地址处,然后将设备树 imx6ull-alientek-emmc.dtb下载到 DRAM 中的 0X83000000 地址处,最后之后命令 bootz 启动,命令如下:
tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 80800000 – 83000000
异常TFTP error: 'Permission denied' (0)
:这里是zImage需要在ubuntu上修改权限:sudo chmod 777 zImage
=> tft 80800000 zImage
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'zImage'.
Load address: 0x80800000
Loading: *
TFTP error: 'Permission denied' (0)
Starting again
修改zImage文件权限之后正常执行:
=> tft 80800000 zImage
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
########
1.8 MiB/s
done
Bytes transferred = 6788696 (679658 hex)
4、tft下载设备树
tftp 83000000 imx6ull_liefyuan_emmc.dtb
需要修改权限sudo chmod 777 imx6ull_liefyuan_emmc.dtb
后才能下载:
=> tftp 83000000 imx6ull_liefyuan_emmc.dtb
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'imx6ull_liefyuan_emmc.dtb'.
Load address: 0x83000000
Loading: ###
1.3 MiB/s
done
Bytes transferred = 38823 (97a7 hex)
bootz 80800000 – 83000000
出错了!错误信息如下:
=> bootz 80800000 – 83000000
Kernel image @ 0x80800000 [ 0x000000 - 0x679658 ]
Wrong Ramdisk Image Format
Ramdisk image is corrupt or invalid
原来是bootz 80800000 – 83000000
中间的横杠应该要写成英文符!
bootz 80800000 - 83000000
正确的启动信息:
=> bootz 80800000 - 83000000
Kernel image @ 0x80800000 [ 0x000000 - 0x678d40 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8300c7a6
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.15-gb8ddbbc (alientek@ubuntu) (gcc version 5.3.0 (GCC) ) #1 SMP PREEMPT Wed Apr 29 17:39:59 CST 2020
[ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Freescale i.MX6 ULL 14x14 EVK Board
[ 0.000000] Reserved memory: created CMA memory pool at 0x98000000, size 128 MiB
2、emmc启动Linux
上面就是我们通过 tftp 和 bootz 命令来从网络启动 Linux 系统,如果我们要从 EMMC 中启动 Linux 系统的话只需要使用命令 fatload 将 zImage 和 imx6ull_liefyuan_emmc.dtb 从 EMMC 的分区 1 中拷贝到 DRAM 中,然后使用命令 bootz 启动即可。
先使用命令 fatls 查看要下 EMMC的分区1中有没有Linux镜像文件和设备树文件:
命令为:
fatls mmc 1:1
打印信息:
=> fatls mmc 1:1
6788696 zimage
38823 imx6ull-14x14-emmc-4.3-800x480-c.dtb
39655 imx6ull-14x14-emmc-hdmi.dtb
3 file(s), 0 dir(s)
从上面可以看出,emmc 的分区 1 中存放着三个文件:
- zimage
- imx6ull-14x14-emmc-4.3-800x480-c.dtb
- imx6ull-14x14-emmc-hdmi.dtb
这两个文件分别是 linux 镜像文件和两个设备树。确定有文件就使用fatload将zImage和设备树文件拷贝到DRAM中,地址分别为:0x80800000和0x83000000,最后使用bootz命令启动:
fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
bootz 80800000 - 83000000
正确执行的信息:
=> fatload mmc 1:1 80800000 zImage
reading zImage
6788696 bytes read in 224 ms (28.9 MiB/s)
=> fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
reading imx6ull-14x14-emmc-4.3-800x480-c.dtb
38823 bytes read in 18 ms (2.1 MiB/s)
=> bootz 80800000 - 83000000
Kernel image @ 0x80800000 [ 0x000000 - 0x679658 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8300c7a6
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.15 (liefyuan@ubuntu) (gcc version 4.9.4 (Linaro GCC 4.9-2017.01) ) #1 SMP PREEMPT Sat Dec 12 13:45:03 CST 2020
[ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Freescale i.MX6 ULL 14x14 EVK Board
[ 0.000000] Reserved memory: created CMA memory pool at 0x98000000, size 128 MiB
[ 0.000000] Reserved memory: initialized node linux,cma, compatible id shared-dma-pool
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] PERCPU: Embedded 12 pages/cpu @97b90000 s16832 r8192 d24128 u49152
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048
2 、bootm 命令
bootm 和 bootz 功能类似,但是 bootm 用于启动 uImage 镜像文件。如果不使用设备树的话启动 Linux 内核的命令如下:
bootm addr
addr 是 uImage 镜像在 DRAM 中的首地址。
如果要使用设备树,那么 bootm 命令和 bootz 一样,命令格式如下:
bootm [addr [initrd[:size]] [fdt]]
其中 addr 是 uImage 在 DRAM 中的首地址,initrd 是 initrd 的地址,fdt 是设备树(.dtb)文件在 DRAM 中的首地址,如果 initrd 为空的话,同样是用“-”来替代。
3 、boot 命令
boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统,bootcmd 是一个很重要的环境变量!其名字分为“boot”和“cmd”,也就是“引导”和“命令”,说明这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可以修改的。比如我们要想使用 tftp 命令从网络启动 Linux 那么就可以设置 bootcmd 为tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000
,然后使用 saveenv 将 bootcmd 保存起来。然后直接输入 boot 命令即可从网络启动 Linux 系统,命令如下:
TFT启动
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull_liefyuan_emmc.dtb; bootz 80800000 - 83000000'
saveenv
boot
MMC启动
setenv bootcmd 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb; bootz 80800000 - 83000000'
saveenv
boot
正常执行:
=> setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull_liefyuan_emmc.dtb; bootz 80800000 - 83000000'
=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done
=> boot
FEC1 Waiting for PHY auto negotiation to complete.... done
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
########
525.4 KiB/s
done
Bytes transferred = 6786368 (678d40 hex)
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'imx6ull_liefyuan_emmc.dtb'.
Load address: 0x83000000
Loading: ###
2.2 MiB/s
done
Bytes transferred = 38823 (97a7 hex)
Kernel image @ 0x80800000 [ 0x000000 - 0x678d40 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8300c7a6
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.15-gb8ddbbc (alientek@ubuntu) (gcc version 5.3.0 (GCC) ) #1 SMP PREEMPT Wed Apr 29 17:39:59 CST 2020
[ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Freescale i.MX6 ULL 14x14 EVK Board
[ 0.000000] Reserved memory: created CMA memory pool at 0x98000000, size 128 MiB
[ 0.000000] Reserved memory: initialized node linux,cma, compatible id shared-dma-pool
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] PERCPU: Embedded 12 pages/cpu @97b90000 s16780 r8192 d24180 u49152
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048
[ 0.000000] Kernel command line: noinitrd console=ttymxc0,115200
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 375280K/524288K available (8547K kernel code, 450K rwdata, 2964K rodata, 524K init, 451K bss, 17936K reserved, 131072K cma-reserved, 0K highmem)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xa0800000 - 0xff000000 (1512 MB)
[ 0.000000] lowmem : 0x80000000 - 0xa0000000 ( 512 MB)
[ 0.000000] pkmap : 0x7fe00000 - 0x80000000 ( 2 MB)
[ 0.000000] modules : 0x7f000000 - 0x7fe00000 ( 14 MB)
[ 0.000000] .text : 0x80008000 - 0x80b46274 (11513 kB)
[ 0.000000] .init : 0x80b47000 - 0x80bca000 ( 524 kB)
[ 0.000000] .data : 0x80bca000 - 0x80c3a9a0 ( 451 kB)
[ 0.000000] .bss : 0x80c3d000 - 0x80cadfc4 ( 452 kB)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Preemptible hierarchical RCU implementation.
如果不修改 bootcmd 的话,每次开机 uboot 倒计时结束以后都会自动从 EMMC 里面读取zImage 和 imx6ull-alientek-emmc.dtb,然后启动 Linux。
在启动 Linux 内核的时候可能会遇到如下错误:
“Kernel panic – not Syncing: VFS: Unable to mount root fs on unknown-block(0,0)”
这个错误的原因是 linux 内核没有找到根文件系统,这个很正常,因为没有设置 uboot 的bootargs 环境变量,关于 bootargs 环境变量后面会讲解!此处我们重点是验证 boot 命令,linux内核已经成功启动了,说明 boot 命令工作正常。