initrd शीनिगन्स
यदि आप 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, कर्नेल "प्रवेश बिंदु", कॉल करता है 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।
यह भी ध्यान दें कि रैम इनिट्स और गैर-राम इनिट्स के बीच आगे के अंतर हैं, जैसे कंसोल हैंडलिंग: एंबेड बनाम बाहरी इनट्रैमफ्स के साथ init के निष्पादन में अंतर?
init? वे केवल कमांड लाइन की अनदेखी कर सकते हैं ... आप initrd की जांच करना चाहते हैं और देख सकते हैं कि स्क्रिप्ट वास्तव में क्या कर रहे हैं।