qemu模拟vexpress开发板

1. 问题背景

  最近了解到一个强大的开源虚拟机软件:qemu。利用它可以仿真arm板,正好可以用来巩固一下移植相关的操作。网上关于qemu仿真vexpress开发板的例子较多,我试了几个,感觉还是下面这篇文章比较靠谱:

  https://www.cnblogs.com/pengdonglin137/p/5023342.html 。目前我进行到用qemu加载u-boot,或者加载内核并挂载ramdis根文件系统,也可以利用u-boot来引导内核启动,但是无法挂载根文件系统。


2. 环境介绍

  虚拟机系统:Ubuntu 14.04

  u-boot:           u-boot-2015-04

  linux kernel:   linux-3.4.4

  busybox:        busybox-1.21.0

  toolchain:       arm-none-linux-gnueabi-   (4.6.4)

  qemu:            QEMU emulator version 1.7.91

  这个qemu是直接通过apt在线安装的,在模拟某个arm板前,先看看qemu支不支持。

1 qemu-system-arm -M ?

 


3. U-boot配置

3.1 u-boot缺省配置

  在u-boot-2015.04目录下,先看看关于vexpress的默认配置有哪些,这里我们选vexpress_ca9x4_defconfig来进行默认的配置,使用make指令,可以在命令行指定架构和交叉编译器,也可以写死在Makefile中。 

1 ls configs/ | grep vexpress
2 make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- vexpress_ca9x4_defconfig

 

3.2 u-boot环境变量

  这里主要设置bootargs,bootcmd和bootm。我们可以把这些东西写死到include/configs/vexpress_common.h中,否则就要进入u-boot后手动敲命令设置,而且设置好后也不能save(没有flash)。

  bootcmd:对应宏CONFIG_BOOTCOMMAND,是u-boot启动时会自动执行的命令。

  bootargs:是u-boot传递内核的参数。

  bootm: ${kernel_addr} ${ramdisk_addr} ${dtb_addr}  依次是内核镜像地址,根文件镜像地址,设备树地址

211 /* Basic environment settings */     
212 #if 0                              
213 #define CONFIG_BOOTCOMMAND      "run bootflash;"  //将原有的宏注释掉
214 #endif                             
215                                    
216 #define CONFIG_IPADDR    192.168.222.21  //本机IP
217 #define CONFIG_NETMASK   255.255.255.0   //掩码
218 #define CONFIG_SERVERIP  192.168.222.20  //服务器IP:tftp服务和nfs服务
219                                    
220 #define CONFIG_BOOTCOMMAND \       
221     "tftp 0x60008000 uImage3.4.4; " \
222     "tftp 0x63000000 ramdisk_zy.img; " \
223     "setenv bootargs root=/dev/mmcblk0 console=ttyAMA0; " \
224     "bootm 0x60008000 0x63000000; " 

3.3 生成u-boot.bin

  同样使用make指令,指定一下ARCH和CROSS_COMPILE。后面的-j2是指定2个核同时编译,增加编译速度。目标文件是一个二进制文件,u-boot.bin,这就是要烧写到flash或者qemu要加载的对象。

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j2

  

  生成好u-boot后,先用qemu测试一下能否加载。这里参数的意义就直接抄过来吧。

-M vexpress-a9 模拟vexpress-a9单板,你可以使用-M ?参数来获取该qemu版本支持的所有单板

-m 512M 单板运行物理内存512M

-kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage  告诉qemu单板运行内核镜像路径

-nographic 不使用图形化界面,只使用串口

-append "console=ttyAMA0" 内核启动参数,这里告诉内核vexpress单板运行,串口设备是哪个tty。

 20     qemu-system-arm \
 21         -M vexpress-a9 \
 22         -m 256M \   
 23         -kernel /home/linux/qemu_linux/u-boot-2015.04/u-boot \
 24         -serial stdio \
 25         -append "root=/dev/mmcblk0 nolock rw console=tty0" \

  启动后使用print指令打印环境变量,可以发现在3.2中设置的环境变量在u-boot中有所体现。

  


4. Linux内核配置

  和u-boot的配置步骤类似。先找找缺省配置文件。

ls arch/arm/configs/ | grep vexpress

  

  make 默认配置。

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- vexpress_defconfig

