W jaki sposób jądro montuje partycję root?


29

Moje pytanie dotyczy uruchomienia systemu Linux z osobnej partycji / boot. Jeśli większość plików konfiguracyjnych znajduje się na osobnej / partycji, w jaki sposób jądro poprawnie montuje go podczas uruchamiania?

Wszelkie rozwinięcie tego byłoby świetne. Mam wrażenie, że brakuje mi czegoś podstawowego. Najbardziej interesuje mnie proces i kolejność operacji.

Dzięki!

EDYCJA: Myślę, że to, o co musiałem zapytać, było bardziej zgodne z plikiem dev, który jest używany w parametrze jądra root. Powiedzmy na przykład, że podaję parametr root jako root = / dev / sda2. W jaki sposób jądro ma mapowanie pliku / dev / sda2?


Chociaż ludzie poniżej omawiają initrd, mało jest dyskusji na temat tego, dlaczego używa się initrd. Mam wrażenie, że dystrybucje takie jak Debian chcą używać jednego jądra na wielu różnych maszynach o tej samej architekturze, ale być może na bardzo różnym sprzęcie. Jest to możliwe dzięki modułowej obsłudze sprzętu za pośrednictwem modułów jądra. Inicjalizacja initrd nie wymaga dużego wsparcia sprzętowego, a kiedy to robi, ładuje niezbędne moduły sprzętowe, aby kontynuować. Docenia się opracowania / poprawki tego.
Faheem Mitha

Nie możesz zamontować / boot bez uprzedniego zamontowania /, ponieważ nie ma katalogu / boot bez /.
psusi

Odpowiedzi:


20

Linux początkowo uruchamia się z ramdyskiem (zwanym initrd„INITial RamDisk”) jako /. Ten dysk ma wystarczającą ilość miejsca, aby znaleźć prawdziwą partycję główną (w tym wszelkie wymagane sterowniki i moduły systemu plików). Montuje partycję root na tymczasowym punkcie montowania na initrd, a następnie wywołuje pivot_root(8)zamianę root i tymczasowych punktów montowania, pozostawiając initrdpozycję do umountedycji i włączony system plików root /.


2
Co jeśli nie masz initrd takiego jak LFS (linuxfromscratch.org)?
Pan Shickadance

@Pan. Shickadance: Nie sprawdzając, jak działa LFS, zgaduję, że upewniają się, że jądro ma w nim skompilowane wszystkie niezbędne moduły (lub załadowane przez GRUB 2, która jest na tyle nowa, że ​​jeszcze nie zauważyło tego wiele dystrybucji), więc można uruchomić na rzeczywistej partycji root.
geekozaur

4
@Pan. Shickadance. Nie tylko LFS nie ma initrd. Każdy, kto skompiluje własne jądro, może nie używać initrd, co robię na Gentoo.
jonescb

1
@Faheem: moduły grub2 to nie to samo, co moduły jądra. Widzę pewną zdolność grub2 do ładowania modułów jądra, ale nie wiem, czy to zadziała dla jądra Linuksa, czy tylko dla * BSD (gdzie ładowanie modułów jądra przez bootloader jest normalne). Podejrzewam, że jądra należy nauczyć, gdzie szukać mapy adresów dla załadowanych modułów, i każdy musi przejść do grub2 (grub1 jest nadal standardem w niektórych dystrybucjach).
geekozaur

1
Initrd został zastąpiony przez initramfs, ponieważ pivot_root uznano za brudny hack.
psusi

41

W czasach starożytnych jądro było mocno zakodowane, aby znać główną / mniejszą liczbę root fs i montowało to urządzenie po zainicjowaniu wszystkich sterowników urządzeń wbudowanych w jądro. rdevNarzędzie może być wykorzystywane do zmiany numeru urządzenia głównego w jądrze bez konieczności ponownej kompilacji.

