init non è "generato" (come processo figlio), ma piuttosto exec
ti piacerebbe questo:
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
sostituisce l'intero processo in atto. L'init finale è ancora il primo processo (pid 1), anche se è stato preceduto da quelli in Initramfs.
L'Initramfs /init
, che è uno script della shell Busybox con pid 1, exec
s a Busybox switch_root
(quindi ora switch_root
è pid 1); questo programma cambia i punti di montaggio in modo /mnt/root
sarà il nuovo /
.
switch_root
poi di nuovo exec
s a /sbin/init
del tuo vero filesystem di root; in tal modo rende il tuo vero sistema init il primo processo con pid 1, che a sua volta può generare un numero qualsiasi di processi figli.
Certamente potrebbe essere fatto altrettanto bene con uno script Python, se in qualche modo riuscissi a inserire Python nel tuo Initramfs. Anche se non hai intenzione di includere busybox comunque, dovresti reimplementare scrupolosamente alcune delle sue funzionalità (come switch_root
, e tutto ciò che normalmente faresti con un semplice comando).
Tuttavia, non funziona su kernel che non consentono script binari (CONFIG_BINFMT_SCRIPT=y
), o piuttosto in tal caso dovresti avviare direttamente l'interprete e fare in modo che carichi il tuo script in qualche modo.
La chiamata di sistema exec del kernel Linux comprende nativamente gli shebang
Quando il file eseguito inizia con i magic byte #!
, dicono al kernel di usare #!/bin/sh
come:
- fare e
exec
chiamata di sistema - con l'eseguibile
/bin/sh
- e con argomento CLI:percorso dello script corrente
Questo è esattamente lo stesso che accade quando esegui un normale script di shell utente con:
./myscript.sh
Se il file fosse iniziato con i byte magici .ELF
invece di #!
, il kernel sceglierà invece il caricatore ELF per eseguirlo.
Maggiori dettagli su:Perché le persone scrivono #!/usr/bin/env python shebang sulla prima riga di uno script Python? | Overflow dello stack
Una volta che hai questo in mente, diventa facile accettare quel /init
può essere qualsiasi cosa che il kernel può eseguire, incluso uno script di shell, e anche perché /bin/sh
sarà il primo eseguibile in quel caso.
Ecco un esempio eseguibile minimo per coloro che vogliono provarlo:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init