È possibile causare l'esecuzione del codice facendo confusione con la riga di comando del kernel. Il metodo più ovvio è sostituire init con qualcos'altro. L'applicazione più comune di questo è lanciare una shell molto presto nel processo di avvio, di solito perché è necessario riparare qualcosa o perché tutto il resto è molto gravemente rotto, ad esempio:
init=/bin/bash
Tieni presente che a questo punto del processo di avvio, i filesystem sono ancora montati in sola lettura. Inoltre, ci sono un sacco di cose che non funzionano correttamente. Poiché non hai un vero init in esecuzione, l'arresto e il riavvio non funzioneranno. Devi rimontare manualmente il filesystem di root in sola lettura e chiamare reboot -f
per riavviare, per esempio.
Non ho idea se puoi passare argomenti per bash in questo modo. Non ho mai provato. In teoria, se riesci a passare -c
a bash, puoi dire a quel processo bash di fare qualsiasi cosa. Ma potrebbe trasformarsi in un argomento abbastanza lungo, e non so se il kernel consentirebbe tali cose.
La seconda cosa che puoi fare. È possibile copiare un ramfs iniziale (initramfs) nel filesystem e configurare il bootloader per utilizzarlo config.txt
. Esistono diversi modi per ottenere script in un initramfs per fare cose speciali. Dovrai preparare uno speciale initramfs per questo scopo (vedi initramfs-tools (8)), quindi non sono sicuro che questa sia una soluzione migliore di un'immagine personalizzata.
Potresti includere lo script in / boot (ho riso del tuo suggerimento su macchine "normali", ma questo sarebbe il bit a cui puoi accedere da quelle macchine) e tentare di avviarlo usando la riga init del kernel, ma i file su filesystem dos non sono eseguibile a meno che tu non lo faccia per l'intero filesystem.
Se fossi in me, creerei un'immagine personalizzata che utilizza dhcp per configurare la rete e che contiene uno script personalizzato che viene eseguito all'avvio. Questo script verifica la presenza di un file specifico che funge da flag. Se il file esiste, non fare nulla. In caso contrario, configura le cose, quindi crea il file flag.
Il tuo script di configurazione potrebbe persino estrarre la cosa reale da un server http. Questo significa che non devi creare una nuova immagine se devi modificare qualcosa.
Questa dovrebbe essere la soluzione meno stressante.
Un'ultima possibilità, ma dovrai farlo su una macchina "non regolare" :-) Puoi montare il filesystem ext4 su un dispositivo loop e copiare i file su di esso senza scriverlo prima su sdcard. Per un'immagine standard di Raspbian Jessie, sarebbe qualcosa del genere:
sudo losetup /dev/loop0 /tmp/gw.img -o 62914560
sudo mount /dev/loop0 /mnt
sudo cp /my/superduper/script.sh /mnt
sudo umount /dev/loop0
sudo fsck -f /dev/loop0 # This is optional
sudo losetup -d /dev/loop0
Mi piace fare un fsck forzato sul mio filesystem prima di creare immagini. Imposta il conteggio dei montaggi su zero al primo avvio :-)
EDIT : dopo molti mesi e più esperienza. Vuoi guardare u-boot. Sostituisci il bootloader con u-boot. Questo può essere fatto da una "macchina normale". Dopo aver avviato u-boot, è possibile avviare in rete una distribuzione da cui è possibile eseguire facilmente il flashing della scheda SD, oppure in teoria è possibile eseguire il flashing della scheda direttamente, anche se non ho idea di quanto sia difficile.
Essenzialmente u-boot porta l'avvio di rete su Raspberry Pi, qualcosa che non supporta da solo.