initrd shenanigans
initrd 또는 initramfs를 사용하는 경우 다음을 명심하십시오.
rdinit=
대신에 사용 init=
경우에 rdinit=
주어지지 않는, 시도 기본 경로는 다음과 같습니다 /sbin/init
, /etc/init
, /bin/init
과 /bin/sh
는 아니지만/init
initrd를 사용하지 않을 때는 /init
첫 번째 경로를 시도한 후 다른 경로를 시도합니다.
v4.15 RTFS : 모든 것이 https://github.com/torvalds/linux/blob/v4.15/init/main.c 파일에 포함되어 있습니다.
먼저 우리는 그것을 배웁니다.
execute_comand
전달 된 것입니다 : init=
ramdisk_execute_command
전달 된 것입니다 : rdinit=
에서 볼 수 있듯이 :
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
/*
* In case LILO is going to boot us with default command line,
* it prepends "auto" before the whole cmdline which makes
* the shell think it should execute a script with such name.
* So we ignore all arguments entered _before_ init=... [MJ]
*/
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
static int __init rdinit_setup(char *str)
{
unsigned int i;
ramdisk_execute_command = str;
/* See "auto" comment in init_setup */
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("rdinit=", rdinit_setup);
여기서 __setup
명령 줄 매개 변수를 처리하는 마법의 방법입니다.
start_kernel
커널 "entry point"는을 호출 하고 스레드에서 rest_init
"호출" kernel_init
합니다.
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
그런 다음 kernel_init
을 수행합니다
static int __ref kernel_init(void *unused)
{
int ret;
kernel_init_freeable();
[...]
if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\n",
ramdisk_execute_command, ret);
}
[...]
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
panic("Requested init %s failed (error %d).",
execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/admin-guide/init.rst for guidance.");
}
그리고 kernel_init_freeable
않습니다 :
static noinline void __init kernel_init_freeable(void)
{
[...]
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
}
TODO : 이해하십시오 sys_access
.
또한 램 초기화와 비램 초기화 사이에는 추가적인 차이점이 있습니다. 예 : 콘솔 처리 : 내장형 대 외부 initramfs를 사용한 초기화 실행의 차이?
init
? 그들은 단순히 명령 줄을 무시하고있을 수 있습니다 ... initrd 를 검사 하고 스크립트가 실제로 무엇을하고 있는지 확인할 수 있습니다.