Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1515038
  • 博文数量: 230
  • 博客积分: 474
  • 博客等级: 下士
  • 技术积分: 1955
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 18:40
文章分类

全部博文(230)

文章存档

2020年(3)

2019年(3)

2018年(12)

2017年(13)

2016年(11)

2015年(55)

2014年(74)

2013年(39)

2012年(2)

2011年(18)

我的朋友

分类: 虚拟化

2015-08-11 15:28:05

转自:http://blog.csdn.net/pll621/article/details/6458003

Jump to: navigationsearch

如果你想拥有一块开发板,而又不想花钱,那你就可以自己做一个虚拟开发板。

虚拟开发板是用QEMU模拟出来的一块板子,实际上就是一个虚拟机。

Contents

[hide]

调试模式

QEMU

下载QEMU

通常我们有两种方式来获取源代码:

   $ tar zxvf qemu-0.13.0.tar.gz
  • 用git工具来抓取源代码:
   $ git clone git://git.qemu.org/qemu.git

安装QEMU

现在我们可以进到QEMU的源代码目录中,执行以下命令安装QEMU的ARM仿真部分到本机的'/opt/qemu/'目录下

   $ ./configure --prefix=/opt/qemu --target-list=arm-softmmu,arm-linux-user --enable-debug
   $ make -s
   $ make install -s

添加 "PATH=/opt/qemu/bin:$PATH" 到文件 '/etc/profile' 中, 然后执行以下命令,就可以在控制台直接运行QEMU相关命令了

   $ . /etc/profile

我们可以从QEMU下载页面中下载arm-test-0.2.tar.gz, 这是ARM Linux 2.6的测试内核和initrd磁盘镜像(感谢Paul Brook)。

   $ tar zxvf arm-test-0.2.tar.gz
   $ cd arm-test
   $ qemu-system-arm -kernel zImage.integrator -initrd arm_root.img -nographic -append "console=ttyAMA0"

命令将启动一个带命令行的ARM虚拟机,键入"CTRL-a x"可以退出。好了,安装完成。

bootloader

准备交叉编译工具

打开网页Sourcery G++ Lite Edition for ARM,依次点击" GNU/Linux > Packages > Recommended Packages > IA32 GNU/Linux Installer"。 下载后,将它安装到目录'/opt'中:

   $ chmod +x arm-VERSION-arm-none-linux-gnueabi.bin
   $ ./arm-VERSION-arm-none-linux-gnueabi.bin

安装完成后,我们可以在目录'/opt/CodeSourcery/Sourcery_G++_Lite/bin'中找到我们需要的交叉编辑工具。可以写一个"hello world"测试程序来测试一下它们:

   $ sudo mkdir -p /usr/gnemul
   $ sudo ln -sf /opt/CodeSourcery/Sourcery_G++_Lite/arm-none-linux-gnueabi/libc /usr/gnemul/qemu-arm
   $ arm-none-linux-gnueabi-gcc -o hello hello.c
   $ qemu-arm hello

如果我们可以看到有"hello world"或者别的你让输出的字符出现在屏幕上了, 交叉编译工具就准备好了.

下载U-Boot

   $ git clone git://git.denx.de/u-boot.git

交叉编译U-Boot

到U-Boot的根目录下,然后执行:

   $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- versatilepb_config
   $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -s

在目录下将会产生文件'u-boot'和'u-boot.bin'。

同时我们也可以在'tools'目录中得到工具"mkimage", 在编译Linux内核uImage时将会用到它,所以

   $ sudo ln -sf `pwd`/tools/mkimage /usr/local/bin/mkimage

现在我们可以在控制台中启动U-Boot了:

   $ qemu-system-arm -M versatilepb -nographic -kernel u-boot

启动成功后会显示命令提示符"VersatilePB #",现在就可以输入像"printenv"等U-Boot命令了。 输入组合键"CTRL-a x"即可以退出。