W końcu pojawiły się programy ładujące i mogły przekazać wiersz poleceń do jądra. Jeśli root=argument został przekazany, informowało to jądro, gdzie znajduje się root fs zamiast wbudowanej wartości. Sterowniki wymagały dostępu, które wciąż musiały być wbudowane w jądro. Podczas gdy argument wygląda jak normalny węzeł urządzenia w /devkatalogu, oczywiście nie ma /devkatalogu przed zamontowaniem root fs, więc jądro nie może tam znaleźć węzła dev. Zamiast tego niektóre dobrze znane nazwy urządzeń są zakodowane na stałe w jądrze, aby ciąg mógł zostać przetłumaczony na numer urządzenia. Z tego powodu jądro może rozpoznać takie rzeczy jak /dev/sda1, ale nie bardziej egzotyczne rzeczy takie jak /dev/mapper/vg0-rootUUID woluminu.

Później initrdpojawił się na zdjęciu. Wraz z jądrem moduł ładujący initrdładowałby obraz, który był pewnego rodzaju skompresowanym obrazem systemu plików (obraz gzipped ext2, obraz romfów gzip, wreszcie squashfs stał się dominujący). Jądro rozpakuje ten obraz na ramdysk i zamontuje go jako root fs. Ten obraz zawierał kilka dodatkowych sterowników i skryptów rozruchowych zamiast prawdziwego init. Te skrypty rozruchowe wykonały różne zadania w celu rozpoznania sprzętu, aktywacji takich rzeczy, jak tablice RAID i LVM, wykrycia UUID i parsowania wiersza poleceń jądra w celu znalezienia prawdziwego katalogu głównego, który może być teraz określony przez UUID, etykietę woluminu i inne zaawansowane rzeczy. Następnie zamontował prawdziwy root fs /initrd, a następnie wykonał pivot_rootwywołanie systemowe w celu wymiany jądra /i/initrd, a następnie uruchom /sbin/initna prawdziwym katalogu głównym, który następnie odmontuje /initrdi uwolni ramdysk.

Wreszcie, dzisiaj mamy initramfs. Jest to podobne do tego initrd, ale zamiast być skompresowanym obrazem systemu plików ładowanym do ramdysku, jest to skompresowane archiwum CPIO. Tmpfs jest montowany jako root, a archiwum jest tam rozpakowywane. Zamiast używać pivot_root, co uważano za brudny hack, initramfsskrypty rozruchowe montują prawdziwy root /root, usuwają wszystkie pliki z root tmpfs, a następnie chrootdo /rooti wykonują /sbin/init.


1
Czy po chroot tmpfs jest automatycznie odmontowany? Czy to po prostu znika?
jiggunjer

@ jiggunjer, nie, wciąż tam jest, jest po prostu pusty (poza tym, że zawiera katalog / root) i nie jest już używany.
psusi

Nauczyłem się czegoś nowego o każdej iteracji root fs, o której wspomniałeś. Świetna odpowiedź!
jpaugh

3

Wygląda na to, że pytasz, w jaki sposób jądro „wie”, która partycja jest partycją główną, bez dostępu do plików konfiguracyjnych na / etc.

Jądro może akceptować argumenty wiersza poleceń, jak każdy inny program. GRUB lub większość innych programów ładujących może akceptować argumenty wiersza poleceń jako dane wprowadzane przez użytkownika lub przechowywać je i udostępniać różne kombinacje argumentów wiersza poleceń za pośrednictwem menu. Program ładujący przekazuje argumenty wiersza poleceń do jądra, gdy je ładuje (nie znam nazwy ani mechaniki tej konwencji, ale prawdopodobnie jest to podobne do sposobu, w jaki aplikacja odbiera argumenty wiersza poleceń z procesu wywołującego w uruchomionym jądrze).

Jedną z tych opcji wiersza poleceń jest rootokreślenie głównego systemu plików, tj root=/dev/sda1.

Jeśli jądro używa initrd, bootloader jest odpowiedzialny za poinformowanie jądra, gdzie się znajduje, lub umieszczenie initrd w standardowej lokalizacji pamięci (tak myślę) - przynajmniej tak działa na moim Guruplug.

Jest całkowicie możliwe, aby nie podać jednego, a następnie wywołać panikę jądra natychmiast po rozpoczęciu narzekań, że nie może znaleźć głównego systemu plików.

Mogą istnieć inne sposoby przekazania tej opcji do jądra.


