Wie hängt ein Kernel die Root-Partition ein?

29

Meine Frage bezieht sich auf das Booten eines Linux-Systems von einer separaten / boot-Partition. Wenn sich die meisten Konfigurationsdateien auf einer separaten / Partition befinden, wie hängt der Kernel sie beim Booten korrekt ein?

Jede Ausarbeitung wäre toll. Ich habe das Gefühl, dass mir etwas Grundlegendes fehlt. Ich beschäftige mich hauptsächlich mit dem Ablauf und der Reihenfolge der Operationen.

Vielen Dank!

EDIT: Ich denke, was ich fragen musste, war mehr nach dem Vorbild der dev-Datei, die im root-Kernel-Parameter verwendet wird. Angenommen, ich gebe meinen root-Parameter als root = / dev / sda2 an. Wie hat der Kernel eine Zuordnung der Datei / dev / sda2?

Mr. Shickadance
quelle
Obwohl die unten genannten Personen initrd behandeln, gibt es kaum Diskussionen darüber, warum initrd verwendet wird. Mein Eindruck ist, dass Distributionen wie Debian einen Kernel auf vielen verschiedenen Maschinen mit derselben Architektur, aber möglicherweise sehr unterschiedlicher Hardware verwenden möchten. Möglich wird dies durch die Modularisierung der Hardware-Unterstützung über Kernel-Module. Die initrd benötigt zum Booten nicht viel Hardwareunterstützung und lädt anschließend die erforderlichen Hardwaremodule, um fortzufahren. Ausarbeitungen / Korrekturen hierzu sind erwünscht.
Faheem Mitha
Sie können / boot nicht mounten, ohne vorher / gemountet zu haben, da es kein / boot-Verzeichnis ohne / gibt.
Psusi

Antworten:

19

Linux bootet zunächst mit einer Ramdisk (genannt initrd, für "INITial RamDisk") als /. Auf dieser Festplatte befindet sich gerade genug, um die eigentliche Root-Partition (einschließlich aller erforderlichen Treiber- und Dateisystemmodule) zu finden. Es hängt die Root-Partition auf einem temporären Mount-Punkt auf dem ein initrdund ruft dann auf pivot_root(8), den Root- und den temporären Mount-Punkt auszutauschen, wobei die initrdzu umountbearbeitende Position und das eigentliche Root-Dateisystem erhalten bleiben /.

Geekosaurier
quelle
2
Was ist, wenn Sie keine initrd wie LFS (linuxfromscratch.org) haben?
Mr. Shickadance
@Herr. Shickadance: Nachdem ich nicht untersucht habe, wie LFS die Dinge macht, würde ich vermuten, dass sie sicherstellen, dass im Kernel alle erforderlichen Module kompiliert sind (oder über GRUB 2 geladen wurden, wobei diese Möglichkeit neu genug ist, dass es noch nicht viele Distributionen bemerkt haben) kann auf der eigentlichen Root-Partition starten.
Geekosaurier
4
@Herr. Shickadance. Es ist nicht nur LFS, das keine initrd hat. Jeder, der seinen eigenen Kernel kompiliert, hat die Möglichkeit, keine initrd zu verwenden, was ich auf Gentoo mache.
Jonescb
1
@Faheem: grub2-Module sind nicht dasselbe wie Kernel-Module. Ich sehe eine Möglichkeit für grub2, Kernelmodule zu laden, aber eine Sache, die ich nicht weiß, ist, ob das für den Linux-Kernel oder nur für * BSD funktioniert (wo der Bootloader, der Kernelmodule lädt, normal ist). Ich vermute, dem Kernel muss beigebracht werden, wo die Adresszuordnung für geladene Module zu finden ist, und jeder muss zu grub2 wechseln (grub1 ist in einigen Distributionen immer noch Standard).
Geekosaurier
1
Die initrd wurde durch initramfs ersetzt, da pivot_root als schmutziger Hack angesehen wurde.
Psusi
40

In der Antike war der Kernel schwer zu erkennen, ob es sich um eine Major / Minor-Nummer des Root-Dateisystems handelt, und er hat dieses Gerät gemountet, nachdem alle im Kernel integrierten Gerätetreiber initialisiert wurden. Das rdevDienstprogramm kann verwendet werden, um die Root-Gerätenummer im Kernel-Image zu ändern, ohne sie erneut kompilieren zu müssen.

