虚拟开发板

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

虚拟开发板是用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 filehw/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

References

External links

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
韦东山老师为啥要录升级版嵌入式视频?200x年左右,嵌入式Linux在全世界、在中国刚刚兴起。我记得我2005年进入中兴时,全部门的人正在努力学习Linux。在2008年,我写了一本书《嵌入式Linux应用开发完全手册》。它的大概内容是:裸机、U-boot、Linux内核Linux设备驱动。那时还没有这样讲解整个系统的书,芯片厂家Linux开发包也还不完善,从bootloader到内核,再到设备驱动都不完善。有全系统开发能力的人也很少。于是这书也就恰逢其时,变成了畅销书。我也根据这个思路录制了视频:裸机、U-boot、Linux内核Linux设备驱动。收获些许名声,带领很多人进入Linux世界。11年过去了,嵌入式Linux世界发生了翻天覆地的变化① 基本系统能用芯片厂家都会提供完整的U-boot、Linux内核、芯片上硬件资源的驱动。方案厂家会做一些定制,比如加上某个WIFI模块,会添加这个WIFI模块的驱动。你可以使用厂家的原始方案,或是使用/借鉴方案商的方案,做出一个“能用”的产品。② 基础驱动弱化;高级驱动专业化基础的驱动,比如GPIO、UART、SPI、I2C、LCD、MMC等,有了太多的书籍、视频、示例代码,修修改改总是可以用的。很多所谓的驱动工程师,实际上就是“调参工程师”。我们群里有名的火哥,提出了一个概念:这些驱动就起一个“hardware enable”的作用。高级的驱动,比如USB、PCIE、HDMI、MIPI、GPU、WIFI、蓝牙、摄像头、声卡。体系非常复杂,很少有人能讲清楚,很多时候只是一笔带过。配置一下应用层工具就了事,能用就成。这些高级驱动,工作中需要专门的人来负责,非常专业。他们是某一块的专家,比如摄像头专家、音频专家。③ 项目为王你到一个公司,目的是把产品做出来,会涉及APP到内核到驱动全流程。中小公司玩不起华为中兴的配置,需要的是全面手。大公司里,只负责很小很小一块的镙丝钉,位置也不太稳固啊。所以,如果你不是立志成为某方面的专家,那就做一个全栈工程师吧。④ 调试很重要都说代码是3分写7分调,各种调试调优技术,可以为你的升职加薪加一把火。基于上述4点,我录制的全新视频将有这些特点:1. 快速入门,2. 实战项目,3. 驱动大全,4. 专题,5. 授人以渔,6. 要做任务另外,我们会使用多款芯片同时录制,先讲通用的原理,再单独讲各个板子的操作。这些芯片涵盖主流芯片公司的主流芯片,让你学习工作无缝对接。1.快速入门入门讲究的是快速,入门之后再慢慢深入,特别是对于急着找工作的学生,对于业余时间挑灯夜读的工作了的人,一定要快!再从裸机、U-boot、内核、驱动这样的路线学习就不适合了,时间就拉得太长了。搞不好学了后面忘了前面。并且实际工作中并不需要你去弄懂U-boot,会用就行:U-boot比驱动还复杂。讲哪些内容?怎么讲呢?混着讲比如先讲LED APP,知道APP怎么调用驱动,再讲LED硬件原理和裸机,最后讲驱动的编写。这样可以快速掌握嵌入式Linux的整套开发流程,不必像以前那样光学习裸机就花上1、2个月。而里面的裸机课程,也会让你在掌握硬件操作的同时,把单片机也学会了。讲基础技能中断、休眠-唤醒、异步通知、阻塞、内存映射等等机制,会配合驱动和APP来讲解。这些技能是嵌入式Linux开发的基础。而这些驱动,只会涉及LED、按制、LCD等几个驱动。掌握了这些输入、输出的驱动和对应的APP后,你已经具备基本的开发能力了。讲配置我们从厂家、从方案公司基本上都可以拿到一套完整的开发环境,怎么去配置它?需要懂shell和python等配置脚本。效果效率优先以前我都是现场写代码、现场写文档,字写得慢,降低了学习效率。这次,效果与效率统一考虑,不再追求所有东西都现场写。容易的地方可先写好代码文档,难的地方现场写。2.实战项目会讲解这样的涉及linux网关/服务器相关项目(不限于,请多提建议):                   定位为:快速掌握项目开发经验,丰满简历。涉及的每一部分都会讲,比如如果涉及蓝牙,在这里只会讲怎么使用,让你能写出程序;如果要深入,可以看后面的蓝牙专题。3. 驱动大全包括基础驱动、高级驱动。这些驱动都是独立成章,深入讲解。虽然基础驱动弱化了,但是作为Linux系统开发人员,这是必备技能,并且从驱动去理解内核是一个好方法。在讲解这些驱动时,会把驱动的运行环境,比如内核调度,进程线程等概念也讲出来,这样就可以搭建一个知识体系。没有这些知识体系的话,对驱动的理解就太肤浅了,等于在Linux框架下写裸机,一叶障目,不见泰山。定位为:工具、字典,用到再学习。4. 专题想深入学习的任何内容,都可独立为专题。比如U-boot专题、内核内存管理专题、systemtap调试专题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值