busybox switch_root가 작동하는 데 문제가 있습니다.

busybox switch_root가 작동하는 데 문제가 있습니다.

저는 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로 카드를 마운트하는 데 문제가 있지 않을까 생각했는데, exec가 기본값이라고 믿고 마운트가 성공하지 못할 때 명시적으로 exec 옵션을 전달해 보았습니다.

답변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_rootinitramfs init 스크립트의 명령이 .ie switch_root로 끝나야 함을 의미합니다.exec

exec switch_root ...

"찾을 수 없음" 오류의 또 다른 문제는 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
  1. 위의 순서로 initrd.img를 종료한 후 내 메모리가 해제됩니까?

  2. linuxrc 끝에 switch_root를 수행하지 않고 그냥 종료하면 어떻게 되나요? 이렇게 하면 이전 initrd img에서 내 메모리가 확보되지 않나요?

관련 정보