qemu 模拟-arm-mini2440开发板-启动u-boot,kernel和nfs文件系统
qemu
本文介绍了如何编译u-boot、linux kernel,然后用qemu启动u-boot和linux kernel,达到与开发板上一样的学习效果!
虽然已经买了2440开发板,但是在实际学习开发过程中,还是觉得不方便,既然这样,那就用qemu模拟2440开发板,让学习来的更方便些吧!有些万一模拟机上模拟不出来的或者有问题的,再到开发板上验证!
下面是我5天正常上班工作之余的时间的成果,很开心,因为我感觉又像linux大神迈进了一大步!10/12/20139:13:23 PM
qemu-mini2440
http://repo.or.cz/w/qemu/mini2440.git
这个可以在windows下模拟mini2440,核心及全部外设,液晶包括其中。可以在程序窗口
中显示。还可以模拟sd卡,以及DM9000网卡驱动,可以映射到本地虚拟网卡上。
Get a local copy of the mini2440 repository with this command:
git clone https://code.google.com/p/mini2440/
git clone git://repo.or.cz/qemu/mini2440.git
mini2440 u-boot
git clone git://repo.or.cz/u-boot-openmoko.git
使用qemu 建立mini2440的模拟仿真环境
http://www.cnblogs.com/jinmu190/archive/2011/03/21/1990698.html
1. 首先下载安装qemu for mini2440
git clone git://repo.or.cz/qemu/mini2440.gitqemu
如果感觉速度慢,直接打包下载
http://repo.or.cz/w/qemu/mini2440.git/snapshot/HEAD.tar.gz
解压后,源代码的主目录中:
$ ./configure--target-list=arm-softmmu --prefix=/usr/local/qemu/mini2440
$ make -j4
$ sudo make install
(其中--prefix=/usr/local/qemu/mini2440表示install的目录;make -j4表示4个目标同时构建,jobs=4,一般来说编译速度会更快些)
然后将bin路径添加到环境变量中方便使用qemu-system-arm
可能出现的错误:
Error: zlib checkfailed:sudo apt-get install zlib1g-dev
ERROR: QEMU requiresSDL or Cocoa for graphical output:sudo apt-get -y installlibsdl-dev
下面两种方法都可以实现mini2440在qemu上运行,使用的qemu都是上面步骤1生成安装的,不能apt-get install,自动安装的对mini2440单板不支持。
测试安装结果:
我们可以从QEMU下载页面中下载arm-test-0.2.tar.gzhttp://wiki.qemu.org/download/arm-test-0.2.tar.gz这是ARM Linux 2.6的测试内核和initrd磁盘镜像(感谢Paul Brook)。
方法一:
2. 下载u-boot for mini2440
git clone git://repo.or.cz/u-boot-openmoko/mini2440.gitu-boot
或者打包下载
http://repo.or.cz/w/u-boot-openmoko/mini2440.git/snapshot/HEAD.tar.gz
(注意采用打包下载的时候这几个包的文件名可能相同,注意区分)解压后,配置Makefile文件,打开Makefile文件,CROSS_COMPILE变量赋值,即自己所使用的交叉编译工具链,比如我的是arm-linux-,保存退出,找不到就不用改,另外(编译uboot的时候,大家可以将设置初始IP的代码修改为自己想要的IP,比如和自己主机IP一个网段,以方便以后的实验))输入
$ make mini2440_config
$ make -j4
几分钟编译完成后,即在当前目录下生成名为 u-boot.bin 的文件,注意如果想在之后使用u-boot 的nfs下载文件功能,需要将net/nfs.c文件中的NFS_TIMEOUT = 2UL修改为 NFS_TIMEOUT = 20000UL 否则会造成nfs文件下载失败。
然后将u-boot.bin文件拷贝到qemu-mini2440/mini2440文件夹下。将tools/mkimage加到环境变量中,kernel生成uImage需要使用此工具。
3. 下载 linux kernelfor mini2440
git clone git://repo.or.cz/linux-2.6/mini2440.gitkernel
(可以使用原mini2440开发板的内核源代码)
$ make mini2440_defconfig ARCH=arm
$ make -j4 ARCH=arm CROSS_COMPILE=arm-linux- uImage
之后会在arch/arm/boot/目录下生成uImage 文件,将此文件复制到qemu目录下的mini2440文件夹下,并将mini2440文件夹中的mini2440_start.sh作如下修改
添加cmd的 kernel 行为-kernel "$base/uImage" \,回到上层目录后运行
$ sh mini2440/mini2440_start.sh
网上说这时应该看到qemu启动后进入了u-boot界面下,输入命令
# bootm
就会看到linux内核启动的画面。
Bullshit!!!!!!!!
让我一步步分析,最多进得去u-boot界面,但怎么可能看得见内核启动画面??!!
但是根据实际情况是看不见linux启动画面的,下面我们看看mini2440_start.sh做了哪些工作?
首先创建一个dd if=/dev/zero of="$name_nand" bs=2112 count=65536为128MB的nand flash镜像文件(包含OOB),但是此nand flash根本没有初始化,里面为全0x00,根本无法运行起来,想要运行起来情况方法二的flashing工具。
后面就是启动模拟器了:
qemu-system-arm-M mini2440 -serial stdio -mtdblock mini2440/ mini2440_nand128.bin -show-cursor-usb -usbdevice keyboard -usbdevice mouse -net nic,vlan=0 -net tap,vlan=0,ifname=tap0-monitor telnet::5555,server,nowait
此处经常报错Could not initialize device 'tap',网上给了一堆无用答案,实际上是要初始化一个虚拟网卡,看方法二。
其他的就不想分析了,此处就提供方法二qemu-system-arm多种实用参数吧!
方法二:
QEMU模拟FriendlyArm的Mini2440开发板
本文基于的开发环境是Ubuntu10.04和buildroot-2012.05.tar.gz。(其他版本的环境可能会出很多问题,所以编译u-boot和kernel时统一用此buildroot中的交叉编译工具)
2. 下载编译Buildroot (2012.05)
一般说来,我们需要三样东西来正常启动一个嵌入式操作系统:引导程序(bootloader),内核镜像和根文件系统镜像。那我们是不是接下来需要下载一个bootloader(比如u-boot,supervivi之类),编译之;下载任意版本的linux内核,编译之(当然要适配mini2440);一点一点生成自己的根文件系统,再制作成jffs2,yaffs2之类的格式呢?编译这三样东西的交叉编译工具链Cross-compiler toolchain 要制作。
交叉编译工具链和根文件系统都是一点一点制作。。。,很费时间()。虽然我们在制作根文件系统时是可以偷懒使用Busybox这样的“瑞士军刀”,但是还不够方便,Buildroot,一款超好用的开源软件,能一次过帮我们把交叉编译工具链和三样东西都生成出来。
首先我们下载Buildroot,Buildroot项目每三个月就有一个新版本,但是最好是使用buildroot-2012.05.tar.gz,其他较新版本会出很多错,最后会说到。首先我们安装wget这个小工具,便于下载Buildroot:
$ sudo apt-get install wget
接着下载Buildroot:
$ cd ~
$ wget http://buildroot.org/downloads/buildroot-2012.05.tar.gz
$ tar zxvf buildroot-2012.05.tar.gz
或者到buildroot主页http://buildroot.uclibc.org/download.html下载http://buildroot.uclibc.org/downloads/buildroot-2012.05.tar.bz2
在让Buildroot为我们生成三个镜像前,需要对其进行一些配置。Mini2440开发板的基本所需配置已经集成在Buildroot里了(众多defconfig文件中的一个),省了不少功夫。在此基础上,我们只需再进行少许配置,就可以让Buildroot开工了。
我们选取mini2440_defconfig来生成我们的.config文件,再用make menuconfig 进一步配置:
$ cd buildroot-2012.05
$ make mini2440_defconfig
$ make menuconfig
一个方便的配置窗口会跟着出现,是基于Kconfig的配置机制:
以下列出比较重要的几个编译选项,需要改动的几项用红色表示:
- Toolchains :在Toolchains目录里,Kernel Headers须要选取Linux内核版本的适配的编译链版本。默认是设置为3.3.x。后面的Kernel(内核版本)我使用的是3.3.7,所以没问题,这里不用改也可以。当然也可以使用诸如3.0.x这样的版本,只要跟之后的Kernel版本适配就好了。
- Bootloaders :默认是U-boot,也可以选用其他版本的Bootloader。本文就用默认的U-boot。
- Kernel :Kernel version默认是3.0.4,因为之前Toolchains目录选择的是3.3.x版本,所以这里须要改选,比如3.3.7版本。
- Package Selection for the target :Target packages中Busybox已经包含在里面了,我们也可以选择更多的项目,比如Qt,EFL,directfb之类的图形库。在Graphic libraries and application子目录里选择。
- Filesystem images :本文中使用的是jffs2格式的根文件系统(也是Buildroot默认的),因为之后要制作NAND镜像,所以需要配置成一个每页512字节和16字节的ECC的NAND类型。在Flash Type这项,改为NAND flash with 512B Page and 16 KB erasesize。
这些都配置好之后,就可以请出我们最喜欢的命令了-- make :
$ make
此时你可以倒杯茶,或者可以烤一只鸡。。。总之干点别的,让Buildroot忙活去吧。如果中间出现错误,一般是没装必要的东西,照错误提示安装就好,然后接着make。
如果一切顺利,make 结束后,在buildroot-2012.05目录的output/images/子目录下可以找到生成的三个文件:
- u-boot.bin :bootloader的镜像
- uImage :u-boot格式的(用mkimage命令生成的)Linux内核镜像
- rootfs.jffs2 :jffs2格式的根文件系统镜像(这个工程默认用的是jffs2根文件系统)
至此,Buildroot完成了他艰巨的任务,可以让他一边休息去了。我们进入下面的系统制作和启动部分。
如果我们想用其中的工具,可以将/work/qemu/buildroot-2012.05/output/host/usr/bin加入到环境变量中。
另外,此工具中的linux源码解压到了:buildroot-2012.05/output/build/linux-3.3.7目录。
也可以用dl目录中的linux-3.3.7.tar.bz2,然后用下面两条命令对其进行编译,是一样的。
$ make mini2440_defconfigARCH=arm 使用默认配置
$ make menuconfigARCH=arm 配置内核的时候要带选项
$ make -j4 ARCH=armCROSS_COMPILE=arm-linux- uImage 编译内核
待会儿就知道,这个目录有多帅,默认就可以在qemu中正确运行^_^
3. 在QEMU中运行编译好的系统
a) 生成NAND镜像并初始化
在开始前,先说一下:如果你想要比较快捷的话,可以直接去看d)、强大的工具-- Flashimg,Flashimg是一个不错的软件,可以使用内核镜像,bootloader镜像和根文件系统镜像快速生成NAND或NOR文件。共享在git 上面,http://gitorious.org/flashimg
如果在QEMU里生成NAND的话,会花不少时间。所以我们可以利用闲置的内存(RAM)-- tmpfs
$ mkdir nand
$ sudo mount -t tmpfs none nand/
我们接下来将从零开始生成一个NAND镜像文件。一般NAND的大小我们可以设定成64MB (NOR镜像文件一般设为2MB)。我们来做一下简单的计算:要生成一个64MB的NAND,每个块是512字节,还要加上16字节的ECC,所以每个块是528字节。总共需要的块数是:(64 * 1024 * 1024) / 528 = 127100
用dd 命令来生成一个NAND镜像:
$ dd if=/dev/zero of=nand/nand.bin bs=528 count=127100
我们现在有了一个NAND镜像文件了,接下来要使用u-boot来初始化它。我们需要首先将Buildroot替我们生成的u-boot.bin 文件拷贝到nand.bin 相同的文件夹下:
$ cp ~/buildroot-2012.05/output/images/u-boot.bin ~/nand/
启动U-boot以便进行NAND的初始化:
$ qemu-system-arm -M mini2440 -serial stdio -mtdblocknand/nand.bin
U-boot启动了,并且会显示一些Warning信息:
NAND: Bad block table not found for chip 0
Bad block table not found for chip 0
64 MiB
*** Warning - bad CRC or NAND, using default environment
别担心,显示这些信息很正常,因为我们的NAND文件还没初始化呢。接下来初始化:
MINI2440 # nand scrub
MINI2440 # nand createbbt
MINI2440 # reset
至此,我们的NAND文件已经准备好了。现在可以将其从tmpfs拷贝到电脑硬盘,然后卸载掉tmpfs。
$ cp nand/nand.bin .
$ sudo umount nand/
$ rmdir nand
b) 基于NFS启动
这里插进一段用NFS启动的实做。
在嵌入式开发阶段,通常我们会操作一个挂载在NFS上的系统,这样更加方便,快捷,无需每次都烧写NAND或NOR文件。接下来我们用NFS启动系统:
之前在~/buildroot-2012.05/output/images/ 这个目录里,除了生成rootfs.jffs2文件外,还生成了rootfs.tar文件,是根文件系统的压缩文件包。我们在/srv 文件夹下新建一个nfsroot文件夹以储存解压的根文件系统:
$ sudo mkdir /srv/nfsroot/
$ cd /srv/nfsroot/
$ sudo tar xvf ~/buildroot-2012.05/output/images/rootfs.tar
接着需要在/etc/exportfs 文件里增加以下一行,使NFS能认识/srv/nfsroot/这个目录:
/srv/nfsroot/ 192.168.42.0/24(rw,sync,no_root_squash,no_subtree_check)
使其生效:
$ sudo exportfs -r
然后,我们生成并配置一个 tap0 接口:
$ sudo tunctl -u $USER -t tap0
$ sudo ifconfig tap0 192.168.42.1
此时ifconfig发现多了一块网卡。
(当启动qemu使用了-net nic -nettap,ifname=tap0参数时,报错warning: could not configure /dev/net/tun: no virtual network emulationCould not initialize device 'tap',就需要按照上面方法配置一下网卡,这才是正解,网上给出的答案又麻烦又无效;但是记住,经过此设置后,ubuntu是无法连接外网的,此设置重启后无效)
现在我们已经可以来启动QEMU了,不过在此之前,还要将uImage也拷贝到HOME目录(nand.bin 已经在HOME目录了):
$ cd ~
$ cp ~/buildroot-2012.05/output/images/uImage .
Ok,我们启动QEMU+NFS:
$ qemu-system-arm -M mini2440 -serial stdio -mtdblocknand.bin -kernel uImage -net nic -net tap,ifname=tap0,script=no,downscript=no
MINI2440 # setenv bootargs root=/dev/nfs rw nfsroot=192.168.42.1:/srv/nfsroot/ip=192.168.42.2
MINI2440 # bootm
输入Buildroot的密码,默认是root, 此时系统启动了,可以看到QEMU的窗口和可爱的Linux小企鹅。
c) 基于NAND镜像启动
因为以之前的a)生成的nand.bin来继续生成最终版的nand.bin(还要往里面添加u-boot.bin,uImage和rootfs.jffs2)过程太过繁琐且容易出错,在此我就不赘述了,可以参看网上的相关文章。我们直接用一个更强大的工具来生成最终版的nand.bin 。更方便,且不容易出错。
d) 强大的工具 -- Flashimg
如前面时提到的,flashimg是一个由网友FabriceJouhaud 开发的软件,可以很快捷地生成NAND或NOR镜像文件。我们首先下载flashimg:
$ git clone git://gitorious.org/flashimg/flashimg.git
编译安装
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
要生成NAND或NOR镜像文件,可以先把之前Buildroot替我们生成的三个文件:u-boot.bin, uImage和rootfs.jffs2 拷贝到flashimg文件夹下,生成NAND或NOR镜像文件:
$ flashimg -s64M -t nand -f nand.bin -p uboot.part -w boot,u-boot.bin -w kernel,uImage -w root,rootfs.jffs2-z 512
$ flashimg-s 2M -t nor -f nor.bin -p uboot.part -w boot,u-boot.bin -w kernel,uImage -w root,rootfs.jffs2
最后,启动系统,我们以NAND文件为例:
$ qemu-system-arm-M mini2440 -serial stdio -mtdblock nand.bin -usbdevice mouse
启动之后,还需要配置一下(其中mini2440=3tb 是为了使屏幕分辨率成为320*240,横向显示。默认是240*320,是竖着的)
MINI2440 # nboot kernel
MINI2440 # setenv bootargs root=/dev/mtdblock3rootfstype=jffs2 console=ttySAC0,115200 mini2440=3tb
MINI2440 # saveenv
MINI2440 # bootm
输入Buildroot的密码,默认是 root
我们再一次看到了亲切的小企鹅。
(用Vmware 6.5.2build-156735 | ubuntu-10.04.2-dvd-i386.iso | qemu-system-arm QEMU PC emulator version0.10.50 | buildroot-2012.05.tar.gz测试通过,如果不使用图形界面运行正常,需要使用图形界面就要用ssh登陆后启动2440系统一次,然后虚拟机中启动2440系统,才能成功看见小企鹅,交替运行,否则报错:Floating point exception;
使用buildroot-2013.08.1.tar.bz2时,kernel中后不断出错:WARNING:at drivers/mtd/nand/nand_base.c:846 nand_wait+0x14c/0x16c() [<c0148ff8>] (jffs2_flush_wbuf_gc+0xb8/0x13c)from [<c002a9b0>] (process_one_work+0x10c/0x350))
实际使用过程中的说明:
1、qemu-system-arm -M mini2440 -serial stdio -mtdblock nand.bin -usbdevicemouse 在nand.bin中可以不需要u-boot.bin,在当前执行这条命令的文件夹下有u-boot.bin即可,一开始进入的u-boot是当前目录下的u-boot.bin。
2、用jz2440的u-boot.bin可以在menu中f选项格式化nandflash文件nand.bin。
3、u-boot中可以使用tftp下载文件到内存,使用tftp是只需要设置服务器IP即可,自己的ip设置后无法ping通。使用u-boot中的tftp前提是按照b)中设置网卡和启动方式。
4、在启动qemu时如果出现错误Floating point exception (core dumped),可以添加-nographic选项,在通常情况下,Qemu使用SDL来显示VGA输出.使用这个选项,我们可以禁止所有的图形输出,这样Qemu只是一个简单的命令行程序.模拟的串口将会重定向到命令行.所以,我们仍然可以在Qemu平台上使用串口命令来调试Linux内核.
5、带网络功能,不带图形界面的启动命令:qemu-system-arm -M mini2440-serial stdio -mtdblock nand.bin -usbdevice mouse -kernel uImage -net nic -net tap,ifname=tap0,script=no,downscript=no-nographic
我真发现我是个天才!!嘿嘿嘿嘿,qemu上模拟2440开发基本全部搞定,u-boot/kernel/nfs文件系统10/12/2013 8:58:58 PM
6、u-boot可以与主机tftp的设置为:ipaddr=10.0.0.111 serverip=10.27.100.117 tap0 10.27.100.200 不在一个网段,不知道为什么,现在能用就行了
7、开发板nfs访问虚拟机,ifconfig 10.0.0.111 mount -t nfs -o nolock 10.27.100.117:/work/nfs/nfsroot/work 如果mount:mounting 10.27.100.117:/work/nfs/nfsroot on /mnt failed: Permission denied 则修改服务器的/work/nfs/nfsroot/10.27.100.117/24(rw,sync,no_root_squash,no_subtree_check) 的ip地址为*即可。
8、进入u-boot后以nfs挂载跟文件系统:setenv bootargs 'noinitrdmem=64M console=ttySAC0 root=/dev/nfs nfsroot=10.27.100.117:/work/nfs/nfsrootip=10.0.0.111' 以后开发应用程序或者驱动模块就方便了。
9、
qemu 调试
调试U-Boot
当调用QEMU时添加 -s 和-S 选项
•-s -gdbtcp::1234 的所写
•-S 在启动时停止CPU (键入'c'才会开始执行)
$ qemu-system-arm -M versatilepb -nographic-kernel u-boot -s -S
调试U-Boot时,加载文件'u-boot'到gdb(记住不是'u-boot.bin'),'u-boot'是一个ELF格式的文件,它含有所有调试时会用到的符号信息,不像'u-boot.bin'是在执行"stripe"命令后,剔除了调试信息的文件。另开一个控制台窗口执行ARM的交叉调试工具并加载文件'u-boot':
$ arm-none-linux-gnueabi-gdb u-boot
(gdb) target remote :1234
(gdb) b do_printenv
Breakpoint 1 at 0x10080f4: file cmd_nvedit.c, line 147.
(gdb) c
Continuing.
此时在QEMU的控制台窗口中, 将会有如下显示:
U-Boot 2010.06 (Aug 312010 - 16:23:16)
DRAM: 0 Bytes
Flash: 64 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: SMC91111-0
VersatilePB #
在提示符"VersatilePB#"后输入U-Boot命令"printenv",它的执行将会被gdb中断:
VersatilePB # printenv
在gdb的控制台窗口中, 将会显示:
Breakpoint 1, do_printenv (cmdtp=0x1015520, flag=0, argc=1,argv=0xfddee4)
at cmd_nvedit.c:147
147 if (argc == 1) {
(gdb)
从这儿开始我们就可以使用普通的gdb调试命令进行调试了, 不错!
qemu-common
在Linux下编译安装QEMU在Linux下编译安装QEMU
1.系统环境及版本
Linux发行版本:ubuntu 8.04
安装QEMU-0.9.1
2.准备工作
在QEMU主页http://wiki.qemu.org/Index.html下载源代码并解压
建立编译环境:
$ sudo apt-get install build-essential
编译安装QEMU,最重要的工具就是gcc。在大多数主机,特别是x86架构的PC机上,gcc 4.x是不被QEMU所支持的。build-essential中包含的是gcc 4.x,为了正确编译,需要低版本的gcc 3.x(gcc32 或gcc34),低版本安装后,QEMU的配置脚本(configure script)在配置时会自动搜寻到。我安装的是gcc 3.4:
$ sudo apt-get install gcc-3.4cpp-3.4
安装QEMU需要SDL开发库的支持,可以在其下载页面上下载源代码编译安装,但是推荐在apt中安装,不容易出问题:
$ sudo apt-get install libsdl1.2-dev
另外,还需要安装zlib和ESD:
sudo apt-get install zlib1g-dev zlib1g-dbg libesd0-dev
3 编译安装QEMU
$ ./configure --prefix=/usr/local/qemu
不加上prefix选项也是可以的。这个选项的作用是指定安装目录。如果不指定prefix,则可执行文件默认放在/usr/local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc。由于QEMU不能用make uninstall的方法卸载,指定安装目录可以便于卸载(其实就是删掉整个安装目录)。
然后
$ make
$ sudo make install
至此,QEMU安装完成。
4.设置环境变量
如果./configure时使用了prefix选项,还需要设置环境变量PATH,否则bash是找不到qemu的命令的(除非你输入该命令的具体路径,如/usr/local/qemu/bin/qemu)。编辑/etc/profile
$ sudo vim /etc/profile
在文件中添加
PATH="$PATH:/usr/local/qemu/bin"export PATH
保存,退出,并用Ctrl+Alt+Backspace重新启动X Window。