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.
阅读(3345) | 评论(0) | 转发(0) |