I'm working on an embedded ARM device running Linux (kernel 3.10), with NAND memory for storage. I'm trying to build a minimal linux which will reside on its own partition and carry out updates of the main firmware.
The kernel uses a very minimal root fs which is stored in a ramfs. However, I can't get it to boot. I get the following error:
[ 0.794113] List of all partitions:
[ 0.797600] 1f00 128 mtdblock0 (driver?)
[ 0.802669] 1f01 1280 mtdblock1 (driver?)
[ 0.807697] 1f02 1280 mtdblock2 (driver?)
[ 0.812735] 1f03 8192 mtdblock3 (driver?)
[ 0.817761] 1f04 8192 mtdblock4 (driver?)
[ 0.822794] 1f05 8192 mtdblock5 (driver?)
[ 0.827820] 1f06 82944 mtdblock6 (driver?)
[ 0.832850] 1f07 82944 mtdblock7 (driver?)
[ 0.837876] 1f08 12288 mtdblock8 (driver?)
[ 0.842906] 1f09 49152 mtdblock9 (driver?)
[ 0.847928] No filesystem could mount root, tried: squashfs
[ 0.853569] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
[ 0.861806] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.73 #11
[ 0.867732] [<800133ec>] (unwind_backtrace+0x0/0x12c) from [<80011a50>] (show_stack+0x10/0x14)
(...etc)
The root fs is built by the build process, using the following (simplified for clarity):
# [Copy some things to $(ROOTFS_OUT_DIR)/mini_rootfs]
cd $(ROOTFS_OUT_DIR)/mini_rootfs && find . | cpio --quiet -o -H newc > $(ROOTFS_OUT_DIR)/backup.cpio
gzip -f -9 $(ROOTFS_OUT_DIR)/backup.cpio
This creates $(ROOTFS_OUT_DIR)/backup.cpio.gz
The kernel is then built like this:
@$(MAKE) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) \
CONFIG_INITRAMFS_SOURCE="$(ROOTFS_OUT_DIR)/backup.cpio.gz" \
CONFIG_INITRAMFS_ROOT_UID=0 CONFIG_INITRAMFS_ROOT_GID=0
I think this means it uses the same config as the main firmware (built elsewhere), but supplies the minimal ramfs image using CONFIG_INITRAMFS_SOURCE.
From Kernel.Org, the ramfs is always built anyway, and CONFIG_INITRAMFS_SOURCE is all that is needed to specify a pre-made root fs to use. There are no build errors to indicate that there is a problem creating the ramfs, and the size of the resulting kernel looks about right. backup.cpio.gz is about 3.6 MB; the final zImage is 6.1 MB; the image is written to a partition which is 8 MB in size.
To use this image, I set some flags used by the (custom) boot loader which tell it to boot from the minimal partition, and also set a different command line for the kernel. Here is the command line used to boot:
console=ttyS0 rootfs=ramfs root=/dev/ram rw rdinit=/linuxrc mem=220M
Note that the nimimal root fs contains "/linuxrc", which is actually a link to /bin/busybox:
lrwxrwxrwx 1 root root 11 Nov 5 2015 linuxrc -> bin/busybox
Why doesn't this boot? Why is it trying "squashfs" filesystem, and is this wrong?
SOLVED! It turned out that a file name used by the (custom) build system had changed as part of an update, and so it was not putting the correct kernel image into the firmware package. I was actually trying to boot the wrong kernel with the "rootfs=ramfs" parameter, one which didn't have a ramfs.
So, for future reference, this error occurs if you specify "rootfs=ramfs" but your kernel wasn't built with any rootfs built in (CONFIG_INITRAMFS_SOURCE=... NOT specified)