http://elasticsheep.com/2011/01/building-and-emulating-a-basic-arm-linux-system/
http://www.embedu.org/Column/Column334.htmhttp://www.arm.com/community/software-enablement/linux.php
Using QEMU for Embedded Systems Developmenthttp://www.linuxforu.com/2011/06/qemu-for-embedded-systems-development-part-1
QEMU ARM Emulator使用参数 http://blog.youkuaiyun.com/rockwill/article/details/6400033U-Boot Introduction: http://www.360doc.com/content/06/1027/15/13362_242497.shtml
U-Boot的移植U-Boot Practically Porting Guide(转)http://www.cnitblog.com/zouzheng/articles/40300.html
1) 安装 QEMU
- git clone git://git.qemu.org/qemu.git
- cd qemu
- ./configure --target-list=arm-softmmu --prefix=/usr
- make && make install
sudo apt-get install qemu-kvm qemu-kvm-extras
2) 开发板选择
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/index.html
有两个板子 :
a) Versatile Application Baseboard for ARM926EJ-S
b) Versatile Platform Baseboard for ARM926EJ-S
qemu-system-arm -M ?
Supported machines are:
syborg Syborg (Symbian Virtual Platform)
musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
mainstone Mainstone II (PXA27x)
n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
sx1 Siemens SX1 (OMAP310) V2
sx1-v1 Siemens SX1 (OMAP310) V1
tosa Tosa PDA (PXA255)
akita Akita PDA (PXA270)
spitz Spitz PDA (PXA270)
borzoi Borzoi PDA (PXA270)
terrier Terrier PDA (PXA270)
connex Gumstix Connex (PXA255)
verdex Gumstix Verdex (PXA270)
lm3s811evb Stellaris LM3S811EVB
lm3s6965evb Stellaris LM3S6965EVB
realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
versatilepb ARM Versatile/PB (ARM926EJ-S)
versatileab ARM Versatile/AB (ARM926EJ-S)
integratorcp ARM Integrator/CP (ARM926EJ-S) (default)
我们也能发现Qemu已经支持这两种ARM开发板
versatilepb ARM Versatile/PB (ARM926EJ-S)
versatileab ARM Versatile/AB (ARM926EJ-S)
我这里选择 versatile PB
3) 准备文件系统
3.1) Bootloader
$ git clone git://git.denx.de/u-boot.git
到U-Boot的根目录下,然后执行:
$ sb2 make versatilepb_config ARCH=arm
$ sb2 make all ARCH=arm
在目录下将会产生文件'u-boot'和'u-boot.bin'。
u-boot 含有调试信息,u-boot.bin不含有调试信息
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
现在我们可以在控制台中启动U-Boot了:
$ qemu-system-arm -M versatilepb -nographic -kernel u-boot
启动后会显示命令提示符"VersatilePB #",现在可以输入U-Boot命令了
"CTRL-a x"退出
调试U-Boot
$ qemu-system-arm -M versatilepb -nographic -kernel u-boot -s -S
-s -gdb tcp::1234 //用port号1234
-S 在启动时停止CPU (键入'c'才会开始执行)
$ sb2 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调试命令进行调试了, 不错!
b) Linux内核
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
编译Linux内核
$ sb2 make ARCH=arm versatile_defconfig -s
$ sb2 make ARCH=arm 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 #
c) rootfs
3) NFS 方式
sudo -S qemu-system-arm \
-m 256 \ //set virtual RAM size to megs MB [default=128]
-M myarm\ // Machine Name
-kernel zImage \ //kernel image
-append root="/dev/nfs nfsroot=10.0.0.1:/targets/arm-generic/rootfs rw ip=10.0.0.2:10.0.0.1:10.0.0.1:255.255.255.0" / \\kernel command line
-net nic,vlan=0 \ //create a new Network Interface Card and connect it to VLAN 'n'
-net tap,vlan=0,ifname=tap0,script=qemu-ifup& \\connect the host TAP network interface to VLAN 'n' and use the network scripts 'file' (default=/etc/qemu-ifup)
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.