Bociek PLD - Pisarz
I. Informacje podstawowe
II. Instalacja
III. Podręcznik użytkownika
IV. Podręcznik administratora
Kernel i urządzenia
Initrd
V. Tworzenie PLD - Praktyczny poradnik
VI. O podręczniku
O tej książce
Spis treści
Inne wersje tego dokumentu
PDF
HTML (jeden plik)
TXT
Odnośniki
Tworzymy dokumentację PLD
Strona PLD
Listy dyskusyjne PLD

Initrd

<- ->
 

Wstęp

W PLD wszystkie możliwe sterowniki są dostępne w postaci tzw. modułów, przez co nie są one "widoczne" dla jądra w trakcie startu systemu. Aby system wystartował wymaganych jest kilka modułów i innych komponentów koniecznych do zamontowania głównego systemu plików (root filesystem):

  • moduły kontrolera urządzeń masowych (IDE/SATA/SCSI) np.: sata_nv, sata_sil, sd_mod

  • systemu plików na głównej partycji systemowej np.: xfs, reiserfs

  • elementy konieczne do złożenia woluminów opartych o LVM lub programowy RAID

Jedynym sposobem dostarczenia tych sterowników jest umieszczenie ich w specjalnym "obrazie" zwanym initrd (initial ramdisk). Obraz ten jest plikiem wczytywanym przez bootloader, tak więc dodatkowo musimy właściwie skonfigurować bootloader - wskazać położenie obrazu. Obraz przechowywany jest w katalogu /boot i ma nazwę initrd-{$wersja_jądra}.gz, do niego zaś prowadzi łącze o nazwie initrd.

Initrd jest tworzony przy każdej instalacji/aktualizacji kernela. Bywa jednak, że nasz obraz nie jest wygenerowany prawidłowo i jesteśmy zmuszeni do utworzenia go samodzielnie. Źle utworzony uniemożliwi uruchomienie systemu, ujrzymy wtedy następujący komunikat:

Kernel panic: VFS: Unable to mount root fs...

Jądro mówi nam, że nie może zamontować głównego systemu plików, gdyż brakuje mu jakiegoś komponentu. Może się to zdarzyć, że nasz sprzęt nie został prawidłowo wykryty lub próbujemy uruchomić PLD z naszego dysku na innym komputerze (o innym kontrolerze urządzeń masowych).

Systemu nie można uruchomić więc musimy skorzystać z operacji chroot-a, możemy w tym celu użyć dowolnej dystrybucji linuksa jednak chyba najwygodniejsze będzie użycie PLD-Live lub RescueCD.

Przygotowanie

Poniżej przedstawiono trzy metody generowania initrd. W większości wypadków wystarczy nam pierwszy ze sposobów, pozostałe są trudniejsze gdyż musimy znać nasz sprzęt i system plików partycji "/". Jeśli obraz nie jest tworzony prawidłowo przez pierwszą metodę musimy się zadowolić dwoma pozostałymi. Druga i trzecia metoda mają jedną zasadniczą przewagę nad pierwszą - mogą być przeprowadzane na dowolnej maszynie.

W dwóch pierwszych metodach użyjemy skryptu /sbin/geninitrd z pakietu geninitrd. Jest to wygodny automat, który stara się wykryć sprzęt, system plików i czy główny system plików jest stworzony na LVM/soft RAID. Skrypt geninitrd wymaga prawidłowych wpisów w /etc/fstab i podmontowanego /proc. Tak więc jeśli generujemy initrd w systemie typu chroot to wydajemy polecenie (z chroota):

# mount /proc

Opis wykrywania sprzętu i dobierania właściwych modułów opisano w tym dokumencie.

Automatyczne generowanie initrd

W razie potrzeby edytujemy plik /etc/sysconfig/geninitrd i ustawiamy jaki rodzaj urządzenia (SCSI, IDE, RAID) ma być automatycznie wykrywany:

## Do install SCSI modules (if / is on SCSI partition)?
PROBESCSI=yes

## Do install IDE modules (if / is on IDE partition)?
PROBEIDE=yes

## Do install RAID modules (if RAID is used)?
PROBERAID=yes

Teraz przyszedł czas na wygenerowanie obrazu wg schematu

