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的源码很熟悉,直接改更方便。 

  

猜你喜欢

转载自www.cnblogs.com/bigsissy/p/11145926.html