转自:http://www.cnblogs.com/riskyer/p/3366001.html
qemu
本文介绍了如何编译u-boot、linux kernel,然后用qemu启动u-boot和linux kernel,达到与开发板上一样的学习效果! 虽然已经买了2440开发板,但是在实际学习开发过程中,还是觉得不方便,既然这样,那就用qemu模拟2440开发板,让学习来的更方便些吧!有些万一模拟机上模拟不出来的或者有问题的,再到开发板上验证! 下面是我5天正常上班工作之余的时间的成果,很开心,因为我感觉又像linux大神迈进了一大步!//:: 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 . 首先下载安装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=,一般来说编译速度会更快些) 然后将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 *)。 方法一: . 下载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需要使用此工具。 . 下载 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= 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= -net tap,vlan=,ifname=tap0-monitor telnet::,server,nowait 此处经常报错Could not initialize device 'tap',网上给了一堆无用答案,实际上是要初始化一个虚拟网卡,看方法二。 其他的就不想分析了,此处就提供方法二qemu-system-arm多种实用参数吧! 方法二: QEMU模拟FriendlyArm的Mini2440开发板 本文基于的开发环境是Ubuntu10.04和buildroot-2012.05.tar.gz。(其他版本的环境可能会出很多问题,所以编译u-boot和kernel时统一用此buildroot中的交叉编译工具) . 下载编译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..x。后面的Kernel(内核版本)我使用的是3.3.7,所以没问题,这里不用改也可以。当然也可以使用诸如3..x这样的版本,只要跟之后的Kernel版本适配就好了。 - Bootloaders :默认是U-boot,也可以选用其他版本的Bootloader。本文就用默认的U-boot。 - Kernel :Kernel version默认是3.0.4,因为之前Toolchains目录选择的是3..x版本,所以这里须要改选,比如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 KB erasesize。 这些都配置好之后,就可以请出我们最喜欢的命令了-- make : $ make 此时你可以倒杯茶,或者可以烤一只鸡。。。总之干点别的,让Buildroot忙活去吧。如果中间出现错误,一般是没装必要的东西,照错误提示安装就好,然后接着make。 如果一切顺利,make 结束后,在buildroot-.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..tar.bz2,然后用下面两条命令对其进行编译,是一样的。 $ make mini2440_defconfigARCH=arm 使用默认配置 $ make menuconfigARCH=arm 配置内核的时候要带选项 $ make -j4 ARCH=armCROSS_COMPILE=arm-linux- uImage 编译内核 待会儿就知道,这个目录有多帅,默认就可以在qemu中正确运行^_^ . 在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字节。总共需要的块数是:( * * ) / = 用dd 命令来生成一个NAND镜像: $ dd if=/dev/zero of=nand/nand.bin bs= count= 我们现在有了一个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 Bad block table not found for chip 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/(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 $ 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*,是竖着的) MINI2440 # nboot kernel MINI2440 # setenv bootargs root=/dev/mtdblock3rootfstype=jffs2 console=ttySAC0, mini2440=3tb MINI2440 # saveenv MINI2440 # bootm 输入Buildroot的密码,默认是 root 我们再一次看到了亲切的小企鹅。 (用Vmware 6.5.2build- | ubuntu-10.04.-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..tar.bz2时,kernel中后不断出错:WARNING:at drivers/mtd/nand/nand_base.c: nand_wait+0x14c/0x16c() [<c0148ff8>] (jffs2_flush_wbuf_gc+0xb8/0x13c)from [<c002a9b0>] (process_one_work+0x10c/0x350)) 实际使用过程中的说明: 、qemu-system-arm -M mini2440 -serial stdio -mtdblock nand.bin -usbdevicemouse 在nand.bin中可以不需要u-boot.bin,在当前执行这条命令的文件夹下有u-boot.bin即可,一开始进入的u-boot是当前目录下的u-boot.bin。 、用jz2440的u-boot.bin可以在menu中f选项格式化nandflash文件nand.bin。 、u-boot中可以使用tftp下载文件到内存,使用tftp是只需要设置服务器IP即可,自己的ip设置后无法ping通。使用u-boot中的tftp前提是按照b)中设置网卡和启动方式。 、在启动qemu时如果出现错误Floating point exception (core dumped),可以添加-nographic选项,在通常情况下,Qemu使用SDL来显示VGA输出.使用这个选项,我们可以禁止所有的图形输出,这样Qemu只是一个简单的命令行程序.模拟的串口将会重定向到命令行.所以,我们仍然可以在Qemu平台上使用串口命令来调试Linux内核. 、带网络功能,不带图形界面的启动命令: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// :: PM 、u-boot可以与主机tftp的设置为:ipaddr=10.0.0.111 serverip=10.27.100.117 tap0 10.27.100.200 不在一个网段,不知道为什么,现在能用就行了 、开发板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/(rw,sync,no_root_squash,no_subtree_check) 的ip地址为*即可。 、进入u-boot后以nfs挂载跟文件系统:setenv bootargs 'noinitrdmem=64M console=ttySAC0 root=/dev/nfs nfsroot=10.27.100.117:/work/nfs/nfsrootip=10.0.0.111' 以后开发应用程序或者驱动模块就方便了。 、 qemu 调试
调试U-Boot 当调用QEMU时添加 -s 和-S 选项 •-s -gdbtcp:: 的所写 •-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 : (gdb) b do_printenv Breakpoint at 0x10080f4: file cmd_nvedit.c, line . (gdb) c Continuing. 此时在QEMU的控制台窗口中, 将会有如下显示: U-Boot 2010.06 (Aug - ::) DRAM: Bytes Flash: MiB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: SMC91111- VersatilePB # 在提示符"VersatilePB#"后输入U-Boot命令"printenv",它的执行将会被gdb中断: VersatilePB # printenv 在gdb的控制台窗口中, 将会显示: Breakpoint , do_printenv (cmdtp=0x1015520, flag=, argc=,argv=0xfddee4) at cmd_nvedit.c: if (argc == ) { (gdb) 从这儿开始我们就可以使用普通的gdb调试命令进行调试了, 不错! qemu-common
在Linux下编译安装QEMU在Linux下编译安装QEMU .系统环境及版本 Linux发行版本:ubuntu 8.04 安装QEMU-0.9. .准备工作 在QEMU主页http://wiki.qemu.org/Index.html下载源代码并解压 建立编译环境: $ sudo apt-get install build-essential 编译安装QEMU,最重要的工具就是gcc。在大多数主机,特别是x86架构的PC机上,gcc .x是不被QEMU所支持的。build-essential中包含的是gcc .x,为了正确编译,需要低版本的gcc .x(gcc32 或gcc34),低版本安装后,QEMU的配置脚本(configure script)在配置时会自动搜寻到。我安装的是gcc 3.4: $ sudo apt-get install gcc-.4cpp-3.4 安装QEMU需要SDL开发库的支持,可以在其下载页面上下载源代码编译安装,但是推荐在apt中安装,不容易出问题: $ sudo apt-get install libsdl1.-dev 另外,还需要安装zlib和ESD: sudo apt-get install zlib1g-dev zlib1g-dbg libesd0-dev 编译安装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安装完成。 .设置环境变量 如果./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。