GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué puede hacer que pasar init=/path/to/program al kernel no inicie el programa como init?

travesuras de initrd

Si está utilizando initrd o initramfs, tenga en cuenta lo siguiente:

  • rdinit= se usa en lugar de init=

  • si rdinit= no se proporciona, las rutas predeterminadas intentadas son:/sbin/init , /etc/init , /bin/init y /bin/sh pero no /init

    Cuando no se usa initrd, /init es el primer camino probado, seguido de los demás.

v4.15 RTFS:todo está contenido dentro del archivo https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Primero aprendemos que:

  • execute_comand es lo que se pasa a:init=
  • ramdisk_execute_command es lo que se pasa a:rdinit=

como se puede ver en:

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

donde __setup es una forma mágica de manejar los parámetros de la línea de comandos.

start_kernel , el "punto de entrada" del núcleo, llama a rest_init , que "llama" kernel_init en un hilo:

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Entonces, kernel_init hace:

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

y kernel_init_freeable hace:

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

TAREAS:entender sys_access .

También tenga en cuenta que existen más diferencias entre los inicios ram y los inicios no ram, p. manejo de la consola:¿Diferencia en la ejecución de init con initramfs incrustado vs. externo?


en

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

Encontré:

Al depurar un sistema de archivos raíz normal, es bueno poder arrancar con "init=/bin/sh". El equivalente de initramfs es "rdinit=/bin/sh", y es igual de útil.

Así que probablemente intente ridinit=/bin/sh


Mirando la fuente del kernel de Linux, veo que si el archivo /init existe, el kernel siempre intentará ejecutarlo suponiendo que está haciendo un arranque de ramdisk. Verifique su sistema para ver si /init existe, si existe, entonces ese es probablemente su problema.


Linux
  1. ¿Cuál es la fuente actual del kernel de Linux?

  2. ¿Cómo puedo iniciar un programa como root usando el administrador de ventanas?

  3. ¿Cómo puedo saber la ruta absoluta de un proceso en ejecución?

  4. ¿Cuál es el número máximo de direcciones IP que se pueden asignar a una computadora determinada?

  5. Pasar opciones a un programa:¿cuál es la convención para un guión frente a dos?

¿Detectar el sistema Init usando el shell?

¿Cuál es la ruta a mi directorio de inicio raíz? ¿Cómo se puede cambiar?

Ruta absoluta vs relativa en Linux:¿Cuál es la diferencia?

Hacer que la computadora emita un pitido de forma remota en el altavoz incorporado

Cambié la RUTA, ahora recibo el comando no encontrado para todo

libvirt:¿cómo puedo hacer que un dominio se inicie cuando se inicie el host?