Dipende interamente dai servizi che desideri avere sul tuo dispositivo.
programmi
Puoi fare il boot di Linux direttamente in una shell . Non è molto utile in produzione - chi vorrebbe solo avere una shell seduta lì - ma è utile come meccanismo di intervento quando si dispone di un bootloader interattivo: passare init=/bin/sh
alla riga di comando del kernel. Tutti i sistemi Linux (e tutti i sistemi unix) hanno una shell in stile Bourne / POSIX /bin/sh
.
Avrai bisogno di una serie di utility di shell . BusyBox è una scelta molto comune; contiene una shell e utility comuni per il file e la manipolazione di testo ( cp
, grep
, ...), la configurazione della rete ( ping
, ifconfig
, ...), la manipolazione di processo ( ps
, nice
, ...), e vari altri strumenti di sistema ( fdisk
, mount
, syslogd
, ...). BusyBox è estremamente configurabile: è possibile selezionare gli strumenti desiderati e persino le singole funzionalità al momento della compilazione, per ottenere il giusto compromesso dimensioni / funzionalità per la propria applicazione. A parte sh
, il minimo che non si può davvero fare nulla senza è mount
, umount
e halt
, ma sarebbe atipico per non avere anche cat
, cp
, mv
, rm
,mkdir
, rmdir
, ps
, sync
E pochi altri. BusyBox si installa come un singolo binario chiamato busybox
, con un collegamento simbolico per ogni utility.
Viene chiamato il primo processo su un normale sistema unix init
. Il suo compito è avviare altri servizi. BusyBox contiene un sistema init. Oltre al init
binario (di solito si trova in /sbin
), avrai bisogno dei suoi file di configurazione (di solito chiamati /etc/inittab
- alcuni moderni sostituti di init eliminano quel file ma non li troverai su un piccolo sistema incorporato) che indicano quali servizi avviare e quando. Per BusyBox, /etc/inittab
è facoltativo; se manca, si ottiene una shell di root sulla console e lo script /etc/init.d/rcS
(posizione predefinita) viene eseguito all'avvio.
Questo è tutto ciò di cui hai bisogno, oltre ovviamente ai programmi che rendono il tuo dispositivo utile. Ad esempio, sul mio router di casa che esegue una variante OpenWrt , gli unici programmi sono BusyBox, nvram
(per leggere e modificare le impostazioni in NVRAM) e utilità di rete.
A meno che tutti i tuoi eseguibili non siano staticamente collegati, avrai bisogno del caricatore dinamico ( ld.so
, che può essere chiamato con nomi diversi a seconda della scelta di libc e delle architetture del processore) e di tutte le librerie dinamiche ( /lib/lib*.so
, forse alcune di queste /usr/lib
) richieste da questi eseguibili.
Struttura di directory
Lo standard di gerarchia dei filesystem descrive la struttura di directory comune dei sistemi Linux. È orientato verso installazioni desktop e server: molte di esse possono essere omesse su un sistema incorporato. Ecco un minimo tipico.
/bin
: programmi eseguibili (alcuni invece potrebbero essere presenti /usr/bin
).
/dev
: nodi dispositivo (vedi sotto)
/etc
: file di configurazione
/lib
: librerie condivise, incluso il caricatore dinamico (a meno che tutti gli eseguibili non siano staticamente collegati)
/proc
: mount point per il filesystem proc
/sbin
: programmi eseguibili. La distinzione /bin
è che si /sbin
tratta di programmi che sono utili solo all'amministratore di sistema, ma questa distinzione non è significativa sui dispositivi incorporati. È possibile creare /sbin
un collegamento simbolico a /bin
.
/mnt
: utile avere nei filesystem di root di sola lettura come punto di montaggio scratch durante la manutenzione
/sys
: mount point per il filesystem sysfs
/tmp
: posizione per i file temporanei (spesso un tmpfs
mount)
/usr
: Contiene le sottodirectory bin
, lib
e sbin
. /usr
esiste per file extra che non si trovano nel filesystem di root. Se non lo possiedi, puoi creare /usr
un collegamento simbolico alla directory principale.
File del dispositivo
Ecco alcune voci tipiche in un minimo /dev
:
console
full
(scrivendoci riporta sempre "nessuno spazio lasciato sul dispositivo")
log
(un socket che i programmi usano per inviare voci di registro), se hai un syslogd
demone (come quello di BusyBox) che legge da esso
null
(si comporta come un file sempre vuoto)
ptmx
e una pts
directory , se si desidera utilizzare pseudo-terminali (ovvero qualsiasi terminale diverso dalla console), ad esempio se il dispositivo è collegato in rete e si desidera telnet o ssh in
random
(restituisce byte casuali, blocco dei rischi)
tty
(indica sempre il terminale del programma)
urandom
(restituisce byte casuali, non si blocca mai ma potrebbe non essere casuale su un dispositivo appena avviato)
zero
(contiene una sequenza infinita di byte null)
Oltre a ciò avrai bisogno di voci per il tuo hardware (tranne le interfacce di rete, queste non ottengono voci /dev
): porte seriali, archiviazione, ecc.
Per i dispositivi incorporati, normalmente si creano le voci del dispositivo direttamente sul filesystem di root. I sistemi di fascia alta hanno uno script chiamato MAKEDEV
per creare /dev
voci, ma su un sistema incorporato lo script spesso non è raggruppato nell'immagine. Se è possibile collegare a caldo alcuni componenti hardware (ad es. Se il dispositivo ha una porta host USB), allora /dev
dovrebbe essere gestito da udev (è possibile che sia ancora presente un set minimo sul filesystem di root).
Azioni all'avvio
Oltre al filesystem di root, è necessario montarne alcuni in più per il normale funzionamento:
- procfs on
/proc
(praticamente indispensabile)
- sysfs on
/sys
(praticamente indispensabile)
tmpfs
filesystem on /tmp
(per consentire ai programmi di creare file temporanei che saranno nella RAM, piuttosto che sul filesystem di root che potrebbe essere in flash o in sola lettura)
- tmpfs, devfs o devtmpfs su
/dev
se dinamico (vedere udev in "File dispositivo" sopra)
- devpts su
/dev/pts
se si desidera utilizzare [pseudo-terminali (si veda l'osservazione sulla pts
sopra)
È possibile creare un /etc/fstab
file e chiamare mount -a
o eseguirlo mount
manualmente.
Avvia un demone syslog (oltre che klogd
per i log del kernel, se il syslogd
programma non se ne occupa), se hai un posto dove scrivere i log.
Successivamente, il dispositivo è pronto per avviare servizi specifici dell'applicazione.
Come creare un filesystem di root
Questa è una storia lunga e diversificata, quindi tutto ciò che farò qui è dare alcuni suggerimenti.
Il filesystem di root può essere mantenuto nella RAM (caricato da un'immagine (di solito compressa) nella ROM o nella memoria flash), o su un filesystem basato su disco (memorizzato nella memoria ROM o nella memoria flash) o caricato dalla rete (spesso tramite TFTP ) se applicabile . Se il filesystem di root è nella RAM, impostalo come initramfs - un filesystem RAM il cui contenuto viene creato all'avvio.
Esistono molti framework per assemblare immagini di root per sistemi embedded. Ci sono alcuni suggerimenti nelle FAQ di BusyBox . Buildroot è popolare, che consente di creare un'immagine di root completa con un'installazione simile al kernel Linux e BusyBox. OpenEmbedded è un altro di questi framework.
Wikipedia ha un elenco (incompleto) delle più diffuse distribuzioni Linux integrate . Un esempio di Linux incorporato che potresti avere vicino a te è la famiglia di sistemi operativi OpenWrt per dispositivi di rete (popolare sui router domestici di tinkerer). Se vuoi imparare per esperienza, puoi provare Linux da Scratch , ma è orientato verso sistemi desktop per hobbisti piuttosto che verso dispositivi embedded.
Una nota sul kernel Linux vs Linux
L'unico comportamento inserito nel kernel di Linux è che il primo programma lanciato all'avvio. (Non entrerò nelle sottigliezze di initrd e initramfs qui.) Questo programma, tradizionalmente chiamato init , ha l'ID processo 1 e ha alcuni privilegi (immunità ai segnali KILL ) e responsabilità (raccolta di orfani ). Puoi eseguire un sistema con un kernel Linux e avviare quello che vuoi come primo processo, ma poi quello che hai è un sistema operativo basato sul kernel Linux e non quello che normalmente viene chiamato "Linux" - Linux , nel senso comune del termine, è un sistema operativo simile a Unix il cui kernel è il kernel Linux. Ad esempio, Android è un sistema operativo che non è simile a Unix ma basato sul kernel Linux.