Schließlich kamen Bootloader und konnten eine Befehlszeile an den Kernel übergeben. Wenn das root=Argument übergeben wurde, teilte dies dem Kernel mit, wo sich die Wurzel fs anstelle des eingebauten Werts befand. Die Treiber mussten auf das zugreifen, das noch in den Kernel eingebaut werden musste. Während das Argument wie ein normaler Geräteknoten im /devVerzeichnis aussieht , gibt es offensichtlich kein /devVerzeichnis, bevor das Root-Dateisystem eingehängt ist, so dass der Kernel dort keinen Dev-Knoten finden kann. Stattdessen sind bestimmte bekannte Gerätenamen fest im Kernel codiert, sodass die Zeichenfolge in die Gerätenummer übersetzt werden kann. Aus diesem Grund kann der Kernel Dinge wie /dev/sda1, aber keine exotischen Dinge wie /dev/mapper/vg0-rootoder eine Volume-UUID erkennen.

Später initrdkamen die ins Bild. Zusammen mit dem Kernel initrdlud der Bootloader das Image, das eine Art komprimiertes Dateisystem-Image war (gzipped ext2-Image, gzipped romfs-Image, squashfs wurde schließlich dominant). Der Kernel dekomprimierte dieses Image auf eine RAM-Disk und stellte die RAM-Disk als Root-Fs bereit. Dieses Image enthielt einige zusätzliche Treiber und Boot-Skripte anstelle eines echten init. Diese Boot-Skripte führten verschiedene Aufgaben aus, um Hardware zu erkennen, Dinge wie RAID-Arrays und LVM zu aktivieren, UUIDs zu erkennen und die Kernel-Befehlszeile zu analysieren, um den echten Root zu finden, der nun durch UUID, Datenträgerbezeichnung und andere erweiterte Dinge angegeben werden kann. Es hat dann die realen Root-Fs eingehängt /initrdund dann den pivot_rootSystemaufruf ausgeführt , um den Kernel zu tauschen /und/initrd, dann exec /sbin/initauf der realen Wurzel, die dann /initrddie Ramdisk aushängen und freigeben würde.

Endlich haben wir heute die initramfs. Dies ähnelt dem initrd, ist jedoch kein komprimiertes Dateisystem-Image, das auf eine Ramdisk geladen wird, sondern ein komprimiertes cpio-Archiv. Ein tmpfs wird als root gemountet und das Archiv dort extrahiert. Anstelle von using pivot_root, was als schmutziger Hack angesehen wurde, initramfsmounten die Boot-Skripte den realen Root /root, löschen alle Dateien im tmpfs-Root, dann chrootin /rootund exec /sbin/init.

Psusi
quelle
1
Werden die tmpfs nach der Chroot automatisch ausgehängt? Verschwindet es einfach?
Jiggunjer
@jiggunjer, nein, es ist immer noch da, es ist nur leer (abgesehen davon, dass es das / root-Verzeichnis enthält) und wird nicht mehr verwendet.
Psusi
Ich habe etwas Neues über jede von Ihnen erwähnte Iteration von Root-Fs gelernt. Gute Antwort!
Jpaugh
3

Klingt so, als würden Sie fragen, woher der Kernel weiß, welche Partition die Root-Partition ist, ohne auf Konfigurationsdateien unter / etc zuzugreifen.

Der Kernel kann wie jedes andere Programm Befehlszeilenargumente akzeptieren. GRUB oder die meisten anderen Bootloader können Befehlszeilenargumente als Benutzereingabe akzeptieren oder sie speichern und verschiedene Kombinationen von Befehlszeilenargumenten über ein Menü verfügbar machen. Der Bootloader übergibt die Befehlszeilenargumente beim Laden an den Kernel (ich kenne den Namen oder die Funktionsweise dieser Konvention nicht, aber es ähnelt wahrscheinlich der Art und Weise, wie eine Anwendung Befehlszeilenargumente von einem aufrufenden Prozess in einem laufenden Kernel empfängt).

Eine dieser Befehlszeilenoptionen ist root, wo Sie das Root-Dateisystem angeben können, dh root=/dev/sda1.

Wenn der Kernel eine initrd verwendet, ist der Bootloader dafür verantwortlich, dem Kernel mitzuteilen, wo er sich befindet, oder die initrd an einem Standardspeicherort abzulegen (glaube ich) - so funktioniert es zumindest auf meinem Guruplug.

Es ist durchaus möglich, dass Sie keine angeben und Ihre Kernel-Panik sofort nach dem Beginn der Beschwerde auftritt, dass kein Root-Dateisystem gefunden wird.

Es gibt möglicherweise andere Möglichkeiten, diese Option an den Kernel weiterzuleiten.

