init není "vytvořen" (jako podřízený proces), ale spíše exec
chtěl bych toto:
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
nahradí celý proces na místě. Finální init je stále prvním procesem (pid 1), i když mu předcházely ty v Initramfs.
Initramfs /init
, což je skript shellu Busybox s pid 1, exec
s na Busybox switch_root
(takže nyní switch_root
je pid 1); tento program změní vaše přípojné body tak, že /mnt/root
bude nový /
.
switch_root
pak znovu exec
s na /sbin/init
vašeho skutečného kořenového souborového systému; díky tomu je váš skutečný init systém prvním procesem s pid 1, který zase může vytvořit libovolný počet podřízených procesů.
Určitě by to šlo stejně dobře udělat pomocí skriptu Python, pokud se vám nějak podařilo zapéct Python do vašich Initramfs. Ačkoli pokud přesto neplánujete zahrnout busybox, museli byste pracně znovu implementovat některé jeho funkce (například switch_root
a vše ostatní, co byste obvykle dělali pomocí jednoduchého příkazu).
Nefunguje však v jádrech, která neumožňují binární soubory skriptů (CONFIG_BINFMT_SCRIPT=y
), nebo spíše v takovém případě byste museli spustit interpret přímo a nechat jej nějakým způsobem načíst váš skript.
Syscall exec linuxového jádra rozumí shebangům nativně
Když spuštěný soubor začíná magickými bajty #!
, říkají jádru, aby použilo #!/bin/sh
jako:
- dělat a
exec
systémové volání - se spustitelným souborem
/bin/sh
- a s argumentem CLI:cesta k aktuálnímu skriptu
To je přesně totéž, co se stane, když spustíte běžný skript uživatelského prostředí shell s:
./myscript.sh
Pokud soubor začínal magickými bajty .ELF
místo #!
, jádro by místo toho vybralo zavaděč ELF, aby jej spustilo.
Další podrobnosti na:Proč lidé píší #!/usr/bin/env python shebang na první řádek skriptu Python? | Přetečení zásobníku
Jakmile to budete mít na paměti, bude snadné přijmout to /init
může být cokoli, co může jádro spustit, včetně skriptu shellu, a také proč /bin/sh
bude v takovém případě prvním spustitelným souborem.
Zde je minimální spustitelný příklad pro ty, kteří to chtějí vyzkoušet:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init