Sei sulla pagina 1di 6

PE GG G /L U GR G UR

In rete si trovano molte toolchain pre-compilate, 2GT N GP G Q N RTQITCOOC QTG CN Q N GNNQ


nel nostro caso utilizzeremo la Linaro Toolchain .P Z UGORTG NQ U GUUQ P RGP GP GOGP
Binaries [3], una toolchain ottimizzata per le più G C Q G I TC NC RTQRT C CRRN EC QPG.
recenti famiglie di CPU ARM (Cortex A8, A9, La prima fase della ricompilazione del kernel
etc.). consiste nel processo di con gurazione. Esso
Il setup della toolchain è costituito dai seguenti permette di scegliere la particolare architettura
passaggi: che vogliamo utilizzare per il layer di basso li-
• download dei binari della toolchain da internet: vello, assieme a tutti i driver e le funzionalità di
https://launchpad.net/linaro-toolchain-binari- alto livello che vogliamo fornire alle applicazioni
es/trunk/2012.09/+download/... user-space.
• estrazione del pacchetto .tar.bz2:
Come abbiamo detto la piattaforma Versati-
le Express è già supportata

• setup della variabile di ambiente PATH per pienamente dal kernel Linux,
rendere disponibili i binari della toolchain quindi possiamo procedere direttamente alla
dalla shell corrente: con gurazione senza dover applicare patch o
modi care codice:

)DVH SUHSDUD LR H GHO NHU HO


