Die Bootreihenfolge des Linux-Betriebssystems. Linux-Boot-Phasen. Herunterfahren des Linux-Systems

Linux wird wie jedes andere Betriebssystem in mehreren Hauptphasen geladen: -> Dosystem-Boot -> Bootloader Linux-> Sekundärer Bootloader -> Laden des Benutzerbereichs ( DRIN).

Dieser Ansatz ist erforderlich, da das Betriebssystem eine logisch komplexe Struktur ist und es daher für einen Computer ziemlich schwierig ist, es zu laden. Aufgrund dieser Komplexität und Unverständlichkeit schien die Idee, den Boot-Prozess des Betriebssystems in elementarere Phasen zu unterteilen. Die erste Stufe ist die einfachste und leichteste für einen Computer, und die letzte ist die größte und schwierigste.

Ziehen Sie das Booten vor dem System in Betracht

Die Aufgabe vor dem Systemstart besteht darin, auszuwählen, wie der Kernel gebootet wird Betriebssystem .

Der Benutzer kann wählen, wie genau der Kernel geladen werden soll. Zur Auswahl ist ein spezielles Steuerungssystem erforderlich. Ein solches Kontrollsystem wird normalerweise als Lader... V Linux Die beliebtesten und am häufigsten verwendeten Bootloader sind der Bootloader LILO (Linux-Loader) und Bootloader GRUB (Grand Unified Bootloader)... Sie bieten dem Benutzer die Möglichkeit, einen vorkonfigurierten Boottyp auszuwählen. Beide Loader verfügen über Optionen für die Text- (Konsole) und die grafische Benutzeroberfläche. Die Haupt- und Kernaufgabe solcher Loader besteht darin, den Kernel und alles Notwendige für einen erfolgreichen Start des Systems in den Arbeitsspeicher des Computers zu laden.

In diesen Einstellungen können Sie den Standard-Linux-Boot auswählen, den Sie aufrufen können Systemdienstprogramm(ein kleines Spezialprogramm), schreiben vor, welche Programme beim Booten des Betriebssystems aktiviert werden sollen, und vieles mehr.

Auf so einfache Weise haben wir den "OS-Kernel-Loader" herausgefunden Linux«!

Linux wird normalerweise nach Windows platziert, damit GRUB überschrieben wird. Windows-Bootloader und beide Systeme beim Booten angezeigt. Standardmäßig steht Linux an erster Stelle, Windows endet am Ende. Jemand kann mit dieser Bestellung nicht zufrieden sein.. Es gibt noch einen weiteren wichtigen Parameter - die Wartezeit.

Normalerweise muss man 10 Sekunden warten, und erst dann wird das erste OS geladen. Dieser Parameter kann leicht geändert werden.

Alles, was Sie tun müssen, ist die Datei zu bearbeiten "Grub.cfg"... Sicherheitshalber arbeiten wir mit einer Kopie der Datei auf dem Desktop. Um die Änderungen zu speichern, muss die Datei als Administrator geöffnet werden - dazu verwenden wir die Konsole.

1 ... Wir gehen in den Ordner " booten / grub /"Und kopiere die Datei" grub.cfg" Auf dem Bildschirm. Dies kann über die Konsole oder über den Dateimanager erfolgen..


Wenn Sie die Konsole wählen, geben Sie den Befehl ein: " sudo cp /boot/grub/grub.cfg / home / kij / Desktop /» .


"Kij"- Dies ist der Benutzername, Sie haben ihn wahrscheinlich anders.

2 ... Öffne die Datei " grub.cfg"Auf dem Desktop in einem Texteditor. Wir tun dies über die Konsole: "s udo kate /home/kij/Desktop/grub.cfg»

« Kate" - Das Texteditor Linux Mint KDE 15. Wenn Sie eine andere Distribution haben, ist der Editor höchstwahrscheinlich anders, zum Beispiel „ gedit».

3. Achten Sie auf die Zeile „ Standard setzen = 0».

Jedes Element in GRUB ist nummeriert:

Linux - 0;

Linux ... Wiederherstellungsmodus - 1;

Gedächtnistest - 2;

Gedächtnistest (eine weitere Modifikation) - 3;

Windows 7 - 4.


Sie können es ein wenig anders haben. In meinem Fall sollte die Standardanzeige 4 sein, dann wird Windows standardmäßig gestartet.

4. Jetzt ändern wir den temporären Parameter. Wir suchen das Gleiche" grub.cfg"String" Timeout setzen = ...».


Wir belichten so viel wie nötig. Wenn der Computer von mehreren Benutzern verwendet wird, stellen Sie eine lange Zeitüberschreitung ein - 30 Sekunden.Wenn Sie ständig ein Betriebssystem laden, stellen Sie 2-3 Sekunden ein.

5. Wir speichern die Änderungen. Schließen Sie den Editor.

6. Kopieren Sie die Datei vom Desktop zurück in den Systemordner. Wir verwenden den Befehl „ sudo cp /home/kij/Desktop/grub.cfg / boot / grub /».


Das war's, jetzt starten wir den Computer neu, um sicherzustellen, dass die Parameter richtig eingestellt sind.

Der beste Weg, um zu verstehen, wie das Linux-Betriebssystem funktioniert, besteht darin, seine Bootstraps zu verfolgen. Beim Booten werden all jene Mechanismen gestartet, die das Betriebssystem in Gang setzen. Dieser Prozess ist komplex, mehrstufig und manchmal verwirrend. Es ist interessant, es zu studieren, und die Entdeckungen, die Sie dabei machen, können Sie sehr überraschen.

Im Allgemeinen kann das Booten einer Linux-Distribution in 5 Phasen unterteilt werden:

  1. Lader.
  2. Kernel-Start und -Initialisierung.
  3. Hardwareerkennung, Treiberdownload und Verbindung Dateisysteme.
  4. Starten von Systemdiensten (Daemons).
  5. Starten Sie eine grafische oder Konsolenbenutzersitzung.

Wir werden alle Phasen durchgehen und herausfinden, was beim Booten einer typischen Linux-Distribution passiert, die auf dem Weg leicht in Richtung BSD, macOS und Android abweicht. In vielen Fällen hilft Ihnen dies zu verstehen, warum der Linux-Boot-Prozess genau so ist, wie er ist.

1. Bootloader

Alles beginnt mit dem Bootloader, dem das BIOS beim Start der Maschine die Kontrolle übergibt. Früher, als Linux noch nicht so populär war, wurde LILO (Linux Loader) als Bootloader verwendet - er ist einfach, sehr primitiv und erlaubt Ihnen nicht, die Boot-Konfiguration im Handumdrehen zu ändern. Tatsächlich war die Konfigurationsdatei in den Bootloader selbst eingenäht und musste nach jeder Änderung der Einstellungen neu installiert werden: Ich habe den Kernel aktualisiert, die Neuinstallation vergessen, und Ihr Laptop bootet nicht mehr.

Heute ist Grub, ursprünglich für das Betriebssystem GNU/Hard entwickelt, für das Booten von Linux auf fast jeder Distribution verantwortlich. Grub ist viel komplexer als LILO und eigentlich selbst ein komplettes Betriebssystem. Es liest nicht nur die Boot-Konfiguration (normalerweise /boot/grub/grub.cfg) direkt von der Festplatte, sondern ermöglicht Ihnen auch, diese Konfiguration an Ort und Stelle zu reparieren. Grub hat eine eingebaute Kommandozeile, arbeitet mit einem Dutzend verschiedener Dateisysteme und ermöglicht die Bildung komplexer Bootketten.

Sobald der Benutzer den gewünschten Menüpunkt auswählt (oder nach Ablauf eines Timeouts), findet Grub das zu diesem Menüpunkt gehörende Bild Linux-Kernel auf der Festplatte (normalerweise die Datei /boot/vmlinuz) sowie das daran angehängte initramfs-Image (dazu später mehr), lädt sie in den Speicher und übergibt die Kontrolle an den Kernel.

Shift muss gehalten werden, um das Grub-Menü in Ubuntu zu sehen

2. Kernel und initramfs

Nachdem der Kernel die Kontrolle erhalten hat, beginnt er mit der Initialisierung: Das Speicherverwaltungs-Subsystem wird gestartet, der Interrupt-Handler wird konfiguriert und die notwendigen weitere Arbeit Kerndatenstruktur. Wenn diese Arbeit erledigt ist, entpackt der Kernel das initramfs-Archiv (normalerweise /boot/initramfs-linux.img und ist ein gzip-komprimiertes cpio-Archiv) in das Dateisystem unter Arbeitsspeicher(tmpfs), macht es zum Root-Dateisystem und führt das /init-Skript aus (der Name kann bei verschiedenen Distributionen unterschiedlich sein).