调试U-Boot

当调用QEMU时添加 -s 和 -S 选项

  • -s -gdb tcp::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 31 2010 - 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调试命令进行调试了, 不错!

Linux内核

下载Linux内核

   $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

交叉编译Linux内核

   $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- versatile_defconfig -s
   $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage -s

编译完成后会在目录'arch/arm/boot'中生成文件'uImage'。

加载Linux内核

下载并安装 TFTP Server

Open TFTP Server的主页上下载opentftpmtV1.63.tar.gz,然后安装它:

   $ tar zxvf opentftpmtV1.63.tar.gz
   $ mv opentftp/ /opt/
   $ cd /opt/opentftp/

修改配置文件'opentftpd.ini'来指定tftpserver的工作目录, 也就是向外提供tftp服务的目录, 比如, 我们添加"/opt/versatilepb/firmware"这行字到配置文件'opentftpd.ini'的[HOME]条目下,然后将编译好的Linux内核uImage链接到这个目录下:

   $ ln -sf PATH_TO_LINUX_KERNEL/arch/arm/boot/uImage /opt/versatilepb/firmware/

用如下命令来启动tftpserver:

   $ mkdir -p /opt/versatilepb/firmware
   $ sudo rc.opentftp start

显示"Server opentftpd started"说明tftpserver已经启动.

我们可以将如下两行文字添加到文件'/etc/rc.d/rc.local'中,使得tftpserver可以在开机时自动启动:

   $ /opt/opentftp/rc.opentftp start
   $ /opt/opentftp/rc.opentftp status
准备qemu-ifup和qemu-ifdown

用TAP网络接口是QEMU通往真实网络的标准方式。

如果不存在设备'/dev/net/tun',用如下命令创建它:

   $ sudo mkdir -p /dev/net
   $ sudo mknod /dev/net/tun c 10 200
   $ sudo /sbin/modprobe tun

我们也可以将如上命令添加到文件'/etc/rc.d/rc.local'中, 使得设备在每次开机时就被自动创建。

参考QEMU/Networking, 做出两个文件: 'qemu-ifup' 和 'qemu-ifdown', 但是不需要其中与openvpn相关的那一行,注释掉就可以了:

   $ sudo cp qemu-ifup qemu-ifdown /etc/
   $ sudo chmod +x qemu-ifup
   $ sudo chmod +x qemu-ifdown
tftpboot uImage

假设虚拟开发板的IP是:192.168.1.123, PC主机(tftpserver)的IP是:192.168.1.234.

   $ sudo qemu-system-arm -M versatilepb -nographic -net nic -net tap,ifname=tap0 -kernel $PATH_TO_YOUR_U-BOOT/u-boot
   U-Boot 2010.09 (Dec 15 2010 - 18:16:35)
   DRAM:  0 Bytes
   ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB
   Flash: 0 Bytes
   *** Warning - bad CRC, using default environment
   In:    serial
   Out:   serial
   Err:   serial
   Net:   SMC91111-0
   VersatilePB # sete ipaddr 192.168.1.123
   VersatilePB # sete serverip 192.168.1.234
   VersatilePB # sete bootfile uImage
   VersatilePB # tftpboot
   SMC91111: PHY auto-negotiate timed out
   SMC91111: MAC 52:54:00:12:34:56
   Using SMC91111-0 device
   TFTP from server 192.168.1.234; our IP address is 192.168.1.123
   Filename 'uImage'.
   Load address: 0x7fc0
   Loading: T ###################################T ##############################
            ##########################################
   done
   Bytes transferred = 1556392 (17bfa8 hex)
   VersatilePB # iminfo
   ## Checking Image at 00007fc0 ...
      Legacy image found
      Image Name:   Linux-2.6.36.2
      Image Type:   ARM Linux Kernel Image (uncompressed)
      Data Size:    1556328 Bytes = 1.5 MiB
      Load Address: 00008000
      Entry Point:  00008000
      Verifying Checksum ... OK
   VersatilePB #