geninitrd [opcje] {$initrd} {$wersja_jądra} np.:

# geninitrd -v -f /boot/initrd-2.6.16.35-1.gz 2.6.16.35-1

Parametr -v odpowiada za "gadatliwość" programu, zaś -f wymusza nadpisanie istniejącego obrazu.

Ręczne generowanie initrd

Metoda ta wymaga precyzyjnej znajomości używanego sprzętu i systemu plików, gdyż sami musimy wskazać odpowiednie moduły. Jest jednak konieczna, w przypadku problemów z automatycznym wykryciem wymaganych sterowników lub jeśli chcemy operację wykonać na innej maszynie niż docelowa.

Możemy wpisać listę koniecznych modułów do odpowiedniej sekcji w pliku /etc/sysconfig/geninitrd:

## Basic modules to be loaded
BASICMODULES=""

## Modules that should be loaded before anything (i.e. jbd for ext3)
PREMODS=""

lub zmodyfikować wywołanie geninitrd poprzez użycie parametru --with:

geninitrd [opcje] --with={$nazwa_modułu} {$initrd} {$wersja_jądra}

Dużym ułatwieniem zadania jest automatyczne dołączanie modułów zależnych od wskazanego (o ile takie są). Poniżej zamieszczono przykładowe wywołanie geninitrd dla systemu plików ext3 i kontrolera IDE PDC20268 firmy Promise:

# geninitrd -v --with=ext3 --with=pdc202xx_new  /boot/initrd-2.6.16.35-1.gz 2.6.16.35-1

Gdy zawiedzie geninitrd

Możemy zmodyfikować zawartość obrazu wygenerowanego przez geninitrd, aby to zrobić rozpoczynamy od skopiowania initrd w inne miejsce i rozpakowania go:

# gunzip initrd-2.6.16.35-1.gz

rozpakowany plik montujemy jako loop:

mkdir /tmp/initrd-src
# mount -o loop initrd-2.6.16.35-1 /tmp/initrd-src

Tworzenie initrd rozpocznijmy od skopiowania zawartości katalogu w inne miejsce:

# cp -a /tmp/initrd-src initrd-moje
cp: czytanie `initrd-src/bin/sh': Błąd wejścia/wyjścia

Pomimo tego błędu dobrze się skopiowało, warto jednak sprawdzić uprawnienia i atrybuty pliku (ewentualnie poprawić na takie jak w oryginale)

Aby dodać moduł, musimy go skopiować z naszego systemu do odpowiedniego katalogu w initrd-moje/lib/modules/*/, następnie do skryptu initrd-moje/linuxrc dodać wpis "insmod {$moduł}" na wzór już istniejących ({$moduł} musi zawierać pełną ścieżkę do pliku).

Przyszedł czas na wygenerowanie initrd:

# genromfs -d initrd-moje -f initrd-nowy

Kompresujemy nowy initrd:

# gzip -9 initrd-nowy

Teraz już pozostało tylko skopiowanie pliku initrd-nowy.gz do /boot i nadanie mu odpowiedniej nazwy.

Bootloader

Musimy się upewnić czy łącze symboliczne /boot/initrd wskazuje na prawidłowy obraz. Jeśli używamy LiLo wydajemy polecenie:

# lilo

W przypadku Grub-a nic nie musimy robić.

Na koniec restartujemy komputer i system powinien uruchomić się bez problemu. Konfigurację bootloaderów szerzej opisano w tym dokumencie.

Uwagi

Częste zmiany używanego obrazu initrd mogą być uciążliwe, można to obejść łącząc do jednego obrazu większą ilość modułów. Aby to zrobić możemy dopisać nazwy modułów do przedstawionych poniżej opcji w pliku /etc/sysconfig/geninitrd:

## Basic modules to be loaded
BASICMODULES=""

## Modules that should be loaded before anything (i.e. jbd for ext3)
PREMODS=""

możemy też użyć opcji --with programu geninitrd. Warto pamiętać żeby nie przesadzać z ich ilością, może to spowodować wolniejszy start systemu i niepotrzebne zużycie pamięci operacyjnej przez nieużywane sterowniki.

 
<- ->