A questo punto abbiamo tutti gli strumenti ne- Le variabili di ambiente ARCH e CROSS_COM-
cessari per iniziare a sviluppare sulla board vir- PILE sono informazioni per il compilatore; esse
tuale. permettono di selezionare la particolare archi-
Il primo passo consiste nel reperire i sorgenti tettura (ARCH) e la particolare versione com-
“mainline” del kernel da http://www.kernel.org e pilatore (CROSS_COMPILE) per generare il
ricompilarli per la nostra archiettura target. codice oggetto.
Al momento della stesura di questo articolo l’ul- L’opzione “vexpress_defcon g” viene usata dal
timo kernel del ramo “stable” è il 3.5.4, proce- kernel nel processo di build: essa permette di
diamo quindi al download e all’estrazione dei selezionare la con gurazione di default (defcon-
sorgenti: g) stabilita dalla comunità di sviluppatori che
mantengono il codice per tale architettu-
ra. Le varie con gurazioni *_defcon g per
ARM si trovano tutte in arch/arm/con gs/*.
Il kernel Linux supporta un’ampia gamma di In ne resta da effettuare il passo di compilazio-
architetture e piattaforme eterogenee: fonda- ne vero e proprio:
mentalmente esso è composto da un layer di
basso livello
(./arch/*) che si interfaccia direttamente con il La ricompilazione di un intero kernel richiede
particolare hardware ed esporta ai livelli più alti dai 5 ai 10 minuti. Al termine, se tutto è andato
interfacce generiche indipendenti dall’hardware correttamente, troveremo il seguente le nelle
sottostante. directory dei sorgenti del kernel:
PE GG G /L U GR G UR

Il le zImage rappresenta l’immagine della ash


per la nostra board virtuale. In questo caso il
singolo kernel richiede 2.4MB. Al momento però
non abbiamo ancora nessuna applicazione, i
2.4MB rappresentano solo il “contenitore” dove
far girare le applicazioni utente.

HVWDUH LO NHU HO V OOD ERDUG LUW DOH


E’ possibile testare il kernel appena generato
sull board virtuale QEMU lanciando il comando
seguente:

QEMU emula un ambiente identico ad una bo-


ard Versatile Express sica, quindi per il kernel
non fa nessuna differenza, di fatto è come ese-
guirlo sull’hardware reale. Con le opzioni `-serial
stdio -display none` stiamo dicendo a QEMU di
collegare la seriale emulata direttamente alla
console da cui lanciamo il comando. Con `-ap-
pend console=ttyAMA0”` stiamo invece dicendo
al kernel di ridirigere tutti i suoi messagi verso
la seriale primaria. In pratica per noi sarà come
avere aperto una sessione seriale sulla board.
Ecco il risultato pratico una volta eseguito il co-
mando sopra:
PE GG G /L U GR G UR

In output possiamo vedere i messaggi di un tipi-


co boot di Linux. Il kernel è partito correttamen-
te, rilevando tutti i dispositivi hardware emulati
dalla board virtuale, come se questa fosse effet-
tivamente una board sica.
Al termine della fase di boot otteniamo tuttavia
un kernel panic (cioè un
errore irreversibile che compromette il funziona-
mento del sistema). Il motivo di tale errore lo
possiamo trovare nei messaggi immediatamen-
te precedenti al panic:
In pratica per il kernel non esiste nessun root
lesystem. Come abbiamo detto il kernel è solo
un contenitore in cui girano le applicazioni, una
volta terminato il processo di boot il kernel cerca
di montare un lesystem radice (root) da uno
dei dispositivi a blocchi rilevati ed eseguire un
binario denominato “init”. Se questo binario non
viene trovato il kernel non sa cosa fare e entra
nella condizione di panic.

Nella prossima puntata vedremo come creare


un root lesystem adatto al kernel, continuando
a seguire stessa loso a di questo tutorial: ge-
nerando tutto completamente da zero.

LIHULPH WL
1. http://en.wikipedia.org/wiki/Board_support_
package
2. http://en.wikipedia.org/wiki/QEMU
3. http s://launchp ad.net/linaro -toolchain-
binaries/+download
4. http://wiki.qemu.org/Main_Page
5. http://www.arm.com/products/tools/deve-
lopment-boards/versatile-express/i...

UGI Q N N PM RGT CEEG GTG TG COGP G CNN CT EQNQ U N NQI G RCT GE RCTG CNNC UE UU QPG
R GOEGNG TQP EC EQO GODG G IP N P Z RCT GP Q C GTQ T EQOR NCTG MGTPGN
PE GG G /L U GR G UR

3U S U LR G O URR ILO P
, WURG LR H Tale archivio, chiamato P TCOHU [2], viene in-

N
ella prima puntata (http://it.emcelettronica. cluso nell’immagine del kernel ad una locazione
com/embedded-gnulinux-partendo-da-ze- pre ssata e viene estratto dal kernel stesso in
ro-ricompil...) abbiamo visto come ricompi- RAM durante l’inizializzazione.
lare un kernel Linux per una generica board di GU C UQN QPG C N CP CII Q PQP T
sviluppo virtuale ARM-based. Il kernel rappre- E G GTG PGUU P G EG T GT CII P Q
senta una sorta di contenitore di applicazioni per ash, dischi o supporti di memoria ester
che girano in spazio utente. In questa nuova P S CNU CU PC TC, dato che per il kernel
puntata vedremo come preparare i contenuti è suf ciente poter accedere solo alla RAM per
dello spazio utente, ovvero come preparare un montare l’initramfs. Spesso questo approccio
root lesystem minimale.Il kernel rappresen- viene utilizzato in ambito embedded nelle fasi
ta una sorta di contenitore di applicazioni che iniziali di testing delle nuove board per avere
girano in spazio utente. In questa nuova pun- praticamente a tempo zero un sistema GNU/Li-
tata vedremo come preparare i contenuti dello nux funzionante.
spazio utente, ovvero come preparare un root Vediamo un esempio pratico di un initramfs con-
lesystem minimale. tenente un unico le: il classico esempio “ GNN
TN ”.
UHDUH URRW ILOHV VWHP L 0 Per prima cosa scriviamo un semplice program-
O L LWUDPIV ma C in /tmp/init.c:
Nella puntata precedente ci siamo lasciati con il
seguente errore restituito dal kernel che abbia-
mo compilato:

Il kernel è partito correttamente, ma non è ri- E lo cross-compiliamo con lo stesso cross-com-


uscito a trovare un root lesystem da montare pilatore che abbiamo usato nella puntata scorsa
per avviare il processo init e passare il controllo per compilare il kernel:
allo user-space.
La soluzione più semplice per creare un root -
lesystem è di usare parte della RAM come se
fosse un lesystem vero e proprio. Il kernel per- : come mai abbiamo usato l’opzione
mette di includere al suo interno un archivio in -static?
formato cpio [1] (in pratica è una sorta di tar o URQU C : Con l’opzione “-static” richiediamo
zip). al compilatore di includere direttamente nel bi-
PE GG G /L U GR G UR

nario stesso tutte le librerie necessarie, invece più di tempo al boot per ridurre lo spazio oc-
di tentare di caricarle dinamicamente a run-time. cupato può essere vantaggioso, ad esempio se
Come abbiamo detto il nostro initramfs conterrà dovessimo collocare kernel e initramfs in una
un unico le, quindi a run-time non sarà possi- ash di dimensioni ridotte, o scaricarli da una
bile trovare le librerie dinamiche all’interno del connessione di rete lenta, etc.
lesystem. L’initramfs che abbiamo creato noi richiede uno
: come mai il programma C che abbia- spazio di 244KB:
mo scritto contiene un loop che non esce mai?
URQU C : In Linux ogni processo viene ge-
nerato come glio di un altro processo. Quando
un processo padre termina prima del processo
glio quest’ultimo viene immediatamente adot- E’ giunto il momento di testare se tutto funziona.
tato dal processo di sistema speciale “init” (il Utilizziamo quindi lo stesso comando visto nella
cui PID è 1), che ne diviene il nuovo processo puntata scorsa per avviare la board virtuale, con
padre. Questa operazione viene chiamata re- l’aggiunta dell’opzione “-initrd /tmp/initramfs”
parenting, ed avviene automaticamente a cura per caricare anche l’initramfs:
del kernel. La terminazione del processo “init”
viene vista dal kernel come un errore irreversi-
bile e quando accade il kernel entra nello stato
di panic. Per questo motivo il nostro init non può Il risultato è il seguente:
Booting Linux on physical CPU 0

terminare.
A questo punto possiamo spostarci in /tmp e
creare l’initramfs:
E’ importante notare che il binario contenuto
all’interno dell’initramfs è stato chiamato “ P ”.
Questo perché il kernel si aspetta di trovare un
le con questo nome; se rinominiamo il le que-
sto non verrà eseguito al termine del processo
di boot.
Notare inoltre che con “I R ” abbiamo com-
presso l’initramfs. Il kernel supporta vari formati
di compressione e riesce ad accedervi anche in
questo caso, a costo di spendere un po’ più di
tempo in fase di boot per effettuare la decom-
pressione. Tuttavia, in certi casi, perdere un po’
PE GG G /L U GR G UR

Molto bene! Il kernel ha avviato il nostro loop


“ GNN TN ” al termine del processo di boot.
Q CTG E G C S GU Q R P Q CDD COQ P MGT
PGN . P Z EQORNG Q C PQU TC URQU QPG.
Potremmo quindi modi care il semplice “ GN
N TN ” (/tmp/init.c) per implementare anche
qualcosa di più complesso, come ad esempio
un piccolo GE UGT GT 6 2 2 O N CUM.
Il programma seguente crea un processo ser-
ver che accetta connessioni TCP/IP sulla por-
ta 8080; per ogni connessione ricevuta viene
creato un nuovo processo glio che legge un
messaggio dal client e lo rimanda indietro tale e
quale (tutto tramite TCP/IP):

Potrebbero piacerti anche