GNU/Linux >> Belajar Linux >  >> Linux

Apa yang membuat lewat init=/path/to/program ke kernel tidak memulai program sebagai init?

kejahatan awal

Jika Anda menggunakan initrd atau initramfs, perhatikan hal berikut:

  • rdinit= digunakan sebagai pengganti init=

  • jika rdinit= tidak diberikan, jalur default yang dicoba adalah:/sbin/init , /etc/init , /bin/init dan /bin/sh tetapi bukan /init

    Saat tidak menggunakan initrd, /init adalah jalur pertama yang dicoba, diikuti oleh yang lainnya.

v4.15 RTFS:semuanya ada di dalam file https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Pertama kita pelajari bahwa:

  • execute_comand adalah apa pun yang diteruskan ke:init=
  • ramdisk_execute_command adalah apa pun yang diteruskan ke:rdinit=

seperti yang dapat dilihat dari:

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

di mana __setup adalah cara ajaib untuk menangani parameter baris perintah.

start_kernel , "titik masuk" kernel, memanggil rest_init , yang "memanggil" kernel_init di utas:

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Lalu, kernel_init melakukan:

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

dan kernel_init_freeable melakukan:

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:pahami sys_access .

Perhatikan juga bahwa ada perbedaan lebih lanjut antara init ram dan init non-ram, mis. penanganan konsol:Perbedaan eksekusi init dengan initramf tersemat vs. eksternal?


Aktif

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

Saya menemukan:

Saat men-debug sistem file root normal, senang bisa boot dengan"init=/bin/sh". Setara dengan initramfs adalah "rdinit=/bin/sh", dan ini sama bergunanya.

Jadi mungkin coba ridinit=/bin/sh


Melihat sumber kernel Linux, saya melihat bahwa jika file /init ada, kernel akan selalu berusaha untuk menjalankannya dengan asumsi melakukan boot ramdisk. Periksa sistem Anda untuk melihat apakah /init ada, jika ya, mungkin itu masalah Anda.


Linux
  1. Apa yang saya gunakan di linux untuk membuat program python dapat dieksekusi

  2. Apa yang dapat menyebabkan SIGHUP dihasilkan?

  3. Bagaimana saya bisa memulai program sebagai root menggunakan window manager?

  1. Bagaimana saya bisa mengetahui jalur absolut dari proses yang sedang berjalan?

  2. Berapa jumlah maksimum IP yang dapat diberikan ke komputer tertentu?

  3. Mengubah PATH, sekarang saya mendapatkan perintah tidak ditemukan untuk semuanya

  1. Deteksi Sistem Init Menggunakan Shell?

  2. Linux – Membuat Daemon Memulai Dengan Linux?

  3. Apa yang dapat menyebabkan sinyal 11?