나는 겪고있다사용자 정의 initramfs 설정을 위한 튜토리얼그것은 다음과 같이 말합니다:
누락된 유일한 것은 /init입니다. 이는 일단 로드되면 커널에 의해 실행되는 initramfs의 루트에 있는 실행 파일입니다. sys-apps/busybox에는 모든 기능을 갖춘 셸이 포함되어 있으므로 이는 /init 바이너리를 간단한 셸 스크립트로 작성할 수 있음을 의미합니다(컴파일해야 하는 어셈블러나 C로 작성된 복잡한 응용 프로그램으로 만드는 대신).
다음으로 시작하는 쉘 스크립트로 init의 예를 제공합니다.#!/bin/busybox sh
지금까지 제가 받은 인상은 init가 시작되는 기본 프로세스이고 다른 모든 사용자 공간 프로세스는 궁극적으로 init의 하위 프로세스라는 것입니다. 그러나 주어진 예에서 첫 번째 프로세스는 실제로 bin/busybox/ sh
나중에 init에서 생성됩니다.
이것이 올바른 설명인가요? 예를 들어, 당시에 통역사를 사용할 수 있었다면 Python 스크립트 등으로 init를 작성할 수 있습니까?
답변1
init는 (하위 프로세스로서) "생성"되지 않지만 exec
다음과 같습니다.
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
전체 프로세스를 교체합니다. 이전에 Initramfs의 프로세스였음에도 불구하고 최종 init는 여전히 첫 번째 프로세스(pid 1)입니다.
Initramfs 는 pid 1, s를 Busybox (현재 pid 1)로 /init
사용하는 Busybox 쉘 스크립트입니다 . 이 프로그램은 마운트 지점을 변경하여 새로운 .exec
switch_root
switch_root
/mnt/root
/
switch_root
그러면 실제 루트 파일 시스템이 다시 exec
액세스 됩니다 /sbin/init
. 따라서 실제 초기화 시스템이 pid 1의 첫 번째 프로세스가 되고, 결과적으로 여러 하위 프로세스가 생성될 수 있습니다.
물론 Python을 Initramfs에 굽는 데 성공했다면 Python 스크립트를 사용하여 수행할 수도 있습니다. 어쨌든 busybox를 포함할 계획이 없다면 해당 기능 중 일부( switch_root
일반적으로 간단한 명령으로 수행하는 다른 모든 기능 포함)를 다시 구현해야 하는 수고를 겪어야 합니다.
그러나 스크립트 바이너리( )를 허용하지 않는 커널에서는 작동하지 않습니다 CONFIG_BINFMT_SCRIPT=y
. 이 경우 인터프리터를 직접 시작하고 어떻게든 스크립트를 로드해야 합니다.
답변2
Linux 커널의 exec 시스템 호출 자체는 shebang을 이해합니다.
실행된 파일이 매직 바이트로 시작하면 #!
커널에 다음을 사용하도록 지시합니다 #!/bin/sh
.
- do 및
exec
시스템 호출 - 실행 파일이 있음
/bin/sh
- CLI 매개변수를 사용합니다: 현재 스크립트의 경로
이것이 바로 일반 사용자 공간 쉘 스크립트를 실행할 때 일어나는 일입니다:
./myscript.sh
.ELF
대신 파일이 매직 바이트로 시작하면 #!
커널은 이를 실행하기 위해 ELF 로더를 선택합니다.
자세한 내용은 다음을 참조하세요.사람들이 Python 스크립트의 첫 번째 줄에 #!/usr/bin/env python shebang을 쓰는 이유는 무엇입니까? |스택 오버플로
/init
이것을 기억하고 나면 커널이 쉘 스크립트를 포함하여 무엇이든 실행할 수 있다는 것과 /bin/sh
이 경우 커널이 첫 번째 실행 파일이 되는 이유를 쉽게 받아들일 수 있습니다 .
시험해 보고 싶은 분들을 위해 실행 가능한 최소 예제는 다음과 같습니다.https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init