Booting Linux with U-Boot on QEMU ARM

In recent months I played with QEMU emulation of an ARM Versatile Platform Board, making it run bare metal programs, the U-Boot boot-loader and a Linux kernel complete with a Busybox-based file system. I tried to put everything together to emulate a complete boot procedure, but it was not so simple. What follows is a description of what I’ve done to emulate a complete boot for an emulated ARM system, and the applied principles can be easily transferred to other different platforms.

Prerequisites

qemu-system-arm: can be installed on Ubuntu with “sudo apt-get install qemu-kvm-extras“, on Debian with “aptitude install qemu” as root.

mkImage: can be installed with the package uboot-mkimage. Alternatively, it is compiled from U-Boot source.

The boot process

On real, physical boards the boot process usually involves a non-volatile memory (e.g. a Flash) containing a boot-loader and the operating system. On power on, the core loads and runs the boot-loader, that in turn loads and runs the operating system. QEMU has the possibility to emulate Flash memory on many platforms, but not on the VersatilePB. There are patches ad procedures available that can add flash support, but for now I wanted to leave QEMU as it is.

QEMU can load a Linux kernel using the -kernel and -initrd options; at a low level, these options have the effect of loading two binary files into the emulated memory: the kernel binary at address 0x10000 (64KiB) and the ramdisk binary at address 0x800000 (8MiB). Then QEMU prepares the kernel arguments and jumps at 0x10000 (64KiB) to execute Linux. I wanted to recreate this same situation using U-Boot, and to keep the situation similar to a real one I wanted to create a single binary image containing the whole system, just like having a Flash on board. The -kernel option in QEMU will be used to load the Flash binary into the emulated memory, and this means the starting address of the binary image will be 0x10000 (64KiB).

Understanding memory usage during the boot process is important because there is the risk of overwriting something during memory copy and relocation. One feature of U-Boot is self-relocation, which means that on execution the code copies itself into another address, which by default is 0x1000000 (16MiB). This feature comes handy in our scenario because it frees lower memory space in order to copy the Linux kernel. The compressed kernel image size is about 1.5MiB, so the first 1.5MiB from the start address must be free and usable when U-Boot copies the kernel. The following figure shows the solution I came up with:

Timeline of the memory usage

At the beginning we have three binary images together: U-Boot (about 80KiB), Linux kernel (about 1.5MiB) and the root file system ramdisk (about 1.1MiB). The images are placed at a distance of 2MiB, starting from address 0x10000. At run-time U-boot relocates itself to address 0x1000000, thus freeing 2MiB of memory from the start address. The U-Boot command bootm then copies the kernel image into 0x10000 and the root filesystem into 0x800000; after that then jumps at the beginning of the kernel, thus creating the same situation as when QEMU starts with the -kernel and -initrd options.

Building U-Boot

The problem with this solution is that U-Boot, when configured to be built for VersatilePB, does not support ramdisk usage, which means that it does not copy the ramdisk during the bootm command, and it does not give any information about the ramdisk to the kernel. In order to give it the functionality I need, I patched the original source code of U-Boot before compilation. The following code is the patch to apply to u-boot-2010.03 source tree:

I also changed the boot arguments (CONFIG_BOOTARGS)so that they are the same as those given from QEMU command line, and then added a command (CONFIG_BOOTCOMMAND) to start the Linux boot automatically. To apply the patch:

make CROSS_COMPILE=arm-none-eabi- versatilepb_config
make CROSS_COMPILE=arm-none-eabi- all

The building process will create a u-boot.bin image that supports ramdisks for the VersatilePB. Incidentally, it will also build the mkimage executable in the tools directory; it can be used instead of the one installed with Debian/Ubuntu packages.

Creating the Flash image

As I said earlier, I need to create a flash image in which the three binary images are placed at a distance of 2MiB. U-Boot needs to work with binary images wrapped with a custom header, created using the mkimage tool. After creating the Linux and root file system images, we can write them inside a big binary at a given address with the dd command. Assuming that we have in the same directory: u-boot.bin, zImage and rootfs.img.gz, the list of commands to run are:

