Saya mencoba men-debug skrip init pada sistem Linux; Saya mencoba meneruskan init=/bin/sh
ke kernel untuk memulai sh
tanpa memulai init
sehingga saya dapat menjalankan urutan init secara manual.
Apa yang saya temukan adalah kernelnya sudah mulai init
. Selama bootup, salah satu pesan printk adalah baris perintah, dan itu menunjukkan bahwa baris sedang diatur dengan benar; selain itu, saya dapat mempengaruhi hal-hal lain menggunakan baris perintah kernel. Saya telah memeriksa untuk memastikan jalannya ada; ya.
Ini adalah sistem busybox, dan init adalah symlink ke busybox; jadi untuk memastikan busybox tidak melakukan sihir aneh ketika PID-nya adalah 1, saya juga mencoba menjalankan program non-busybox seperti init; itu juga tidak berhasil. Tampaknya apa pun yang saya lakukan, init dijalankan.
Apa yang bisa menyebabkan perilaku ini?
init
? Mereka mungkin mengabaikan baris perintah ... Anda mungkin ingin memeriksa initrd dan melihat apa yang sebenarnya dilakukan skrip.Jawaban:
Melihat sumber kernel Linux, saya melihat bahwa jika file / init ada, kernel akan selalu berusaha untuk menjalankannya dengan asumsi bahwa ia melakukan boot ramdisk. Periksa sistem Anda untuk melihat apakah / init ada, jika ada, maka itu mungkin masalah Anda.
sumber
execute_command
terlebih dahulu, yang berasal dariinit=
parameter baris perintah kernel . Jika tidak dapat menjalankannya, ia akan mencetak peringatan dan mencoba dijalankaninit
di berbagai lokasi. Ini ada diinit/main.c
dalam fungsiinit_post()
. Saya melihat-lihat pesan printk kernel dan menemukan peringatan di output kernel saya, jadi sekarang saya harus mencari tahu mengapa itu tidak dapat memulai / bin / sh atau hal lain yang saya coba untuk mulai.rdinit
ketika boot dari ramdisk rupanya: unix.stackexchange.com/a/430614/32558shenanigans initrd
Jika Anda menggunakan initrd atau initramfs, perhatikan hal berikut:
rdinit=
digunakan sebagai gantiinit=
jika
rdinit=
tidak diberikan, jalur bawaan berusaha adalah:/sbin/init
,/etc/init
,/bin/init
dan/bin/sh
tapi tidak/init
Ketika tidak menggunakan initrd,
/init
adalah jalan pertama dicoba, diikuti oleh yang lain.v4.15 RTFS: semuanya ada di dalam file https://github.com/torvalds/linux/blob/v4.15/init/main.c .
Pertama kita pelajari itu:
execute_comand
adalah apa pun yang diteruskan ke:init=
ramdisk_execute_command
adalah apa pun yang diteruskan ke:rdinit=
seperti yang bisa dilihat dari:
di mana
__setup
cara ajaib menangani parameter baris perintah.start_kernel
, "titik masuk" kernel, panggilanrest_init
, yang "dipanggil"kernel_init
di utas:Lalu,
kernel_init
apakah:dan
kernel_init_freeable
tidak:TODO: mengerti
sys_access
.Juga perhatikan bahwa ada perbedaan lebih lanjut antara init ram dan init non-ram, misalnya penanganan konsol: Perbedaan dalam pelaksanaan init dengan initramfs yang tertanam vs eksternal?
sumber
Di
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Saya menemukan:
Jadi mungkin coba ridinit = / bin / sh
sumber
Anda dapat mengkustomisasi kernel Linux Anda dan mengkompilasi ulangnya. Untuk kernel 4,9, Edit fungsi "kernel_init" di init / main.c dan coba jalankan baris berikut terlebih dahulu:
Selain itu, ini mungkin disebabkan oleh parameter kernel yang diteruskan oleh BootLoader.
sumber