私はinitramfsを使用して起動する組み込みARM Linuxシステムを開発しています。 (ここにはいくつかの背景があります。より早い 質問、興味があれば。 )これまでは、ここで受けた助けのおかげで、initramfsが組み込まれたTFTPを通じてカーネルを起動することができました。 MMCドライバは、新しいルートファイルシステムを含むSDカードを検出してマウントすることができます。ただし、busybox switch_rootを使用してSDカードのファイルシステムに切り替える最後の手順を完了することはできません。
initramfsシェルプロンプトで、カーネルを新しいファイルシステムに切り替える必要があると思います。
switch_root -c /dev/console /mnt/root /sbin/init.sysvinit
ただし、これはbusybox(switch_rootのエイリアス)に次のマニュアルページを印刷させます。
/ # 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
-c オプションは例に含まれているものと同じで、/dev/console が存在するため、正しいオプションだと思います。
/ # 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も存在します。
/ # ls /mnt/root
bin etc linuxrc mnt sys var
boot home lost+found proc tmp
dev lib media sbin usr
init実行可能ファイルが存在します。
/ # 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
ところで、奇妙な点があります。
/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
本当に謎です。私がどこで間違っているのかわかりません。ソースを確認してみると、http://git.busybox.net/busybox/tree/util-linux/switch_root.c?id=1_17_4
これは init.sysvinit 実行可能ファイルではありません。 SDカードでは何もできません。たとえば、
/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
ここで何が起こっているのか知っている人はいますか?私はnoexecでカードをマウントするのに問題があるのではないかと思いました。
答え1
switch_root
コマンドラインで機能しない理由は、busyboxの次のコードによるものです。
if (st.st_dev == rootdev || getpid() != 1) {
// Show usage, it says new root must be a mountpoint
// and we must be PID 1
bb_show_usage();
}
あなたはPID 1ではないので、このジレンマに陥りましたbb_show_usage
。これはswitch_root
、initramfs initスクリプトのコマンドが.ieswitch_root
で終わる必要があることを意味します。exec
exec switch_root ...
「見つかりません」エラーのもう1つの問題は、initramfsルートファイルシステムに共有ライブラリがないため、実行可能ファイルに必要な共有ライブラリが見つからないことです。これswitch_root
が利用可能な場合、exec
「見つかりません」エラーが消える可能性があります。
答え2
switch_root -c /dev/console /mnt/root /mnt/root/sbin/init.sysvinit
私のために動作します。私は同じ問題がありましたが、うまくswitch_root -c /dev/console /mnt/root /sbin/init.sysvinit
いきませんでした。
私に働いてくれる人がいなくてすみません。
私はext2ファイルシステムを作成し、静的に構築されたビジボックスとすべてのソフトリンクをコピーしました。ビジーボックスには粘着性のあるビットがあります。 (-rwsr-sr-x 権限).私は/linuxrcを持っていますが、/etc/ディレクトリにはあまりありません。 ext2ファイルシステムからイメージを作成するには、次のコマンドを使用しています。
mkimage -C gzip -A ppc -O linux -T ramdisk -a 0x2000000 -n "ramdisk" -d initrd-ext2 initrd.img
initrd.imgをカーネルの一部ではなく/boot/に別々のファイルとして保存します。
linuxrcの内容は次のとおりです。
#!/bin/sh (#!/bin/busybox shも試しました)
mkdir -p /proc /dev /sys /mnt /tmp
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mknod /dev/misc/rtc0 c 254 0
mdev -s
mkdir -p /new_root
mount /dev/mmcblk0p2 /new_root
exec switch_root -c /dev/console /new_root /sbin/init
私のカーネルが正しくロードされ、initrd.imgがロードされ、linuxrcが実行されますが、最終的にはswitch_rootは使い方のヘルプを提供します。
しかし、私のシステムは引き続き新しいrootfsを起動してロードします。以下は順序です。
RAMDISK: ext2 filesystem found at block 0
RAMDISK: Loading 10240KiB [1 disk] into ram disk... done.
VFS: Mounted root (ext2 filesystem) on device 1:0.
Starting initramfs boot...
Waiting 5 seconds for devices to settle...
kjournald starting. Commit interval 5 seconds
EXT3 FS on mmcblk0p2, internal journal
EXT3-fs: mounted filesystem with writeback data mode.
BusyBox v1.21.0.git (2012-10-17 00:34:21 PDT) 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.
-c DEV Reopen stdio to DEV after switch
VFS: Mounted root (ext3 filesystem) on device 179:2.
Trying to move old root to /initrd ... /initrd does not exist. Ignored.
Unmounting old root
Trying to free ramdisk memory ... okay
Freeing unused kernel memory: 200k init
INIT: version 2.86 booting
Please wait: booting...
mount: sysfs already mounted or /sys busy
mount: according to mtab, sysfs is already mounted on /sys
Starting udev
udev: starting version 154
Root filesystem already rw, not remounting
Caching udev devnodes
上記の順序でinitrd.imgを終了した後、私のメモリは解放されますか?
linuxrcの末尾にswitch_rootを実行せずにただ終了するとどうなりますか?これにより、以前のinitrd imgから私のメモリが解放されませんか?