4.1 内核加载地址和启动选项配置

  编译内核我们可以通过menucofig先看一下具体的配置内容。在boot option中我们可以配置一下下图中的内容,这是用来设定内核启动一些参数,可以通过boot loader来传递参数(bootargs),也可以设定默认参数。

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig

  编译内核。这里要说明一下LOADADDR=0x60008000,在上一篇博客我有简单的搜集一些资料,可以参考(虽然还是似懂非懂。。。),不过按照设置可以在qemu中跑起来。这里的LOADADDR我是参考arch/arm/mach-vexpress/Makefile.boot来设置的,其内容如下图。

这里直接生成了uImage(用于u-boot引导),当然zImage也会同时生成。如果编译过程中提示缺少mkimage工具,可以通过apt在线安装,也可以自己下,这里就不再多说。

make LOADADDR=0x60008000  ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage -j2

  

  同样,可以先用qemu加载一下。内核可以起来,但是由于没有指定根文件系统,内核会报错。所以下一步我们要制作根文件系统。

 20     qemu-system-arm \
 21         -M vexpress-a9 \
 22         -m 256M \   
 23         -kernel uImage \
 24         -serial stdio \
 25         -append "root=/dev/mmcblk0 nolock rw console=tty0" \

  


5.  busybox制作根文件系统

5.1 配置busybox

  本文制作的根文件系统 = busybox(包含基础的Linux命令)  + 运行库 。那么根文件系统放在哪里?依赖于每个开发板支持的存储设备,可以放到Nor Flash上,也可以放到SD卡,甚至外部磁盘上。最关键的一点是你要清楚知道开发板有什么存储设备。

   进入busybox,运行  make menuconfig。配置静态建立busybox。

File systems --->
		Pseudo filesystems ---> 
			[*] Virtual memory file system support (former shm fs)
			[*] Tmpfs POSIX Access Control Lists

  

  然后运行 make install  。完成后,会在busybox目录下生成_install目录,该目录下的程序就是单板运行所需要的命令。将这里面的内容全部复制到一个新建的文件夹,如rootfs下面。

  还有很重要的一点就是etc/目录下的内容,这里一般有4个文件,可以手动进行配置,也可以直接从网上下。https://files.cnblogs.com/files/pengdonglin137/etc.tar.gz

 

  简单说一下4个文件的作用:

  1. /etc/fstab 文件负责配置Linux开机时自动挂载的分区。
  2. rcS是一个脚本文件,在inittab文件中本解析调用,用于配置Linux系统。这个可以参考https://www.cnblogs.com/lp1129/articles/3148858.html
  3. init程序需要读取配置文件/etc/inittab.inittab是一个不可执行的文本文件,它有若干行指令所组成。可以参考https://www.cnblogs.com/jason-lu/articles/3272963.html
  4. /etc/profile:这个文件是每个用户登录时都会运行的环境变量设置,注意是全局的

  到目前为止,一个mini的根文件系统就制作好了,我们可以通过nfs来直接挂载到这个rootfs,也可以把它制作成ramdisk镜像,直接烧录到flash中。

5.2 制作ramdisk镜像

  运行以下命令,这里解释一下4-7的作用,先创建一个临时目录,用于挂载制作好的根文件系统,再把rootfs的内容复制到这个根文件系统中,类似于我们平时使用u盘。

1 sudo dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
2 sudo mkfs.ext3 rootfs.ext3
3 
4 sudo mkdir -p tmpfs
5 sudo mount -t ext3 rootfs.ext3 tmpfs/ -o loop
6 sudo cp -r rootfs/*  tmpfs/
7 sudo umount tmpfs·

  接下来,用qemu加载内核和ramdisk。最后的 -sd 即是模拟一个sd卡,里面存放着跟文件系统。

qemu-system-arm \
    -M vexpress-a9 \
    -m 256M \
    -kernel /home/linux/qemu_linux/linux-3.4.4/arch/arm/boot/zImage \
    -nographic \
    -append "root=/dev/mmcblk0 rw console=ttyAMA0" \
    -sd ~/qemu_linux/rootfs.ext3

 

 6. 结果

  理想结果,用qemu加载u-boot,再通过u-boot来引导内核,内核直接加载ramdisk,或者通过nfs来加载rootfs。

  实际结果:上面黄字标注的没有实现成功。。。

  如下图,u-boot自启动后成功从tftp服务器下载了内核镜像和ramdisk。

  但是无法挂载根文件系统:

 

  

 

posted @ 2019-07-07 10:16  bigsissy  阅读(4149)  评论(0编辑  收藏  举报