init tidak "ditelurkan" (sebagai proses anak), melainkan exec
ingin ini:
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
menggantikan seluruh proses di tempat. Init terakhir masih merupakan proses pertama (pid 1), meskipun didahului dengan yang ada di Initramfs.
Initramfs /init
, yang merupakan skrip shell Busybox dengan pid 1, exec
s ke Busybox switch_root
(jadi sekarang switch_root
adalah pid 1); program ini mengubah titik pemasangan Anda jadi /mnt/root
akan menjadi /
baru .
switch_root
lalu sekali lagi exec
s ke /sbin/init
dari sistem file root Anda yang sebenarnya; sehingga menjadikan sistem init Anda yang sebenarnya sebagai proses pertama dengan pid 1, yang pada gilirannya dapat menelurkan sejumlah proses anak.
Tentu saja itu bisa dilakukan dengan skrip Python, jika Anda entah bagaimana berhasil memasukkan Python ke dalam Initramfs Anda. Meskipun jika Anda tidak berencana untuk menyertakan busybox, Anda harus dengan susah payah menerapkan kembali beberapa fungsinya (seperti switch_root
, dan semua hal lain yang biasanya Anda lakukan dengan perintah sederhana).
Namun, ini tidak berfungsi pada kernel yang tidak mengizinkan binari skrip (CONFIG_BINFMT_SCRIPT=y
), atau lebih tepatnya dalam kasus seperti itu Anda harus memulai penerjemah secara langsung dan membuatnya memuat skrip Anda.
Syscall exec dari kernel Linux memahami shebang secara native
Saat file yang dieksekusi dimulai dengan byte ajaib #!
, mereka memberi tahu kernel untuk menggunakan #!/bin/sh
sebagai:
- lakukan dan
exec
panggilan sistem - dengan
/bin/sh
yang dapat dieksekusi - dan dengan argumen CLI:jalur ke skrip saat ini
Ini persis sama dengan yang terjadi saat Anda menjalankan skrip shell userland biasa dengan:
./myscript.sh
Jika file dimulai dengan byte ajaib .ELF
bukannya #!
, kernel akan memilih loader ELF untuk menjalankannya.
Lebih detail di:Mengapa orang menulis #!/usr/bin/env python shebang pada baris pertama skrip Python? | Stack Overflow
Setelah Anda memikirkan hal ini, mudah untuk menerima /init
itu bisa apa saja yang dapat dieksekusi oleh kernel, termasuk skrip shell, dan juga mengapa /bin/sh
akan menjadi eksekusi pertama dalam kasus tersebut.
Berikut adalah contoh minimal yang dapat dijalankan bagi mereka yang ingin mencobanya:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init