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
execchiamata 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