WSL2下Ubuntu22.04使用Qemu搭建虚拟Vexpress-A9开发板(六)——U-boot+emmc启动

        在第四部分《通过U-boot引导加载内核》中,我们发现U-boot的环境变量修改后无法保存,需要修改源代码来固化环境变量,对启动参数的修改造成了不便。因此本节将继续深入探讨如何将U-boot的环境变量存储在emmc内,同时使用emmc存储Linux内核、设备树以及根文件系统,并在此基础上尝试引导启动最小Linux操作系统。

制作emmc镜像文件

        本节制作的emmc镜像文件共256MB,分为两个部分,第一部分存放uImage和dtb,大小为32MB,第二部分存放根文件系统,大小为224MB。

创建挂载路径

sudo mkdir /mnt/rootfs
sudo mkdir /mnt/uboot

创建自动打包脚本

cd /home/workspace/objects
vim makefs-arm32.sh

# 将makefs-arm32.sh的内容替换为以下内容
dd if=/dev/zero of=rootfs-arm.ext3 bs=1M count=256

echo "hard disk partition!"
sgdisk -n 0:0:+32M -c 0:uboot rootfs-arm.ext3
sgdisk -n 0:0:0 -c 0:rootfs rootfs-arm.ext3
sgdisk -p rootfs-arm.ext3

echo "mount loop device!"
LOOPDEV=`losetup -f`
echo $LOOPDEV
sudo losetup $LOOPDEV  rootfs-arm.ext3
sudo partprobe $LOOPDEV
sudo losetup -l
ls -l /dev/loop*

echo "format disk to ext3"
echo ${LOOPDEV}p1
echo ${LOOPDEV}p2
sudo mkfs.ext3 ${LOOPDEV}p1
sudo mkfs.ext3 ${LOOPDEV}p2
sudo mount -t ext3 ${LOOPDEV}p1 /mnt/uboot -o loop
sudo mount -t ext3 ${LOOPDEV}p2 /mnt/rootfs -o loop
sudo cp -rf rootfs-arm32/* /mnt/rootfs/
sudo cp vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/uboot/
sudo cp vexpress-v2p-ca9/arch/arm/boot/uImage /mnt/uboot/
sudo umount /mnt/rootfs/
sudo umount /mnt/uboot/
sudo losetup -d $LOOPDEV

运行自动打包脚本

./makefs-arm32.sh

将生成一个256MB的镜像文件rootfs-arm.ext3

修改U-boot环境变量的保存位置

        上一小节生成的emmc镜像分为两部分,我们把环境变量存储在第一部分最后256KB的位置,以保证它不会与Linux内核和设备树互相干扰。

重新编译U-boot

cd /home/workspace/u-boot-2022.07-rc3
./automake_arm32.sh

        在menuconfig界面设置环境变量存储设备,以及环境变量在设备中的具体位置和大小。由于需要将环境变量存储在emmc镜像的第一个分区的最后256KB位置,所以环境变量的设备号为emmc0,分区号为0,偏移量为0x02000000-0x00040000=0x01FC0000,大小为0x00040000。

menuconfig设置路径为:Environment->Environment in an MMC device 

保存配置后,退出menuconfig,等待U-boot编译完成。

加载U-boot修改环境变量

创建自动运行脚本

cd /home/workspace/objects
vim qemu-start-uboot-arm32-emmc.sh

# 在qemu-start-uboot-arm32-emmc.sh文件内添加以下内容
#!/bin/bash
sudo tunctl -u root -t tap0
sudo ifconfig tap0 172.16.16.10 promisc up
sudo route add -net 172.16.0.0 netmask 255.255.0.0 dev tap0
sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -o eth0 -j MASQUERADE
sudo netfilter-persistent save
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 \
	-sd rootfs-arm.ext3

 运行qemu-start-uboot-arm32-emmc.sh脚本

./qemu-start-uboot-arm32-emmc.sh

在U-boot自动挂载倒计时结束前按任意键进入命令行模式

可以注意到,此时emmc镜像中仍然未存储环境变量,加载的是默认环境变量,bootargs和bootcmd均为此前的预设值。

在U-boot命令行中输入以下代码

setenv bootargs 'root=/dev/mmcblk0p2 rw console=ttyAMA0,38400n8'
setenv bootcmd "load mmc 0:1 0x60003000 uImage;load mmc 0:1 0x60500000 vexpress-v2p-ca9.dtb;bootm 0x60003000 - 0x60500000;"
saveenv

保存成功后,重新启动U-boot

reset

U-boot将顺利运行,从rootfs-arm.ext3镜像文件中引导内核、设备树以及根文件系统。

猜你喜欢

转载自blog.csdn.net/cotex_A9/article/details/132403724