3
To właściwe wytłumaczenie, gdy nie ma initrd / initramfs, ale brakuje mu fragmentu układanki. Zwykle jądro identyfikuje urządzenie, na przykład /dev/sda1dlatego, że jest to wpis w systemie plików. Możesz zrobić cp -p /dev/sda1 /tmp/fooi /tmp/fooreprezentować to samo urządzenie. W wierszu poleceń jądra jądro korzysta z wbudowanego analizatora składni, który jest zgodny ze zwykłą konwencją nazewnictwa urządzeń: sda1oznacza pierwszą partycję pierwszego dysku podobnego do SCSI.
Gilles 'SO - przestań być zły'

@Gilles, więc współczesne jądra wciąż nie są w stanie obsłużyć montowania woluminu na podstawie UUID? bez initrdlub initramfsmam na myśli. To musi być „prosta” partycja w /dev/sdxformie?
jiggunjer

1
@jiggunjer Nowoczesne jądra obsługują wyszukiwanie woluminu według UUID. Zobaczyć init/do_mounts.c.
Gilles „SO- przestań być zły”

1

Grub montuje /bootpartycję, a następnie wykonuje jądro. W konfiguracji Gruba informuje jądro, które ma być używane jako urządzenie root.

Na przykład w Grub's menu.lst:

kernel /boot/linux root=/dev/sda2

1

No dalej, GRUB nie „montuje” / bootuje, po prostu czyta „menu.lst” i niektóre moduły, nie jest też częścią jądra LINUX. Kiedy wywołujesz jądro, przekazujesz argument „root” z partycją root. W najgorszym przypadku jądro wie, że właśnie zamontowano / boot (LOL).

Dalej: geekozaur ma rację, Linux używa początkowego ramdysku w formacie skompresowanego obrazu, a następnie montuje prawdziwy główny system plików, wywołując pivot_root. Linux zaczyna więc działać z obrazu, a następnie z lokalnego dysku.


1
Grub zdecydowanie ma możliwość „zamontowania” systemu plików, szczególnie w grub2. Oczywiście, wszystko, co jest w stanie / robić / z nim, to szukać jądra rozruchowego z jednego lub drugiego paska, ale to wciąż rośnie. Ponadto Linux nie wymaga initrd, chyba że jądro skompilowało sterowniki kluczowe dla twojego dysku twardego jako moduły.
Shadur

5
ibm.com/developerworks/linux/library/l-linuxboot To dość zwięzłe podsumowanie tego, co robi jądro Linux podczas uruchamiania.
jsbillings

2
@Shadur, ze strony montowania : Wszystkie pliki dostępne w systemie Unix są ułożone w jednym dużym drzewie, hierarchii plików, zrootowanym w /. Pliki te można rozłożyć na kilka urządzeń. Polecenie mount służy do dołączenia systemu plików znalezionego na niektórych urządzeniach do dużego drzewa plików. - Ponieważ systemy plików używane przez GRUBa nie są dołączone do hierarchii plików, NIE jest ono montowane .
D4RIO

1
@Shadur, BTW: Oczywiste jest, że initrd nie jest konieczny, ponieważ jest to po prostu kolejny główny system plików, ale ogólnie jest używany jako mały root podczas rozruchu, ponieważ jądro ładuje niezbędne do rozruchu, następnie uruchamia, a na końcu ładuje wszystko inne.
D4RIO

1
@ d4rio Są one montowane przez GRUB, a nie Linux - łatwiej to zrozumieć, gdy myślisz o grub jako o własnym systemie mikrojądrowym, a nie tylko o bootloaderze.
Shadur

1

Program ładujący, bez względu na to, czy jest grub, czy lilo, czy cokolwiek innego, informuje jądro, gdzie ma szukać root=, i opcjonalnie ładuje początkowy ramdysk do pamięci initrdprzed uruchomieniem jądra.

Jądro następnie ładuje się, testuje sterowniki sprzętu i urządzeń i rozgląda się po systemie pod kątem tego, co widzi (możesz przejrzeć te informacje diagnostyczne, pisząc dmesg; obecnie prawdopodobnie przewija się zbyt szybko, aby je zobaczyć), a następnie próbuje zamontować partycję wymienioną w root=parametr.

Jeśli initrd jest obecny, najpierw jest montowany, a wszystkie moduły / sterowniki urządzeń są ładowane i sprawdzane przed zamontowaniem głównego systemu plików. W ten sposób możesz skompilować sterowniki dysków twardych jako moduły i nadal mieć możliwość rozruchu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.