概述
Das U-Boot是一个开源的主引导加载程序,用于嵌入式设备中打包指令以引导设备的操作系统内核,常用于ARM体系架构的嵌入式设备引导和加载Linux内核和文件系统。
U-Boot支持串口上运行命令行界面。使用命令行,用户可以加载和引导内核,可能会更改默认参数。还有命令可以读取设备信息,读取和写入闪存,从串行端口或网络下载文件(内核,引导映像等),操作设备树,以及使用环境变量(可以写入持久存储),用于控制U-Boot行为,例如自动引导前的默认引导命令和超时,以及以太网MAC地址等硬件数据。
配置文件
U-Boot的重要配置信息在文件中定义:
include/configs/<board>.h
例如,MX6默认通用配置文件是:
include/configs/mx6_common.h
在这个配置文件中(或者自己重新创建新的配置文件中),你可以配置如下常用的一些功能:
#define CONFIG_BOOTCOMMAND "fatload mmc 0 40007000 uImage; bootm 40007000"
配置启动命令是从mmc0的fat分区加载uImage到0x40007000的内存地址处,然后从这里启动内核。
#define CONFIG_BOOTDELAY 3
配置启动U-Boot之后有3秒的时间可以按回车键进入命令行界面,如果配置成0就不能打断启动过程。
#define CONFIG_CMD_MII
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_TFTPGET
这是网络相关的配置,支持以太网MII,ping, dhcp和tftp下载功能。
#define CONFIG_DEFAULT_CONSOLE "console=ttySAC2,115200n8\0"
配置默认的串口输出是ttySAC2。
#define CONFIG_EXTRA_ENV_SETTINGS \
"ipaddr=192.168.0.202\0" \
"serverip=192.168.0.15\0" \
通过CONFIG_EXTRA_ENV_SETTINGS
参数来设置U-Boot环境。U-Boot环境是一块内存块,保存在永久存储器上,并在U-Boot启动时复制到RAM。它用于存储可用于配置系统的环境变量。环境受CRC32校验和保护。除了上面配置的ipaddr和serverip外还有如下常用环境变量
变量 | 说明 |
---|---|
bootargs | 此变量的内容作为引导参数(也称为“命令行”)传递给Linux内核。 |
bootcmd | 此变量定义在初始倒计时未中断时自动执行的命令字符串。该命令仅在bootdelay定义变量时执行 ! |
bootdelay | 复位后,U-Boot将在执行bootcmd变量内容之前等待这个秒数 。在此期间打印倒计时,可以通过按任意键来中断倒计时。 |
ethaddr | 第一个/唯一以太网接口的以太网MAC地址 |
ipaddr | IP地址; 需要tftp命令 |
loadaddr | 像tftp或的 命令的默认加载地址loads |
serverip | TFTP服务器IP地址; 需要tftp命令。 |
常用命令和实践
进入命令行后一些常用的命令如下:
命令 | 说明 |
---|---|
help | 打印在线帮助 |
bootm | 从内存启动应用程序镜像 |
bootz | 从内存中启动Linux zImage |
ext4load | 从Ext4分区加载二进制文件 |
ext4ls | 列出目录中文件 |
fatinfo | 打印有关文件系统的信息 |
fatls | 列出目录中的文件 |
fatload | 从dos文件系统加载二进制文件 |
md | 内存显示 |
mm | 内存修改(自动递增) |
mtest | 简单的RAM测试 |
mw | 内存写 |
mmc | MMC子系统 |
ping | 给主机发送ICMP ECHO_REQUEST |
printenv | 打印环境变量 |
reset | 复位CPU |
setenv | 设置环境变量 |
saveenv | 将环境变量保存到持久存储 |
usb | usb子系统 |
tftpboot | 使用TFTP协议通过网络启动映像 |
设置环境变量
使用setenv
来设置tftp相关的环境变量,然后用printenv
打印这些变量
U-Boot> setenv ethaddr 00:11:22:33:44:55
U-Boot> setenv serverip 192.168.1.100
U-Boot> setenv ipaddr 192.168.1.1
U-Boot> printenv
ethaddr=00:11:22:33:44:55
ipaddr=192.168.1.1
serverip=192.168.1.100
使用saveenv
(如果有这个命令的话)来保存这些变量
U-Boot> saveenv
内存命令
使用md
和mw
来显示和修改内存数据,md
和mw
命令的格式比较类似
mw [.b, .w, .l] address value [count]
[.b, .w, .l]
对应[字节8bits,字16bits,双字32bits]
下面把内存0x82000000-0x82000100置零(部分显示log省略)
U-Boot> mw.b 0x82000000 0 0x100
U-Boot> md.l 0x82000000
82000000: 00000000 00000000 00000000 00000000 ................
82000010: 00000000 00000000 00000000 00000000 ................
82000020: 00000000 00000000 00000000 00000000 ................
82000030: 00000000 00000000 00000000 00000000 ................
USB/MMC子系统
先用usb start
让U盘正常工作,然后使用fatload
从0设备号U盘第1分区里面把u-boot.bin
拷贝到内存0x82000000
位置,然后再从内存0x82000000
位置把u-boot.bin
拷贝到eMMC的u-boot放置区(这里是扇区0x2-0x400)
U-Boot> usb start
U-Boot> fatload usb 0:1 0x82000000 u-boot.bin
U-Boot> mmc write 0x82000000 0x2 0x400
如果USB/MMC盘已经存在FAT/EXT4分区,可以使用fatls/ext4ls
来列出分区里面的文件信息
U-Boot> fatls usb 0:1
system volume information/
47353868 ramdisk.cpio.gz.u-boot
497068 uimage
494592 emmc.dtb
这里是从0设备号U盘的第一个FAT分区里面列出所有文件信息。
下面尝试用U盘来加载和启动Linux ramfs
U-Boot> fatload usb 0:1 0x80000000 uImage
U-Boot> fatload usb 0:1 0x82000000 emmc.dtb
U-Boot> fatload usb 0:1 0x83800000 ramdisk.cpio.gz.u-boot
U-Boot> setenv bootargs 'console=ttySAC2,115200n8 root=/dev/ram0 rw ramdisk_size=0x10000000 loglevel=7'
U-Boot> bootm 0x80000000 0x83800000 0x82000000
这里先通过fatload
把内核镜像,DTB以及ramfs镜像从U盘加载到内存里,然后配置Linux内核引导参数,最后从内存启动Linux ramfs。
使用tftp来加载和启动Linux ramfs
首先使用ping
命令确保与tftp server连通
U-Boot> ping 192.168.1.100
host 192.168.1.100 is alive
从tftp server端加载和启动Linux ramfs
U-Boot> tftpboot 0x80000000 uImage
U-Boot> tftpboot 0x82000000 emmc.dtb
U-Boot> tftpboot 0x83800000 ramdisk.cpio.gz.u-boot
U-Boot> setenv bootargs 'console=ttySAC2,115200n8 root=/dev/ram0 rw ramdisk_size=0x10000000 loglevel=7'
U-Boot> bootm 0x80000000 0x83800000 0x82000000
这里先通过tftpboot
把内核镜像,DTB以及ramfs镜像加载到内存里,然后配置Linux内核引导参数,最后从内存启动Linux ramfs。