Then the Linux kernel will execute inside the emulated screen and the message “Please press Enter to activate this console” will appear, indicating that the root file system is working and so the boot process completed successfully. If something doesn’t work, one can always check that the system works without U-Boot, with the following command:

The kernel should uncompress and execute up to the activation of the console.

This procedure has room for improvements and optimizations, for example there’s too much memory copying here and there, where mostly everything can be executed in place. It is anyway a nice exercise and a good starting point that reveals interesting details about the boot process in embedded systems. As usual, this is possible mainly due to the fact that all the tools are free and open source.

The screen should be black at first, but the terminal should show the autoboot countdown and some other messages. If you see nothing on the terminal, then surely the problem is not in Linux or Busybox. Are you using u-boot version 2010.03? Try to make just u-boot work, once you have created u-boot.bin, with the following command:

Ok, I found the problem. It was I was using the dd command wrong. When the pc is creating the 6M file, the console doesn’t write anything. I interpreted this as I must enter then the rest of dd commands. And when I end entering this, I was terminating the first proccess.

The result was a blank file.

Thank you for helping me realize this and congratulations for the great info you have in the blog. All is workin fine now-

It’s just context that helps the “patch” program to verify that it is indeed modifying the right piece of code. The lines that are actually changed in the patch are those with “+” or “-” as the first character of the line. See http://en.wikipedia.org/wiki/Diff#Context_format

Currently i’m working on arm-linux(embedded system).
The process of my booting up is that initially i have got a bootloader(u-boot) which initializes kernel and then kernel takes care of rest. But can anyone please tell me a more regarding the basics:
1) What happens when initially the board is powered on or reset(beginning from cpu)?
2)bootloader initializes kernel, but who initializes bootloader? I mean something should be there which is activated by default on being powered up or reset, which in turn must be starting bootloader? (this is what i think)

I have tried to search in google regarding this, but everywhere i get the results directly beginning from uboot, but who starts uboot, that i haven’t found upto now.
Can anyone please help me regarding these basics?
If possible, please provide me with the links where i can get these details both from hardware and software point of view.

The answer depends on the hardware system you are using. For example if you are using a BeagleBoard it’s different than using a RealView versatile board. QEMU has its own implementation of the boot, that prepares the minimum for a Linux kernel and then jumps to address 0x10000, and is very different than what real hardware does.
Usually you have a ROM at a particular address (can be 0x00000000 or 0xFFFF0000, …) that executes when the hardware is reset. It should turn on the clocks and it should configure the memory interfaces, then it can jump to a fixed address or load some code from Flash and execute it. This procedure and its code is very specific to the architecture so you should find the information on the manual of the hardware platform.
Here are a couple of links for the Beagleboard:

Oh sorry balau, thanks for your reply but i forgot to mention the details regarding the board. It’s using a soc called S3C2440 having arm9 architecture. Can you please send me a mail i.d of yours(yahoo, gmail or rediff) so that i can mail you the introductory pdf regarding the board i’m working upon.

By the way balu, you have sent me the link regarding android boot process. As far as i know, Android is nothing but a different flavour of linux. So, can you send me any links where it will be mentioned regarding the boot process of embedded linux(2.6.30.4) specifically. The link that you have sent regarding the android is really conceptual and to the core. As far as i feel, almost the same principle would be working for linux. Still, if you can explain me regarding the exact booting process of embedded linux or atleast send me some links, dat would really be great. Looking forward for your help. :)

Dear Sattu,
my mail is in my About Me page.
I never looked in details the internal process of Linux booting, but I’m expecting that it’s very similar (if not the same) for Android and for any Linux distribution for ARM.
The Linux kernel itself contain some information that can be useful:ARM BootingSamsung-S3C24XX documents

I don’t know how to do it currently but I know they are actively working on it, especially Grant Likely of Secretlab.
The last update I have read for Device Tree support on ARM is the following presentation: ARM Device Tree status report.

If your problem is the “-pflash” support, you can try these instructions : Using U-Boot and Flash emulation in Qemu
Other than that, you can try a newer u-boot version like the 2010.03, since you are using a version 1.1.6) of 5 years ago and maybe they fixed something.
You can also see that I have similar errors in my output (no DRAM and no Flash), but the execution continues correctly because everything is in RAM.

