Le distribuzioni live di Linux sono oggi molto popolari, dopo la nascita della famosa Knoppix molti possesori di computer hanno potuto provare il pinguino sulla loro macchina. Distribuzioni live con Kernel Linux RTAI purtoppo non sono molte, se ne possono trovare in rete solo due realmente funzionanti su piattaforma Intel x86: RTAI Testsuite LiveCD [Issaris] e BDI-EMC della Sherline (si veda [Sherline], [linuxcnc]). Entrambe forniscono una shell e una suite di programmi, senza i rispettivi sorgenti e quindi già compilati; sono quindi strumenti rivolti all'utente finale e non ad un ambito di studio accademico; nessuna delle due inoltre ha un ambiente grafico e non sono nemmeno presenti i tool di compilazione. Oltre a queste esistono alcuni documenti, reperiti attraverso uno dei siti non ufficiali di RTAI [rtai.dk], su come costruirsi in pochi passi una semplice distribuzione live di RTAI su CD e su pen drive USB ([allin],[SUPSI]), come i precedenti due casi anche questo non mette in luce e approfondisce i passaggi tecnici alla base della procedura per ottenere il risultato; non permette inoltre di creare un ambiente stabile con i tool di compilazione e un minimo supporto all'ambiente grafico. RTAI Testsuite LiveCD Analizzando più a fondo la distribuzione RTAI Testsuite LiveCD si nota che tutti i test che effettua provengono dal pacchetto di RTAI: in particolare i programmi utilizzati sono quelli della directory /testsuite. La distribuzione consta di un solo CD dagli esigui 9MB, contiene infatti oltre ad i succitati test ed RTAI, che in totale non richiedono più di 5MB, il kernel di Linux, BusyBox, una serie di script, che sono il vero e proprio cuore del prodotto, e un file system, il tutto però compresso con gunzip. Il punto di forza di questo progetto sta nel sistema di raccolta dati: alla fine dei test viene richiesto di salvare i risultati oppure di inviarli al centro di raccolta. L'intero processo di valutazione del sistema su cui viene eseguendo la distribuzione è guidato, consta infatti di una semplice interfaccia grafica da shell (ottenibile comodamente con il comando `dialog`) stile installazione Slackware. BDI-EMC La distribuzione BDI-EMC (Brain Dead Install - Enhanced Machine Controller) o più precisamente la sua versione live: BDI Live, è un derivato della distribuzione Morphix. Durante la fase di boot, non viene avviato il classico kernel di una distribuzione Morphix, ma uno prodotto ad-hoc, in particolare con il supporto RTAI. La distribuzione BDI-EMC nasce per uso industriale nel campo del controllo numerico delle macchine, in particolare la branch BDI [bdi4emc] si occupa di integrare il software di controllo, con esigenze real-time, con un ambiente grafico ad uso di applicazioni CAD/CAM. La versione live però non ha ambiente grafico, probabilmente per esigenze di spazio sul supporto fisico. In tutte le distribuzioni EMC è presente una suite di programmi per il controllo di macchinari industriali che usa RTAI come sottosistema per garantire una schedulazione in tempo reale fondamentale in quest'ambito. # TODO START Possono esserci svariati utilizzi di una distribuzione live: si va dalla necessità di provare un sistema, per esempio potremmo fare dei test sulla nostra macchina per vedere se RTAI da dei buoni risultati di latenza; alla possibilità che ad ogni riavvio si ritrova il sistema sempre funzionante, infatti su un cd non possiamo scriverci; a motivi scolastici, potremmo usare una distribuzione live in modo didattico distribuendola a tutte le persone che frequentano un corso in modo che questi possano provare il sistema senza doverselo installare sulla loro macchina perdendo parecchio tempo, e nel rischio di perdere i loro dati accumulati magari in tutta la storia del loro personal computer... Soprattuto quest'ultima ha motivato lo sviluppo di una distribuzione live di RTAI con tutti gli strumenti di compilazione necessari a far girare sulla propria macchina Linux RTAI e poter provare il proprio codice senza intaccare il proprio hard disk. Lo sviluppo quindi è stato preceduto da una approfondita analisi di alcune distribuzioni live free presenti su internet tra cui la famosa Knoppix e SLAX, una recente distribuzione live basata su Slackware, oltre alle precedenti distribuzioni sopra presentate. # TODO END Costruzione di una distribuzione live Linux In questa sezione verranno analizzati i passi per creare in proprio una distribuzione live di Linux, si focalizzarà quindi l'attenzione sulle necessità di un sitema real-time basato su RTAI. Segue un elenco dei componenti base di una distribuzione live: 1.il kernel 2.il loader del disco CDROM 3.l'immagine RAM iniziale (initrd) 4.la procedura di init 5.i moduli del kernel 6.i pacchetti software Oltre a questi partecipano alla distribuzione live tutti i pacchetti software necessari ad avere un sistema "utilizzabile", come i tool di sviluppo cioè il gcc, con le librerie, gli include e gli header del kernel in uso, un ambiente grafico, e per ultimi, ma di fondamentale importanza, gli applicativi di base a riga di comando (cd, ls, rm, mkdir, ps, cat ...) Il Kernel Il kernel [krn] è il cuore del sistema operativo, la scelta di quale versione utilizzare è stata fatta in base alle patch del kernel disponibili nel pacchetto dell'ultima release di RTAI, la 3.3, utilizzata nel progetto. Le patch disponibili, non numerose, hanno fatto optare per il kernel 2.6.13 che in base a più prove si è dimostrato quello più stabile relativamente alle modifiche apportate da RTAI. Questa versione del kernel viene inoltre dichiarata stabile anche per la distribuzione Slackware Linux [slack] correntemente utilizzata. A scelta ultimata si effettua il download dei sorgenti del kernel da [krn] e di RTAI da [rtai.org]; nel corso di tutto il testo gli esempi e le istruzioni riportate si riferiscono alle scelte effettuate per il progetto: cioè, come già scritto, Kernel-2.6.13 e RTAI3.3. Si decomprimono quindi i pacchetti scaricati nella directory /usr/src/: root@eakon:~# cd /usr/src root@eakon:/usr/src# tar xvjf linux-2.6.13.tar.bz2 root@eakon:/usr/src# tar xvjf rtai-3.3.tar.bz2 E' quindi necessario configurare il kernel: il numero di moduli e funzionalità presenti è molto alto grazie alla grande proliferazione di periferiche hardware di diversi produttori; non è quindi il caso di scelgliere oculatamente le caratteristiche volute minimizzando i componenti scelti, se si segue questa via si rischia di avere un kernel che su alcune macchine funziona ma su molte altre no, magari visualizzando il simpaticissimo messaggio "kernel panic". Per evitare situazioni del genere l'alternativa migliore è prendere il file di configurazione da una delle maggiori distribuzioni di Linux; si è quindi preso il file .config relativo alla disrtibuzione Linux Slackware 10.2 kernel 2.6.13 dalla directory kernels/test26.s del CD1 e copiato nella directory dove si sono prima decompressi i sorgenti del kernel: root@eakon:/~# cd /mnt/cdrom/kernels/test26.s root@eakon:/mnt/cdrom/kernels/test26.s# cp config /usr/src/linux-2.6.13/.config Seguendo la nuova guida di RTAI 3.3 [rtai3.3] si passa quindi alla patch del kernel, le patch si possono trovare all'interno dell'albero dei sorgenti di RTAI in particolare per l'architettura x86 nella directory base/arch/i386/patches. Si va quindi nella directory del kernel e si esegue la patch: root@eakon:/~# cd /usr/src/linux-2.6.13 root@eakon:/usr/src/linux-2.6.13# patch -p1 < /usr/src/rtai-3.3/base/arch/i386/patches/hal-linux-2.6.13-i386-1.0-09.patch Con questa patch viene inserito il nuovo sotto sistema ADEOS-ipipe [ADEOS],[ipipe] nel kernel di Linux; nelle precedenti versioni di RTAI era possibile scegliere se aggiungere al kernel il sottosistema rthal oppure ADEOS, il primo mantenuto da RTAI ed il secondo dal progetto ADEOS, con l'uscita di ADEOS-ipipe gli sviluppatori hanno definito la loro predilezione per quest'ultimo e la branch di RTAI che seguiva rthal è stata soppressa. Si passa quindi alla configurazione del kernel e alla configurazione di RTAI: root@eakon:/usr/src/linux-2.6.13# make xconfig root@eakon:/usr/src/linux-2.6.13# cd ../rtai-3.3 root@eakon:/usr/src/rtai-3.3# make xconfig Le opzioni di configurazione non sono state modificate: si è solo accertato che tra le opzioni del kernel fosse disabilitato il supporto APIC; si è infatti verificato che tale componente non si sposa bene con RTAI provocando su molte macchine un kernel panic. E' necessario però settare correttamente nelle opzioni di RTAI la directory dei sorgenti del kernel. Dopo di che si compila prima il kernel e poi RTAI: root@eakon:/usr/src/rtai-3.3# cd ../linux-2.6.13 root@eakon:/usr/src/linux-2.6.13# make all root@eakon:/usr/src/linux-2.6.13# make module_install root@eakon:/usr/src/linux-2.6.13# cd ../rtai-3.3 root@eakon:/usr/src/rtai-3.3# make root@eakon:/usr/src/rtai-3.3# make install root@eakon:/usr/src/rtai-3.3# make module_install Questa sequenza è quella che viene anche consigliata in [rtai3.3], il make xconfig di RTAI fa infatti un controllo di consistenza del file di configurazione del kernel; eventuali inconsistenze vengono quindi segnalate prima della compilazione evitando così di spendere parecchio tempo in lunghe e tediose compilazioni che non vanno a buon fine. Il loader del disco CDROM La fase più delicata di una distribuzione live è sicuramente la fase iniziale di inizializzazione di sistema, ovvero la fase di boot. Per capire in modo preciso come questa avviene è necessario un nutrito background culturale di architettura degli elaboratori. In sintesi è necessario sapere che a seguito dell'avvio del BIOS della macchina, che crea un ambiente software primitivo, questo passa il controllo della macchina ad un indirizzo di codice contenuto nell'MBR se vogliamo avviare il nostro sistema operativo da disco fisso, si è nella medesima situazione anche nel caso di un SO su CD: il controllo del sistema viene lasciato ad un programma presente nel boot sector del CD. Il compito di questo programma di avvio è di eseguire le operazioni necessarie affinchè il sistema possa avviarsi e funzionare in modo stabile. Una volta che queste condizioni sono raggiunte viene quindi avviato il kernel. Le condizioni di cui si parla sopra sono: - il kernel si trovi in memoria ram, e possa quindi essere eseguito dal processore; - esista, se necessario, un filesystem in memoria ram. In sostanza quindi il loader deve essere in grado di effettuare delle copie da un dispositivo lettore CD/DVD a memoria centrale, decomprimere i dati copiati, se necessario, fare output a monitor e passare il controllo al kernel impostandogli alcuni parametri di esecuzione. Come bootloader del CD si è scelto ISOLINUX [iso], strumento che fa ormai parte della più ampia suite di boot loader SYSLINUX. ISOLINUX è un boot loader per PC x86 (Linux/i386) ed è garantito per gli standard cd-rom della famigla ISO9660/El Torito. Per rendere un cd-rom "bootable" è necessario creare una directory "isolinux" nella cartella principale della propria distribuzione e copiarci dentro tutti i file del pacchetto isolinux più il kernel ed una eventuale disco immagine RAM (initrd). Si è scelto di costruire la distribuzione nella cartella di root, in particolare in /root/livecd; isolinux si può facilmente trovare nel CD 1 della Slackware nella directory isolinux, riportiamo quindi i comandi necessari: root@eakon:~# mkdir livecd root@eakon:~# cd livecd root@eakon:~/livecd# mkdir isolinux root@eakon:~/livecd# mkdir kernels root@eakon:~/livecd# mkdir live Quest'ultimi due comandi non servono in questo momento, ma vengono qui riportati per omogeneità con [ddk]. Si prosegue quindi con la copia dei file dal cdrom della Slackware: root@eakon:~/livecd# cd /mnt/cdrom/isolinux root@eakon:/mnt/cdrom/isolinux# cp -a * /root/livecd/isolinux A questo punto sarà necessario cambiare i file di configurazione di ISOLINUX come isolinux.cfg per adattarlo al progetto. Prima di provare il CD e verificare il funzionamento del bootloader è necessario copiare il kernel, con i relativi file System.map e .config, nella directory kernels del progetto. E' possibile anche copiarne alcuni dal cd della distribuzione. Con i seguenti comandi si copia il kernel prima creato: root@eakon:/mnt/cdrom/isolinux# cd /root/livecd/kernels root@eakon:~/livecd/kernels# mkdir RTAI root@eakon:~/livecd/kernels# cd RTAI root@eakon:~/livecd/kernels/RTAI# cp /usr/src/linux-2.6.13/arch/i386/boot/bzImage bzImage root@eakon:~/livecd/kernels/RTAI# cp /usr/src/linux-2.6.13/System.map System.map root@eakon:~/livecd/kernels/RTAI# cp /usr/src/linux-2.6.13/.config .config root@eakon:~/livecd/kernels/RTAI# cd ../.. Si passa quindi alla modifica del file isolinux.cfg, per specificare il kernel di avvio oppure configurare una lista di kernel boot tra cui scegliere, per ogni kernel è necessario aggiungere le seguenti righe: ~ label rtlive ~ kernel /kernels/rtai.26/bzImage ~ append initrd=initrd.img init=linuxrc-live load_ramdisk=1 prompt_ramdisk=0 ramdisk_size=8282 rw root=/dev/ram SLACK_KERNEL=rtai.26 Lo statement 'label' è seguito dal nome che alla schermata di boot del cd-rom deve essere digitato per utilizzare la configurazione sotto presente; 'kernel' è seguito dal path assoluto (rispetto al file system del cd-rom) dell'immagine compressa del kernel; infine lo statment 'append' presenta una lista di parametri di configurazione che verranno passati al kernel di partenza. Il parametro 'initrd' indica il nome della immagine disco ram (segue "L'immagine RAM iniziale"), 'init' specifica il programma, o script, di avvio del sistema (vedi "La procedura di init"), 'load_ramdisk' 'prompt_ramdisk' ramdisk_size' specificano le caratteristiche del disco ram da usare, rispettivamente se usarlo, se richidere una conferma di uso, e lo spazio di memoria necessario per questo; 'rw' inidica che il file system di root è in lettura scrittura e 'root' ne identifica il percorso nel formato standard VFS. Le tre righe sopra non sono sufficienti a ISOLINUX per l'avvio, è necessario aggiungerne almeno un altro paio sopra: ~ default /kernels/rtai.26/bzImage initrd=initrd.img init=linuxrc-live load_ramdisk=1 prompt_ramdisk=0 ramdisk_size=8282 rw root=/dev/ram SLACK_KERNEL=rtai.26 ~ prompt 1 ~ timeout 5 ~ display message.txt Dove lo statement 'default' è seguito dal path del kernel, sempre relativo alle directory contenute nel cd-rom, e dalle sue opzioni di avvio. 'prompt' permette di scegliere all'utente tra più kernel o configurazioni di avvio diverse preventivamente messe a disposizione con il costrutto su definito LABEL/KERNEL/APPEND. Il parametro 'timeout' definisce per quanto tempo il bootloader deve attendere l'input dall'utente; il tempo è espresso in decimi di secondo. Si può quindi creare un immagine iso bootabile con un minimo di sistema operativo; si usi il comando: root@eakon:~/livecd# mkisofs -o livecd.iso -R -J -hide-rr-moved -v -d -N -no-emul-boot -boot-load-size 32 -boot-info-table -sort isolinux/iso.sort -b isolinux/isolinux.bin -c isolinux/isolinux.boot . Si nota l'utilizzo di '-no-emul-boot': questa opzione permette di eseguire la fase di boot, in base alle norme "El Torito" [eltorito], senza emulare la presenza di più dischetti o un hard-disk sul CD-ROM; ciò è molto importante, infatti se non avessimo specificato l'opzione, il loader del bios, sarebbe andato in cerca di una immagine di un floppy disk, all'interno del CD-ROM, questo ci avrebbe obbligato a non poter avere una immagine initrd, o un kernel, di dimensioni maggiori di 2.88MB. Per scrivere la iso su un cd si può usare il programma di masterizzazione preferito oppure: root@eakon:~/livecd# cdrecord -v dev=ATAPI:0,0,0 driveropts=burnfree livecd.iso In conclusione a questa sezione si vuol mettere in evidenza il fatto che la procedura di creazione e raffinamento di una distribuzione liveCD è una procedura lunga e costosa, anche piccole modifiche richiedono di ricreare l'immagine e quindi scrivere un nuovo cd. Per il fattore costo si è risolto il problema con dei cd riscrivibili, per risolvere il fattore tempo si sarebbe potuto utilizzare un sitema di emualazione come [vmware] riducendo così di molto i tempi di sviluppo. L'immagine RAM iniziale (initrd) ISOLINUX oltre a copiare il kernel in RAM ed eseguirlo permette anche la copia di una immagine del disco in RAM: l'initrd. Questa immagine è fondamentale per gli scopi di questo progetto: all'avvio del kernel è infatti necessario specificare quale file system montare come root, per gli scopi prefissi il filesystem sarà contenuto nel cd; non è possibile infatti montare il CD come file system, il kernel potrebbe non riconoscerlo; inoltre non è di interesse montare un file system della macchina dell'utente. Il filesystem si deve quindi creare e deve essere specificato al kernel al momento dell'avvio. Considerando che non viene r itenuta una buona scelta dare al kernel come filesystem di root il cdrom da cui viene effettuato il boot, perchè come già detto può essere che il kernel non lo riconosca, è necessario utilizzare un disco RAM iniziale che contiene un file system di base. Un disco immagine RAM è un file compresso che contiene un intero filesystem popolato con gli applicati ritenuti importanti. Si può immaginare un disco immagine RAM come un file ISO, al suo interno però si possono utilizzare tutti i file system per cui si trovano dei tool come ext2, ext3... Viene chiamato immagine RAM perchè questo file viene di solito messo in RAM. E' un parte di codice del kernel che procede al suo avvio. Nell'immagine è inoltre necessario, essendo il disco di avvio, installare una shell. Seguendo la scelta comune di molte distribuzioni è si sceglie di inserire la shell BusyBox [busybox], questa occupa molto meno spazio dell'insieme di applicativi che sostituisce, infatti è si una shell ma ingloba anche gli applicativi più usati come ls, cp, cd, ps, insmod, modprobe... per questo motivo l'eseguibile busybox viene chiamato "multicall binary". Considerando i passaggi precedenti, e andando a spulciare tra le directory create, in /root/livecd si trova già un file initrd.img in isolinux. Non è il caso di sostituirlo ma basta modificarlo secondo le esigenza, se si necessita di ricrearlo da zero una ottima spiegazione si può trovare in [emb]. Per poter accedere all'immagine è necessario scomprimere e montarla in una directory: root@eakon:~/livecd# cd .. root@eakon:~# mkdir img root@eakon:~# cd img root@eakon:~/img# cp ../livecd/isolinux/initr.img initrd.gz root@eakon:~/img# gunzip -c initrd.gz >initrd.img root@eakon:~/img# mkdir mnt root@eakon:~/img# mount -o loop initrd.img mnt A questo punto è possibile effettuare tutte le modifiche che si vogliono in particolare nel prossimo punto sarà necessario sostituire lo script di init. Per rimettere "a posto" l'immagine è necessario eseguire i seguenti comandi: root@eakon:~/img# umount /root/img/mnt root@eakon:~/img# gzip < initrd.img > initrd.gz root@eakon:~/img# cp initrd.gz ../livecd/isolinux/initr.img Si può quindi ricompilare l'immagine ISO e rimasterizzarla. Esistono molti documenti in rete relativi all'immagine del disco RAM iniziale in particolare si consiglia [giac]. La procedura di init La procedura di init è la procedura di inizializzazione di un sistema operativo Linux e risulta molto critica: qualsiasi errore dà un kernel panic, può quindi risultare particolarmente flustrante perchè l'unica soluzione è la ricompilazione dell'intero progetto. Un ottima documentazione di questo fine processo si può trovare in [rubini98]. Esistono in rete numerosi script che permettono di creare la "propria" distribuzione live, non tutti funzionano sempre però a causa delle varie versioni dei diversi componenti di un sistema e alla scrittura non sempre molto precisa degli autori; un valido esempio è sicuramente [live.org]. Un'analisi di questi script risulta molto interessante: si noterà come la maggior parte di questi fa semplicemente un check delle librerie necessarie ad i programmi da inserire nella distribuzione e crea uno shell script con cui avviare il sistema. Dopo che il kernel riconosce i componenti principali del sistema avvia un programma di inizializzazione; questo è di solito /sbin/init, ma può essere cambiato. E' stato quindi prodotto un file di inizializzazione che prima di avviare init crei l'ambiante per il successivo avvio del sistema. L'ambiente consta di un file/system in lettura scrittura e di tutti gli applicativi che un utente desidera, oltre alle configurazione dei dispositivi periferici. Questo script è stato chiamato linuxrc-live ed è stato inserito nella directory / dell'immagine d'avvio initrd.img. Allorquando il kernel finisce il suo processo di avvio ed inizia la fase di "init" viene eseguito un programma che si deve trovare nella directory di root, tale programma non può essere killato, e non può nemmeno terminare fino alla chiusura della macchina: in caso contrario il sistema risponderà con un kernel panic. Se si sceglie di usare uno script di init si dovrà disporre nella directory radice, all'avvio, dell'interprete della shell (sh, ash...). Si sceglie ovviamente questa strada per la distribuzione live: non è il caso di scrivere un programma complicato come init da zero, inoltre l'utilizzo di init stesso non è possibile, perchè verrà utilizzato successivamente per avviare il sistema operativo presente su CD-ROM. L'obiettivo è infatti di ricreare un ambiente ideale di avvio per "init". Non è possibile avere due istanze di init sulla stessa macchina perchè cercano di accedere alle stesse risorse e non permettono un avvio e spegnimento corretto del sistema (si è comunque provata anche questa soluzione e viene caldamente sconsigliata anche se funzionante). Il filesystem di partenza viene caricato in RAM grazie all'adozione di initrd; la RAM è una memoria a lettura scrittura, non lo è però il supporto CD-ROM su cui si dovranno copiare i programmi della distribuzione live, nasce quindi il problema di come poter fare per usare dei programmi, come per esempio l'X server, che necessitano di poter scrivere. Una prima idea può essere quella di utilizzare l'approccio di impacchettare tutto il contenuto della distribuzione all'interno dell'immagine ram disk; questa soluzione è funzionale su alcuni sistemi ma non tutti i PC sono equipaggiati con un grosso quantitativo di RAM, tutta l'immagine viene copiata in RAM e poi scompressa: si può inceppare in una mancanza di spazio su questo tipo di memoria. Tale espediente spinge quindi a limitare lo spazio richiesto dall'immagine disco RAM, si è scelto di non andare oltre la decina di megabyte, questo anche per diminuire i tempi di copia dal CD alla memoria dell'immagine compressa e far partire quindi immediatamente il processo di avvio del kernel. E' evidente quindi che montare il CD-ROM come dispositivo di root è riduttivo perchè la scrittura su di esso non è possibile. Un disco virtuale su cui leggere e scrivere è invece facilmente ricavabile dalla RAM; a tale scopo esiste il file system tmpfs [tmpfs]. Questo file system viene inizializzato con una serie di parametri che permettono di configurare quanta memoria, in percentuale o in byte, deve essere usata dal disco virtuale in ram; se è presente una partizione di swap tmpfs usa anche questa come spazio di memoria RAM. Per esempio, per montare il filesystem tmpfs nella directory /var/tmpfsdir, con una richiesta di spazio pari al 20% della memoria virtuale attualmente disponibile: root@eakon:~# cd /var root@eakon:/var# mkdir tmpfsdir root@eakon:/var# mount -t tmpfs -o "size=60%" tmpfs tmpfsdir Resta però il fatto che non si sa come avere a disposizione una directory del CD come directory di root del sistema e di come poterci scriere sopra. Fortunatamente tale esigenza è soddisfatta da un filesystem di nuova generazione: Unionfs [union], [uslax]. Unionfs è un file system sviluppato alla Stony Brook university (NY) e permette di inserire in unico punto di mount (un'unica directory) più filesystem; il quotidiano uso di mount dovrebbe aver insegnato a tutti che in un unica directory può essere montato un unico file system, e ripetuti mount di diversi dispositivi sulla stessa directory fanno si che i file che vi si trovano corrispondono sempre all'ultimo file system che si è montato. Ma Unionfs è molto di più di un file system, permette infatti di poter scegliere la directory del file system da montare e non costringe quindi a scegliere per forza la directory di root, inoltre contiene un insieme di tool per la sua gestione (unionctl, uniondbg, unionimap). A questo punto, come sopra si è illustarato il funzionamento del file system tmpfs, si illustra come funziona il file system unionfs: root@eakon:/var# mkdir union root@eakon:/var# mkdir readonly root@eakon:/var# mount -t unionfs -o debug=0,dirs=/var/tmpfsdir=rw unionfs union root@eakon:/var# unionctl union --add --after /var/tmpfsdir --mode ro readonly In questo esempio si sono create oltre alla cartella tmpfsdir (in cui si usa il fs tmpfs) anche la cartella union e readonly, quest'ultima viene usata come cartella a sola lettura, una volta montato unionfs al suo contenuto sarà possibile accederci ma non si potrà scrivere, tutte le scritture nella directory union verranno effettuate nella directory tmpfsdir. Risulta chiaro che questo piccolo esempio fa capire come comportarsi nel caso di una LiveCD: la directory readonly può quindi essere sostituita con quella in cui si è montato il CD. Salta subito all'occhio come Unionfs non tratti "dispositivi fisici" come un normale file system bensì directory. Per una comprensione più approfondita dell'argomento si rimanda a [union]. Risulta infine necessario specificare che unionfs viene di solito compilato come modulo del kernel, se lo si vuole utilizzare durante il processo di avvio è quindi necessario includerlo nell'immagine initrd, nella corretta directory, insieme ad i suoi file di utilità. Possiamo quindi fare un sommario di quelli che sono i passaggi di inizializzazione fin qui discussi e quelli ancora da analizzare: 1. bios boot 2. cd-rom boot loader (copia del kernel e di initrd.gz) 3. avvio del kernel 4. script di avvio (linuxrc-live): a. mount di proc b. mount di sysfs c. caricamento dei moduli del kernel necessari (presenti in initrd.gz) d. ricerca dei dispositivi logici e. individuazione del cd-rom di boot f. mount del cd-rom di boot g. mount di tmpfs h. mount di unionfs i. unione del cdrom e tmpfs l. cambio della directory radice m. creazione di un file /etc/fstab n. exec dell'init nella nuova directory radice 5. avvio del sistema Il punto 4.c verrà coperto nel sottocapitolo successivo, tutte le parti non discusse, tranne la 5, seguono. Dopo che Linux avvia lo script di init il sistema è in uno stato fetale, non si può quindi esigere niente da esso: necessita dell'inizializzazione. Una delle prime cose da fare è senz'altro montare il filesystem proc e sysfs [sysfs], questi permettono di aver a disposizione dell'utente tutti quelli che sono i costrutti interni del kernel; è quindi possibile utilizzarli per determinare la configurazione HW del sistema e determinare quelli che sono i dispositivi logici, la loro configurazione e quindi creare il file /etc/fstab. Come fare questi script? La via più breve è copiare quelli che ci sono già nella Slackware nella directory /etc/rc.d/. Un'ultimo passo, delicato ed allo stesso tempo molto importante, è il 4.n che si è realizzato con il seguente codice nel file linuxrc-live: ~ pivot_root . mnt ~ exec $CHROOT . sbin/init dev/console 2>&1; La prima riga scambia la directory corrente con mnt, mentre la seconda esegue l'init della nuova radice applicando anche una ridirezione degli errori a standard output; quest'ultima feature si è scelta di aggiungerla per facilitare il debugging dei programmi RTAI kernel space che usando 'printk' possono in questo modo facilmente vedere i messaggi stampati senza usare il comando 'dmesg'. I moduli del kernel I moduli del kernel sono sicuramente stati una grande innovazione se non altro perchè hanno permesso agli sviluppatori di ridurre il tempo nel ciclo di sviluppo di un driver; questo grazie alla possibilità di aggiungere e rimuovere il modulo nel kernel in tempo di esecuzione senza dover ogni volta ricompilare tutto da capo e perdere quindi numerose ore. Il file di configurazione che si è scelto per la compilazione del kernel, che si era detto non necessitava di modifiche, causa la creazione di molti moduli, questa scelta è stata fatta per prevedere un kernel molto flessibile che possa funzionare su numerose macchine anche molto diverse; in particolare la cartella che contiene i moduli (/lib/modules/2.6.13) è di circa 25MB. Dato che si è cercato di compilare la maggior parte di driver come moduli, alcuni di essi è essenziale farli partire all'avvio in modo che il kernel possa riconoscere e gestire più periferiche possibili. Ciò comporta che alcuni moduli vengano inseriti nella directory /lib/modules/2.6.13 della immagine del disco RAM; per il loro corretto funzionamento è poi necessario usare il comando 'depmod'. Prima di illustrare la serie di comandi da utilizzare è meglio chiarire quali sono i moduli necessari da spostare nell'immagine initrd. Se si vuol usare unionfs sarà necessario il suo modulo e tutti i moduli da cui dipende che sono quelli della cartella /fs/nls (insieme di moduli di gestione dei caratteri); essenziali sono poi i moduli del mouse e di eventuali dispositivi di puntamento non standard, driver usb e ieee1394. Va quindi scelto un piccolo set di questi moduli dalla propria directory /lib/modules/2.6.13/ (quello che si è prodotto non supera il megabyte). Una volta scelti i moduli ed inseriti nella directory, diciamo, /lib/modules/2.6.13-small è necessario creare il file delle dipendenze in modo che 'modprobe' possa avviare i moduli con facilità. Perciò: root@eakon:~# cd /lib/modules/2.6.13-small root@eakon:/lib/modules/2.6.13-small# depmod -b /lib/modules/2.6.13-small A questo punto se vogliamo che tutto funzioni correttamente si apra il file modules.dep e si faccia il 'replace' della stringa '2.6.13-small' con la stringa '2.6.13' la maggior parte degli editor di testo lo permettono. La directory 2.6.13-small va quindi copiata nella corrispondente directory dell'immagine RAM dove però il nome andrà ricambiato in '2.6.13'. I pacchetti software Fino ad ora si sono create le fondamenta della distribuzione live ora si passa alla costruzione del file system della distribuzione live con il quale l'utente finale interagirà. E' perciò necessario selezionare e installare nel file system tutti gli applicativi utente ed amministrativi in base all'utilizzo che si deve fare della distribuzione. La fonte degli applicativi può essere qualsiasi, prendendo spunto da [ddk] e forti del fatto che ci si è sempre basati su Slackware, si sceglie di fare una selezione dei pacchetti da questa offerti e installarli nella directory /root/livecd/live: directory root del LiveCD. Per installare un pacchetto di Slackware è necessario dalla directory del cd dove è presente il pacchetto: root@eakon:~# cd /mnt/cdrom/slackware/a root@eakon:/mnt/cdrom/slackware/a# installpkg -root /root/livecd/live aaa_base-10.2.0-noarch-2.tgz Ribadiamo ancora una volta che con questa distribuzione ci si propone di dare un SO Linux con RTAI, con il quale si può programmare, in particolare si vuol anche permettere di compilare moduli del kernel, un ambiente grafico può essere d'aiuto. Si può quindi procedere con la copia dell'intero insieme dei pacchetti della serie 'a': root@eakon:~# cd /mnt/cdrom/slackware/a root@eakon:/mnt/cdrom/slackware/a# installpkg -root /root/livecd/live * Dopo di che, per non arrivare subito a sforare la capacità del cd, con l'aggiunta spropositata di qualsiasi pacchetto, si ritiene necessario far seguire una lista dei pacchetti scelti: * serie xap windowmaker-0.92.0-i486-1.tgz xxgdb-1.12-i386-1.tgz * serie x x11-6.8.2-i486-3.tgz x11-fonts-100dpi-6.8.2-noarch-3.tgz x11-fonts-misc-6.8.2-noarch-3.tgz x11-fonts-scale-6.8.2-noarch-3.tgz * serie tcl tcl-8.4.11-i486-1.tgz tclx-8.3.5-i486-2.tgz tix-8.1.4-i486-2.tgz tk-8.4.11-i486-1.tgz * serie l glib-1.2.10-i386-2.tgz glib2-2.6.6-i486-1.tgz glibc-2.3.5-i486-5.tgz glibc-profile-2.3.5-i486-5.tgz gtk+-1.2.10-i386-3.tgz libungif-4.1.3-i486-1.tgz libusb-0.1.8-i486-1.tgz zlib-1.2.3-i486-1.tgz * serie d bin86-0.16.15-i486-1.tgz binutils-2.15.92.0.2-i486-3.tgz ccache-2.4-i486-1.tgz cscope-15.5-i486-2.tgz distcc-2.18.3-i486-2.tgz flex-2.5.4a-i486-3.tgz gcc-3.3.6-i486-1.tgz gcc-g++-3.3.6-i486-1.tgz gcc-gnat-3.3.6-i486-1.tgz gcc-objc-3.3.6-i486-1.tgz gdb-6.3-i486-1.tgz libtool-1.5.20-i486-1.tgz m4-1.4.2-i486-1.tgz make-3.80-i386-1.tgz Per finire la distribuzione manca solo copiare nella directory /root/livecd/live la directory /usr/realtime, copiare i sorgenti del kernel e creare i device a blocchi necessari a RTAI. Finite le numerose copie è necessario utilizzare dei programmi di verifica che mettono a posto il lavoro fatto: root@eakon:/mnt/cdrom/slackware# cd /root/livecd/live root@eakon:/root/livecd/live# ldconfig -r /root/livecd/live Se si vogliono verifiare gli applicativi copiati in termini di dipendeze dalle librerie: root@eakon:/root/livecd/live# chroot . root@eakon:/# ldd /path/to/binary Per ritornare all'albero delle directory precedente basta scrivere 'exit' e premere invio. Applicativo d'esempio ... Conclusioni Eventuali futuri miglioramenti saranno necessari per poter permettere alla distribuzione di non avere il solo winow manager WindowMaker, aggiungere quindi altri tool grafici tra cui LTT (condizionatamente alla disponibilità di nuove patch) per il debugging dei processi e magari Octave per poter sfruttare le librerie di comunicazione offerte da RTAI, non per ultimo si potrebbe inserire anche RTAI-Lab. Inserire nuovi programmi significa o disporre al posto di un CD-ROM di un DVD, perchè questi supporti hanno capacità limitata, oppure comprimere in qualche modo il contenuto del cd-rom; se si sceglierà la seconda strada un ottimo strumento che ci viene in aiuto è il file system squashfs: un file system compresso e dalle buone prestazioni temporali per quanto riguarda la decompressione dei file al volo.