ARM Versatile Express Emulation On Qemu From Scratch : Part 2

In My previous Tutorial ARM Versatile Express Emulation On Qemu From Scratch :Part 1 i have explained how to setup Embedded Linux Setup using Qemu, Cross-compiling Linux source code for ARM target , Cross_compiling Compiling Busybox-based Rootfile system.

In this tutorial will explore more on compiling BusyBox dynamically and Need for Mounting the root filesystem via NFS which i have already explained here NFS.

Environment Introduction:

Host ubuntu                                   :- 14.04
Linux kernel version: linux        :-4.9.0
busybox version: busybox          :-1.25.0
Cross compiler tool chain:arm :-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux gnu.tar.bz2
qemu version                                :- qemu-2.7.0

1.Download and Installation of QEMU:
2.ARM Cross_Compiler Tool chain installation:

For above 1 and 2 refer the procedure from Previous tutorial .

3.Download Linux kernel source code : Refer for compilation instruction from this Post.

4.Compiling Busybox for ARM on QEMU :  compilation instruction are similar as the previous one .

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

In previous tutorial i enabled Build BusyBox as a static binary.

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

As i told in my previous tutorial here i will explain why Static or Shared?

Under the BusyBox Settings/Build Options menu is the option “Build BusyBox as a static binary.”  This is false by default, resulting in the BusyBox file being linked with shared libraries. Thus the final BusyBox binary is much smaller because a large chunk of the code resides in another file: the C standard library used when compiling the software that must also be present on the final root file system. When you’re using a shared library, the operating system performs the final link at runtime by loading both the executable and shared library and fixing the references in the program to run code in the shared library.

When statically linked, all the code the program uses resides in the file. The code is loaded into memory and executed. This is a much faster operation than loading a file with shared libraries, in exchange for a larger memory footprint, because a fresh copy of the code is loaded for each instance of BusyBox executed. If the BusyBox executable contains just a few executables, the rule of thumb is about a 200KB program size. Static linking then makes sense because of the increased performance and savings from not needing the shared libraries.

Onward we will stick to Dynamic and shared library which will simplify while adding and executing user level application on target without much worry about shared and dynamic libraries. Don’t Enable this below option.

[ ] Build BusyBox as a static binary (no shared libs).

Compile Busybox:

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

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/lib/
$ mkdir -p _install/etc/init.d/

Download below files from github and copy to rootfs.

$ 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 the permission of rcS file.

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

When BusyBox was built with shared libraries, you need to copy them into the root file system and place them into the /lib directory. These files can be copied from the sysroot directory of the toolchain. BusyBox links against the m and c libraries.

Copy all the library files

$ cp -a arm-2014.05/arm-none-linux-gnueabi/libc/lib/* _install/lib/.

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

Instead of creating ext3 image we will stick to NFS . The nfs is explained here Network File System protocol .

Create a directory NFS_rootfs under /.

$ mkdir /NFS_rootfs
$ chown 1000:1000 /NFS_rootfs
$ cp -a busybox-1.25.0/_install/* /NFS_rootfs

Edit the file /etc/exports adding the following line in host machine:

$ sudo vi /etc/exports


Verify the nfs mounts properly by below commands

$ sudo exportfs -av
$ mkdir ~/nfs
$ mount localhost:/NFS_rootfs ~/nfs
# check rootfs mounted under /nfs and the unmount it
$ umount ~/nfs

QEMU offers a network model that allows to access the host as thought it was connected with an Ethernet network. The details of the default connection can be found in the documentation; briefly, a virtual LAN is created where the guest virtual system is given address while the host workstation can be accessed using address

Yes finally we are at last stage of booting Linux with nfs as rootfs.

qemu-system-arm -M vexpress-a9 -dtb linux/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel linux/arch/arm/boot/zImage -append "root=/dev/nfs nfsroot= rw ip= init=/linuxrc console=ttyAMA0" -serial stdio



Let me know if you have any questions or comments.


1)Pro Embedded Linux
2)Embedded Linux Primer



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.

3 Responses to ARM Versatile Express Emulation On Qemu From Scratch : Part 2

  1. Pingback: Simple Hello World !! | LearningFromU

  2. Pingback: Embedded Linux Device Driver Module:1 | LearningFromU

  3. Pingback: Debugging Linux Kernel using QEMU | LearningFromU

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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s