ARM Versatile Express Emulation On Qemu From Scratch: Part 1

In My previous Tutorial about Buildroot explains the complete Embedded Linux Emulation on ARM Versatile Board (QEMU) using automated Buildroot tools. Now lets look in to some basics elements of Embedded Linux System and compile a Linux kernel for an ARM architecture from scratch. Since i don’t have ARM boards and i will be using an emulated platform i.e QEMU for learning, it’s possible to control and debug many aspects of the system, and also that it’s safer to experiment to do on a virtual machine without the risk of breaking a physical board which might cost u buy one more.

Here I am using the Versatile Express product to emulate because it’s well supported by the mainline Linux kernel,by the mainline UBoot and by mainline QEMU.  Moreover, this hardware platform runs on the Cortex-A9 core, which is an ARM CPU that is included in many smartphones today.

**EDITED on 30th Dec 2016**


Git Repos:




Environment Introduction:

Host ubuntu :- 12.04
Linux kernel version: linux-4.4
busybox version: 1.24.0
Cross compiler tool chain: arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux gnu.tar.bz2
qemu version: qemu-2.5

Download and Installation of QEMU:

You can find more information about Qemu .

$ mkdir Source_Code
$ cd Source_Code
$ git clone git://
$ cd qemu
$ git checkout remotes/origin/stable-2.5 -b stable-2.5
$ cd ../../
$ mkdir -p Binary_images/Qemu_Bin
$ cd Qemu_src/qemu
$ cd Source_Code/qemu
$ ./configure --target-list=arm-softmmu --prefix= Path to your/Binary_images/Qemu_Bin
$ make
$ make install

ARM Cross_Compiler Tool chain installation:
A quick introduction about Cross_Compiler :
The difference between a Native compiler (gcc) and a cross-compiler(e.g arm-none-linux gnueabi-gcc) is that the Native compiler runs on an architecture (for example x86_64) and produces binaries for the same architecture.  A cross-compiler produces binaries for a different architecture (in our case ARMv7). In detail will be explained in upcoming Tutorials. Download binary from below website:

Download Source code:

–> arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

copy to your Binary_images/ARM_Cross_Tools

$ mkdir -p Binary_images/ARM_Cross_Tools
$ cd Binary_images/ARM_Cross_Tools
$ tar xvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

Export binaries by adding at the end of bashrc file ,this is one time activity.

$ vi ~/.bashrc
export PATH= path to /Embedded_Linux_Virtual_Setup/Binary_images/ARM_Cross_Tools/arm-2014.05/bin:$PATH

e.g export PATH=/home/Vinay/Embedded_Linux_Virtual_Setup/Binary_images/ARM_Cross_Tools/arm-2014.05/bin:$PATH

once above file saved close terminal and open again to restart bashrc file

Download Linux kernel source code :

$ cd Source_Code
$ git clone
$ cd linux
# Switch to version v4.4
$ git checkout v4.4

Prepare for compilation:

Load default config for target board i.e vexpress_defconfig. defconfig explained here

$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- vexpress_defconfig

Adjust or enable some settings as of now not required in future it might required.

$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig

Compile the kernel

$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- all

Verify qemu and kernel can run successfully:

~/Binary_images/Qemu_Bin/qemu-system-arm -M vexpress-a9 -m 512M -dtb ./arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ./arch/arm/boot/zImage -append “console=ttyAMA0” -serial stdio

Introduction parameters qemu command:

  •  qemu-system-arm:- ARM architecture emulation
  •  -M vexpress-a9:-simulation vexpress-a9 veneer , for different target u can find by  command qemu-system-arm -M ? which list supported target.
  •  -dtb file :- Use file as a device tree binary (dtb) image and pass it to the kernel on  boot.
  •  -kernel: to provide the Linux kernel image zImage
  • -append “console=ttyAMA0”:- kernel boot parameters, here to tell the kernel vexpress board runs, serial device which tty.

QEMU will execute the Linux image, then kernel will display many boot messages and then it will stop ,kernel panic saying that it didn’t find a root filesystem. Let’s then create the Minimal Rootfilesystem

