Failed to execute /init

harmic picture harmic · Mar 24, 2015 · Viewed 9.2k times · Source

I am trying to build a basic root filesystem using Buildroot, for an embedded system (the Banana PI D1).

I am using a kernel from an SDK supplied by the SoC vendor. From this repo I am using only the kernel, found in src/kernel.

There's nothing remarkable about the Buildroot configuration. It builds with no errors and the resulting root filesystem looks like it contains everything I would expect.

I have configured it to build the filesystem as an initramfs embedded within the zImage.

The kernel appears to start up correctly, but cannot load init and then panics:

Booting Linux on physical CPU 0
Linux version 3.4.35 ([email protected]) (gcc version 4.8.4 (Buildroot 2015.02) ) #7 Sat Mar 21 22:59:18 AEDT 2015
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
...
Kernel command line: root=/dev/mtdblock1 ro init=/sbin/init mem=64M console=ttySAK0,115200
...
Freeing init memory: 4632K
Failed to execute /init
Failed to execute /sbin/init.  Attempting defaults...
mmc0: host does not support reading read-only switch. assuming write-enable.
mmc0: new SDHC card at address 0007
mmcblk0: mmc0:0007 SD08G 7.42 GiB 
 mmcblk0: p1
Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

I have tried a number of troubleshooting steps:

  1. I've built a root filesystem using this miniroot project (took some doing, as it is quite out of date). It booted OK, using the same kernel as I am trying to use with the buildroot root fs.

  2. I've tried using both uClibc and eglibc

  3. I've tried using Buildroot's own cross-tools as well as the cross tools supplied by the SoC vendor

  4. I've confirmed that the built rootfs does include an /init (it does!)

There is a gist here containing the buildroot configuration, a copy of the kernel boot log, and a listing of the contents of the generated filesystem.

What steps can I take to troubleshoot this further?

Update:

  1. The generated rootfs.cpio.gz weighs in at 2139200 bytes. I have read that there is a maximum size of initramfs you can use, but I have not been able to find where the hard limit is documented.

  2. I have attached a listing of the generated root filesystem to the gist linked above.

  3. I have unpacked the rootfs on the host and inspected it. /init contains this:

    #!/bin/sh
    # devtmpfs does not get automounted for initramfs
    /bin/mount -t devtmpfs devtmpfs /dev
    exec 0</dev/console
    exec 1>/dev/console
    exec 2>/dev/console
    exec /sbin/init $*
    

    /sbin/init is a symlink to /bin/busybox.

    /bin/busybox is dynamically linked:

    $ file busybox
    busybox: setuid ELF 32-bit MSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, stripped
    $ ../../../host/usr/bin/armeb-buildroot-linux-gnueabi-readelf -a busybox | grep "Shared library:"
     0x00000001 (NEEDED)                     Shared library: [libc.so.6]
    

    libc.so.6 is present in /lib. /lib32 is a symlink to /lib for good measure.

  4. The device has 64M RAM.

  5. Both the vendor's cross tools and the buildroot cross tools are set up for eabi

Answer

harmic picture harmic · Mar 25, 2015

As suggested by @sawdust, the problem was that the CPU was not supposed to be run in big endian mode.

After changing the target to 'ARM (Little Endian)', cleaning and re-building, it now boots correctly.

In retrospect this should have been obvious - inspecting the vendor's kernel image:

$ file zImage
zImage: Linux kernel ARM boot executable zImage (little-endian)