U-Boot 是一个主要用于嵌 入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPS、x86、68k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。
在上一个章节中,我们直接使用qemu引导启动了Linux内核,这和实际使用开发板时的情况不符,是因为qemu自带bootloader功能,可以直接引导内核。为了更贴近真实使用场景,本节将探讨如何在qemu搭建的虚拟Vexpress-A9开发板内使用U-boot引导和加载Linux内核。
编译安装U-boot
下载并解压U-boot源码
cd /home/workspace
wget https://ftp.denx.de/pub/u-boot/u-boot-2022.07-rc3.tar.bz2
tar -xvf u-boot-2022.07-rc3.tar.bz2
制作automake_arm32.sh自动编译脚本
cd u-boot-2022.07-rc3
vim automake_arm32.sh
# 在automake_arm32.sh中添加下列代码
# !/bin/bash
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- clean
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- mrproper
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_ca9x4_defconfig O=../objects/u-boot-arm
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig O=../objects/u-boot-arm
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j12 O=../objects/u-boot-arm
运行automake_arm32.sh编译安装U-boot
./automake_arm32.sh
出现以下提示说明U-boot已编译安装完毕
配置主机tftp服务器
安装tftp服务器
sudo apt-get install tftp-hpa tftpd-hpa xinetd
配置tftp路径文件
sudo mkdir -p /sync/tftp
sudo chmod 777 /sync/tftp
sudo vim /etc/default/tftpd-hpa
# 在tftpd-hpa文件下添加以下内容
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/sync/tftp" #该路径即为tftp可以访问到的路径
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
重启tftp服务器
sudo /etc/init.d/tftpd-hpa restart
将设备树和Linux内核文件拷贝到tftp目录下
cd /home/workspace/objects
sudo cp vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /sync/tftp/
sudo cp vexpress-v2p-ca9/arch/arm/boot/uImage /sync/tftp/
主机网络配置详见:WSL2下Ubuntu22.04使用Qemu搭建虚拟Vexpress-A9开发板(三)——挂载根文件系统
sudo tunctl -u root -t tap0
sudo ifconfig tap0 172.16.16.10 promisc up
试运行U-boot
创建qemu-start-uboot-arm32.sh脚本文件
cd /home/workspace/objects
vim qemu-start-uboot-arm32.sh
# 在qemu-start-uboot-arm32.sh内添加以下代码
sudo qemu-system-arm \
-M vexpress-a9 \
-m 512M \
-kernel u-boot-arm/u-boot \
-net tap,ifname=tap0,script=no,downscript=no \
-net nic,macaddr=00:16:3e:00:00:01 \
-nographic \
运行qemu-start-uboot-arm32.sh脚本文件
./qemu-start-uboot-arm32.sh
出现以下界面说明运行成功(注意在Hit any key to stop autooot出现时按任意键进入命令行)
在U-boot命令行下输入以下代码,尝试引导内核
setenv bootargs 'root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc console=ttyAMA0 ip=172.16.16.20'
setenv ipaddr 172.16.16.20
setenv serverip 172.16.16.10
setenv netmask 255.255.0.0
saveenv
tftp 60003000 uImage
tftp 60500000 vexpress-v2p-ca9.dtb
bootm 60003000 - 60500000
出现以下界面说明引导成功
固化U-boot环境变量
在试运行过程中,需要输入代码修改U-boot的环境变量,如果每次启动都需要如此,则太过麻烦。真实开发板由于内置了NAND/MMC Flash,修改后的环境变量可以使用saveenv保存下来,但是我们这部分还没有把NAND/MMC相关支持完全做好。因此需要在U-boot源码上做一些修改,将环境变量固化下来。
修改配置文件
cd /home/workspace/u-boot-2022.07-rc3
vim configs/vexpress_ca9x4_defconfig
# 将CONFIG_BOOTCOMMAND的值修改为:
CONFIG_BOOTCOMMAND="tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc ip=172.16.16.20 console=ttyAMA0';bootm 0x60003000 - 0x60500000;"
修改头文件
vim include/configs/vexpress_common.h
// 在vexpress_common.h文件末尾#endif之前添加以下代码:
#define CONFIG_IPADDR 172.16.16.20
#define CONFIG_NETMASK 255.255.0.0
#define CONFIG_SERVERIP 172.16.16.10
重新编译U-boot
./automake_arm32.sh
编译完成后,进入objects目录运行U-boot
cd /home/workspace/objects
./qemu-start-uboot-arm32.sh
运行结果应与试运行成功引导内核后一致。