Initrd - discul de ramă inițial - cum să devii programator

Discul inițial RAM pentru încărcarea Linux (initrd) este un sistem de fișiere temporar rădăcină care este montat în timpul procesului de bootare a sistemului în memorie RAM pentru a suporta modelul de boot pe 2 nivele. Initrd constă din diferite fișiere executabile și drivere care vă permit să montați un sistem de fișiere root real, după care initrd






Demontați și eliberați memoria. În multe sisteme încorporate, initrd rămâne sistemul de fișiere rădăcină. Acest articol explorează un disc RAM bootabil pentru kernelul Linux 2.6, inclusiv procesul de creare și utilizare a acestuia în kernel-ul Linux.

Ce este un disc RAM bootabil?

Un disc RAM bootabil (Initrd) este o imagine a sistemului de fișiere rădăcină care este montat înainte ca fs root-ul real să fie disponibil. Initrd este conectat la kernel și este încărcat ca parte a kernelului în timpul procesului de boot al sistemului. Kernel-ul montează imaginea initrd, care conține modulele necesare pentru montarea rădăcină fs și pentru următoarea tranziție la această rădăcină ca principală.

Initrd conține un set minimal de directoare și fișiere executabile pentru încărcarea modulelor, de exemplu insmod pentru încărcarea modulelor kernel-ului.

În cazul unui sistem desktop sau server, sistemul de fișiere temporar initrd. Durata sa de viață este scurtă și servește doar ca o legătură cu rădăcina fs. În sistemele încorporate nu există dispozitive de stocare înregistrabile, deci initrd este o rădăcină permanentă fs. Acest articol explorează ambele opțiuni.

Initrd dispozitiv intern

Imaginea initrd conține minimul necesar de fișiere executabile și de sistem pentru a doua etapă a încărcării linux. În funcție de versiunea linux pe care o utilizați, metodele de creare a initrd diferă.

Începând cu Fedora Core 3, în mod implicit, imaginea initrd este o arhivă cpio comprimată. În loc să montați fișierul utilizând dispozitivul buclă, trebuie să utilizați programul cpio. Pentru a examina conținutul arhivei cpio, utilizați următoarea secvență de comandă:

Listarea 2. Studiul initrd (FC3 și mai târziu)

# mkdir temp; cd temp
# cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz
# gunzip initrd-2.6.14.2.img.gz
# cpio -i -make-directoare

Ca rezultat, avem un sistem de fișiere rădăcină mică, al cărei conținut sunt prezentate în Listarea 3. Intervalul de mică, dar necesară a aplicațiilor prezente în directorul directorul / bin, inclusiv nash (nu un shell, script interpret), insmod pentru modulele de kernel de încărcare, și LVM (utilitar pentru gestionarea LVM ).

Listarea 3. Structura implicită initrd (pentru FC3)

Interesul pentru listare 3 reprezintă fișierul init de la rădăcină. Acest fișier, ca și în procesul tradițional de pornire a linuxului, începe când imaginea initrd este despachetată în memorie. Vom discuta acest proces mai târziu în acest articol.

Utilitare pentru crearea imaginii initrd

Să ne întoarcem la început și să amestecăm oficial modul în care este creată imaginea initrd. Pentru sistemele linux tradiționale, imaginea initrd este generată în timpul procesului de instalare. Un număr mare de programe, cum ar fi mkinitrd, pot fi folosite pentru a crea un initrd cu bibliotecile și modulele necesare pentru a comunica cu fs rădăcină reală. Mkinitrd este în esență o coajă obișnuită
astfel încât să puteți vedea cum se obține rezultatul dorit. Există, de asemenea, YAIRD (încă un Mkinitrd) - un program care vă permite să configurați aproape orice parametru în initrd.

Comanda cpio Utilizarea comenzii cpio. puteți să manipulați fișierele cpio. Fișierul Cpio este în esență o simplă concatenare a fișierelor cu anteturi. Formatul de fișier cpio vă permite să lucrați atât cu fișiere ascii, cât și cu fișiere binare. Pentru compatibilitate, utilizați ascii, pentru a reduce dimensiunea - versiunea binară.

Creați manual o imagine initrd individuală

Datorită faptului că pe multe sisteme încorporate bazate pe linux nu există nici un hard disk, initrd este, de asemenea, o constantă fs. Lista 4 arată cum se creează o imagine initrd. Eu folosesc un desktop standard cu linux, astfel încât să puteți încerca aceste fără a avea un sistem încorporat cu linux. Nu numărăm compilația pentru altul
platforma, conceptul de creare a unei imagini initrd este același pentru sistemele încorporate și computerele convenționale (inclusiv serverele).

