I am trying to cross-compile and boot a Linux 2.6 kernel for ARM using QEMU. I have basically followed the same instructions that are included in seemingly every single tutorial on the topic.


  1. Download and compile kernel

    $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- versatile_defconfig
    $ #Disabled loadable modules and enabled initramfs
    $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all
  2. Compile Busybox

    $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- arm
    $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
  3. Create cpio archive from Busybox _install directory

    $ cd $BUSYBOX/_install
    $ find . | cpio -o -Hnewc | gzip > ../initramfs.gz
  4. Boot using qemu-system-arm

    $ qemu-system-arm -M versatilepb -m 200M -kernel $KERNEL/arch/arm/boot/zImage -initrd $BUSYBOX/initramfs.gz -append "root=/dev/ram0"

The result is this:

enter image description here

It looks like the kernel does not recognize the file system, but I don't know how to fix that. These are basically the exact steps that every single tutorial follows. There is no such thing as a "cpiofs" to enable in the kernel source.

  • It looks like the kernel cannot find the MEDIA the rootfs is on. I am familiar with the 4.x kernel more than the 2.6... Here is a line from my notes qemu-system-arm -M versatileab -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh" Note the root=/dev/ram. Check that RD_GZIP=Y in kernel menuconfig for compressed cpio support, or what ever compression you want to use. If you do not need a separate cpio file for your rootfs, include it in your zImage. Point the INITRAMFS_SOURCE in menuconfig to the _install folder of busybox.
    – jc__
    Mar 28 '16 at 13:41
  • Is there a reason that you are using 2.6 vs. a newer kernel? In my experience there have been some fixes for the armv5 in the newer kernel.
    – jc__
    Mar 28 '16 at 13:44
  • It doesn't HAVE to be a 2.6. I am just working towards trying to run it on some older HTC Android hardware which happens to be 2.6. I have also tried a 3.2 kernel with the same result. RD_GZIP=y. Mar 28 '16 at 14:46
  • Also, if i use "root=ram" or "root=ram0" the error message is the same, but "root=ram1" changes the error to "unknown-block(1,1)". Ie: the block minor number changes with the parameter's ramdisk number. Mar 28 '16 at 14:48
  • I believe the unknown block() means that the kernel cannot find the block device (the ram disk). No disk no rootfs. I assume you mean root=/dev/ram and root=/dev/ram0.
    – jc__
    Mar 28 '16 at 14:56


The solution, as suggested, was to embed the initrd image into the kernel by pointing CONFIG_INITRAMFS_SOURCE to my BusyBox's "_install" directory. Many thanks to jc__ for that tip.

Also, for anyone else trying this, it is worthy of note that I needed to create in the Busybox _install directory:

  • dev/console
  • dev/loop0

as mentioned in this: https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.