GNU/Linux >> Linux Esercitazione >  >> Linux

Cosa può impedire al passaggio init=/path/to/program al kernel di avviare il programma come init?

imbrogli initrd

Se stai usando initrd o initramfs, tieni presente quanto segue:

  • rdinit= è usato al posto di init=

  • se rdinit= non viene fornito, i percorsi predefiniti tentati sono:/sbin/init , /etc/init , /bin/init e /bin/sh ma non /init

    Quando non si utilizza initrd, /init è il primo percorso provato, seguito dagli altri.

v4.15 RTFS:tutto è contenuto all'interno del file https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Per prima cosa apprendiamo che:

  • execute_comand è tutto ciò che viene passato a:init=
  • ramdisk_execute_command è tutto ciò che viene passato a:rdinit=

come si può vedere da:

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

dove __setup è un modo magico di gestire i parametri della riga di comando.

start_kernel , il "punto di ingresso" del kernel, chiama rest_init , che "chiama" kernel_init su un thread:

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Quindi, kernel_init fa:

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

e kernel_init_freeable fa:

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

DA FARE:capire sys_access .

Si noti inoltre che ci sono ulteriori differenze tra gli init ram e gli init non ram, ad es. gestione della console:Differenza nell'esecuzione di init con initramfs incorporato o esterno?


Su

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

Ho trovato:

Quando si esegue il debug di un normale filesystem di root, è utile poter eseguire l'avvio con "init=/bin/sh". L'equivalente initramfs è "rdinit=/bin/sh", ed è altrettanto utile.

Quindi probabilmente prova ridinit=/bin/sh


Guardando il sorgente del kernel Linux, vedo che se il file /init esiste, il kernel tenterà sempre di eseguirlo supponendo che stia eseguendo un avvio da ramdisk. Controlla il tuo sistema per vedere se /init esiste, se esiste, probabilmente è questo il tuo problema.


Linux
  1. Rileva il sistema Init usando la shell?

  2. Cosa fa esattamente oldconfig nel makefile del kernel di Linux?

  3. Qual è l'attuale sorgente del kernel Linux?

  4. Come posso avviare un programma come root usando il window manager?

  5. Come posso conoscere il percorso assoluto di un processo in esecuzione?

Qual è il percorso della mia home directory principale, come può essere modificato?

Percorso assoluto vs relativo in Linux:qual è la differenza?

Cosa può causare la generazione di SIGHUP?

Far suonare da remoto il computer sull'altoparlante incorporato

Qual è il numero massimo di IP che possono essere assegnati a un determinato computer?

Cosa può causare un segnale 11?