Listing 4. Utilizați (mkird) pentru a crea o imagine initrd individuală

# Servicii de menaj ...
rm -f /tmp/ramdisk.img
rm -f /tmp/ramdisk.img.gz

# Constantine Ramdisk
RDSIZE = 4000
BLKSIZE = 1024

# Creați o imagine ramdiscală goală
dd dacă = / dev / zero = = / tmp / ramdisk.img bs = $ BLKSIZE count = $ RDSIZE

# Faceți-l un sistem de fișiere cu montare ext2
/ sbin / mke2fs -F -m 0 -b $ BLKSIZE /tmp/ramdisk.img $ RDSIZE

# Montați-o astfel încât să putem popula
mount /tmp/ramdisk.img / mnt / initrd -t ext2 -o buclă = / dev / loop0

# Populați sistemul de fișiere (subdirectoare)
mkdir / mnt / initrd / bin
mkdir / mnt / initrd / sys
mkdir / mnt / initrd / dev
mkdir / mnt / initrd / proc

# Luați busybox și creați legăturile simbolice
pushd / mnt / initrd / bin
cp /usr/local/src/busybox-1.1.1/busybox.
Câmpul de coș de gunoi
Supravegherea casei de lucru
Mesajul ecou din cutie
Sunt ocupate în ls
Pisica de busy
Sunt ocupate cu ps
Mesagerie în buzunar dmesg
Sincronizarea busybox-ului
popd

# Luați fișierele dev necesare
cp -a / dev / console / mnt / initrd / dev
cp -a / dev / ramdisk / mnt / initrd / dev
cp -a / dev / ram0 / mnt / initrd / dev
cp -a / dev / null / mnt / initrd / dev
cp -a / dev / tty1 / mnt / initrd / dev
cp -a / dev / tty2 / mnt / initrd / dev

# Ecuațiți sbin cu bin
pushd / mnt / initrd
In-s bin sbin
popd

# Creați fișierul inițial
cat >> / mnt / initrd / linuxrc <

Listing 4. Scriptul mkird pentru crearea automată a unei imagini

Pentru a crea imaginea initrd, începeți prin crearea unui fișier gol utilizând
pseudo device / dev / zero (doar un flux de zerouri) ca intrare
fluxul către fișierul ramdisk.img. Ca rezultat, obținem un fișier cu dimensiunea 4
Megabytes (4000 blocuri pentru 1 kilobyte). Apoi, folosind comanda
mke2fs, crează în acest fișier sistemul de fișiere ext2. După fișier






formatat în ext2, montați-l în directorul / mnt / initrd ca
dispozitiv bucla. La punctul de montare, aveți acum un director,
care reflectă sistemul de fișiere ext2 al fișierului și acolo puteți deja
colecta imaginea initrd.

Următorul pas este crearea subdirectoarelor necesare: / bin, / sys,
/ dev și / proc. Numai necesare sunt necesare pentru a asigura cerințele necesare
de exemplu, nu sunt necesare biblioteci (această condiție este adevărată
Când toate fișierele executabile din imaginea initrd sunt compilate
static).

Pentru a vă asigura că o astfel de rădăcină furnizează funcționalitatea necesară, utilizați
BusyBox. Această aplicație este o singură cale pentru multe utilități,
care sunt utilizate în mod obișnuit în sistemele linux (cum ar fi cenușă, awk, sed,
insmod etc.). Avantajul lui BusyBox este că acesta, inclusiv el însuși
funcționalitatea multor utilități necesare, are o dimensiune mult mai mică.
Aceasta este o ieșire ideală pentru sistemele încorporate. Copiați BusyBox în director
/ bin în sistemul de fișiere rădăcină al imaginii dvs. initrd. crea
legăturile simbolice necesare (pentru aceeași cenușă, awk, sed, etc.) în
directorul / bin de pe BusyBox. BusyBox află ce utilitate a fost pornită și
oferă funcțiile necesare. Un număr mic de linkuri sunt create
în acest director pentru ca scriptul init să funcționeze (aceste linkuri indică din nou
același lucru pe BusyBox).

Următorul pas este să creați fișierele de dispozitiv necesare. Eu le copiez
direct din directorul / dev din sistemul de operare folosind opțiunea -a (pentru
cp) pentru a salva atributele de fișier.

