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:
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.
I've tried using both uClibc and eglibc
I've tried using Buildroot's own cross-tools as well as the cross tools supplied by the SoC vendor
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:
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.
I have attached a listing of the generated root filesystem to the gist linked above.
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.
The device has 64M RAM.
Both the vendor's cross tools and the buildroot cross tools are set up for eabi
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)