Compiling Busybox for ARM on QEMU :
A Minimal root file system to do basic operations.

Download Busybox from

$ cd busybox
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- defconfig


A default configuration file is created. To change it to our needs:

Enable or disable some settings as mentioned below

$make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig

Busybox Settings —> Build Options —>
[*] Build BusyBox as a static binary (no shared libs)

The Reason for selection this option i will explain in future tutorial with example to understand it well.

Compile Busybox

$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install

The above command builds Busybox and creates a directory called _install containing the root filesystem tree.

Next, you need to create folder for mounting Virtual file systems like proc, sys and init scripts.

$ mkdir -p _install/proc/
$ mkdir -p _install/sys/
$ mkdir -p _install/tmp/
$ mkdir -p _install/root/
$ mkdir -p _install/var/
$ mkdir -p _install/mnt/
$ mkdir -p _install/dev/
$ mkdir -p _install/Home/
$ mkdir -p _install/etc/init.d/ 

Download below files from git

Download and copy.
$ git clone
1. copy fstab to  _install/etc/
2. copy inittab to _install/etc/
3. copy rcS to  _install/etc/init.d/

Once above file created and added change permission of rcS file.

$ chmod a+x _install/etc/init.d/rcS
$ chmod 777 _install/etc/init.d/rcS

Create ext3 image file and Copy all the files in our _install folder to image:

$ dd if=/dev/zero of=RootFS.ext3 bs=1M count=$((32))
$ sudo mkfs.ext3 RootFS.ext3
$ mkdir tmpfs
$ sudo mount -t ext3 RootFS.ext3 tmpfs/ -o loop
$ sudo cp -r _install/* tmpfs/.
$ sudo umount tmpfs

Yes Finally we are in last stage of emulation

The complete command is to emulate:

~/Qemu_/Binary_images/Qemu_Bin/bin/qemu-system-arm -M vexpress-a9 -dtb path to your linux folder/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel path to your linux folder/arch/arm/boot/zImage -append "root=/dev/mmcblk0 console=ttyAMA0" -sd path to your busybox-1.24.0/RootFS.ext3 -serial stdio

e.g ~/vinay/workpace/Binary_images/Qemu_Bin/bin/qemu-system-arm -M vexpress-a9 -dtb ~/vinay/workpace/linux-4.4/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ~/vinay/workpace/linux-4.4/arch/arm/boot/zImage -append "root=/dev/mmcblk0 console=ttyAMA0" -sd ~/vinay/workpace/busybox-1.24.0/RootFS.ext3 -serial stdio

Hope this tutorial will give you insight Qemu, Linux,Cross_toolchain ,Busybox compilation and building from scratch and booting UP in Qemu. Next Tutorial will be on More details and explanation of this tutorial

The command will launch QEMU and open the black graphical window, and the boot messages will be displayed in the host terminal instead of the black window 1.png 2


Refer this putting everything together U-boot .


Let me know if you have any questions or comments.





About VinayMahadev

I am passionate about Embedded Linux systems . I believe in "If you want to learn something, read about it. If you want to understand something, write about it. If you want to master something, teach it". Here I am just trying to connect the Dots.
Gallery | This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

8 Responses to ARM Versatile Express Emulation On Qemu From Scratch: Part 1

  1. Pingback: Inside the Linux Kernel Build Process | LearningFromU

  2. Manjunath Goudar says:

    good job…………
    Here if possible explain about own arm toolchain build process….

    Liked by 1 person

  3. VinayMahadev says:

    Thank you… That’s tedious job to explain about toolchain that i will be telling in separate tutorial in future


  4. Pingback: Uncompressing Linux……. done, booting the kernel | LearningFromU

  5. Pingback: U-boot: ARM Versatile Express Emulation On Qemu With NFS as Rootfs | LearningFromU

  6. Pingback: ARM Versatile Express Emulation On Qemu From Scratch :Part 2 | LearningFromU

  7. Kaiwan says:

    Hi, nice tutorial. I’ve hosted a small project which does similar stuff and tries to automate it via scripts; pl see:

    Liked by 1 person

  8. VinayMahadev says:

    Thank you, sure will look in to that


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s