Hello Balau ,
Thanks a lot for all the posts ! They’ve been highly informative.
Well, I was trying out the different meathods booting linux , and for the most part it worked fine .
In this case however , while execting qemu , i don’t get the auto boot message but get the uboot promt instead.
So I thought i’ll enter bootm 0x0021000 after looking into the figure. This worked and kernel bootup continued. When it came to the rootfs part , the rootfs wasn’t detected. So instead i used bootm 0x0021000 0x0041000 .. didnt solve the problem .
Could you please help me out ?

I think you miss some “zeros” at the end of the address you are using. they should be “0x210000″ and “0x410000″
In case you have only typed it wrong in this comment but you are using the right addresses in your tests:
What does it say inside the U-Boot prompt if you run “iminfo 0x210000″ and “iminfo 0x410000″?
If U-Boot doesn’t auto-boot maybe there’s something wrong in the patching or in the compilation. It should at least give you the same messages that you get when you run “bootm 0×00210000 0×00410000″ by yourself. Can you check by using “-kernel u-boot.bin” in the qemu-system-arm command instead of “flash.bin”? It should fail but give you some error messages about booting. In this case, the problem is the creation of the “flash.bin” image with “dd” command. Also, are all the three files that compose “flash.bin” below 2MiB in size?

Hello , thanks for the reply . The zeros were just a typo.
Its now working .. the patching was the issue. instead this is what i did :
After looking through the patch file i modified the image.c file and added : || defined (CONFIG_VERSATILE)
and in the versatile.h i added
#define CONFIG_BOOTARGS “root=/dev/ram mem=128M rdinit=/sbin/init”
#define CONFIG_INITRD_TAG 1
didn’t add the bootm command as i had to create a larger flash.bin file as the rootfs.uimg was over 3 MB , and so had different memory values.
Nevertheless , it works fine . Thanks a ton !

“.axf” is an executable file, with ELF format, that contains the code and data, but also information about the loading address, sections information, debugging symbols… It is usually run by a simulator or a debugger.
“.bin” is a pure binary file, containing the code and data that can be written inside a Flash to be run by an hardware platform.
If you run QEMU passing an ELF file with the kernel option, QEMU should be able to recognize the executable. But if you create a binary flash image like I do in my example, and put the .axf file inside it, it could not work.
If you have an “.axf” file, you can generate easily a “.bin” file using the “arm-*-objcopy” (in case of GCC toolchains) or “fromelf” (in case of RVDS) tools.

