Chinaunix首页 | 论坛 | 博客
  • 博客访问: 106611
  • 博文数量: 41
  • 博客积分: 2132
  • 博客等级: 大尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-16 16:08
文章分类

全部博文(41)

文章存档

2012年(5)

2011年(3)

2010年(20)

2009年(13)

我的朋友

分类: 嵌入式

2010-04-30 10:24:53

Using U-Boot and Flash emulation in Qemu


For the embedded Linux trainings of , we use virtual machine environments for the practical labs, because we haven't found yet a nice board that matches all our criterias. Qemu, of course, is used in all our labs, and provides a very nice emulation environment since it emulates several CPU architectures often used in embedded systems (ARM, MIPS and PowerPC).

However, until recently, there was no emulation of flash memory in Qemu, which is sad because flash memory is very common in embedded systems, and is handled by different tools, different filesystems than normal block devices, and we wanted our training participants to get used to these tools. We also wanted to allow the training participants to configure, compile and use an embedded bootloader, the famous U-Boot. 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 trainings (this platform is nice because it has Ethernet, serial ports, LCD, etc.). So, I decided to add flash emulation to the Versatile PB platform. It turned out not to be so easy, even if the patches are in the end relatively small.

I've written four small patches for Qemu, which have been written and tested for Qemu revision 5391 from the Subversion repository (I don't think the Flash emulation has yet been part of an official stable Qemu release). They have all been submitted to the Qemu mailing-list. Here are the patches :
  • , which increases the size of the write buffer declared by Qemu in the CFI table of the flash. The advertised buffer size was only 16 bytes, which is small compared to usual buffer sizes, and makes the writing process very slow, at least from U-Boot. The size has been increased to 2048 bytes.
  • , which fixes a problem in the code handling the erase command. When the "erase confirm" command was sent to Qemu, it didn't reset the wcycle variable, which lead Qemu to think that the next command wasn't a new one, but was part of the "erase command", which obviously was wrong. I'm not 100% sure about this patch, since there was already a pfl->wcycle = 1 at the place where it should have been pfl->wcycle = 0. But hey, we'll what the Qemu developers say about it.
  • , which only improves two debugging messages that were useful while working on the other patches. Nothing fancy.
  • , which adds the flash emulation to the Versatile PB platform. It wasn't really easy to understand the qemu_ram_alloc() mechanism, but in the end, it seems to work. The RAM size of a Versatile PB platform is now fixed to 128 MB and the Flash size is fixed to 64 MB. The file containing the flash is specified using the -pflash option. When this option is absent, Qemu falls back to the traditionnal way of loading the kernel given with the -kernel option. If the -pflash option is present, then the contents of the file are used as the contents of the emulated flash, and the emulation starts at the beginning of the Flash (address 0x34000000).

Of course, the goal of all this is to run something on the Flash, basically U-Boot to start with. I've used U-Boot 1.3.4, which also requires , which changes the following things :
  • Switch for the Versatile specific flash driver to the CFI generic flash driver
  • Adjust the flash settings (sector size, location of the environment, etc.)
  • Configure the Ethernet driver for an external PHY, because it seems that Qemu doesn't emulate the PHY operations
  • Fix the timer code to use the CFG_TIMER_CTRL constant instead of hardcoding it
  • Tweak the CFG_HZ and CFG_TIMER_CTRL to get a relatively working time. Without these tweaks, the time was going very fast for U-Boot, all delays were instantaneous, the network timeouts were reached instantaneously. However, the tweaks are only work-arounds at the moment, as I don't have a clear understanding of how the time is handled under Qemu.

With all these patches in place, one can run U-Boot, download a Linux kernel, flash it from U-Boot and run it. Basically, the 128 MB RAM is mapped from 0x0 to 128 MB, and the 64 MB Flash is mapped from 0x34000000 to 0x38000000, with 256 KB sectors. U-Boot is stored at the beginning of the Flash, at address 0x34000000 where the CPU starts its execution. The U-Boot environment is stored in the next sector, at 0x34040000, which leaves the flash free starting at 0x34080000. This is the place where I flash the kernel. To load the kernel from TFTP, I use the RAM address 0x200000 (2 MB), because U-Boot is loaded at address 0x100000 (1 MB).

To create the Flash file, I use :
dd if=/dev/zero of=flash.img bs=1M count=64
dd if=/path/to/u-boot-1.3.4/u-boot.bin of=flash.img conv=notrunc


Then, to run Qemu, I use :
sudo qemu-system-arm -M versatilepb -m 192 -serial stdio -net nic,model=smc91c111 -net tap -pflash flash.img


I get into the U-Boot prompt, and do :
setenv ipaddr 172.20.0.2
setenv serverip 172.20.0.1
setenv bootfile /uImage
setenv bootcmd bootm 34080000
setenv bootargs console=ttyAMA mem=128M
saveenv
tftpboot 200000
protect off 1:2-32
erase 1:2-32
cp.b 200000 34080000 ${filesize}
protect on 1:2-32
boom 34080000


Which basically does :
  • set environnement variables for the IP address of the embedded system, IP address of the server, file to download using TFTP from the server, the default command to run when U-Boot starts, and the kernel command line. The console=ttyAMA allows to get the console on the serial port.
  • save the environment. It is saved in the second flash sector, for 0x34040000 to 0x34080000, so that next time, the previous environment variable settings will be kept.
  • download the kernel image at address 0x200000
  • unprotect flash sectors 2 to 32 (sector 0 is U-Boot, sector 1 is the environment)
  • erase these sectors
  • copy the kernel to the flash. U-Boot is smart enough to know that the destination is a flash memory and that it shouldn't copy to it as usual, but that it should use the flash driver instead.
  • re-protect the flash sectors
  • boot the kernel. And hippy !

Next steps: play with the kernel MTD layer, JFFS2 and other flash filesystems on one hand, and implement the Versatile sound emulation in the other hand.
Il y a 5 commentaires sur cette page. []
阅读(1653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~