init n'est pas "généré" (en tant que processus enfant), mais plutôt exec
j'aimerais ceci :
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
remplace l'ensemble du processus en place. L'init final est toujours le premier processus (pid 1), même s'il a été précédé de ceux de l'Initramfs.
Les Initramfs /init
, qui est un script shell Busybox avec pid 1, exec
s vers Busybox switch_root
(alors maintenant switch_root
est pid 1); ce programme change vos points de montage donc /mnt/root
sera le nouveau /
.
switch_root
puis encore exec
s à /sbin/init
de votre véritable système de fichiers racine ; ainsi, votre véritable système d'initialisation devient le premier processus avec le pid 1, qui à son tour peut générer un nombre quelconque de processus enfants.
Certes, cela pourrait tout aussi bien être fait avec un script Python, si vous avez réussi à intégrer Python dans votre Initramfs. Bien que si vous ne prévoyez pas d'inclure de toute façon busybox, vous devrez réimplémenter minutieusement certaines de ses fonctionnalités (comme switch_root
, et tout ce que vous feriez habituellement avec une simple commande).
Cependant, cela ne fonctionne pas sur les noyaux qui n'autorisent pas les binaires de script (CONFIG_BINFMT_SCRIPT=y
), ou plutôt dans un tel cas, vous devriez démarrer l'interpréteur directement et lui faire charger votre script d'une manière ou d'une autre.
L'appel système exec du noyau Linux comprend nativement les shebangs
Lorsque le fichier exécuté commence par les octets magiques #!
, ils disent au noyau d'utiliser #!/bin/sh
comme :
- faire et
exec
appel système - avec l'exécutable
/bin/sh
- et avec l'argument CLI :chemin vers le script actuel
C'est exactement la même chose qui se produit lorsque vous exécutez un script shell userland normal avec :
./myscript.sh
Si le fichier avait commencé par les octets magiques .ELF
au lieu de #!
, le noyau choisirait le chargeur ELF à la place pour l'exécuter.
Plus de détails sur :Pourquoi les gens écrivent-ils le shebang python #!/usr/bin/env sur la première ligne d'un script Python ? | Débordement de pile
Une fois que vous avez cela en tête, il devient facile d'accepter que /init
peut être tout ce que le noyau peut exécuter, y compris un script shell, et aussi pourquoi /bin/sh
sera le premier exécutable dans ce cas.
Voici un exemple exécutable minimal pour ceux qui veulent l'essayer :https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init