qemu模拟vexpress开发板(续)
Posted bigsissy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qemu模拟vexpress开发板(续)相关的知识,希望对你有一定的参考价值。
1. 问题描述
续接上文,利用qemu模拟cortex-a9开发板,流程:qemu ===> u-boot ===> kernel ===> nfsroot
||
======> ramdisk
进行到kernel引导根文件系统时,总是失败。经过尝试,终于解决了!!!
2. 解决方法
2.1 关于bootargs
前文说过,u-boot可以通过 bootargs 这个环境变量来传递参数给内核,那么可以传递哪些参数?格式又是如何?这个问题我找了好久,还是有些糊涂,我曾试图到u-boot的官网上去找找文档,结果登不上。。。昨天又试了一下,登上了!
有提示:可以在 Documentation/initrd.txt 和 Documentation/nfsroot.txt 找到相关内容。因为我这边主要是无法挂载nfs,所以可以先看看关于这个的说明:
按照这个说明,我们可以把参数写到u-boot中的vexpress_common.h 中,主要是IP那一项。
1 /* Basic environment settings */ 2 #if 0 3 #define CONFIG_BOOTCOMMAND "run bootflash;" //注释原有宏 4 #endif 5 6 #define CONFIG_IPADDR 192.168.222.21 7 #define CONFIG_NETMASK 255.255.255.0 8 #define CONFIG_SERVERIP 192.168.222.20 9 #define CONFIG_GATEWAYIP 192.168.222.1 10 11 /* 12 "setenv bootargs ‘root=/dev/nfs nfsroot=192.168.222.20:/source/rootfs_qemu, " 13 "proto=tcp,nfsvers=3,nolock rw console=ttyAMA0,init=/linuxrc ip=192.168.222.21‘; " 14 */ 15 #define CONFIG_BOOTCOMMAND 16 "tftp 0x60008000 uImage4; " 17 "tftp 0x63000000 vexpress-v2p-ca9.dtb; " 18 "setenv bootargs ‘root=/dev/nfs nfsroot=192.168.222.20:/source/rootfs_qemu, " 19 "proto=tcp, nfsver=3, nolock rw console=ttyAMA0, init=/linuxrc " 20 "ip=192.168.222.21:192.168.222.20:192.168.222.1:255.255.255.0‘; " 21 "bootm 0x60008000 - 0x63000000; "
编辑好后保存退出,重新编译u-boot。然后运行qemu,结果如下。我们设置的IP参数的确传递给了内核,但是仍然无法挂载根文件系统!
那么问题到底出现在哪呢?首先根文件系统是没问题的,之前测试过,nfs服务应该也没问题(其实有问题,但我没有往这个方向想,因为我用实际的板子挂载过),我一直怀疑是虚拟机的网络设置有问题,但是不知道怎么验证。后来,我在网上看到这么一句话:用kernel挂载ramdisk,然后尝试连接主机的nfs服务。前文说过,用kernel直接挂载ramdisk,我这里是可行的,所以值得一试。
2.2 在kernel中ping主机测试
前文用的kernel是linux3.4.4,我之前看到的博文好多说要加载设备树,但是我没加载设备树也能启动kernel,并且这个版本的设备树,我使用 make dtbs 无法编译,即使我用 make mrproper 清空了之前的编译文件。所以,我又下载了一个kernel,linux-4.20.4。按照前文的步骤来一遍,发现的确需要设备树,否则无法启动内核。下面的第8行即是附加设备树选项。设备树文件在 arch/arm/boot/dtbs/ 目录下,后缀名为 dts,这个是可以直接编辑的,使用 make dtbs 可以编译设备树文件,生成后缀名为 dtb 二进制文件。
1 sudo qemu-system-arm 2 -M vexpress-a9 3 -m 256M 4 -kernel arch/arm/boot/zImage 5 -nographic 6 -append "root=/dev/mmcblk0 rw console=ttyAMA0" 7 -sd ~/qemu_linux/rootfs.ext3 8 -dtb /tftpboot/vexpress-v2p-ca9.dtb 9 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0
然后 ifconfig 看看本地网络设备,发现只有 lo 这个本地回传地址,编辑 /etc/init.d/rcS 这个脚本,文末加上
ifconfig eth0 192.168.222.21
重启qemu,用 ifconfig 查看,可以发现 eth0 启动了,接下来,ping 主机IP,发现可以ping通,说明qemu的网络没有问题。那么显然,还是nfs有问题。
2.3 在kernel中挂载nfs测试
挂载主机的nfs:
然后我看了下主机 nfs 的配置,/etc/exports,终于发现了问题,之前使用实际的板子挂载/source/rootfs,所以这里设置的共享路径是/source/rootfs,但是这个虚拟机挂载的根文件是/source/rootfs_qemu,难怪挂载不上。修改成/source ,重启主机 nfs 服务。
1 sudo service nfs-kernel-server restart
再运行qemu,终于成功了。
1 sudo qemu-system-arm 2 -M vexpress-a9 3 -kernel u-boot 4 -nographic 5 -m 512M 6 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0
3. 总结
关于u-boot中的bootm、bootargs等参数的设置,其实还有一些不清楚的地方。单说vexpress,在u-boot-2015-04这个版本中,CONFIG_BOOTCOMMAND这个宏是定义在vexpress_common.h中,我们可以直接修改,但是在后面的u-boot版本中,比如说u-boot-2018 中,CONFIG_BOOTCOMMAND这个宏定义在了 /include/config_distro_bootcmd.h 中,而且看起来更加复杂。
我感觉直接改这些文件并不是官方推荐的做法,我找了几个案例,是通过在u-boot交互模式中设置环境变量来进行配置,当然如果对u-boot的源码很熟悉,直接改更方便。
以上是关于qemu模拟vexpress开发板(续)的主要内容,如果未能解决你的问题,请参考以下文章
Qemu搭建ARM vexpress开发环境----NFS网络根文件系统
qemu模拟vexpress-a9及u-boot引导 linux
VMware Ubuntu 20.04 LTS 使用Qemu虚拟机u-boot启动或者配合busybox模拟ARM开发板