web-dev-qa-db-ja.com

busybox switch_rootが機能しない問題

私は組み込みのARM initramfsを使用して起動するLinuxシステムに取り組んでいます。(もしあなたがそうだとしたら、カップルからの背景 以前questions これまでのところ、ここで受け取った助けのおかげで、これまでに、組み込みのinitramfsを使用してTFTP経由でカーネルをブートできます。MMCドライバーは、新しいルートファイルシステムを含むSDカードを検出します。マウントすることはできますが、busybox switch_rootを使用してSDカードのファイルシステムに切り替えて動作させるための最後のステップは取得できません。

Initramfsシェルプロンプトでは、これによりカーネルが新しいファイルシステムに切り替わるはずです。

switch_root -c /dev/console /mnt/root /sbin/init.sysvinit 

ただし、次のように、busybox(switch_rootがエイリアスされている)にそのmanページを印刷させるだけです。

/ # 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のマウントに問題があるのではないかと思いましたが、execがデフォルトであると思い、マウント時にexecオプションを明示的に渡そうとしましたが、成功しませんでした。

5
pingswept

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に陥っています。つまり、initramfs initスクリプトのswitch_rootコマンドは、execを指定してswitch_rootを実行する必要があります。つまり.

exec switch_root ...

「見つかりません」エラーのもう1つの問題は、initramfsルートファイルシステムに実行可能ファイルがないため、実行可能ファイルに必要な共有ライブラリが見つからないことが原因である可能性があります。 switch_rootexecを使用できる場合は、「見つかりません」エラーが発生しない可能性があります。

13
camh

switch_root -c /dev/console /mnt/root /mnt/root/sbin/init.sysvinitは私のために働きました。私は同じ問題を抱えていましたが、switch_root -c /dev/console /mnt/root /sbin/init.sysvinit 動作しませんでした。

申し訳ありませんが、どれもうまくいきませんでした。

私はext2ファイルシステムを作成し、静的に構築されたbusyboxとそのすべてのソフトリンクをコピーしました。そして、busyboxにはスティッキービットがあります(-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
  1. 上記のシーケンスでinitrd.imgを終了すると、RAMは解放されますか?

  2. Linuxrcの最後にswitch_rootを実行せずに終了するだけの場合はどうなりますか?それは私の古いinitrd imgから私のRAMを解放しません。

1