GNU/Linux >> Znalost Linux >  >> Linux

Co může způsobit, že předání init=/cesta/k/programu do jádra nespustí program jako init?

initrd shenanigans

Pokud používáte initrd nebo initramfs, mějte na paměti následující:

  • rdinit= se používá místo init=

  • pokud rdinit= není zadáno, pokusy o výchozí cesty jsou:/sbin/init , /etc/init , /bin/init a /bin/sh ale ne /init

    Když nepoužíváte initrd, /init je první vyzkoušená cesta, následovaná ostatními.

v4.15 RTFS:vše je obsaženo v souboru https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Nejprve se naučíme, že:

  • execute_comand je to, co je předáno:init=
  • ramdisk_execute_command je to, co je předáno:rdinit=

jak je vidět z:

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);

kde __setup je kouzelný způsob manipulace s parametry příkazového řádku.

start_kernel , "vstupní bod" jádra, volá rest_init , který "volá" kernel_init ve vláknu:

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Potom kernel_init dělá:

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.");
}

a kernel_init_freeable dělá:

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:rozumějte sys_access .

Všimněte si také, že existují další rozdíly mezi ram init a non-ram init, např. manipulace s konzolou:Rozdíl v provádění init s embedded a externími initramfs?


Zapnuto

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

Našel jsem:

Při ladění normálního kořenového souborového systému je příjemné zavést systém pomocí "init=/bin/sh". Ekvivalent initramfs je "rdinit=/bin/sh" a je stejně užitečný.

Takže pravděpodobně zkuste ridinit=/bin/sh


Když se podívám na zdroj linuxového jádra, vidím, že pokud soubor /init existuje, jádro se jej vždy pokusí spustit za předpokladu, že spouští ramdisk. Zkontrolujte svůj systém, zda existuje /init, pokud ano, pak je to pravděpodobně váš problém.


Linux
  1. Zjistit iniciační systém pomocí Shell?

  2. Linux – nechat démona spustit s Linuxem?

  3. Linux – Proč nemůže jádro spustit inicializaci?

  1. Co používám na linuxu k vytvoření spustitelného programu python

  2. Co znamená __init v kódu jádra Linuxu?

  3. Co může způsobit generování SIGHUP?

  1. Jak mohu spustit program jako root pomocí správce oken?

  2. Jak mohu znát absolutní cestu běžícího procesu?

  3. Jaký je maximální počet IP adres, které lze danému počítači přiřadit?