It seems to me that the code goes into an “undefined” exception, as the PSR value say (The 32 bit PSR) and then the code somehow tries to change the mode to 0 (the code that exits QEMU can be found in the QEMU source, file “target-arm/helper.c”
The registers R14 (link register) and R15 (program counter) have strange values: at memory address 0x70023160 should not be any memory and so any code.
Does the zImage still work individually?

In your example, u-boot, Linux kernel, and rootfs are placed at the distance of 2MiB in flash.bin. Is this 2MiB required by u-boot or QEMU. I suspect it is u-boot, right? But I am a little confused because this would limit the kernel size to be less than 2MiB. Also will the flash be loaded at 0x10000 (64KiB) so that QEMU can load u-boot?

Actually the 2MiB size is not required, neither by U-Boot nor by Linux. I chose that size because the images of the three components were all less than 2MiB and I needed an easy way to know where they are. You can change that distance if you want, and it doesn’t need to be the same, it could be 3MiB and 5MiB, the only requirement is that it has enough space to contain the binary files. Once you create a flash.bin file with different placement, you must change the U-Boot “bootm” command with the right addresses.

QEMU doesn’t need to know. The binary you give to QEMU with the “-kernel” option is placed at 0x10000, then the execution starts at that address. It is U-Boot that needs to know where the kernel and root filesystem are placed, and you need to pass this information with the “bootm” command.

Thanks very much for the tutorials; they all work wonderfully! Now I hope to get an open core Microblaze clone (openfire2) working on my Spartan3e starter kit board. Then I will hopefully reproduce these experiments on real hardware and be on my way!

I am facing an issue while using qemu for booting with flash.bin.
Error:
“can’t open /dev/tty3: no such file or directory” message is being displayed repetitively.
If use ‘ls’ command File system directories are displaying.

In my tutorial the file must be placed in “_install/etc/init.d/rcS” into the busybox source tree after busybox compilation. Then with the “cpio” command you create a root filesystem image from the _install directory, and it must contain the local “etc” directory that must appear in the QEMU terminal when you do “ls /”

Hi Balau,
I want to get familiarization with u-boot code for versatile PB.
For that I want use GDB on Qemu. Could you please provide info
for using GDB on QEMU(How to). And also could you please provide good URL’S or docs for learning u-boot functionality from scratch.

QEMU can easily act as a GDB server. When QEMU is run with the “-s -S” options, it will start waiting for a GDB connection on port 1234. Then you can connect using the “target remote localhost 1234″ command inside a GDB session. See also my old post Hello world for bare metal ARM using QEMU for an example on debugging a bare metal ARM program, such as U-Boot.

Keep in mind that on Ubuntu the QEMU package does not support debugging very well. I had to compile it from source to make it work.

Debugging U-Boot is a little more complicated because it relocates itself. In this page there is a tutorial on how to debug it: Debugging of U-Boot. When you make the u-boot.elf program the debugging symbols should already be included by default (i mean the “-g” option of GCC).

There is much information in the “README” file inside the U-Boot source tree, and some other things in the “doc” directory, but I don’t think there is documentation to explain the internals of the source code.

Hi Balau,
I want to install linux on arm6410 with sd card or usb.but,when i insert the sd card to arm6410 i can see the documents in the sd card but i can’t start the boot linux.for that what i must do to firstly.can you examine the first steps. or after insert sd card ,must i write some commands for starting install linux. thanks for answer.

Unfortunately I am not familiar with the hardware you’re working on. I suppose the hardware came with a manual, so maybe there’s some information about the boot procedure there. The boards often have some configuration switches that change the way the processor behaves during boot (for example they might have a “Boot from SD” configuration).

I think that you need to prepare the SD card from a PC, using a procedure similar to the one I used in this post and then writing directly on the SD card block device instead of a binary file. Then you can insert the SD card in the board and try to boot. I never did this procedure myself, though.

For anyone trying to reproduce this, at least on a recent Ubuntu host, you may need to pass “-cpu all” or “-cpu cortex-a8″ to qemu. The libgcc that gets linked to u-boot appears to be compiled with thumb2 instructions which are not implemented in the Versatile cpu.

I don’t get any u-boot console output without this flag, and using gdb I can see that the cpu takes an exception during __udivsi3() called from serial_init().

Thanks for commenting, Grant. As an aside, I really appreciate your work.

The toolchain has “multilibs” and should link the correct libraries based on compiler flags. If I have time I’ll take a look, maybe it’s just a matter of configuring U-Boot for the correct ARM architecture, because the default expects a newer (thumb2-capable) processor.

Hello Balau, This information is really helpful for getting started. I was trying trying to get the same up in Ubuntu. I have not been able to build the image u-boot.bin. I made the patch fixes mentioned above but I am getting some undefined reference errors. Some of the errors are pasted below for reference:

In my “uboot.map” file that is generated I see that all the functions are present in linking stage:flash_init: drivers/mtd/libmtd.a(cfi_flash.o)
copy_filename: net/libnet.a(net.o)
eth_initialize: net/libnet.a(eth.o)
BootFile: net/libnet.a(net.o)
env_init: common/libcommon.a(env_flash.o)
serial_init: drivers/serial/libserial.a(serial_pl01x.o)

I suggest re-trying again from a clean state using “make distclean” and then redoing the “make CROSS_COMPILE=arm-none-eabi- versatilepb_config” and “make CROSS_COMPILE=arm-none-eabi- all” commands in my post.
If even that doesn’t work, you can retry by setting environmental variable “export ARCH=arm” and recompile.

but when i try to simulate without u-boot just with rootfs and zimage, it works good
first i was working with version of u-boot 1.7 , i expected that it was the error but i used the mentioned version in your explain and applied the patch and tried to make flash.bin again but i have the same error :(

I’m sorry but my method will not work with a root filesystem that big. My method can be used to boot an intermediate initrd (ramdisk) that is able to load some modules and boot the real root. Depending on your hardware you can place the root filesystem on a server on the network, on an SD card, an USB disk/flash or a SATA drive. More information on the usage of initial ramdisk can be found in kernel source in “Documentation/initrd.txt”

It means the “qemu-system-arm” program has not been correctly installed. The installation depends on the Linux distribution you are using, I already specified the steps in the “prerequisites” section. Be aware that this article has been written in 2010 so the way to install “qemu-system-arm” may have changed.

It’s not a problem of toolchain, it’s a problem of u-boot version. There are some versions in which old hardware does not compile properly because they changed some of the internals. If you try to do the same with the 2010.03 or 2011.12 they should compile fine.

QEMU can load a Linux kernel using the -kernel and -initrd options; at a low level, these options have the effect of loading two binary files into the emulated memory: the kernel binary at address 0x10000 (64KiB) and the ramdisk binary at address 0x800000 (8MiB).

Sorry but I don’t understand what information that you need is not present in this sentence.

Hi Balau,
Thank for your reply.
My question is :
What are the QEMU default load address’s into the emulated memory – not in this case but generally – for the kernel and initrd files without using U-Boot, in command like this
qemu-system-arm -kernel file -initrd file …

The default addresses are indeed 0×10000 for the kernel and 0×800000 for the initrd.
I think I have confused you because in my example I used the same addresses for U-Boot booting.
My plan was:
– I see what QEMU does when I pass kernel and ramdisk from command line
– I recreate the same state using U-Boot
The result is that after the bootm command, the kernel and the ramdisk are in the same addresses that they would have been if I passed them to QEMU from the command line.
I hope I have clarified the situation.

When U-Boot executes “bootm 0x210000 0x410000” it copies the two images into their load addresses and then launches Linux with some parameters.
If you run QEMU as you want to do, you already have the ramdisk in place. For this reason, you don’t need the second argument to bootm, but you need to tell the kernel that the ramdisk is there. For this, I think you can append “initrd=0x800000” to the BOOTARGS that U-Boot passes to Linux.

You are right: I just tried and the ramdisk is placed at 0xd00000 instead.
I discovered this address my doing “md 0 64” and inspecting the data that looked like an address.
Then I misinterpreted the initrd parameter, it should be something like “initrd=0xd00000,2M“, where the value after the comma is the size of the ramdisk (I rounded by eccess).
With these modifications it works for me.

No idea, but I haven’t investigated either.
It might have something to do with the kernel binary size, but it may also have been changed in QEMU source code.
In my opinion it should not change anything relevant, we could just accept the fact that the ramdisk is placed at an arbitrary address.

Suppose that I’d like to pass to the linux kernel the following parameters :
console=ttyAMA0 root=/dev/ram rw initrd=0xd00000,2M

Generally, I can pass these parameters, through :
– append option in qemu command
– bootargs in UBOOT environment
– Boot options->kernel command string (at the time of kernel configuration)

It is possible to pass them in every of this mentioned above way but only in one at once?

Sometimes I’ve kernel image compiled with some parameters in kernel command string and u-boot.bin compiled with other parameters in bootargs. At time of software developing the most comfortable way for me is to change the kernel parameters in qemu command in append option.
Can I launch linux in QEMU in the way mentioned above with different parameters in qemu line, u-boot.bin and kernel image? If yes, which parameters will be passed to linux kernel?

The kernel parameters in your case are those passed by U-Boot. The one in QEMU “-append” option never reach the kernel.
This is because QEMU prepares ATAGS that U-Boot does not read, and then U-Boot prepares its own ATAGS (from bootargs) to be passed to the kernel.
See Documentation/arm/Booting.txt for information about what should be passed to Linux kernel.
In physical world scenario, U-Boot saves its environment in the flash, so you can have an U-Boot image with default parameters, and then a sector of the flash that contains your parameters.

Are you sure you need to use U-Boot? If you don’t use U-Boot then you can pass the kernel parameters with QEMU without problems.

You can’t know if you missed any bootargs by looking only at the tail of the log.
You could add “console=ttyAMA0” to the current bootargs (and QEMU must be launched with “-serial stdio“) to display more info on the terminal.
Try to find a line near the beginning of the log starting with “Kernel command line: “. Those are the bootargs.
Then in the middle of the log you should find a line such as “Trying to unpack rootfs image as initramfs...“. The lines around that could contain useful hints about why the kernel isn’t mounting the filesystem.

Exactly..I missed to give you the details about boot args.
setenv bootargs ‘console=ttyAMA0,115200n8 root=/dev/ram rw’
I have created uImage loaded at addr1 and created ramdisk of mkimage compatible loaded at
addr2 (addr1 > addr2).
I did below command
$ bootm $addr1 $addr2

The kernel has to run something (in userspace) when the boot ends, otherwise it panics. This “something” is usually the init program.
I don’t know if using both “root=/dev/ram” and “rdinit=/sbin/init” is the cleanest way to do it, but I noticed that without “rdinit” the kernel does not try to mount the ramdisk and so it panics.

Let me clear my complete opinion.
I am convinced that if you try “setenv bootargs ‘console=ttyAMA0,115200 root=/dev/ram rw rdinit=/sbin/init’“, it will work.
This is because, as said in Linux “Documentation/early-userspace/README” and in other parts of the web, the “initramfs” way of booting Linux expects that the ramdisk is a cpio archive, it mounts it and then tries to execute “/init“. In our case we don’t have “/init” so we have two options:
1. creating a link such as “ln -s ./sbin/init ./init” in the busybox _install directory before creating the cpio archive (I haven’t tried it actually)
2. adding “rdinit=/sbin/init” to the kernel parameters (as specified in my blog post and in my past replies to you)

I think “root=/dev/ram” is superfluous, it should work without it because we don’t reach the point where we mount the root filesystem.
But implementing one of the two ways above is necessary to boot Linux with the ramdisk.

If it still doesn’t work, then you should also check the other parts of the kernel messages as I already said, because something could have gone wrong in mounting the initramfs.

I don’t know, it seems to be printed by “display_dram_config” function in “board.c” file (in u-boot-2010.03 the file is in “lib_arm” directory).
Maybe the new u-boot versions fixed this information, but I don’t remember if they still support VersatilePB.

What do you mean “what about Uboot commands history”? You wanted to ask why it does not work for you?
If that was the question, my answer is still “I don’t know” as before, and I don’t have time right now to check the source code to try to understand why it does not work.

In my environment, it is clear that it does not understand the “arrow” keys as “go up in history of commands”.
U-Boot is made to be small, I suppose giving it a command history is considered bloat for what it should do.
I tend to agree, because if everything works you should never need to access U-Boot command shell.

This is great Balau, thanks for your articles. It serves as a great reference point for my project which is to get u-boot and a linux kernel up and running on the ST-E U8500 platform. Unfortunately QEMU seems to have issues…

a. you could use the exact same versions that I used and the exact same configuration to make it work, and then little by little change from my setup to yours to see when things start to go bad. I used Linux 2.6.33, U-Boot 2010.03 and busybox 1.16.0. For example I see that your root filesystem is bigger than mine, in particular bigger than 2MiB. I don’t know if that could be a problem.

b. you could launch QEMU with -s -S options and then attach with arm-…-gdb using “target remote localhost:1234″, then put a breakpoint on the start of Linux execution (for example using “file vmlinux” and putting a breakpoint on start_kernel) and when the breakpoint is reached display the content of 0x00800000 to see if ramdisk has been corrupted (check if the data is the same as rootfs.cpio.gz).

About your second question:

rootfs.uimg is just rootfs.cpio.gz with a U-Boot header attached at the beginning. Linux can’t understand U-Boot headers so the second command will not work and I did not expect otherwise.

I am using U-Boot(compressed) and two kernel Image(uImage). I want to add some code in U-Boot which will select kernel based of time stamp(or using any other way if you have in mind). I am using MIPS architecture.

For example:-

If kernel-1 is new, U-Boot will boot Kernel-1. and leave kernel-2 as it is.
If kernel-2 is new, U-Boot will boot kernel-2. and leave kernel-2 as it is.
Questions:-

Is it possible to do so?
How can I add such functionality in U-boot?
Where to chage the code for the same?

I don’t think U-Boot was made for something like that.
You could modify the source code of U-Boot around the autoboot functionality, and use the timestamp added by mkimage to choose.
I don’t think it’s simple, you could ask U-Boot mailing lists.

If I search the displayed message “Booting kernel from” in U-Boot source code (2010.03), it’s present in “common/cmd_bootm.c“, in function boot_get_kernel. Following back the calls in the same C file it’s quite easy to find the point where the kernel is loaded.

Hi Balau. I have been following your post to run linux via uboot on qemu. I followed your steps and when I run the “flashed” image on qemu, i always get the error “Uncompressing Linux… done, booting the kernel.
Bad ram offset 8000000″.

I can run u-boot by itself and kernel also by itself (although with kernel, i keep getting spew about /dev/ttyxxx not found). But when I create a flash image, i get this error.

I am using zynq_zc702 based U-Boot 2011.03 source for running on zynq’s based qemu. Individually i am able to run the u-boot.bin and zimage with rootfs from the qemu. As you suggested I combined u-boot, zimage and rootfs into a single image(flash.bin) for supporting autoboot and I made the changes to include/configs/zynq_common.h.

I believe it’s just a matter of adding “#define DEBUG 1” somewhere like in “include/config_defaults.h“.
U-Boot is full of “debug(...)” calls that are enabled by this macro to be expanded as printf.
You can increase the value of DEBUG to print also “debugX(level, ...)” messages.
These macros are defined in “include/common.h“.

hi, when i use
qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append “root=/dev/ram mem=128M rdinit=/sbin/init” -serial stdio,
everything works fine.
But if i use
qemu-system-arm -M versatilepb -m 128M -kernel flash.bin -serial stdio
uboot is able to find kernel image and ramdisk image, but when kernel starts, kernel is not able to find ramdisk.
Do you where is the problem?

@ML
The first partition is probably used only by the boot (u-boot?) to run the kernel with the chosen parameters. The second seems to be the root filesystem.
You can’t emulate u-boot, the kernel or the modules for the wm8650 with QEMU because they depend strictly on the hardware and the memory map, and QEMU does not emulate wm8650.

@Nicholas
Is it possible that the ramdisk is too big (> 2MiB)?
You can also run QEMU with -s option, then when the kernel fails you connect to it with arm gdb, by executing “target remote localhost:1234″ in the gdb prompt, and then check that the content of the memory containing the ramdisk is as expected, for example by executing “dump binary mem.bin 0x00800000 0x00A00000″ and check that mem.bin corresponds to rootfs.img.gz (you can do an hexdump -C of both files and diff them graphically).

I don’t know why it happened but I recommend changing the source code manually since it’ a few lines of code, and in the process try to see if the source code is different from what it’s expected.
Another explanation is that you copied also the line numbers from the site, they don’t have to be copied.

The error is generated while executing U-Boot, Linux is not yet started.
R15 is program counter, R14 is return address; you can see where the program crashed from U-Boot disassembly. You can disassemble it by running something like arm-none-eabi-objdump -S u-boot >u-boot.dis. U-Boot should already be compiled with debugging symbols, otherwise try to enable them by adding -g to CFLAGS.
You can also try to run QEMU with -s -S options and then attach to it with arm-none-eabi-gdb using u-boot as file for symbols and debug info. Then you can break at do_bootm_linux (that’s the last function U-Boot should execute) or at abort_boot (that’s the last thing your U-Boot prints) and try to debug from there.

Hi Balu
I try to debug decompress part of linux kernel. But my Breakpoint does not hit.
To run linux on qemu i ran following command.
qemu-system-arm -M versatilepb -m 128M -s -S -kernel arch/arm/boot/zImage
and on gdb side ran this command
arm-none-eabi-gdb target remote localhost:1234
after that
file ./arch/arm/boot/compressed/vmlinux
then add breakpoint
like b __setup_mmu
None of my breakpoint hit .
Only break point after MMU_ENABLE hit like start_kernel

The part of software that runs before the decompression is position independent code. In my case (probably also in yours) the zImage is loaded in 0x60010000, and that’s the address containing start, but in the vmlinux ELF the address is 0. I tried the GDB command add-symbol-file arch/arm/boot/compressed/vmlinux 0x60010000 instead of file arch/arm/boot/compressed/vmlinux and it seems to load the symbols to their right addresses, try it also in your setup.

Hi Balau,
I followed your steps as mentioned.But Still not able to hit the breakpoints.
I checked with gdb and dump the 0x60010000 location.
x/10wx 0x60010000
0x60010000: 0x00000000 0x00000000 0x00000000 0x00000000
0x60010010: 0x00000000 0x00000000 0x00000000 0x00000000
0x60010020: 0x00000000 0x00000000
It shows nothing . So might be in my case load address of zImage will be different.
I have question:-
1) How to find the address where zImage loaded in qemu.

I checked with gdb and dump the location 0x00010000 location. I got this location when i searched for zImage header magic number 0x016f2818.
I matched with my zImage Hexdump but when i load the elf file with add-symbol-file arch/arm/boot/compressed/vmlinux 0x00010000 and put some breakpoint.
It halt that place and show function input_data() with no code.

I checked with add-symbol-file arch/arm/boot/compressed/vmlinux 0x60010000
but still breakpoints not hitting. When i dump the 0x60010000 on gdb it shows
0x00000000 . When i dump the 0x00010000 on gdb it has same footprint as my zImage.
But when i add-symbol-file arch/arm/boot/compressed/vmlinux 0x00010000 and put breakpoint on this address. It stops there but function it shows input_data(). Please let me know how you find the load address 0x60010000 on your system.

I launched QEMU with -s -S (so it’s stopped before executing anything) and then connected with gdb. With something like x/10i $pc you can see the code at current program counter. At the beginning QEMU puts a couple of its own instructions to jump to the user code. So I stepi a few times until it jumps, and at that point it jumps to the beginning of the binary passed by -kernel option. That address should be the offset that you pass to add-symbol-file. I tried with versatilepb to make it similar to your setup and I find your same problem, and it is strange, but it is easily worked around if you stepi until you reach start or if you break start and then continue.

i used this command :-
add-symbol-file ./arch/arm/boot/compressed/vmlinux 0x00010000 -s .piggydata 0x00014610
and now i am able to put break points and debug the code.
I found out that in arch/arm/boot/compressed/vmlinux
.piggydata 001d28e0 00004610 00004610 0000c610 2**0
which means .piggydata starthe at 0x4610 and length 001d28e0 which overlaps the 0x00010000 address. i.e. gdb not able put the breakpoints . so remap that section also .

Hi Balau,
I compiled U-Boot and run QEMU with “u-boot” (ELF file) and I can see u-boot message.
$ qemu-system-arm -M vexpress-a9 –kernel u-boot -nographic
But I just saw nothing when using “u-boot.bin”:
$ qemu-system-arm -M vexpress-a9 –kernel u-boot.bin -nographic
The cross-compiler I use is “arm-linux-gnueabi” and my linux distrubution is Ubuntu 12.04.
I also tried to re-compiled U-Boot with “versatile_defconfig” and run qemu with “versatilepb”. I still can’t see any boot message.
Do you have any idea?

I am quite sure that if you give QEMU an ELF it will load it using the information about the segments of data, code, etc. and then it will execute from the entry point. But if you run a binary it will simply place it as is into a given address (different for each machine) and then jump to that address. You can try to run QEMU with -s -S and attach to it with GDB by running arm-linux-gnueabi-gdb u-boot and then (gdb) target remote localhost:1234; in this way you can run step-by-step and see what is happening with program counter and memory content.

Hi Balau,
I ran QEMU with GDB but u-boot.bin just can’t be executed.
I tried to decode u-boot ELF file and found entry point is 0×60800000.
So, I generated image file with mkimage and set entry point to 0×60800000. In this way, it worked.

[…] for one of the ARM-based machines that QEMU supports. I settled for VersatilePB after finding this old-ish article. Rather optimistically I thought that maybe, just maybe things had change in a year and that the […]