I'm working on an embedded ARM Linux system that boots using initramfs. (Here's some background from a couple earlier questions, if you're interested.) So far, thanks in part to help received here, I can boot the kernel via TFTP with an embedded initramfs. The MMC driver detects an SD card containing a new root filesystem, which I can then mount. However, I cannot get the final step, using busybox switch_root to switch to the filesystem on the SD card, to work.
At the initramfs shell prompt, I think this should make the kernel switch to the new filesystem:
switch_root -c /dev/console /mnt/root /sbin/init.sysvinit
However, it just makes busybox (to which switch_root is aliased) print its man page, like this:
/ # switch_root -c /dev/console /mnt/root /sbin/init.sysvinit
BusyBox v1.17.4 (2010-12-08 17:01:07 EST) multi-call binary.
Usage: switch_root [-c /dev/console] NEW_ROOT NEW_INIT [ARGS]
Free initramfs and switch to another root fs:
chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,
execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.
Options:
-c DEV Reopen stdio to DEV after switch
I think the -c option is correct, since it's the same as what is contained in the example, and /dev/console exists.
/ # ls -l /dev
total 0
crw-r--r-- 1 0 0 5, 1 Jan 1 00:28 console
brw-r--r-- 1 0 0 7, 0 Dec 21 2010 loop0
brw-r--r-- 1 0 0 179, 0 Dec 21 2010 mmcblk0
brw-r--r-- 1 0 0 179, 1 Dec 21 2010 mmcblk0p1
brw-r--r-- 1 0 0 179, 2 Dec 21 2010 mmcblk0p2
brw-r--r-- 1 0 0 179, 3 Dec 21 2010 mmcblk0p3
brw-r--r-- 1 0 0 179, 4 Dec 21 2010 mmcblk0p4
/mnt/root also exists.
/ # ls /mnt/root
bin etc linuxrc mnt sys var
boot home lost+found proc tmp
dev lib media sbin usr
The init executable exists:
/ # ls -lh /mnt/root/sbin/
<snip>
lrwxrwxrwx 1 0 0 19 Dec 21 2010 init -> /sbin/init.sysvinit
-rwxr-xr-x 1 0 0 22.8K Dec 21 2010 init.sysvinit
But here's something strange:
/mnt/root/sbin # pwd
/mnt/root/sbin
/mnt/root/sbin # ls -l | grep init.sysvinit
lrwxrwxrwx 1 0 0 19 Dec 21 2010 init -> /sbin/init.sysvinit
-rwxr-xr-x 1 0 0 23364 Dec 21 2010 init.sysvinit
/mnt/root/sbin # ./init.sysvinit
/bin/sh: ./init.sysvinit: not found
/mnt/root/sbin # /mnt/root/sbin/init.sysvinit
/bin/sh: /mnt/root/sbin/init.sysvinit: not found
That's totally mystifying. I'm not sure where I'm going wrong. I've looked at the source, which is at http://git.busybox.net/busybox/tree/util-linux/switch_root.c?id=1_17_4
It's not just the init.sysvinit executable. I can't execute anything from the SD card. For example:
/mnt/root/bin # ./busybox
/bin/sh: ./busybox: not found
/mnt/root/bin # /mnt/root/busybox
/bin/sh: /mnt/root/busybox: not found
/mnt/root/bin # ls -l | grep "2010 busybox"
-rwxr-xr-x 1 0 0 462028 Dec 21 2010 busybox
Anyone have a clue what's amiss here? I thought it might be some problem with mounting the card noexec, but I believe exec is the default, and I tried passing the exec option explicitly at mount with no success.