कर्नेल को प्रोग्राम के रूप में पासिंग इनिट = / पाथ / टू / प्रोग्राम नहीं बना सकता है?


13

मैं लिनक्स सिस्टम पर एक init स्क्रिप्ट को डीबग करने का प्रयास कर रहा हूं; मैं init=/bin/shइसे शुरू करने के shबिना इसे चालू करने के लिए कर्नेल को पास करने की कोशिश कर रहा हूं initताकि मैं मैन्युअल रूप से init अनुक्रम के माध्यम से चला सकूं।

मैंने पाया है कि कर्नेल initवैसे भी शुरू हो रहा है। बूटअप के दौरान, प्रिंटक संदेशों में से एक कमांड लाइन है, और यह दिखा रहा है कि लाइन ठीक से सेट हो रही है; इसके अलावा, मैं कर्नेल कमांड लाइन का उपयोग करके अन्य चीजों को प्रभावित कर सकता हूं। मैंने यह सुनिश्चित करने के लिए जाँच की है कि मार्ग मौजूद है; ऐसा होता है।

यह एक बिजीबॉक्स सिस्टम है, और यह इनबॉक्स बिजीबॉक्स का सिम्बल है; इसलिए यह सुनिश्चित करने के लिए कि व्यस्त पीक अजीब जादू नहीं करता है जब इसकी पीआईडी ​​1 है, तो मैंने एक गैर-व्यस्त बॉक्स प्रोग्राम को इनिट के रूप में चलाने की कोशिश की; यह भी काम नहीं किया। ऐसा लगता है कि कोई फर्क नहीं पड़ता कि मैं क्या करता हूं, इनिट चलाया गया।

इस व्यवहार के कारण क्या हो सकता है?


आधार डिस्ट्रो क्या है जो के लिए बिजीबॉक्स का उपयोग कर रहा है init? वे केवल कमांड लाइन की अनदेखी कर सकते हैं ... आप initrd की जांच करना चाहते हैं और देख सकते हैं कि स्क्रिप्ट वास्तव में क्या कर रहे हैं।
आरोन डी। मरास्को

यह कोई डिस्ट्रो नहीं है - यह मेरा अपना निर्माण है; जिसके कारण मैं init स्क्रिप्ट को डीबग करना चाह रहा हूं।
शॉन जे। गोफ

जवाबों:


3

लिनक्स कर्नेल स्रोत को देखते हुए, मैं देखता हूं कि यदि फ़ाइल / इनिट मौजूद है, तो कर्नेल हमेशा यह मानकर चलता है कि यह रैमडिस्क बूट कर रहा है। यह देखने के लिए अपने सिस्टम की जाँच करें कि क्या / init मौजूद है, यदि यह होता है, तो संभवतः यह आपकी समस्या है।


दरअसल, यह execute_commandपहले चेक करता है , जो कर्नेल कमांड लाइन init=पैरामीटर से आता है । यदि यह इसे निष्पादित नहीं कर सकता है, तो यह एक चेतावनी प्रिंट करता है और initविभिन्न स्थानों में चलाने की कोशिश करता है । यह init/main.cफ़ंक्शन में है init_post()। मैंने कर्नेल प्रिंट के संदेशों को देखा और अपने कर्नेल के आउटपुट में चेतावनी को पाया, इसलिए अब मुझे यह पता लगाना होगा कि यह क्यों शुरू नहीं हो सकता है / बिन / श या कुछ और जिसे मैं शुरू करने की कोशिश करता हूं।
शॉन जे। गोफ

जिस कोड को मैंने देखा (v3.2.2 मुझे लगता है) ने सेट की जाँच की ramdisk_execute_command अगर यह परेशान था और फिर इसे चलाने की कोशिश की, तो आपको वह चालू नहीं होना चाहिए। बहुत बुरा है, क्योंकि मुझे कुछ और नहीं दिखता जो इसे समझाएगा।
काइल जोन्स

रमिस्कrdinit से बूट करते समय आपको इसका उपयोग अवश्य करना चाहिए : unix.stackexchange.com/a/430614/32558
Ciro Santilli 新疆 ing ing ing

8

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 के निष्पादन में अंतर?


4

पर

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

मुझे मिला:

सामान्य रूट फाइलसिस्टम को डिबग करते समय, "init = / bin / sh" के साथ बूट करने में सक्षम होना अच्छा है। Initramfs समतुल्य "rdinit = / bin / sh" है, और यह उतना ही उपयोगी है।

तो शायद उपहास = / बिन / श की कोशिश करें


0

आप अपने लिनक्स कर्नेल को कस्टम कर सकते हैं और इसे पुनः जोड़ सकते हैं। 4.9 कर्नेल के लिए, init / main.c में फंक्शन "k गिरी_इनिट" को एडिट करें और पहले निम्नलिखित लाइन को चलाने की कोशिश करें:

try_to_run_init_process("/bin/sh")

इसके अलावा, यह बूटलॉडर द्वारा पारित कर्नेल मापदंडों के कारण हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.