? 如何在普通用户模式下执行带tap网络的qemu-system-arm?

运行Linux内核

准备ROOTFS
准备NFS
运行uImage

设备驱动

添加一个设备到QEMU

设备驱动程序

GUI

Run Mode

QEMU

Support FLASH on QEMU

Now, the emulation of Intel flashes is present in Qemu (in hw/pflash_cfi01.c) and this emulation is already used in some emulated ARM platforms, but not the Versatile PB platform that we use for our object (this platform is nice because it has Ethernet, serial ports, LCD, etc.). So, we must add flash emulation to the Versatile PB platform. Firstly, we should go into the source code directory of QEMU, and modify the file hw/versatilepb.c, assume to support a 64MB flash device, like this:

--- qemu-0.12.5/hw/versatilepb.c	2010-07-22 20:39:04.000000000 +0800 +++ qemu_armux/hw/versatilepb.c	2010-09-01 11:59:33.000000000 +0800 @@ -16,6 +16,11 @@ #include "pci.h"
 #include "usb-ohci.h"
 #include "boards.h" +#include "flash.h" + +#define VERSATILE_FLASH_ADDR		0x34000000 +#define VERSATILE_FLASH_SIZE (64*1024*1024) +#define VERSATILE_FLASH_SECT_SIZE (256*1024)  
 /* Primary interrupt controller.  */
  @@ -172,7 +177,9 @@ NICInfo *nd;
     int n;
     int done_smc = 0; - +    DriveInfo *dinfo; +    int hasflash = 0; +  if (!cpu_model) cpu_model = "arm926";
     env = cpu_init(cpu_model); @@ -280,13 +287,29 @@ /*  0x101f2000 UART1.  */
     /*  0x101f3000 UART2.  */
     /* 0x101f4000 SSPI.  */ - -    versatile_binfo.ram_size = ram_size; -    versatile_binfo.kernel_filename = kernel_filename; -    versatile_binfo.kernel_cmdline = kernel_cmdline; -    versatile_binfo.initrd_filename = initrd_filename; -    versatile_binfo.board_id = board_id; -    arm_load_kernel(env, &versatile_binfo); +  +    dinfo = drive_get(IF_PFLASH, 0, 0); +    if(dinfo) { +    	if(!pflash_cfi01_register(VERSATILE_FLASH_ADDR,  +				qemu_ram_alloc(VERSATILE_FLASH_SIZE),  +				dinfo->bdrv,  +				VERSATILE_FLASH_SECT_SIZE,  +				VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,  +				4, 0, 0, 0, 0)) { +		fprintf(stderr, "qemu: error registering flash memory./n"); +		exit(1); + } +	hasflash = 1; + } +    if(!hasflash) { +   	versatile_binfo.ram_size = ram_size; +    	versatile_binfo.kernel_filename = kernel_filename; +    	versatile_binfo.kernel_cmdline = kernel_cmdline; +    	versatile_binfo.initrd_filename = initrd_filename; +    	versatile_binfo.board_id = board_id; +    	arm_load_kernel(env, &versatile_binfo); + } else +    	env->regs[15] = VERSATILE_FLASH_ADDR; }  
 static void vpb_init(ram_addr_t ram_size,

then save the file.

U-Boot

burn U-Boot into flash

Firstly, we must create a 64MB flash file, then we can burn the 'u-boot.bin' into the flash:

   $ dd if=/dev/zero of=flash.img bs=1M count=64
   $ dd if=u-boot.bin of=flash.img conv=notrunc
   $ qemu-system-arm -M versatilepb -nographic -pflash flash.img




调试:
设置ip
配置网络:ifconfig eth0 172.27.28.10 netmask 255.255.255.0
设置IP:mount -t nfs -o nolock 172.27.28.203:/home/arm_test /mnt
阅读(1411) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~