Initramfs enthält den grundlegenden Satz von Linux-Distributionskomponenten: Standardsystemverzeichnisse /bin, /lib, /etc usw., einen einfachen Befehlsinterpreter (normalerweise ash), einen Satz BusyBox-Befehle, mehrere Hilfsbibliotheken und einen Satz Kernelmodule (Treiber) für die Arbeit mit verschiedenen Laufwerken und Dateisystemen.

Linux-Boot-Phasen. Inhalt von initramfs.

Die Daseinsberechtigung von initramfs besteht darin, das Henne-Ei-Problem zu lösen: Laden Sie Treiber, um das echte Root-Dateisystem zu mounten, bevor es eingehängt wird. Genau das passiert, wenn das System das Skript /init ausführt. Es erkennt die im System installierten Laufwerke, lädt Treiber in den Kernel, um mit ihnen zu arbeiten, und verbindet dann die erforderliche Partition des erforderlichen Laufwerks (die der Kernel dank des beim Booten übergebenen Root-Parameters erfährt) mit dem Root, wodurch sich überlappen den Inhalt der initramfs. Dann startet das Skript /sbin/init, das den nächsten Schritt des OS-Bootens startet.

Linux laden. Init-Skript von initramfs.

3. Erstinitialisierung

Nachdem das Skript /init von initramfs seine Arbeit beendet hat, startet es das Dienstprogramm /sbin/init des realen Dateisystems. Ab diesem Moment beginnt die Initialisierung des Betriebssystems selbst: Laden der erforderlichen Treiber, Verbinden von Dateisystemen und Swap-Partitionen, Einstellen Netzwerk Schnittstellen und Starten von Systemdiensten.

Historisch gesehen war /sbin/init ein sehr einfaches Dienstprogramm, das nichts anderes tat, als die Kontrolle an bestimmte Skripte abhängig von den übergebenen Parametern zu übertragen (Skripte befanden sich in den Verzeichnissen /etc/rcX.d/, wobei X die Boot-Ebene ist). Jedes Skript war für eine streng definierte Operation verantwortlich: eines verband die in der Datei /etc/fstab aufgeführten Dateisysteme, ein anderes konfigurierte Netzwerkschnittstellen, ein anderes startete den Cron-Daemon (er startet periodische Aufgaben), ein anderer - der Syslog-Daemon (er ist verantwortlich für den Empfang von Protokollnachrichten und das Schreiben auf die Festplatte) und so weiter. Dieser Initialisierungsstil wird nach der UNIX-Version, in der er erschienen ist, SystemV genannt.

Der Vorteil des SystemV-Initialisierungsstils liegt in seiner extremen Einfachheit: Er ist leicht zu verstehen, leicht zu implementieren und leicht zu handhaben. Es entspricht jedoch absolut nicht den modernen Realitäten.

Heute ist das Laden eines Betriebssystems nicht darauf beschränkt, ein paar Treiber zu laden, zwei Dateisysteme zu verbinden, eine Netzwerkschnittstelle zu konfigurieren und drei Dienste zu starten. Eine Standardkonfiguration kann Dutzende verschiedener Daemons enthalten, deren Start lange dauern kann und der Daemon selbst abstürzen kann. SystemV startet Dienste sequentiell und kontrolliert ihren Lebenszyklus nicht, sodass das Laden langsam wird und ein korrekter Betrieb in der Zukunft nicht garantiert wird.

Um diese Probleme zu umgehen, haben die macOS-Entwickler eine Alternative zu /sbin/init namens launchd entwickelt. Das ist ohne Übertreibung eine geniale Entwicklung – launchd versteht es nicht nur, den Lebenszyklus von Diensten zu kontrollieren, sondern startet sie auch erst dann, wenn diese Dienste benötigt werden. Und das tut er auf ganz außergewöhnliche Weise.

Wir werden mehr darüber sprechen, wie dies geschieht. In der Geschichte mit launchd interessiert uns jetzt noch etwas anderes, nämlich dass unter seinem Eindruck sehr systemd geschaffen wurde. Systemd ist heute Bestandteil der meisten Linux-Distributionen. Es ist viel komplexer als /sbin/init und sogar launchd, und es gibt nicht einmal einen Hauch von Runleveln oder Skripten im Design. Systemd arbeitet mit dem Konzept einer Einheit, die einen Dienst, eine Mount-Operation, eine Operation zum Konfigurieren einer Netzwerkschnittstelle und andere imitieren kann.

Linux laden. Konfiguration der Tor-Daemon-Einheit.

Zur Beschreibung von Einheiten wird eine spezielle deklarative Sprache verwendet, daher ist es schwieriger, einen Konfigurationsfehler zu machen als beim Schreiben eines Skripts. Einheiten können Abhängigkeiten voneinander haben und parallel oder bei Bedarf laufen. Zum Beispiel Dienste (Daemons), die nicht von Netzwerkverbindung, können vor den Einstellungen der Netzwerkschnittstelle gestartet werden, andere - sofort nach deren Konfiguration, wieder andere - erst, wenn Anwendungen oder andere Dienste darauf zugreifen.

4. Dämonen starten

Das Starten von Diensten (Daemons) ist einer der Schlüsselpunkte beim Booten von Linux. Einen besonderen Platz nimmt hier der udev-Daemon ein, ohne den eine typische Linux-Distribution nicht lauffähig ist.

Udev verwaltet den Inhalt des Verzeichnisses /dev. Wie wir alle wissen, wird dieses Verzeichnis in Linux-Systemen verwendet, um sogenannte Gerätedateien zu speichern - eine spezielle Art von Dateien, die bestimmte Komponenten eines PCs verkörpern. Mit Hilfe von Gerätedateien in Linux arbeiten Sie mit dem Gerät: Sie lesen die Datei /dev/sda1 und erhalten den Inhalt des ersten Abschnitts des ersten Festplatte, Daten nach /dev/fb0 schreiben und das Bild auf dem Bildschirm anzeigen.

In frühen UNIX war /dev statisch. Es enthielt eine Reihe von Dateien für alle Fälle: auch wenn der PC nicht installiert war Soundkarte, die Datei /dev/dsp für die Audioausgabe existierte noch. Als die Anzahl der verschiedenen Geräte gering war und Plug'n'Play noch nicht geboren war, gab es keine Probleme: nur ein Dutzend oder zwei Dateien. Aber im Laufe der Zeit wurde es immer mehr vermüllt und verwandelte sich schließlich in einen Müllhaufen.

Die erste Lösung für dieses Problem bestand darin, ein virtuelles Dateisystem (devfs) an /dev anzuhängen, dessen Inhalt vom Kernel kontrolliert würde. Es fand alle installierte Hardware und erstellte nur Dateien für die Geräte, die tatsächlich in der Maschine vorhanden sind.

Diese Lösung wird noch in macOS und FreeBSD verwendet, aber die Linux-Entwickler gingen einen anderen Weg. An das Verzeichnis /sys ist ein spezielles sysfs-Dateisystem angehängt. Es ist so etwas wie eine detaillierte Datenbank aller PC-Geräte, vom Prozessor über den Interrupt-Controller bis hin zu Mäusen und Gamepads.

Linux laden. Mit /sys können Sie nicht nur Informationen zu Geräten abrufen, sondern diese auch verwalten.

Mit /sys können Sie nicht nur Informationen zu Geräten abrufen, sondern diese auch verwalten.

Basierend auf den von /sys abgerufenen Informationen erstellt der udev-Daemon Gerätedateien in /dev. Beim ersten Start durchläuft es alle Geräte in /sys, schläft dann ein und wartet, bis ein Gerät hinzugefügt oder entfernt wird: USB-Stick eingesteckt - neue Dateien sind in /sys aufgetaucht, udev ist aufgewacht und hat eine Gerätedatei erstellt basierend darauf in /dev, indem Sie die erforderlichen Treiber herunterladen.

Ein weiterer wichtiger Daemon für UNIX-Systeme ist syslog. Es ist eine Art Aggregator von Anwendungsprotokollen, die alle im Verzeichnis /var/logs ablegen. In auf systemd basierenden Distributionen wird stattdessen normalerweise systemd-journald verwendet, das Protokolle in einem speziellen Binärformat speichert (syslog arbeitet mit Text). Neue Einträge können hinzugefügt, aber nicht gelöscht werden. Dies ist ein Schutz gegen Hacker, die die notwendigen Zeilen aus Dateien löschen könnten, um ihre Spuren im System zu verbergen.

Die durchschnittliche Linux-Distribution hat auch andere Daemons:

  • cron- ist für die termingerechte Erledigung der Aufgaben verantwortlich. Kann Befehle in bestimmten Intervallen oder klar ausführen Zeit einstellen... Der einfachste Anwendungsfall besteht darin, nachts ein Backup zu erstellen;
  • Tassen- Dämon drucken. Verfolgt die Warteschlange der zum Drucken gesendeten Dokumente und gibt sie an den Drucker weiter;
  • systemd-login- verwaltet Benutzersitzungen, ermöglicht Ihnen das schnelle Wechseln zwischen Sitzungen, erteilt die Erlaubnis, Geräte im Namen des Benutzers zu automatisieren und führt andere Aufgaben aus;
  • dbus- ein Daemon, der den Datenbus verwaltet und es Anwendungen ermöglicht, Informationen auszutauschen. Wird hauptsächlich in Desktop-Umgebungen und Grafikanwendungen verwendet;
  • Netzwerk Manager- Konfigurator von Netzwerkschnittstellen. Es wird nur in Desktop-Distributionen verwendet und kann durch ein analoges ersetzt werden. Zum Beispiel wic.

Die meisten Daemons kommunizieren mit Anwendungen und anderen Daemons über UNIX-Sockets. Dies ist der der Datei zugeordnete Kommunikationskanal. Zum Beispiel erstellt der cups-Daemon den Socket /var/run/cups/cups.sock (der Speicherort kann von Distribution zu Distribution variieren). Indem Sie Daten darauf schreiben, können Sie Dokumente zum Drucken senden.

Es ist diese Funktion, die launchd und systemd verwenden, um Daemons nur bei Bedarf zu starten. Der Trick besteht darin, Sockets für alle System-Daemons vorab zu erstellen und Daemons selbst nur dann zu starten, wenn jemand Daten in den Socket schreibt; Es macht keinen Sinn, Cups beim Booten oder zu einem anderen Zeitpunkt auszuführen, wenn niemand Druckaufträge sendet.

5.X Window-System und PAM

Der letzte Ladeschritt ist das Starten des Login-Managers. In der Konsole wird die Login-Manager-Funktion von einer Reihe von getty-Dienstprogrammen ausgeführt (normalerweise wird die fortgeschrittenere Agetty-Version verwendet) und die Anmeldung. Getty ist ein Rudiment aus der Zeit der Mainframes und Remote Terminals (der Name steht für get teletype). Es gibt an das Terminal aus Textnachricht und führt dann das Anmeldedienstprogramm aus, das nach Benutzername und Kennwort fragt. Wenn der Benutzer das richtige Passwort eingibt, startet login die in der Datei /etc/passwd angegebene Shell in seinem Namen.

Der grafische Login-Manager wird als Display-Manager bezeichnet und ist für jede grafische Umgebung unterschiedlich. KDE verwendet den KDM-Manager, GNOME verwendet GDM, und es ist auch möglich, einen universellen Display-Manager wie Slim zu verwenden. In jedem Fall besteht die Aufgabe des Display-Managers darin, ein Fenster anzuzeigen, das nach Benutzername und Passwort fragt, und nach der Autorisierung den Window-Manager entweder direkt zu starten oder eine Reihe von Befehlen auszuführen, die in die Datei ~ / .xinitrc des Benutzers geschrieben wurden.

Linux-Boot-Phasen. Der KDM-Anzeigemanager in Debian.

Gleichzeitig mit dem Start des Display-Managers wird das grafische X Window System gestartet und in modernen Distributionen Xorg. Es ist ein Client-Server-System zur Darstellung von Grafiken auf dem Bildschirm, wobei der Server dafür verantwortlich ist, das von verschiedenen Client-Anwendungen erzeugte Gesamtbild zu arrangieren. Das X Window System ist keine grafische Umgebung, sondern nur eine Ebene, die es Anwendungen ermöglicht, ein Bild an den Bildschirm zu senden und Eingabeereignisse vom Benutzer zu empfangen. Um eine darauf basierende grafische Oberfläche zu erstellen, benötigen Sie außerdem einen Fenstermanager, mit dem der Benutzer die Anwendungsfenster verwalten kann.

Der Windowmanager kann sowohl separat (zB Fluxbox, Window Maker, i3) als auch als Teil einer integrierten Desktop-Umgebung (KDE, GNOME, XFCE) arbeiten. Neben dem Fenstermanager enthalten sie auch eine Reihe von Tools zum Erstellen eines vollwertigen Desktops: eine Taskleiste am unteren oder oberen Bildschirmrand, ein Dock, ein System zum Anordnen von Symbolen auf dem Desktop und mehr. Normalerweise wird jedes dieser Elemente von einer oder mehreren dedizierten Anwendungen gesteuert.

Unabhängig davon, welche Anmeldemethode ein Benutzer verwendet, ist PAM immer für die Zugangskontrolle verantwortlich. Es ist ein modulares Benutzerauthentifizierungssystem, das ihre Identität am meisten überprüfen kann verschiedene Wege, unterwegs eine Reihe von Kontrollen durch. Standardmäßig verwendet PAM nur die Kennwortauthentifizierung, aber durch Ändern der Konfigurationsdateien /etc/pam.d kann die Reihenfolge der Authentifizierung geändert werden, indem Sie beispielsweise Ihren Finger auf den Fingerabdruckscanner legen müssen, fügen Sie a speziellen USB-Stick und sogar die Bestätigung mit einem Smartphone. Wie das geht, haben wir bereits geschrieben.

Linux laden. PAM-Konfigurationsdatei für das Login-Dienstprogramm

Damit ist der Downloadvorgang abgeschlossen. Entweder melden Sie sich an der Konsole an und sehen eine Shell-Eingabeaufforderung oder Sie geben Ihre Kontoinformationen in das Display-Manager-Fenster ein und der Desktop erscheint als Ergebnis.

Statt Schlussfolgerung

So sieht das Laden einer modernen Linux-Distribution aus. Ich habe einige nicht sehr wichtige und nicht sehr interessante Details ausgelassen, aber ich habe versucht, das Wichtigste zu erzählen. Wenn man darüber nachdenkt, ist dies kein so komplizierter Prozess, tatsächlich ist das Betriebssystem bereits in der initramfs-Verbindungsphase bereit, Benutzerbefehle zu akzeptieren, alles andere ist das Starten der Umgebung, die für den vollwertigen Benutzer erforderlich ist arbeiten.

Linux ist ein komplexes Betriebssystem, und das Verfahren zum Ein- und Ausschalten ist mehr als nur das Drücken des Netzschalters. Führen Sie daher die Start- und Stoppvorgänge in Übereinstimmung mit allen Regeln aus, damit das System ordnungsgemäß funktioniert.

Obwohl der Prozess des Bootens eines Systems schon immer recht komplex war, war es noch etwas einfacher, als die Hersteller buchstäblich jeden Aspekt der Hardware definierten und Software... Da Linux nun die Hardware von Personal Computern (PCs) kontrolliert, muss der Bootvorgang den Regeln des PCs folgen. Es gibt viele mögliche Konfigurationen, mit denen man umgehen muss.

Unter Linux-Bootstrap ist verstanden Systemstart beim Einschalten... Da die üblichen Tools des Betriebssystems auf diese Phase noch nicht verfügbar sind, muss sich das System im wahrsten Sinne des Wortes "selbst bedienen". Während dieses Vorgangs wird der Systemkernel in den Speicher geladen und aktiviert. Anschließend wird eine Reihe von Initialisierungsaufgaben ausgeführt, wonach das System bereit ist, Benutzern zu dienen.

Bootstrapping ist eine Phase besonderer Anfälligkeit für das System. Fehler in Konfigurationsdateien, Fehlfunktionen oder das Fehlen der erforderlichen Geräte, Schäden an Dateisystemen können den normalen Start des Computers verhindern. Die Konfiguration von Boot-Modi ist oft eine der ersten Aufgaben, die ein Administrator lösen muss neues System... Leider ist diese Aufgabe eine der schwierigsten und erfordert gute Linux-Kenntnisse, um sie zu lösen.

Beim Einschalten wird der im ROM gespeicherte Bootcode ausgeführt. Es sollte den Kernel starten. Der Kernel fragt den Zustand der Hardwaregeräte ab und startet dann den Init-Daemon, dessen ID immer 1 ist.

Es gibt eine Reihe von Dingen, die passieren müssen, bevor die Registrierungsaufforderung auf dem Bildschirm angezeigt wird. Dateisysteme müssen überprüft und gemountet werden, und System-Daemons müssen ausgeführt werden. Diese Prozeduren werden mithilfe von Shell-Skripten implementiert, die sequentiell vom init-Daemon aufgerufen werden. Diese Skripte werden oft als rc-Dateien bezeichnet, da ihnen das Präfix „rc“ vorangestellt ist. Es steht für „Run Command“ und ist ein Überbleibsel des CTSS-Betriebssystems um 1965. Der genaue Aufbau der Skripte und deren Ausführung ist systemabhängig.

Automatisches und manuelles Laden

Linux-Systeme können automatisch oder manuell booten. Im ersten Fall startet das System von selbst, ohne jegliche Einmischung von außen. Im zweiten Fall geschieht alles bis zu einem bestimmten Zeitpunkt ebenfalls automatisch und vor der Ausführung der wichtigsten Initialisierungsskripte wird die Kontrolle an den Operator (die Person, die am Terminal sitzt) übergeben. An dieser Stelle tritt das System in den sogenannten "Einzelbenutzermodus" ein. Die meisten Systemprozesse wurden noch nicht ausgeführt und andere Benutzer können sich nicht am System anmelden.

Im Arbeitsalltag kommt fast immer die automatische Beladung zum Einsatz. Ein typischer Bootvorgang auf einem modernen Computer sieht so aus: Der Benutzer schaltet den Strom ein und wartet (wartet, wartet, wartet ...), bis das System in den interaktiven Modus geht. Der Systemadministrator muss jedoch nicht nur die Funktionsweise eines automatischen Bootens verstehen, sondern auch wissen, wie das System manuell gebootet wird. Der letzte Ausweg muss gewählt werden, wenn Probleme auftreten, die automatische Downloads unmöglich machen. Dies kann beispielsweise durch ein beschädigtes Dateisystem oder Fehler in der Konfiguration der Netzwerkkarte verursacht werden.

Ladeschritte

Typischer Bootvorgang Linux-Systeme besteht aus sechs Stufen:

  • Erkennung und Konfiguration von Geräten;
  • Erstellen von Kernelprozessen;
  • Bedienhandlungen (nur bei manueller Beladung)
  • Ausführung von Startskripten;
  • im Mehrspielermodus arbeiten.
  • Fast alle Phasen erfordern keine Administratorkontrolle. Sie können steuern, wie das System bootet, indem Sie Startskripts bearbeiten.

    Kernel-Initialisierung

    Der Linux-Kernel ist ein Programm, und der erste Schritt beim Bootstrapping besteht darin, dieses Programm zur späteren Ausführung in den Speicher zu schreiben. Die Kernel-Datei heißt normalerweise /vmlinuz oder /boot/vmlinuz.

    Unter Linux ist das Laden des Kernels ein zweistufiger Prozess. Zuerst wird ein kleines Bootstrap-Programm von der Festplatte in den Speicher des Computers eingelesen (mithilfe von im ROM geschriebenem Code), das dann tatsächlich den Kernel lädt.

    Der Kernel führt Tests durch, um festzustellen, wie viel Speicher dem System zur Verfügung steht. Einige der internen Strukturen des Kernels haben eine feste Größe, sodass der Kernel eine gewisse Menge an physischem Speicher für sich reserviert. Dieser Speicher steht Benutzerprozessen nicht zur Verfügung. Der Kernel gibt an die Konsole eine Nachricht über die Gesamtmenge des physischen Speichers und die dem Benutzer zur Verfügung stehende Speichermenge aus.

    Hardware konfigurieren

    Eine der ersten Aufgaben des Kernels besteht darin, Komponenten zu identifizieren Hardware-... Den Kern bauen für spezifisches System, können Sie angeben, welche Geräte überprüft werden sollen. Bei Aktivierung versucht der Kernel, alle ihm gemeldeten Geräte zu finden und zu initialisieren. Der Kernel gibt eine Zusammenfassung jedes erkannten Geräts an die Konsole aus. Moderne Distributionen enthalten einen Kernel, der auf den meisten Computerhardwarekonfigurationen ausgeführt werden kann, während er minimale Einstellung oder sogar ganz ohne.

    Die beim Konfigurieren des Kernels bereitgestellten Geräteinformationen sind oft unvollständig. In einer solchen Situation versucht der Kernel, die erforderlichen Informationen zu erhalten, indem er die an den Systembus angeschlossenen Geräte abfragt und die erforderlichen Informationen von den entsprechenden Treibern sammelt. Treiber für Geräte, die fehlen oder nicht auf den Pilotton reagieren, werden deaktiviert. Wenn das Gerät später mit dem System verbunden wird, können Sie seinen Treiber dynamisch laden oder aktivieren.

    Kernel-Prozesse

    Nach Abschluss der grundlegenden Initialisierungsphase erstellt der Kernel mehrere „selbstausführende“ Prozesse in dem für Benutzerprogramme reservierten Speicher. Dadurch wird der Standard-Fork-Systemaufruf umgangen.

    Die Anzahl und Art dieser Prozesse hängt vom Betriebssystem ab. Unter Linux sind dies der Init-Daemon (immer 1; es gibt keinen Prozess mit 0) und verschiedene Kernel-Speicher- und Signalhandler, einschließlich der in Tabelle aufgeführten. 1. Alle diese Prozesse haben Bezeichner mit niedrigen Nummern, und ihre Namen in ps-Listen sind in eckige Klammern eingeschlossen (z. B.). Manchmal können Prozessnamen einen Schrägstrich und eine Zahl am Ende enthalten, z. Die Nummer gibt den Prozessor an, auf dem dieser Prozess ausgeführt wird. Diese Informationen können beim Einrichten eines Multiprozessorsystems hilfreich sein.

    Tabelle 1. Einige der gängigsten Linux-Kernel-Prozesse

    Von diesen Prozessen ist nur init ein vollwertiger Benutzerprozess; der Rest sind eigentlich Teile des Kernels, die konzeptionell von Prozessen erstellt wurden.

    Nachdem die aufgelisteten Prozesse erstellt wurden, nimmt der Kernel nicht mehr am Systemstartvorgang teil. Zu diesem Zeitpunkt ist jedoch noch keiner der Prozesse erstellt, die grundlegende Operationen (wie das Anmelden von Benutzern auf dem System) durchführen, und die meisten Daemons laufen nicht. All dies wird (in einigen Fällen indirekt) vom init-Daemon erledigt.

    Bedieneraktion (nur manuelles Laden)

    Soll das System im Single-User-Modus gestartet werden, setzt der Operator in Befehlszeile ein spezielles Flag (das Wort „single“), und der Kernel übergibt diese Informationen an den init-Daemon. Letzterer wiederum übergibt die Kontrolle an den sulogin-Befehl, eine spezielle Version des Login-Befehls, der nach dem Root-Passwort fragt. Bei korrekter Eingabe wird der Befehlsinterpreter mit Superuser-Rechten gestartet. Sie können kein Passwort festlegen, sondern drücken Sie einfach< Ctrl+D >, danach wird der Download im Mehrspielermodus fortgesetzt.

    Im Einzelbenutzermodus werden Befehle ähnlich wie auf einem vollständig geladenen System ausgeführt. Allerdings mounten SUSE, Debian und Ubuntu normalerweise nur die Root-Partition. Um Programme außerhalb der Verzeichnisse /bin, /sbin oder /etc zu verwenden, müssen Sie die verbleibenden Dateisysteme manuell einhängen.

    In vielen Einzelbenutzerumgebungen ist das Stammverzeichnis des Dateisystems schreibgeschützt eingehängt. Wenn /tmp Teil des Root-Dateisystems ist, schlagen viele Befehle fehl, die temporäre Dateien (wie vi) verwenden. Um aus dieser Situation herauszukommen, müssen Sie eine Einzelbenutzersitzung starten, indem Sie das Verzeichnis / im Lese-/Schreibmodus erneut einhängen. Die erforderliche Aktion wird durch den Befehl ausgeführt:

    # mount -o rw, neu mounten /

    Auf Red Hat- und Fedora-Systemen ist das Booten im Einzelbenutzermodus etwas aktiver als üblich. Bis eine Eingabeaufforderung angezeigt wird, versuchen diese Distributionen, alle lokalen Dateisysteme zu mounten. Dies mag auf den ersten Blick bequem erscheinen, kann jedoch bei Verwendung mit einem unterentwickelten Dateisystem problematisch sein.

    Der Befehl fsck, der beschädigte Dateisysteme überprüft und repariert, wird normalerweise während automatischer Download... Wird das System im Einzelbenutzermodus gestartet, muss der Befehl fsck manuell eingegeben werden.

    Wenn der Befehlsinterpreter für den Einzelbenutzermodus beendet wird, fährt das System mit dem Booten im Mehrbenutzermodus fort.

    Ausführen von Systemstartskripten

    Sobald das System Startskripte ausführen kann, kann es bereits Linux heißen. Es ist noch kein vollständig geladenes System, aber es gibt keine „mysteriösen“ Schritte mehr beim Bootvorgang. Skriptdateien sind gewöhnliche Batchdateien, die vom init-Daemon in einem komplexen, aber allgemein verständlichen Algorithmus ausgewählt und ausgeführt werden.

    Die genaue Position, der Inhalt und die Organisation der Startup-Skripte verdienen eine separate Studie.

    Arbeiten im Mehrspielermodus

    Nachdem die Startup-Skripte ausgeführt wurden, ist das System voll funktionsfähig, mit einer Ausnahme: Niemand kann es eingeben. Damit sich ein bestimmtes Terminal (einschließlich der Systemkonsole) beim System anmelden kann, muss ein getty-Prozess ausgeführt werden, der auf Anfragen von diesem Terminal wartet. Der Init-Daemon erzeugt alle notwendigen Getty-Prozesse und beendet die Bootstrap-Phase. Wenn das System für die Ausführung im grafischen Modus konfiguriert ist, erzeugt der Init-Daemon auch die entsprechenden Registrierungsprozesse wie xdm oder gdm.

    Beachten Sie, dass der Init-Daemon auch nach Abschluss des Bootvorgangs eine wichtige Rolle spielt. Es verfügt über einen Einzelbenutzer- und mehrere Mehrbenutzer-Runlevel, die bestimmen, welche Systemressourcen dem Benutzer zur Verfügung stehen.

    Linux auf einem PC booten

    Bisher wurde das allgemeine Bootstrap-Schema beschrieben. Nun müssen einige der wichtigsten (und komplexesten) Phasen genauer betrachtet werden, nachdem zusätzliche Merkmale der Funktionsweise von Personalcomputern analysiert wurden.

    Booten des Systems auf persönlicher Computer ist ein mehrstufiger Prozess. Wenn der Computer eingeschaltet wird, wird der in das ROM geschriebene Code ausgeführt. Seine genaue Lage und Struktur hängen von der Art der Ausrüstung ab. In Computern, die speziell für UNIX oder andere kommerzielle Betriebssysteme entwickelt wurden, wird der Code von einem Entwickler „geflasht“, der den Algorithmus für die Verbindung von Geräten, die grundlegende Netzwerkinitialisierung und die Erkennung lokaler Dateisysteme voreinstellt. Es ist sehr praktisch für Systemadministrator... Er muss nur den Namen der neuen Kernel-Datei eingeben, und der ROM-Code erkennt und liest diese Datei automatisch.

    Auf Personalcomputern wird der Bootcode in Form eines grundlegenden Eingabe-Ausgabe-Subsystems - BIOS (Basic Input / Output System) - dargestellt, das im Vergleich zum proprietären Code von UNIX-Stationen extrem vereinfacht ist. In Wirklichkeit gibt es im BIOS mehrere Codeebenen: für den Computer selbst, für die Grafikkarte, für den SCSI-Adapter, falls vorhanden, und manchmal für andere Peripheriegeräte wie Netzwerkkarten.

    Das eingebettete BIOS kennt Geräte, die sich auf Hauptplatine IDE-Controller (und Festplatten), Netzwerkadapterkarte, Tastatur-Controller, serielle und parallele Anschlüsse. SCSI-Adapter kennen nur Geräte, die direkt an sie angeschlossen sind. Glücklicherweise wurden in den letzten Jahren die komplexen Interaktionen, die für das Zusammenwirken dieser Geräte erforderlich sind, standardisiert und erfordern nun fast keinen Bedienereingriff.

    In modernen Computern ist der BIOS-Code intelligenter als früher. Sie ermöglichen es Ihnen, während der Bootphase in den Konfigurationsmodus zu gelangen, indem Sie eine oder zwei Tasten gedrückt halten. In den meisten Fällen werden die Namen dieser Tasten auf dem Bildschirm angezeigt, sodass Sie nicht in der Dokumentation danach suchen müssen.

    Im Konfigurationsmodus können Sie wählen, von welchem ​​Gerät Sie booten möchten, wobei die Auswahl nicht so groß ist. Typischerweise wird in der Regel die Bootreihenfolge vorgegeben, zum Beispiel: „Zuerst - Diskettenlaufwerk, dann - CD-ROM-Laufwerk, zu guter Letzt - Festplatte“. Leider ist das Booten in einigen BIOSs darauf beschränkt, vom ersten IDE-CD-ROM-Laufwerk oder der ersten Festplatte booten zu können. IDE-Laufwerk... SCSI-Adapter werden ebenfalls erkannt.

    Wenn der Computer bestimmt hat, von welchem ​​Gerät gebootet werden soll, werden die ersten 512 Bytes von der Festplatte gelesen. Dieses Segment der Scheibe wird als Hauptsegment bezeichnet Boot-Record(GZZ). Es speichert ein Programm, das dem Computer mitteilt, welche Partition der Festplatte das sekundäre Bootprogramm (Betriebssystemlader) enthält.

    Das im GZZ befindliche Standardprogramm weist den Computer an, den OS-Bootloader von der ersten Partition der Festplatte zu extrahieren. Linux unterstützt komplexere Programme, die mit mehreren Betriebssystemen und Kerneln arbeiten können.

    Nachdem die Partition gefunden wurde, von der das System booten soll, versucht das GZZ-Programm zu starten Bootprogramm mit diesem Abschnitt verlinkt. Bei Erfolg wird diesem Programm die Berechtigung zum weiteren Laden des Kernels übertragen.

    Das Laden eines Betriebssystems ist ein mehrstufiger Prozess. In verschiedenen Linux-Distributionen Der Ladevorgang kann etwas variieren, aber das allgemeine Schema ist ungefähr gleich und besteht aus den folgenden Phasen:

      Beim Start überträgt der Prozessor die Steuerung an eine spezifische physikalische Adresse im ROM. An diesem Punkt beginnt die Ausführung des BIOS / UEFI-Codes. Die Hardware wird initialisiert und das bootfähige Medium wird ausgewählt. Beim BIOS wird der Bootloader in den RAM eingelesen und die Kontrolle dorthin übertragen. Ein Bootloader belegt normalerweise einen Sektor auf der Festplatte (MBR) und ist auf 384 Byte beschränkt (512 Byte ist ein Festplattensektor, minus 128 Byte ist eine Partitionstabelle). Abhängig vom Typ des Bootgeräts Bootsektor kann an verschiedenen Stellen gelesen werden:

      • Beim Booten von einer Diskette oder Festplatte wird der Loader aus dem ersten Sektor des physischen Mediums gelesen;
      • Beim Booten von CD / DVD - vom ersten Sektor des Images Boot-Diskette befindet sich in der CD-Datenstruktur;
      • Beim Netzwerk-Boot - vom ersten Sektor des Boot-Disk-Image, das vom Server mit dem tftp-Protokoll heruntergeladen wurde.

      Beim Formatieren einer Diskette im MBR wird anstelle eines Bootloaders manchmal ein Programm geschrieben, das auf den Bildschirm den Informationstext "Kein bootfähiges Gerät - Bootdiskette einlegen und beliebige Taste drücken" schreibt.

    1.1 Der Bootloader liest den Hauptlader (GRUB, LiLo, NTLDR) in den Speicher und übergibt ihm die Kontrolle. Da der Bootloader sehr klein ist, sind in seinem Code in der Regel Sektoren hartcodiert, aus denen der Code des Hauptbootloaders gelesen werden muss. Auf der HDD kann dies der Platz zwischen dem MBR und der ersten Partition auf der Platte (Spur Null) oder der reservierte Platz innerhalb des Dateisystems (Inode reserviert in ext2fs) sein. Auf einer Diskette und bei Verwendung eines Disk-Image beim Booten von einer CD oder über ein Netzwerk - der Hauptlader kann sich direkt nach dem Primärlader befinden und das gesamte Volumen des Images einnehmen.

    Beim Booten über UEFI wird der Bootloader komplett aus einer Datei auf einem speziellen Abschnitt gelesen.

      Boot-Kernel (vmlinuz) und zusätzliches Disk-Image (initrd, initramfs). GRUB-Bootloader ist ein Mini-Betriebssystem, das alle gängigen Dateisysteme unterstützt. GRUB sucht nach einer Konfigurationsdatei, die die Pfade zum Kernel-Image und zum sekundären Disk-Image enthält. Bei Bedarf wird das Kernel-Image ins RAM entpackt, es wird ein Speicherbereich gebildet, der die vom Bootloader an den Kernel übergebenen Parameter enthält, einschließlich der Adresse des Auxiliary-Disk-Image.

      Über GRUB bootfähiger Kernel muss den Multiboot- oder Multiboot2-Konventionen entsprechen. Konventionell enthält das Kernel-Image eine Struktur (zB in einem Datenabschnitt), die mit einer magischen Zahl beginnt und Informationen über die gewünschte Position des Kernels im Speicher und den Punkt enthält, an den die Kontrolle übertragen werden soll. Bevor die Kontrolle an den Kernel übergeben wird, wird eine weitere magische Zahl in das EAX-Register gestellt und die Adresse der Tabelle mit den vom Loader vorbereiteten Parametern in das EBX-Register.

      Die Auxiliary-Disk ist aufgrund der Modularität des Kernels für moderne Linux-Systeme notwendig und enthält die Treiber (ATA, NFS, RAID etc.), die für den Zugriff auf das Hauptdateisystem erforderlich sind. Innerhalb des Images befindet sich ein Dateisystem im cpio-Archivformat.

      An dieser Stelle wird ein Prozess mit pid = 1 erstellt, in dem das init-Skript, das sich im Root-Verzeichnis der sekundären Platte befindet, ausgeführt wird. Die an den Kernel übergebenen Parameter werden tatsächlich als Befehlszeilenargumente an init übergeben.

      Das Skript enthält Befehle zum Laden der erforderlichen Treiber in Form von Kernelmodulen, zum Erstellen temporärer Gerätedateien im Verzeichnis /dev für den Zugriff auf diese Module, zum Scannen von Festplattenpartitionen, um RAIDs und logische Volumes zu erkennen und zu initialisieren. Nachdem die logischen Laufwerke initialisiert wurden, wird versucht, das durch den Parameter root = angegebene Root-Dateisystem zu mounten. Im Fall von diskless Netzwerkstart das Root-Verzeichnis ist über NFS verbunden.

      Auf dem Bildschirm werden Meldungen zum Laden von Treibern und zum Suchen nach virtuellen Volumes des LVM-Subsystems angezeigt. Die Phase endet mit dem erneuten Einhängen des Root-Verzeichnisses in das Hauptdateisystem und dem Laden des Hauptprogramms / sbin / init (oder seines Analogons) in den Prozess mit pid = 1.

      Auf klassischem UNIX und älter Linux-Versionen(bis etwa 2012) init liest die Konfigurationsdatei /etc/inittab, initialisiert Textkonsolen und startet normalerweise die erforderlichen Dienste mit einer Reihe von Skripten, die sich in den Verzeichnissen /etc/init.d und /etc/rc*.d befinden. Auf modernen Linux-Distributionen enthält die Datei /sbin/init ein moderneres Dienststartprogramm. Das beliebteste dieser Programme ist systemd, das die Zeit dieser Bootphase erheblich verkürzen kann.

    In dieser Phase werden auf dem Bildschirm Zeilen angezeigt, die über den Start von Diensten und den Erfolg dieses Vorgangs (oder) informieren.

    GRUB-Bootloader

    Booten Sie von der Installationsdiskette in den Rettungsmodus. Um dies zu tun, müssen Sie beim Booten an der boot:-Eingabeaufforderung linux rescue eingeben

    Wenn alles gut geht, wird das Root-Verzeichnis des Hauptsystems unter /mnt/sysimage gemountet, das Boot-Verzeichnis unter /mnt/sysimage/boot. Außerdem werden die aktuellen Verzeichnisse /proc, /sys und /dev in die entsprechenden Unterverzeichnisse /mnt/sysimage eingehängt. Wenn dies nicht der Fall ist, müssen Sie diese Vorgänge manuell ausführen.

    Wenn alle Verzeichnisse gemountet sind, können Sie das Stammverzeichnis ändern

    # Wenn sich herausstellt, dass Sie vergessen haben, etwas zu mounten, können Sie es mit ^ D chroot / mnt / sysimage beenden

    und initrd neu aufbauen

    # kopiere die alte Datei cp -p /boot/initramfs - $ (uname -r) .img / boot / initramfs - $ (uname -r) .img.bak # erstelle einen neuen dracut -f # wenn die Kernel-Version auf dem Hauptsystem unterscheidet sich von Version auf Installationsdiskette, wir geben es explizit an dracut -f /boot/initramfs-2.6.32-358.el6.x86_64.img 2.6.32-358.el6.x86_64

    # kopiere die alte Datei cp -p / boot / initrd - $ (uname -r) .img / boot / initrd - $ (uname -r) .img.bak # erstelle eine neue mkinitrd -f -v / boot / initrd - $ ( uname -r) .img $ (uname -r) # Wenn sich die Kernel-Version auf dem Hauptsystem von der Version auf der Installationsdiskette unterscheidet, geben Sie sie explizit an mkinitrd -f -v /boot/initrd-2.6.18-371 .el5.img 2.6 18-371.el5

    Cd / sync telinit 6

    Vollständiges Beispiel mit i2o_block-Treiber (Adaptec 2010S SCSI-Adapter), der nicht automatisch geladen wird. Das Beispiel läuft auf CentOS 5, da der Standard-CentOS 6-Kernel die Unterstützung für diesen Treiber deaktiviert hat.

    Nach dem Booten von CD in den Rescue-Modus erscheint eine Meldung, dass keine Linux-Partitionen gefunden wurden und diese selbst gemountet werden müssen.

    # Treiber laden insmod i2o_block # Überprüfen, ob alles funktioniert hat lsmod .... dmesg ... # Gerätedateien basierend auf Informationen in dmesg erstellen mkdir / dev / i2o mknod / dev / i2o / hda b 80 0 mknod / dev / i2o / hda1 b 80 1 mknod / dev / i2o / hda2 b 80 2 # VolumeGroup aktivieren lvm vgchange -ay # Mount-Volumes mkdir / mnt / sysimage mount / dev / mapper / VolGroup00-LogVol00 / mnt / sysimage mount / dev / i2o / hda1 / mnt / sysimage / boot # Mount spezielle Verzeichnisse mount --bind / proc / mnt / sysimage / proc mount --bind / dev / mnt / sysimage / dev mount --bind / sys / mnt / sysimage / sys

    Außerdem müssen Sie gemäß den Anweisungen nur beim Erstellen eines Disk-Images die zusätzliche Option --preload = i2o_block für das Programm mkinitrd angeben und die Readahead-Dienste deaktivieren, da sie zum Einfrieren des i2o_block-Treibers führen:

    Chkconfig Early-Readahead aus chkconfig Later-Readahead aus

    Das letzte Mal haben wir darüber gesprochen, was passiert, wenn Linux bootet: Zuerst startet der Bootloader, lädt den Kernel und stellt eine temporäre Festplatte im RAM bereit, der Kernel startet den Init-Prozess, init findet die echte Root-Disk, macht so einen cleveren Flip - stattdessen eines temporären. virtuelle Festplatte eine reale Platte wird an der gleichen Stelle im Root-Verzeichnis gemountet, von dieser realen Platte lädt der Init-Prozess eine andere init in sich, die sich auf dieser realen Platte befindet. Nach all diesen Operationen tritt UNIX in einen normalen Betriebszustand ein.

    In diesem Vortrag erkläre ich, was klassisches Programm init kombiniert mit rc.d-Skripten im System V-Stil. System V ist die klassische Version von UNIX, auf der kommerzielles UNIX aufbaut.

    Wie der Name schon sagt, ist rc.d ein Verzeichnis. Es gibt eine UNIX-Tradition - wenn die gesamte Konfiguration von etwas in eine Datei passt und sie config nennt, dann, wenn sie in separate Dateien aufgeteilt wird, die mit der Hauptdatei verbunden sind, erstellen Sie ein Verzeichnis mit demselben Namen und fügen Sie d - config . hinzu .d zum Namen. Der Buchstabe d bedeutet, dass dies ein Verzeichnis ist und zusätzliche Teile der Konfigurationsdatei vorhanden sind. Das Format der init-Konfigurationsdatei hat zwei Traditionen: die System V-Variante, bei der jedes Konfigurationsdetail in einer separaten Datei im Verzeichnis rc.d gespeichert wird, und die BSD-Tradition, die eine einzelne /etc/rc-Datei mit vielen Skripten enthält und Variablen, die für das Verhalten des Systems verantwortlich sind.

    Auf jeden Fall erstellen wir beim Systemstart einen Prozess mit PID = 1, in dem ein Programm namens init läuft. Wie Sie beim letzten Mal gesehen haben, gerät der Kernel in Panik und beendet die Arbeit, wenn Sie init beenden.

    Die klassische System V-Init liest die Datei /etc/inittab und befolgt eine Reihe von Anweisungen, die in dieser Datei geschrieben sind. Inittab this Textdatei jede Zeile davon ist tatsächlich ein Befehl oder eine Art Verhaltensregel. Inittab sieht so aus:

    id: 3: initdefault:

    si :: sysinit: /etc/rc.d/rc.sysinit

    l3: 3: warten: /etc/rc.d/rc 3

    ca :: ctrlaltdel: / sbin / shutdown -t3 -r now

    Am Anfang der Zeile befindet sich ein Etikett. Worin großartiger Sinn Ich verstehe dieses Etikett nicht wirklich. Wir können davon ausgehen, dass dies ein einfacher Text ist und das war's. Der zweite Punkt ist entweder das sogenannte Lastniveau, oder leerer Wert... Die Laststufe ist entweder eine einzelne Zahl zwischen 0 und 6 oder eine durch Kommas getrennte Liste von Zahlen. Dann gibt es etwas Action. Die Aktionen sind wie folgt: wait, respawn, sysinit, ctrlaltdel. Es gibt noch andere Aktionen, aber dies sind die am häufigsten verwendeten. Schließlich steht am Ende der Zeile ein Befehl mit dem Namen der ausführbaren Datei und den Argumenten, die diesem Befehl übergeben werden müssen.

    Die Aktion sysinit wird einmal beim Systemstart ausgeführt.

    Die ctrlaltdel-Aktion ist eigentlich keine Aktion - es ist der Handler für die Tastenkombination Control Alt Del. Der Push selbst wird vom Kernel des Systems abgefangen und Informationen darüber werden an den init-Prozess gesendet, der einen bestimmten Befehl ausführen muss. Beispielsweise kann der Befehl zum Herunterfahren ausgegeben werden, um den Computer herunterzufahren. Im Prinzip können Sie hier jedes andere Programm schreiben, zum Beispiel echo, das nach Drücken der Strg-Alt-Entf-Taste auf allen Terminals des Systems eine Meldung ausgibt. Kaminkonsole so

    Die Aktion warten bedeutet, dass Sie den Befehl ausführen, warten müssen, bis er abgeschlossen ist, und erst dann mit der Verarbeitung der nächsten Zeilen fortfahren. Ich weiß nicht, ob solche Aktionen parallel ausgelöst werden können. Wahrscheinlich nicht.

    Die Respawn-Aktion bedeutet, dass Sie das Programm starten und, ohne auf den Abschluss zu warten, zu . gehen weitere Maßnahmen... Wird dieses Programm anschließend beendet, muss es neu gestartet werden.

    Es gibt also eine einzelne Ausführung mit Warten auf die Ergebnisse und mehrere Ausführungen im asynchronen Modus - sie starteten, warteten bis zum Ende und starteten die Wörter.

    Laststufen sind eine Konvention, mit der Sie steuern können, welche Dienste geladen werden. Das nächste Analogon in Windows ist das Laden in Sicherheitsmodus wenn nur eine begrenzte Anzahl von Treibern geladen wird und die minimale Anzahl von Diensten gestartet wird, Laden mit Debugging, wenn jede Aktion zusätzlich protokolliert wird und normales vollwertiges Laden.

    Linux hat traditionell 6 Boot-Optionen. Diese Aufteilung ist eher willkürlich.

    0 und 6 sind abgeschaltet. 0 ist ein vollständiges Abschalten des Stroms und 6 ist ein Neustartmodus.

    4 fehlen in Linux insgesamt

    Es gibt noch vier Laststufen:

    1 - Einzelbenutzermodus. Wenn Sie zum Bootloader übergehen Stichwort single, dann befinden wir uns im Einzelbenutzermodus, in dem nur ein Prozess ausgeführt wird und dies die Systemadministrator-Shell ist. Dieser Modus wird für die Systemwiederherstellung verwendet.

    3 - normaler Mehrbenutzer-Textmodus, wenn alle Dienste ausgeführt werden, das Netzwerk aktiv ist, alle Treiber ausgeführt werden.

    2 - auch Textmodus, aber ohne Verbindung von Netzlaufwerken. Der Punkt ist, dass das traditionelle nfs-Netzwerkdateisystem, das in UNIX verwendet wird, extrem widerstandsfähig gegen Netzwerkschäden ist. Wenn wir den Dateiserver ausschalten oder das Netzwerkkabel abschneiden, wird das Netzwerkdateisystem nfs zahlreiche Wiederherstellungsversuche unternehmen und diese Versuche dauern so lange, dass ich nie warten könnte, bis die Fehlermeldung endlich erscheint. Vielleicht geschieht dies in einer Stunde und vielleicht in 6 Stunden. Die ganze Zeit über hält der nfs-Treiber den Computer und lässt nichts zu. Wenn ein Netzwerk- oder Dateiserver in den Einstellungen abgestürzt ist, steht daher, dass beim Start ein Mounten erforderlich ist externe Laufwerke, dann führt ein Versuch, in den vollwertigen Modus zu booten, dazu, dass alles für Sie einfriert. Für diesen Fall ist die zweite Boot-Option vorgesehen - alles ist wie bei der dritten, nur Netzlaufwerke nicht verbinden. Der Netzwerkadapter selbst funktioniert, eine IP-Adresse wird zugewiesen, das Internet ist verfügbar.

    5 ist das gleiche wie 3, aber mit dem Start des x-Fensters - der grafischen Benutzeroberfläche.

    Modus 2 beinhaltet 1+ Multiplayer-Modus. 3 enthält 2+ Mounts von Netzwerkdateisystemen. Schließlich enthält 5 3+ zum Starten des Grafiksubsystems. Ob dies konsequent umgesetzt wird oder nicht, ist ein Distributionsproblem. Im Allgemeinen können Administratoren die inittab-Datei unabhängig konfigurieren, sodass diese Modi sequentiell gestartet werden, oder Sie können alles völlig unabhängig machen - indem wir in den nächsten Modus wechseln, entfernen wir alles, was im vorherigen Schritt gemacht wurde, und richten alles von Grund auf neu ein .

    Betrachten Sie die Zeilen einer echten Datei. Sie sind sehr einfach.

    l3: 3: warten: /etc/rc.d/rc 3

    Es wird ein Programm gestartet, das alle notwendigen Aktionen ausführen muss, die auf der dritten Ebene erwartet werden. Wahrscheinlich müssen Sie auf der dritten Ebene Netzwerkschnittstellen konfigurieren, einen Terminaltreiber starten und einige Dienste starten. Erst wenn dies alles abgeschlossen ist, können wir im System arbeiten. Da wir warten müssen, bis der Startvorgang abgeschlossen ist, wählen wir die Aktion Wait.

    Der Launcher heißt rc und wird mit einer Levelnummer als Parameter ausgeführt. Das Init-Programm selbst ist ziemlich einfach. Sie kann ihre Datei Zeile für Zeile mit einer einfachen Syntax lesen und neue Prozesse starten, indem sie irgendwelche Hilfsprogramme ausführt. Die gesamte Ladestufenlogik ist im rc-Skript versteckt. Durch Ausführen von rc mit Parameter 3 gelangen wir zur dritten Ebene, mit Parameter 5 - zur fünften.

    Das rc-Programm ist auch sehr einfach. Dies ist ein Skript, das alle Dateien in Verzeichnissen ausführt, die dem Ladelevel entsprechen, zum Beispiel /etc/rc3.d/. Diese Verzeichnisse enthalten ausführbare Dateien, die einen Parameter annehmen, entweder start oder stop. Wird die Datei mit dem start-Parameter gestartet, dann startet sie den Dienst, wenn mit dem stop-Parameter, dann stoppt sie ihn. Beispielsweise konfiguriert Netzwerkstart Netzwerkschnittstellen und Netzwerkstopp deaktiviert Schnittstellen. Neben Netzwerkschnittstellen gibt es Skripte zum Verbinden / Trennen von Netzwerkdateisystemen, Starten / Stoppen von Diensten usw.

    Die Namen von Dateien in Verzeichnissen, die nach bestimmten Regeln erstellt wurden. Sie beginnen entweder mit dem Buchstaben K oder dem Buchstaben S, gefolgt von der Nummer und dem Namen des Dienstes.

    Das rc-Skript schaut sich den Inhalt des rc3-Verzeichnisses an und wählt dort alle Dateien aus, die mit dem Buchstaben K (kill) beginnen. Dateien werden in aufsteigender Reihenfolge sortiert und mit dem Stop-Parameter ausgeführt. Dann werden die gleichen Aktionen mit Dateien mit dem Buchstaben S (Start) durchgeführt, die mit dem Startparameter gestartet werden. Das ist im Allgemeinen das gesamte Verfahren, um auf ein bestimmtes Niveau zu gelangen.

    Es ist davon auszugehen, dass das Verzeichnis /etc/rc0.d/ nur Dateien enthält, die mit dem Buchstaben K beginnen, da beim Herunterfahren alles gestoppt werden muss und es pro S eine Datei im Verzeichnis /etc/rc1.d/ gibt, um Starten Sie die Administratorkonsole.

    Zur Vereinfachung der Programmierung gibt es ein separates Verzeichnis /etc/init.d/, das die gleichen Dateien nur ohne den Zahlenbuchstaben am Anfang des Namens enthält. Tatsächlich sind die Dateien in den Ebenenverzeichnissen nur symbolische Links zu den Hauptdateien. /etc/rc3.d/S10apache ist also ein Link zur Datei /etc/init.d/apache. Die Buchstaben und Zahlen im Namen der Links werden benötigt, damit das rc-Skript sie in der richtigen Reihenfolge und mit den richtigen Argumenten aufruft.

    In Systemen, die auf diesem Prinzip aufgebaut sind, müssen Sie zum Starten oder Stoppen eines Dienstes im Verzeichnis /etc/init.d/ die entsprechende Datei finden und mit dem start- oder stop-Parameter starten. Was nicht angenehm ist, Dienste auf diese Weise zu starten - explizites Aufrufen von Skripten. Fakt ist, dass im Team Linux-Linie Autovervollständigung funktioniert super. Mit seiner Hilfe können Sie sehr schnell den Pfad zur Startdatei eingeben.

    Um die spezifische Implementierung vor dem Benutzer zu verbergen, werden zwei Hilfsprogramme über das Skriptsystem und symbolische Links geschrieben.

    Mit dem Programm chkconfig können Sie symbolische Links zu den entsprechenden Skripten manipulieren. Um zu sehen, was auf jeder Ebene beginnt und was aufhört, können Sie den Befehl ls verwenden und die Skripte im entsprechenden Verzeichnis auflisten, aber es ist einfacher, den Befehl chkconfig –list zu verwenden. Das Programm chkconfig durchläuft alle rc-Verzeichnisse und listet auf, was auf jeder Ebene startet und stoppt. Wenn wir möchten, dass etwas beim Systemstart automatisch einen bestimmten Dienst startet, führen wir chkconfig . aus<имя службы>an und das Skript erstellt einen Startlink im richtigen Verzeichnis und mit dem richtigen Namen. Ausführen von chkconfig<имя службы>off bewirkt, dass der Start-Link entfernt und der Stopp-Link erstellt wird. Somit ermöglicht Ihnen das Programm chkconfig, die Liste der Dienste zu verwalten, die zum Zeitpunkt des Systemstarts gestartet werden.

    Ein anderes Programm, service, wird verwendet, um Dienste manuell zu starten und zu stoppen. Service ist ein Wrapper, der es Ihnen ermöglicht, nicht direkt auf das Skript zuzugreifen, sondern den Namen des Service anzugeben und anzugeben, dass wir ihn starten oder stoppen möchten. Die von mir verwendete Bash hat keine automatische Vervollständigung für den Dienstbefehl, daher ist es für mich einfacher, den Pfad zu den Skripts einzugeben.

    In Startskripten müssen die Argumente start und stop unbedingt verarbeitet werden. Darüber hinaus können Sie selbst einige Argumente vorbringen, die etwas Nützliches bewirken.

    Die meisten Skripte verfügen über eine Statusoption, die angibt, ob der Dienst ausgeführt wird oder nicht. Wenn wir start ausführen, erhält das Skript nach erfolgreichem Starten des Dienstes seine PID und schreibt sie in eine bestimmte Datei. Der Stop-Befehl löscht die Datei. Normalerweise werden diese Dateien im Verzeichnis /var/run/ erstellt. Der Befehl status prüft, ob eine solche Datei vorhanden ist. Ist es nicht da, dann heißt es, dass der Dienst nicht läuft. Wenn die Datei vorhanden ist, extrahiert sie die Prozess-ID daraus und überprüft die aktuelle Liste der Prozesse. Wenn diese Kennung vorhanden ist, läuft alles, wenn das Programm aus irgendeinem Grund abbricht, dann zeigt der Status an, dass versucht wurde, diesen Dienst zu starten - die Datei existiert, aber der Dienst selbst wird nicht gestartet.

    Die Neustartoption führt nacheinander zwei Befehle innerhalb des Skripts aus - zuerst stoppen und dann starten. Dieser Befehl ist völlig optional - einfach praktisch. Schließlich gibt es Dienste, mit denen Sie einige Konfigurationsdateien im laufenden Betrieb erneut lesen können. Für sie kommt das Reload-Kommando hinzu, dessen Aufgabe es ist, dem Dienst zu signalisieren, dass sich die Konfiguration geändert hat. Ein separater Fall sind die Befehle save und load, um die Firewall-Konfiguration zu speichern.

    Wenn der Systemadministrator, anstatt einzelne Dienste zu stoppen oder zu starten, das gesamte System auf ein bestimmtes Niveau bringen möchte, kann dies auf zwei Arten erreicht werden. Sie können das Programm /sbin/init direkt aufrufen. Ruft man es mit einer bestimmten Nummer als Parameter auf, dann führt es alle Anweisungen aus der inittab-Datei aus, für die der entsprechende Level geschrieben wurde. Wenn Sie zum Beispiel / sbin / init 1 ausführen, findet init in seinem Konfigurationsdatei alle Stiche, die Stufe 1 haben und diese ausführen. Auf einigen Systemen wird der Shutdown-Befehl als / sbin / init 0 implementiert, da Level 0 zum Herunterfahren des Systems verwendet wird. Kürzlich ist ein spezielles Programm namens telinit erschienen, das zwischen den Ebenen navigiert, was ein Link zu init ist. Seine Aufgabe ist es, dem Init-Prozess ein Signal zu senden, dass der Administrator auf eine bestimmte Ebene wechseln möchte. telinit q weist init an, die inittab-Datei erneut zu lesen. Auf älteren Systemen wurde dies erreicht, indem ein SIGHUP-Signal an einen Prozess mit PID = 1 gesendet wurde (kill –HUP 1).

    Noch ein paar Zeilen in inittab, das ist der Start von Terminals

    1: 2345: Respawn: / sbin / mingetty tty1

    Um einen interaktiven Zugriff auf das System zu ermöglichen, können Sie inittabе über mehrere solcher Zeilen verfügen. 2345 sind die Ebenen, auf denen der Befehl ausgeführt werden muss, Respawn bedeutet, dass das Programm nach Abschluss neu gestartet werden muss. Das getty-Programm ist ein Terminal-Steuerungsprogramm. Traditionell wird ein Terminal in UNIX als Fernschreibmaschine bezeichnet, da die ersten Terminals elektrische Schreibmaschinen waren. Dementsprechend steht tty für Fernschreiber. Mingetty ist ein Programm, das mit virtuellen Terminals auf einem PC arbeiten kann. Sie weiß, wie der Terminaltreiber zu konfigurieren ist, und erhält als Parameter den Namen des zu konfigurierenden Endgeräts. Das Verzeichnis /dev/enthält eine tty1-Gerätedatei, die dem ersten virtuellen Terminal entspricht. Wenn wir ein Modem hätten und es beim Booten initialisieren wollten, könnten wir getty mit dem Parameter ttyS0 aufrufen, der dem COM1-Port entspricht. Beim Initialisieren des Modems könnte man einstellen Zusätzliche Optionen: Verbindungsgeschwindigkeit 19200 Baud, 7 oder 8 Bit pro Byte, Parität, Anzahl Stoppbits.

    S0: 2345: Respawn: / sbin / getty ttyS0 19200 8 n 1

    Als ich das letzte Mal eine Kette gezeichnet habe, in der eine Kopie eines Prozesses durch Aufrufen von fork erstellt wird, lädt eine untergeordnete Kopie durch Aufrufen von exec ein anderes Programm in seinen Speicher und informiert nach Abschluss den übergeordneten Prozess darüber.

    Benutzertextsitzungen sind um diese Ketten herum organisiert: Zuerst erstellt init eine Kopie von sich selbst und führt darin das mingetty-Programm aus. Mingetty initialisiert das Terminal und die Tastatur und führt dann das Anmeldeprogramm im gleichen Prozess aus. Login fordert zur Eingabe eines Benutzernamens und Passworts auf und, wenn alles gut gelaufen ist, weist es sich selbst Benutzerrechte zu und startet im gleichen Prozess beim Überschreiben den Benutzerinterpreter, zum Beispiel bash. Wenn der Benutzer den Befehl exit eingibt, beendet der Interpreter die Lebensdauer dieses Prozesses. Wenn der Prozess beendet wird, wird init dazu aufgefordert. Init schaut sich an, was es tun soll, sieht die Respawn-Aktion, führt das mingetty-Programm erneut aus, das das Terminal neu initialisiert, und wiederholt alles. Somit befindet sich jede Sitzung innerhalb eines Prozesses. Sobald wir die Sitzung verlassen haben, ist unser Prozess beendet und sofort das Programm gestartet, das das Terminal für uns aufräumt und alle Standardeinstellungen wiederherstellt.

    Es gibt ein weiteres spezielles initdefault-Schlüsselwort in der inittab-Datei - die Standardstufe. Wenn init den einzelnen Parameter über den Kernel erhalten hat, booten wir auf Level 1. Wenn nichts durch den Bootloader übergeben wird, wird der Standardwert verwendet. Wenn sich nach der Installation der grafischen Shell herausstellt, dass unser Computer für Grafiken zu schwach ist, können wir die Standardstufe auf 3 setzen und nach dem nächsten Neustart gelangen wir in die dritte Stufe - also in den Textmodus. Wir haben das System ohne grafischen Modus installiert, dann alle Pakete für das x-Fenster installiert, den Standardlevel auf 5 geändert und nach dem nächsten Neustart sind wir sofort in den grafischen Modus gegangen.

    In diesem Skriptsystem möchten Sie manchmal etwas Eigenes tun, zum Beispiel beim Start alle Dateien im Verzeichnis /tmp/ löschen. Dafür gibt es eine eigene Datei namens /etc/rc.local, die nach allen anderen läuft. Es ist nur ein Skript ohne Parameter, in das Sie alles schreiben können, was Sie wollen. Beispielsweise werden auf einem meiner Router beim Systemstart Routing-Tabellen in diese Datei geschrieben. Ich war zu faul zu suchen, wo sich die entsprechenden Standardskripte aus der Distribution befinden, und es erwies sich als einfacher, Befehle in rc.local zu registrieren.