저는 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_root
initramfs 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
위의 순서로 initrd.img를 종료한 후 내 메모리가 해제됩니까?
linuxrc 끝에 switch_root를 수행하지 않고 그냥 종료하면 어떻게 되나요? 이렇게 하면 이전 initrd img에서 내 메모리가 확보되지 않나요?