LawrenceC
quelle
3
Dies ist die richtige Erklärung, wenn es keine initrd / initramfs gibt, aber ein Teil des Puzzles fehlt. Normalerweise identifiziert der Kernel ein Gerät, /dev/sda1weil es ein Eintrag in einem Dateisystem ist. Sie könnten cp -p /dev/sda1 /tmp/foound /tmp/foowürden das gleiche Gerät darstellen. In der Kernel-Befehlszeile verwendet der Kernel einen eingebauten Parser, der der üblichen Gerätenamenskonvention folgt: bezeichnet sda1die erste Partition der ersten SCSI-ähnlichen Festplatte.
Gilles 'SO - hör auf böse zu sein'
@Gilles, damit moderne Kernel das Mounten eines Volumes basierend auf der UUID immer noch nicht bewältigen können? ohneinitrd oder initramfsich meine. Es muss eine "einfache" Partition in der /dev/sdxForm sein?
Jiggunjer
1
@jiggunjer Moderne Kernel unterstützen die Suche nach einem Volume über die UUID. Seheninit/do_mounts.c .
Gilles 'SO - hör auf böse zu sein'
1

Grub hängt die /bootPartition ein und führt dann den Kernel aus. In der Konfiguration von Grub wird dem Kernel mitgeteilt, was als Root-Gerät verwendet werden soll.

Zum Beispiel in Grub's menu.lst:

kernel /boot/linux root=/dev/sda2
jonescb
quelle
1

Komm schon, GRUB "mount" / boot nicht, es liest nur "menu.lst" und einige Module, es ist auch nicht Teil des Linux-Kernels. Wenn Sie den Kernel aufrufen, übergeben Sie mit der Root-Partition ein "root" -Argument. Im schlimmsten Fall weiß der Kernel, dass just / boot gemountet wurde (LOL).

Als nächstes: geekosaur hat recht, Linux verwendet eine erste RAM-Disk im komprimierten Image-Format und hängt dann das echte Root-Dateisystem durch Aufrufen ein pivot_root. Linux wird also von einem Image und dann von Ihrem lokalen Laufwerk gestartet.

D4RIO
quelle
1
Grub kann definitiv ein Dateisystem 'mounten', besonders in grub2. Natürlich ist alles, was es damit tun kann, die Suche nach bootfähigen Kerneln der einen oder anderen Art, aber das wird immer noch möglich. Auch Linux nicht benötigen eine initrd , wenn Ihr Kernel - Treiber von entscheidender Bedeutung für die Festplatte als Module kompiliert.
Shadur
5
ibm.com/developerworks/linux/library/l-linuxboot Dies ist eine ziemlich knappe Zusammenfassung dessen, was der Linux-Kernel beim Booten macht.
Jsbillings
2
@Shadur, aus der Mount- Manpage: Alle Dateien, auf die in einem Unix-System zugegriffen werden kann, sind in einem großen Baum angeordnet, der Dateihierarchie, die unter / verwurzelt ist. Diese Dateien können auf mehrere Geräte verteilt werden. Der Befehl mount dient dazu, das Dateisystem eines Geräts an den großen Dateibaum anzuhängen. - Da Dateisysteme von GRUB verwendet wird, nicht auf die Dateihierarchie gebunden sind, ist es nicht Montage .
D4RIO
1
@Shadur, BTW: Es ist offensichtlich, dass initrd nicht erforderlich ist, da es nur ein anderes Root-Dateisystem ist, aber es wird im Allgemeinen als kleines Root-System zum Booten verwendet, da der Kernel das Notwendige zum Booten lädt, dann bootet und schließlich alles andere lädt.
D4RIO
1
@ d4rio Sie werden von GRUB gemountet, nicht von Linux - es wird einfacher zu verstehen, wenn Sie grub als ein eigenes Mikrokernel-Betriebssystem betrachten, anstatt nur als einen Bootloader.
Shadur
1

Der Bootloader, sei es grub oder lilo oder was auch immer, teilt dem Kernel mit, wo er mit dem root=Flag suchen soll , und lädt optional eine erste RAM-Disk in den Speicher über, initrdbevor er den Kernel bootet.

Der Kernel lädt dann, testet seine Hardware und Gerätetreiber und durchsucht das System nach dem, was er sehen kann (Sie können diese Diagnoseinformationen durch Eingabe überprüfen dmesg; heutzutage scrollt er wahrscheinlich viel zu schnell, um es zu sehen), und versucht dann, die in angegebene Partition zu mounten der root=Parameter.

Wenn eine initrd vorhanden ist, wird diese zuerst gemountet und alle darauf befindlichen Module / Gerätetreiber werden geladen und geprüft, bevor das Root-Dateisystem gemountet wird. Auf diese Weise können Sie die Treiber für Ihre Festplatten als Module kompilieren und trotzdem booten.

Shadur
quelle