Cel mai penultim pas este crearea unui fișier linuxrc. După kernel
montează un disc de tip ram, se caută executarea scriptului de inițializare. Dacă fișierul inițial
nu sa găsit, kernel-ul execută fișierul linuxrc în loc de init. În acest fișier
operațiile de bază sunt efectuate pentru a configura mediul, de exemplu
sistemul de fișiere / proc este montat. În plus față de / proc, am și eu
Sistemul de fișiere / sys este montat și afișează un mesaj către consola. La sfârșit
rulați cenușa (clona Bourne shell) astfel încât să puteți interacționa cu ea
rădăcină fs. Fișierul linuxrc este marcat cu un semn de executabil (+ x) utilizând
comanda chmod.

Ca rezultat, obținem fs rădăcină terminată. Imaginea este demontabilă și
este comprimat cu gzip. Fișierul rezultat (ramdisk.img.gz)
copiat în directorul / boot pentru a putea încărca GRUB
sau lilo.

Pentru a crea un disc RAM inițial, puteți rula pur și simplu mkinitrd și acesta
va compila automat imaginea și o va copia în directorul / boot

Distribuție Linux în initrd Un interesant deschis
sursă, în care întreaga distribuție de linux a fost plasată într-o imagine
initrd, se numește MiniMax. Este nevoie de 32 megaocteți. include în
tu BusyBox și uClibc pentru o dimensiune mai mică. În ciuda celor mici
dimensiune, aceasta este o distribuție bazată pe kernelul 2.6 și poartă suficient
un număr mare de utilități utile.

O alternativă la sistemul de fișiere ext2 Ext2 este standardul
de facto pentru linux, dar dacă există alternative care vă permit să reduceți
dimensiunea imaginii initrd rezultate. De exemplu, romfs (sistemul de fișiere ROM)
cramfs (sistem de fișiere comprimat ROM) și squashfs (un sistem de fișiere foarte comprimat
sistemul este doar pentru citire). Dacă aveți nevoie de ceva pentru a scrie la FS, ext2
destul de potrivit pentru acest lucru. În sfârșit, există și e2compr - acestea sunt extensii
pentru un driver ext2 care acceptă compresia.

Testarea imaginii individuale initrd

Deci, noua dvs. imagine initrd se află în directorul / boot, următorul pas
trebuie să îl testați cu kernel-ul. Reporniți sistemul și când
Apare promptul GRUB, apăsați tasta C, aceasta va muta GRUB la
linia de comandă. Puteți interacționa, de exemplu, cu GRUB'om
Pentru a trimite parametrii specifici kernelului sau pentru a încărca imaginea
initrd,. Comanda kernel pentru a determina care kernel să se încarce și comanda
initrd selectați imaginea initrd. Când sunt definiți acești parametri, tastați
boot-ul și încărcătorul de boot va încărca nucleul specificat și initrd.

Afișarea 5. Încărcarea manuală a kernel-ului și initrd folosind GRUB

grub> kernel /bzImage-2.6.1
[Linux-bzImage, configurare = 0x1400, dimensiune = 0x29672e]

grub> initrd / ramdisk.img.gz
[Linux-initrd @ 0x5f2a000, 0xb5108 octeți]

Uncompressing Linux. OK, bootarea kernel-ului.

Listing 6. Încărcarea kernel-ului linux cu o simplă initrd


md: Autodetectarea matricelor RAID
md: autorun
md. autorun DONE.
RAMDISK: Imagine comprimată găsită la blocul 0
VFS: rădăcină montată (sistem de fișiere ext2).
Eliberarea memoriei nucleului neutilizat: 208k eliberat
/ $ ls
bin etc linuxrc proc sys
dev lib pierdut + găsit sbin
/ $ cat / proc / 1 / cmdline
/ bin / cenușă / linuxrc
/ cd bin
/ bin $ ls
cenușă pisică ecou mount sysctl
busybox dmesg ls ps
/ bin $ touch zfile
/ bin $ ls
cenușă pisică ecou mount sysctl
busybox dmesg ls ps zfile

Procesul de încărcare cu discul RAM inițial

Acum știți cum să vă asamblați imaginea initrd, în această parte a articolului
ia în considerare modul în care kernelul identifică și montează initrd ca root fs.
Am trecut prin acest proces, oprindu-mă la ceva important
funcționează în lanțul de sarcină, explicând ce se întâmplă.

