GNU/Linux >> Tutoriels Linux >  >> Linux

Qu'est-ce qui peut faire en sorte que le passage de init=/path/to/program au noyau ne démarre pas le programme en tant qu'init ?

manigances initrd

Si vous utilisez initrd ou initramfs, gardez à l'esprit ce qui suit :

  • rdinit= est utilisé à la place de init=

  • si rdinit= n'est pas donné, les chemins par défaut tentés sont :/sbin/init , /etc/init , /bin/init et /bin/sh mais pas /init

    Lorsque vous n'utilisez pas initrd, /init est le premier chemin essayé, suivi des autres.

v4.15 RTFS :tout est contenu dans le fichier https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Nous apprenons d'abord que :

  • execute_comand est ce qui est passé à :init=
  • ramdisk_execute_command est ce qui est passé à :rdinit=

comme on peut le voir sur :

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 est une manière magique de gérer les paramètres de la ligne de commande.

start_kernel , le "point d'entrée" du noyau, appelle rest_init , qui "appelle" kernel_init sur un fil :

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Ensuite, kernel_init fait :

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

et kernel_init_freeable fait :

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

À FAIRE :comprendre sys_access .

Notez également qu'il existe d'autres différences entre les initialisations RAM et les initialisations non RAM, par ex. gestion de la console :Différence d'exécution d'init avec initramfs intégré et externe ?


Le

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

J'ai trouvé :

Lors du débogage d'un système de fichiers racine normal, il est agréable de pouvoir démarrer avec "init=/bin/sh". L'équivalent initramfs est "rdinit=/bin/sh", et c'est tout aussi utile.

Essayez donc probablement ridinit=/bin/sh


En regardant la source du noyau Linux, je vois que si le fichier /init existe, le noyau tentera toujours de l'exécuter en supposant qu'il effectue un démarrage sur disque virtuel. Vérifiez votre système pour voir si /init existe, si c'est le cas, alors c'est probablement votre problème.


Linux
  1. Linux - Pourquoi le noyau ne peut-il pas exécuter Init ?

  2. Que dois-je utiliser sous Linux pour rendre un programme python exécutable

  3. Que signifie __init dans le code du noyau Linux ?

  4. Comment puis-je démarrer un programme en tant que root à l'aide du gestionnaire de fenêtres ?

  5. Comment puis-je connaître le chemin absolu d'un processus en cours d'exécution ?

Quel est le chemin d'accès à mon répertoire racine, comment peut-il être modifié ?

Chemin absolu ou relatif sous Linux :quelle est la différence ?

Quelle est la source actuelle du noyau Linux ?

Qu'est-ce qui peut provoquer la génération de SIGHUP ?

Faites biper l'ordinateur à distance sur le haut-parleur intégré

Passer des options à un programme :quelle est la convention entre un tiret et deux ?