임베디드 initramfs와 임베디드 initramfs의 init 실행의 차이점은 무엇입니까?


10

커널 (v4.1-rc5)과 busybox (v1.23.2)로 채워진 initramfs로 구성된 매우 작은 Linux 시스템을 만들고 있습니다. 대부분 잘 작동하지만 임베디드 initramfs와 외부 initramfs 중 어느 것을 사용하는지 / init에서 명령 실행 동작의 차이를 관찰합니다.

/ init 스크립트는 다음과 같습니다.

#!/bin/sh

dmesg -n 1

mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
    setsid cttyhack /bin/sh
done

그런 다음 커널 .config의 CONFIG_INITRAMFS_SOURCE 옵션을 initramfs의 모든 폴더가 들어있는 디렉토리로 설정하거나

find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz

그것을 구축합니다.

그런 다음 CONFIG_INITRAMFS_SOURCE 설정 여부에 관계없이 커널을 컴파일하면 시스템의 두 가지 변형이 발생합니다.

  1. initramfs가 포함 된 이미지

  2. bzImage + rootfs.cpio.gz (외부 initramfs)

내가 지금 사용하는 사람들을 시작할 때 qemu

qemu-system-x86_64 -enable-kvm -kernel bzImage

또는

qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz

다음과 같은 동작 차이가 있습니다.

버전 2 (외부 initramfs)를 사용하면 모든 것이 제대로 작동하고 "환영"이 표시되고 프롬프트가 표시됩니다. 그러나 버전 1 (내장 initramfs)에서는 경고 메시지가 나타납니다.

unable to open an initial console

"환영합니다"가 표시되지 않고 프롬프트가 표시됩니다.

프로세스를 이해하는 한, 두 버전의 initramfs는 동일한 폴더에서 파일을 빌드하거나 커널이 빌드하기 때문에 동일한 파일을 포함해야합니다.

이 행동에 대한 설명을 도와 줄 사람이 있는지 궁금합니다.

* 업데이트 *

mikeserv가 의견에서 말했듯이 커널에는 기본적으로 최소 내장 initramfs가 포함되어 있습니다. 이것은 외부를 사용할 때 여전히 존재하지만 직접 포함하면 덮어 씁니다. 사양과 달리 실제로 비어 있지는 않지만 dev 폴더, 루트 폴더 및 / dev / console 장치가 포함되어 있습니다. 그런 다음이 장치는 외부 initramfs를 사용할 때 사용되지만 직접 내장하면 덮어 씁니다. 따라서 mknod -m 622 initramfs_src/dev/console c 5 1자신을 임베드 할 때 initramfs 소스에 / dev / console 장치를 포함시켜야합니다 .

Mikeserv, frostschutz 및 JdeBP에게 감사의 말을 전합니다.


/dev/console내장 권한에 어떤 권한이 설정되어 있습니까? 나는 두 가지 경우 에 누가 포장 하는지 에 대한 차이점이 있다고 생각합니다 .
mikeserv 2016 년

비슷한 질문은 물론 stackoverflow.com/questions/10437995 입니다.
JdeBP

@mikeserv 콘솔 장치는 두 빌드에서 동일한 권한과 소유권을 갖습니다.
clw

@JdeBP 두 경우 모두 프롬프트가 표시되고 콘솔 장치가 있기 때문에 그와 비슷한 지 확실하지 않습니다. 한 init에서만 echo를 실행하고 다른 init에서는 echo를 실행할 수 없습니다.
clw

1
권한이 전혀 없다면 initramfs에서 권한이 어떻게 동일 할 수 있습니까?
mikeserv 2016 년

답변:


2

그들은 정말로 동일합니까?

https://wiki.gentoo.org/wiki/Custom_Initramfs#Salvaging에/usr/src/linux/usr/initramfs_data.cpio.gz 설명 된대로 bzImage에서 찾 거나 추출 할 수있는 기본 제공 도구

내장 된 것을 사용하고 대신 외부로 사용하면 작동합니까?

여전히 다른 경우 커널 자체는 동일합니까? ( /proc/config.gz둘 다 비교 )

약간의 차이가 있습니다. 커널이 initramfs가 어디에서 왔는지 신경 쓰지 않습니다. 매개 변수를 qemu전달할 때 다른 설정을 사용하는 것이 더 빠를 것 같습니다 -initrd.

참고로, 당신 /init은 나에게 무한한 껍질을 낳는 것처럼 보입니다. setsid아닙니다 exec. 내가 잘못?


1
이 답변은 모든 질문 인 것 같습니다.
JdeBP

1
@JdeBP : 당신은 4 차원 적으로 생각하지 않습니다!
frostschutz 2018 년

1
@frostschutz 답장을 보내 주셔서 감사합니다! 커널이 빌드 한 initramfs (usr / initramfs_data.cpio.gz)를 외부로 사용하면 잘 작동합니다! 또한 임베디드 initramfs로 컴파일 된 커널에 외부 커널을 제공하면 외부가 임베디드 커널을 덮어 써야하지만 경고가 나타납니다 ( kernel.org/doc/Documentation/filesystems/… ). 따라서 아마도 qemu -initrd가 아니라 커널 자체 내의 것입니다. 나는 CONFIG_INITRAMFS_SOURCE 이외의 다른 것을 바꾸지 않았다.
clw

@frostschutz 응답하기 On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?: 루프는 sh쉘이 종료 될 때까지 블록을 호출하기 때문에 getty 또는 유사한 도구를 모방 합니다.
stefanjunker

@stefanjunker 그리고 setsid는 전혀 차단하지 않는 한 괜찮을 것입니다 ...
frostschutz

1

Buildroot 2018.02가이를 처리하는 방법에 관심이있을 수도 있습니다.

initramfs ( BR2_TARGET_ROOTFS_INITRAMFS=y) 또는 initrd ( BR2_TARGET_ROOTFS_CPIO=n) 를 사용할 때마다 /initrootfs https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/init에 다음 이 추가됩니다.

#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init "$@"

복사는 https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk에 의해 수행됩니다 .

# devtmpfs does not get automounted when initramfs is used.
# Add a pre-init script to mount it before running init
define ROOTFS_CPIO_ADD_INIT
    if [ ! -e $(TARGET_DIR)/init ]; then \
        $(INSTALL) -m 0755 fs/cpio/init $(TARGET_DIR)/init; \
    fi
endef

init 경로가 /initinitramfs를위한 것임을 아는 것도 유용합니다 . 다른 /sbin/init방법 과 달리 init = / path / to / program을 init로 프로그램을 시작하지 않고 커널에 전달할 수있는 것은 무엇입니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.