Pentru ca sistemul să fie inițializat corect după pornirea kernel-ului, este necesar ca toate script-urile și executabilele necesare pentru a porni daemon-ul de inițializare, init, și restul proceselor user-space, să existe în anumite locații în sistemul de fișiere. Acest sistem minimal de fișiere necesar la inițializare poartă numele de root file system sau rootfs. În cazul sistemelor Unix, rootfs-ul are ca rădăcină directorul /
și înglobează o serie de directoare ce contin restul de fișiere necesare. De obicei, în directorul /
nu se află niciun fișier, doar subdirectoare. Aceste subdirectoare sunt organizate în funcție de fișierele pe care le conțin:
/bin
- conține programe și comenzi necesare la inițializare ce pot fi folosite apoi de către un utilizator neprivilegiat în timpul unei sesiuni/sbin
- conține programe asemănătoare cu cele din /bin ca utilitate, dar care pot fi utilizate în general doar de utilizatorul privilegiat root/etc
- conține fișierele de configurare specifice sistemului/lib
- conține bibliotecile folosite de programele din rootfs (cele din /bin
și /sbin
)/dev
- conține referințe la toate dispozitivele periferice; aceste referințe sunt în general fișiere speciale/boot
- conține fișierele necesare bootării și imaginea kernel-ului; este posibil ca acestea să fie păstrate pe un sistem de fișiere separat de rootfs/tmp
- conține fișiere temporare și este de obicei curățat la repornirea sistemului/opt
- conține în principal aplicațiile third-party/proc
, /usr
, /mnt
, /var
, /home
- sunt directoare care, în general, reprezintă puncte în care se pot monta alte sisteme de fișiere pentru a stoca log-uri, biblioteci și alte aplicații și programe folosite de către utilizatori.Standardul Unix recomandă ca rootfs-ul să aibe dimensiuni relativ mici, deoarece orice problemă sau corupere a acestuia poate împiedica inițializarea corectă a sistemului. Dacă, totuși, rootfs-ul devine corupt, există modalități prin care poate fi remediat. O soluție des folosită este de a monta acest sistem de fișiere într-un alt sistem, funcțional, pentru a putea fi explorat și verificat.
În cazul sistemelor embedded, de multe ori spațiul de stocare pe care îl avem la dispoziție este deja limitat: < 32MB. De cele mai multe ori, o bună parte din acest spațiu este ocupat de imaginea kernel-ului. De aceea, în majoritatea cazurilor, rootfs-ul pentru aceste sisteme este fie compus doar din minimul de programe necesar pentru inițializare, fie este stocat pe un server accesibil prin rețea și montat de către kernel la inițializare, folosind protocolul NFS.
Network File System este un protocol dezvoltat de Sun Microsystems în 1984, ce permite unui client să acceseze fișiere aflate pe o altă mașină din rețea. Deoarece protocolul poate rula peste TCP, acesta poate fi folosit fără probleme atât în retele mici (LAN-uri) cât și în rețele extinse (WAN).
În sistemele Unix, există o serie de configurări ce trebuie făcute, atât pe server, cât și pe client, pentru a putea folosi NFS:
mount
; dacă totul este configurat corect, client-ul va putea naviga și folosi sistemul de fișiere de pe server ca pe orice sistem de fișiere local.
nfsd
. /etc/exports
. Utilitarul folosit pentru export-uri temporare se numeste exportfs
.mount
./etc/fstab
Uneori vom fi în situația în care nu avem acces la un server și imaginea de care dispunem pentru sistemul nostru nu este satisfăcătoare. În aceste condiții va trebui să ne creăm propriul rootfs pe care să îl scriem în memoria sistemului embedded.
Imaginea recomandată pentru RaspberryPi, Raspbian, conține două partiții: o partiție FAT
folosită pentru boot și o partiție ext4
pentru rootfs. Fiecare dintre aceste partiții începe de la un anumit offset în cadrul imaginii. Atunci când dorim să creăm o imagine nouă pentru RaspberryPi, trebuie să ne asigurăm că respectăm aceste partiții și formatele lor. Pașii pe care trebuie să îi urmăm sunt:
Pentru fiecare dintre acești pași există utilitare ce ne ajută să realizăm operațiile necesare.
Pentru copierea, și eventual convertirea, unui fișier, la nivel de byte, se poate folosit utilitarul dd.. Folosind dd, putem de asemenea genera fișiere de anumite dimensiuni și le putem stabili conținutul. În cazul nostru, dd este util pentru a inițializa o imagine și pentru a copia în acea imagine conținutul care ne interesează. Dintre parametrii lui dd, cei mai des utilizați sunt:
if
- fișierul de intrare; dacă nu se specifică acest parametru, se va citi de la standard inputof
- fișierul de ieșire; ca și la if
, dacă nu este specificat, se scrie la standard outputcount
- numărul de blocuri de input ce vor fi copiatebs
- numărul de bytes dintr-un bloc
dd
pentru a inițializa cu zerouri un fișier de o dimensiune exactă:
$ dd if=/dev/zero of=<file> bs=1k count=4096
Observați valorile lui count
si bs
. Se vor copia în total 4096 de blocuri de câte 1KB fiecare, rezultând o dimensiune de 4096KB. Fișierul de intrare /dev/zero
este un fișier special din care se pot citi oricâte caractere ASCII NUL (0x00).
Pentru manipularea tabelei de partiții (crearea sau ștergerea partițiilor) se poate folosi utilitarul fdisk. Doar tabele de partiții DOS și disklabel-uri SUN și GNU sunt recunoscute și pot fi manipulate cu fdisk. Utilitarul primește ca parametru device-ul a cărui tabelă de partiții dorim să o modificăm. Un exemplu de apel este:
$ fdisk <device>
Rezultatul acestei comenzi este un prompt nou în care putem folosi tasta m
pentru a afișa un meniu cu opțiunile disponibile. Opțiuni utile pentru crearea și ștergerea de partiții sunt:
p
- afișează tabela curentăd
- șterge o partițien
- crează o partiție nouăw
- salvează tabela și iese.Trebuie reținut că în mod normal fdisk operează cu sectoare și nu cu octeți. Atunci când adăugam o partiție, dacă specificăm doar dimensiunea ei și omitem unitatea de măsură (K, M, G etc.), fdisk va considera numărul specificat în sectoare.
512 bytes
. Aceasta poate fi schimbată folosind opțiunea -b
.primary
și extended
. Un device nu poate avea mai mult de 4 partiții primare.
Crearea unei partiții nu este suficient pentru a putea stoca fișiere. Avem nevoie ca partiția să conțină și un sistem de fișiere. Utilitarul folosit pentru a crea (formata) sisteme de fișiere Linux este mkfs. Parametrii pe care îi primește mkfs sunt device-ul ce trebuie formatat și tipul sistemului de fișiere dorit, specificat cu parametrul -t
.
$ mkfs -t ext2 /dev/fd0
va crea pe device-ul fd0 un sistem de fișiere ext2. În Linux, utilitarul mkfs este împărțit în câte un executabil pentru fiecare tip de sistem de fișiere suportat. Pentru a le vedea pe cele disponibile, deschideți un terminal, scrieți mkfs
și apasați tab.
În sistemele Unix, sistemul de fișiere este unul arborescent unde directoarele pot fi considerate noduri, iar fișierele frunze. Utilitarul mount ne permite să atașăm unui arbore existent un alt subarbore (sistem de fișiere). Apelată fără niciun parametru, această comandă va afișa toate device-urile montate, locația în care sunt montate și opțiunile cu care au fost montate.
mount -t <type> <device> <mount path>
, unde <type> este același ca la mkfs.
1. Dorim ca partiția de rootfs a RaspberryPi-urilor noastre să fie în formatul ext2. Pentru aceasta, ne vom crea propria imagine.
2. Deoarece ne-am propus să modificăm doar formatul partiției, nu și conținutul rootfs-ului, pe acesta îl vom copia din imaginea inițială. Este important ca ownerii și permisiunile fișierelor originale să fie păstrate și în noua imagine.
-o offset=<offset>
a comenzii mount permite montarea un sistem de fișiere care începe la un anumit offset pe device. mount așteaptă valoarea <offset> în bytes.-a
a comenzii cp.
3. Acum că imaginea noastră este gata, vrem să vedem că funcționează. Bootați sistemul in qemu folosind aceasta imagine de kernel si rootfs-ul nou creat.
root=/dev/sda2
pentru linia de comandă a kernel-ului.