Un încărcător, cum ar fi GRUB, identifică kernelul pe care doriți să îl încărcați și
copiază imaginea kernel-ului și initrd-ul în memorie. Puteți găsi o descriere a tuturor
funcțiile necesare din directorul / init din arborele sursă al kernelului.

După ce kernelul și initrd-ul sunt despachetate și copiate în memorie,
miezul este executat. În acest loc, există multe inițializări diferite
proceduri, veți ajunge în funcția init / main.c: init ()
(subdirector / fișier: funcție). Această funcție este doar a
inițializarea subsistemului. De aici vine apelul pentru funcții
init / do_mounts.c: prepare_namespaces (), care pregătește lucrarea
spațiu (montează sistemul de fișiere dev, dispozitiv RAID sau MD și,
în final, initrd în sine). Initrd-ul este încărcat prin apelare
init / do_mounts_initrd.c: initrd_load ().

Funcția initrd_load () apelează init / do_mounts_rd.c: rd_load_image ()
care determină dimensiunea discului RAM pentru ao încărca
init / do_mounts_rd.c: identitate_ramdisk_image (). Această funcție verifică
"numărul magic" al imaginii pentru a determina ce fs din această imagine:
minux, ext2, romfs, cramfs sau gzip. Revenind la funcție
initrd_load_image, init / do_mounts_rd: se numește crd_load (). aceasta
funcția alocă în memorie spațiul de sub discul RAM și consideră suma de control
(CRC), apoi despachetează și încarcă discul RAM în memorie. acum
imaginea dvs. initrd se află într-un bloc adecvat de montat
dispozitiv.

Montarea unui dispozitiv bloc pe măsură ce începe partiția rădăcină
în funcția init / do_mounts.c: mount_root (). Se creează o partiție root și
apelul la init / do_mounts.c: mount_block_root (). De aici se cheamă
init / do_mounts.c: do_mount_root (), care solicită
fs / namespace.c: sys_mount () pentru a monta deja root-ul fs și du-te
în ea. Acesta este locul unde consola 6
mesaj VFS: Rădăcină montată (sistem de fișiere ext2).

În cele din urmă, vi se returnează funcția init și se face un apel
init / main.c: run_init_process. Acest lucru se întâmplă ca urmare a apelului execve
astfel încât începe procesul inițial (în acest caz linuxrc). Linuxrc poate
fi atât un fișier executabil, cât și un script (dacă există un script pentru script
interpret).

Lista 7 prezintă ierarhia funcțiilor. Nu toate funcțiile care participă la
procesul de copiere și montare a discului RAM de inițializare
sunt prezentate aici, dar aici este prezentată o idee generală despre procesul general.

Listarea 7. Ierarhia principalelor funcții implicate în procesul de încărcare și
mount initrd

init / main.c: init
init / do_mounts.c: prepare_namespace
init / do_mounts_initrd.c: initrd_load
init / do_mounts_rd.c: rd_load_image
init / do_mounts_rd.c: identitate_ramdisk_image
init / do_mounts_rd.c: crd_load
lib / inflate.c: gunzip
init / do_mounts.c: mount_root
init / do_mounts.c: mount_block_root
init / do_mounts.c: do_mount_root
fs / namespace.c: sys_mount
init / main.c: run_init_process
execve

Încărcarea sistemelor fără discuri

Scade dimensiunea imaginii initrd

Când creați un sistem încorporat și doriți să obțineți cel mai mic
dimensiune din imaginea initrd, dacă aveți mai multe trucuri pentru a face acest lucru.
Primul sfat este să utilizați BusyBox (descris în articol). BusyBox include
în sine, câteva megabyte de utilități și le comprimă pe toate la câteva sute
kilobyte.

În acest exemplu, BusyBox este compilat static, adică el nu are nevoie de asta
fără biblioteci. Cu toate acestea, dacă aveți nevoie de biblioteci standard
C (pentru programe suplimentare), există câteva modalități de a rezolva această problemă.
Problema fără a folosi un glibc masiv. Prima bibliotecă mică
potrivite pentru scopurile noastre este uClibc, care este minimizat
versiune a bibliotecii standard C pentru sisteme cu spațiu limitat.
O altă bibliotecă, ideală în ceea ce privește spațiul pe disc
spațiul este dietlib. Nu uitați că pentru programele dvs.
a lucrat cu versiunile descrise, aceste programe trebuie să fie recompilate
folosind aceste biblioteci, vor fi necesare unele lucrări suplimentare,
dar merită.







Trimiteți-le prietenilor: