Vorwort: Das Betriebssystem (englisch: Operating System, abgekürzt: OS) ist die Systemsoftware, die Computerhardware und -softwareressourcen verwaltet. Es ist auch der Kern und Eckpfeiler des Computersystems. Das Betriebssystem muss grundlegende Aufgaben wie die Verwaltung und Konfiguration des Videospeichers, die Bestimmung der Priorität von Angebot und Nachfrage der Systemressourcen, die Steuerung von Eingabe- und Ausgabegeräten, den Betrieb von Netzwerken und die Verwaltung von Dateisystemen bewältigen. Das Betriebssystem bietet außerdem eine Bedienoberfläche, über die Benutzer mit dem System interagieren können.
1. Vorbereitung des Linux-Kernels
Die besten Wissenspunkte zur Vorbereitung auf das Verständnis des Linux-Kernels:
C-Sprache verstehen
Wissen Sie ein wenig über Betriebssysteme
Mit einer kleinen Anzahl verwandter Algorithmen vertraut
Computerarchitektur verstehen
Linux-Kernel-Funktionen:
Linux-Kernel-Aufgaben:
1. Aus technischer Sicht ist der Kernel eine Zwischenschicht zwischen Hardware und Software. Seine Funktion besteht darin, Sequenzanforderungen der Anwendungsschicht an die Hardware weiterzuleiten und als Treiber auf unterster Ebene zu fungieren, um verschiedene Geräte und Komponenten im System abzufragen.
2. Auf der Anwendungsebene hat die Anwendung keine Verbindung zur Hardware, sondern nur zum Kernel. Der Kernel ist die unterste Ebene in der Hierarchie, die die Anwendung kennt. In der tatsächlichen Arbeit verkörpert der Kernel die relevanten Details.
3. Der Kernel ist ein Ressourcenverwaltungsprogramm. Verantwortlich für die Zuweisung verfügbarer gemeinsam genutzter Ressourcen (CPU-Zeit, Speicherplatz, Netzwerkverbindungen usw.) zu verschiedenen Systemprozessen.
4. Der Kernel ist wie eine Bibliothek und stellt eine Reihe systemorientierter Befehle bereit. Für die Anwendung sind Systemaufrufe genauso wie der Aufruf gewöhnlicher Funktionen.
Kernel-Implementierungsstrategie:
1.Mikrokernel. Die grundlegendsten Funktionen werden vom zentralen Kernel (Mikrokernel) implementiert. Alle anderen Funktionen werden an unabhängige Prozesse delegiert, die über genau definierte Kommunikations-Sockets mit dem zentralen Kern kommunizieren.
2. Makrokernel. Der gesamte Code des Kernels, einschließlich der Subsysteme (z. B. Videospeicherverwaltung, Dateiverwaltung, Gerätetreiber), wird in eine Datei gepackt. Jede Funktion im Kernel hat Zugriff auf alle anderen Teile des Kernels. Unterstützt derzeit das dynamische Laden und Entladen (Schneiden) von Modulen. Basierend auf dieser Strategie wird der Linux-Kernel implementiert.
Wo wird der Kernel-Mechanismus verwendet?
1. Die Kommunikation zwischen Prozessen (der Adressraum wird im virtuellen Speicher der CPU zugewiesen und der Adressraum jedes Prozesses ist völlig unabhängig; die Anzahl der gleichzeitig ausgeführten Prozesse überschreitet nicht die Anzahl der CPUs). Verwendung eines bestimmten Kernelmechanismus.
2. Das Umschalten zwischen Prozessen (die Anzahl der gleichzeitig ausgeführten Prozesse übersteigt nicht die Anzahl der CPUs) erfordert ebenfalls die Verwendung des Kernel-Mechanismus.
Bei der Prozessumschaltung muss auch der Status wie bei der FreeRTOS-Aufgabenumschaltung gespeichert und der Prozess in den Ruhezustand/Fortsetzungszustand versetzt werden.
3. Prozessplanung. Bestimmen Sie, wie lange dieser Prozess bereits ausgeführt wurde.
Linux-Prozess:
1. Bei einer hierarchischen Struktur hängt jeder Prozess von einem übergeordneten Prozess ab. Der Kernel startet das Init-Programm als ersten Prozess. Dieser Prozess ist für weitere Systeminitialisierungsvorgänge verantwortlich. Der Init-Prozess ist die Wurzel des Prozessbaums, und alle Prozesse stammen direkt oder indirekt von diesem Prozess.
2. Abfrage über den Befehl pstree. Tatsächlich ist der erste Prozess im System systemd und nicht init (dies ist ebenfalls ein Punkt zur Verwirrung)
3. Jeder Prozess im System verfügt über eine eindeutige Kennung (ID), und Benutzer (oder andere Prozesse) können die ID verwenden, um auf den Prozess zuzugreifen.
2. Verzeichnisstruktur des Linux-Kernel-Quellcodes
Der Linux-Kernel-Quellcode besteht aus drei Hauptteilen:
1. Kernel-Kerncode, einschließlich verschiedener in Kapitel 3 beschriebener Subsysteme und Submodule sowie anderer unterstützender Subsysteme wie Energieverwaltung, Linux-Initialisierung usw.
2. Andere nicht zum Kern gehörende Codes, wie z. B. Bibliotheksdateien (da der Linux-Kernel ein eigenständiger Kernel ist, d. h. der Kernel ist nicht von anderer Software abhängig und kann selbst kompiliert werden), Firmware-Sammlungen, KVM ( virtuelle Maschinentechnologie) usw.
3. Kompilieren Sie Skripte, Konfigurationsdateien, Hilfedokumente, Copyright-Erklärungen und andere Hilfsdateien
Verwenden Sie den Befehl ls, um die oberste Verzeichnisstruktur des Kernel-Quellcodes abzuhören. Die spezifische Beschreibung lautet wie folgt:
include/----Kernel-Header-Dateien müssen externen Modulen (z. B. User-Space-Code) bereitgestellt werden. kernel/----Der Kerncode des Linux-Kernels, einschließlich des in Abschnitt 3.2 beschriebenen Prozessplanungssubsystems und Modulen im Zusammenhang mit der Prozessplanung. mm/----Videospeicherverwaltungssubsystem (Abschnitt 3.3). fs/----VFS-Subsystem (Abschnitt 3.4). net/----Das Netzwerksubsystem, das keine Netzwerkgerätetreiber enthält (Abschnitt 3.5). ipc/----IPC-Subsystem (Interprozesskommunikation). arch//----Architekturbezogener Code wie Arm, x86 usw. arch//mach-----spezifischer Maschinen-/Board-bezogener Code. arch//include/asm----architekturbezogene Headerdateien. arch//boot/dts----DeviceTree-Datei. init/----Code im Zusammenhang mit der Initialisierung des Linux-Systemstarts. block/----Stellt die Hierarchie der Blockgeräte bereit. Sound/----Audiobezogene Treiber und Subsysteme können als „Audio-Subsysteme“ betrachtet werden. drivers/----Gerätetreiber (in Linuxkernel 3.10 macht der Gerätetreiber 49,4 % des Codes aus). lib/----implementieren Bibliotheksfunktionen, die im Kernel verwendet werden müssen, wie CRC, FIFO, Liste, MD5 usw. crypto/-----Bibliotheksfunktionen im Zusammenhang mit Verschlüsselung und Entschlüsselung. security/----Bietet Sicherheitsfunktionen (SELinux). virt/----Bietet Unterstützung für die Technologie virtueller Maschinen (KVM usw.). usr/----Code, der zum Generieren von initramfs verwendet wird. Firmware/----Speichern Sie die Firmware, die zum Ansteuern von Geräten von Drittanbietern verwendet wird. Beispiele/----Einige Beispielcodes. tools/----Einige gängige Tools wie Leistungsanalyse, Selbsttests usw. Kconfig, Kbuild, Makefile, Skripte/----Konfigurationsdateien, Skripte usw. werden für die Kernel-Kompilierung verwendet. KOPIEREN----Urheberrechtserklärung. MAINTAINERS----Liste der Betreuer. CREDITS----Liste der wichtigsten Mitwirkenden an Linux. REPORTING-BUGS----Handbuch zur Fehlerberichterstattung. Dokumentation, README----Hilfe, Dokumentation.
[Artikelvorteile] Der Herausgeber empfiehlt seine eigene Linux-Kernel-Technologie-Austauschgruppe: [865977150] hat einige Lernbücher und Videomaterialien zusammengestellt, die ich persönlich für besser halte, und sie in der Gruppendatei geteilt. Bei Bedarf können Sie sie selbst hinzufügen! ! ! Die ersten 100 Personen, die der Gruppe beitreten, erhalten ein zusätzliches Kerninformationspaket im Wert von 699 (einschließlich Video-Tutorials, E-Books, Praxisprojekten und Codes)
3. Kurze Analyse der Linux-Kernel-Architektur
Abbildung 1 Linux-Systemhierarchie
Die Vorderseite ist der Benutzer- (oder Anwendungs-) Bereich. Hier werden Benutzeranwendungen ausgeführt. Unter dem Benutzerbereich befindet sich der Kernelbereich, und hier befindet sich der Linux-Kernel. GNUCLibrary (glibc) ist auch hier. Es bietet einen Systemaufruf-Socket zum Herstellen einer Verbindung mit dem Kernel sowie einen Mechanismus zur Übersetzung zwischen User-Space-Anwendungen und dem Kernel. Dies ist wichtig, da Kernel- und User-Space-Anwendungen unterschiedliche geschützte Adressräume verwenden. Jeder User-Space-Prozess verwendet seinen eigenen virtuellen Adressraum, während der Kernel einen separaten Adressraum belegt.
Der Linux-Kernel kann weiter in drei Schichten definiert werden. Die Vorderseite ist der Systemaufruf-Socket, der einige Grundfunktionen wie Lesen und Schreiben implementiert. Unter dem Systemaufruf-Socket befindet sich der Kernel-Code, der genauer als architekturunabhängiger Kernel-Code definiert werden kann. Dieser Code ist allen von Linux unterstützten Prozessorarchitekturen gemeinsam. Unterhalb dieses Codes befindet sich architekturabhängiger Code, der das sogenannte BSP (BoardSupportPackage) bildet. Dieser Code dient als prozessor- und plattformspezifischer Code für eine bestimmte Architektur.
Der Linux-Kernel implementiert viele wichtige Architektureigenschaften. Auf einer höheren oder niedrigeren Ebene wird der Kernel in Subsysteme unterteilt. Linux kann auch als Ganzes betrachtet werden, da es alle diese Basisdienste in den Kernel integriert. Dies unterscheidet sich von der Architektur des Mikrokernels. Erstere stellt einige grundlegende Dienste wie Kommunikation, E/A, Speicher und Prozessverwaltung bereit. Jeder Kern hat seine eigenen Vorteile, auf die hier jedoch nicht eingegangen wird. Im Laufe der Zeit ist der Linux-Kernel hinsichtlich Videospeicher und CPU-Auslastung effizienter geworden und sehr stabil. Und das Interessanteste an Linux ist, dass es trotz seiner Größe und Komplexität immer noch gut portierbar ist. Linux ist so kompiliert, dass es auf einer großen Anzahl von Prozessoren und Plattformen mit unterschiedlichen architektonischen Einschränkungen und Anforderungen läuft. Ein Gegenbeispiel ist, dass Linux auf einem Prozessor laufen kann, der über eine Grafikspeicherverwaltungseinheit (MMU) verfügt, oder auf Prozessoren, die über keine MMU verfügen.
Der uClinux-Port des Linux-Kernels bietet Unterstützung für Nicht-MMU.
Abbildung 2 Linux-Kernel-Architektur
Die Hauptkomponenten des Linux-Kernels sind: Systemaufruf-Socket, Prozessverwaltung, Speicherverwaltung, virtuelles Dateisystem, Netzwerkstapel, Gerätetreiber und Code für die Hardwarearchitektur.
(1) Systemanruf-Socket
Die SCI-Schicht stellt individuelle Mechanismen bereit, um Funktionsaufrufe vom Benutzerbereich an den Kernel durchzuführen. Wie oben erläutert, ist dieser Sockel architekturabhängig, auch innerhalb derselben Prozessorfamilie. SCI ist eigentlich ein sehr nützlicher Dienst zum Multiplexen und Demultiplexen von Funktionsaufrufen. Die Implementierung von SCI finden Sie in ./linux/kernel und die architekturabhängigen Teile in ./linux/arch.
(2) Prozessmanagement
Der Fokus des Prozessmanagements liegt auf der Durchführung des Prozesses. Im Kernel werden solche Prozesse Threads genannt und repräsentieren einzelne Prozessorvirtualisierungen (Thread-Code, Daten, Stack und CPU-Register). Im Userspace wird im Allgemeinen der Begriff Prozess verwendet, die Linux-Implementierung unterscheidet jedoch nicht zwischen diesen beiden Konzepten (Prozess und Thread). Der Kernel stellt über SCI eine Anwendungsprogrammierschnittstelle (API) bereit, um einen neuen Prozess zu erstellen (Fork, Exec oder PortableOperatingSystemInterface[POSIX]-Funktion), den Prozess zu stoppen (Kill, Exit) und zwischen ihnen zu kommunizieren und zu synchronisieren (Signal oder Then POSIX-Mechanismus). ).
Zur Prozessverwaltung gehört auch die Bewältigung der Notwendigkeit, die CPU zwischen aktiven Prozessen zu teilen. Der Kernel implementiert einen neuen Typ von Planungsalgorithmus, der innerhalb einer festen Zeitspanne arbeitet, unabhängig davon, wie viele Threads um die CPU konkurrieren. Diese Algorithmen werden als O(1)-Scheduler bezeichnet. Der Name bedeutet, dass die Zeit, die zum Planen mehrerer Threads benötigt wird, mit der Zeit übereinstimmt, die zum Planen eines Threads benötigt wird. Der O(1)-Scheduler kann auch mehrere Prozessoren unterstützen (sogenannte symmetrische Multiprozessoren oder SMP). Den Quellcode für die Prozessverwaltung finden Sie in ./linux/kernel und den architekturabhängigen Quellcode in ./linux/arch.
(3) Videospeicherverwaltung
Eine weitere wichtige vom Kernel verwaltete Ressource ist der Videospeicher. Um die Effizienz zu verbessern, wird der Videospeicher bei der Verwaltung des virtuellen Videospeichers durch Hardware gemäß dem sogenannten Videospeicherseitenformat (4 KB für die meisten Architekturen) verwaltet. Linux umfasst Methoden zur Verwaltung des verfügbaren Videospeichers sowie Hardwaremechanismen für chemisches und virtuelles Mapping. Allerdings muss die Videospeicherverwaltung mehr als nur den 4-KB-Puffer verwalten. Linux bietet eine konkrete Darstellung des 4-KB-Puffers, beispielsweise den Slab Allocator. Diese Speicherverwaltungsmodi verwenden einen 4-KB-Puffer als Basis, weisen dann Strukturen daraus zu und verfolgen die Speicherseitennutzung, z. B. welche Speicherseiten voll sind, welche Seiten nicht vollständig verwendet werden und welche Seiten leer sind. Dadurch kann der Modus die Videospeichernutzung dynamisch an die Systemanforderungen anpassen. Um die Nutzung des Videospeichers durch mehrere Benutzer zu unterstützen, wird manchmal der verfügbare Videospeicher verbraucht. Aus diesem Grund können im Linux-Kernel Seiten aus dem Videospeicher verschoben und auf dem Laufwerk C abgelegt werden. Dieser Vorgang wird als Swapping bezeichnet, da die Seiten vom Videospeicher auf die Festplatte ausgelagert werden. Der Quellcode für die Videospeicherverwaltung ist in ./linux/mm zu finden.
(4)Virtuelles Dateisystem
Das Virtual File System (VFS) ist ein sehr nützlicher Aspekt des Linux-Kernels, da es eine universelle Schnittstellendarstellung für das Dateisystem bietet. VFS stellt eine Austauschschicht zwischen SCI und vom Kernel unterstützten Dateisystemen bereit (siehe Abbildung 4).
Abbildung 3 Linux-Dateisystemhierarchie
In VFS handelt es sich um eine gängige API-Darstellung von Funktionen wie Öffnen, Schließen, Lesen und Schreiben. Unter VFS versteht man die Dateisystemdarstellung, die die Implementierungsmethode der untergeordneten Funktionen definiert. Es handelt sich um Plugins für ein bestimmtes Dateisystem (mehr als 50 davon). Der Quellcode für das Dateisystem ist in ./linux/fs zu finden. Unterhalb der Dateisystemschicht befindet sich der Puffercache, der einen gemeinsamen Satz von Funktionen für die Dateisystemschicht bereitstellt (unabhängig vom jeweiligen Dateisystem). Diese Caching-Schicht optimiert den Zugriff auf chemische Geräte, indem sie Daten für einen bestimmten Zeitraum speichert (oder die Daten später vorab abruft, um sie bei Bedarf verfügbar zu machen). Unter dem Puffercache befinden sich Gerätetreiber, die Sockets für bestimmte chemische Geräte implementieren.
(5) Netzwerkstapel
Der Netzwerkstapel ist so konzipiert, dass er der Schichtenarchitektur des simulierten Vertrags selbst folgt. Denken Sie daran, dass das Internet Protocol (IP) der Kernvertrag der Netzwerkschicht ist, der dem Transportvertrag zugrunde liegt (allgemein bekannt als Transmission Control Contract oder TCP). Innerhalb von TCP befindet sich die Socket-Schicht, die über SCI aufgerufen wird. Die Socket-Schicht ist die Standard-API des Netzwerksubsystems, die einen Benutzer-Socket für verschiedene Netzwerkverträge bereitstellt. Vom Raw-Frame-Zugriff über IP Contract Data Units (PDUs) bis hin zu TCP und User Datagram Protocol (UDP) bietet die Socket-Schicht eine standardisierte Möglichkeit, Verbindungen zu verwalten und Daten zwischen verschiedenen Endpunkten zu kommunizieren. Der Netzwerkquellcode im Kernel befindet sich in ./linux/net.
(6) Gerätetreiber
Eine große Menge Code im Linux-Kernel befindet sich in Gerätetreibern, die bestimmte Hardwaregeräte ausführen können. Der Linux-Quellbaum stellt ein Treiber-Unterverzeichnis bereit, das weiter nach verschiedenen unterstützten Geräten wie Bluetooth, I2C, seriell usw. definiert ist. Den Code für den Gerätetreiber finden Sie in ./linux/drivers.
(7) Architekturabhängiger Code
Obwohl Linux weitgehend unabhängig von der Architektur ist, auf der es läuft, gibt es Elemente, die berücksichtigt werden müssen, damit die Architektur ordnungsgemäß funktioniert und eine höhere Effizienz erzielt. Das Unterverzeichnis ./linux/arch definiert die architekturabhängigen Teile des Kernel-Quellcodes, der verschiedene architekturspezifische Unterverzeichnisse enthält (die zusammen das BSP bilden). Für ein typisches Desktop-System wird das x86-Verzeichnis verwendet. Jedes Architektur-Unterverzeichnis enthält viele andere Unterverzeichnisse, und jedes Unterverzeichnis konzentriert sich auf einen bestimmten Aspekt des Kernels, z. B. Booten, Kernel, Speicherverwaltung usw. Dieser architekturabhängige Code ist in ./linux/arch zu finden.
Wenn die Portabilität und Effizienz des Linux-Kernels nicht gut genug sind, bietet Linux auch einige andere Funktionen, die sich darin nur schwer klassifizieren lassen. Als Produktionsbetriebssystem und Open-Source-Software ist Linux eine großartige Plattform zum Testen neuer Verträge und deren Verbesserungen. Linux unterstützt eine Vielzahl von Netzwerkprotokollen, darunter klassisches TCP/IP sowie Erweiterungen zu Hochgeschwindigkeitsnetzwerken (weniger als 1 Gigabit Ethernet [GbE] und 10 GbE). Linux kann auch Verträge wie den Stream Control Transmission Contract (SCTP) unterstützen, der viel mehr Zwischenfunktionen als TCP bietet (und der Nachfolger des Transport-Layer-Vertrags ist). Linux ist auch ein dynamischer Kernel, der das dynamische Hinzufügen oder Löschen von Softwarekomponenten unterstützt. Sie werden als dynamisch ladbare Kernelmodule bezeichnet und können bei Bedarf beim Booten (das Modul wird derzeit für ein bestimmtes Gerät benötigt) oder jederzeit vom Benutzer eingefügt werden.
Eine der neuesten Verbesserungen von Linux ist seine Fähigkeit, als Betriebssystem (Hypervisor genannt) für andere Betriebssysteme verwendet zu werden. Kürzlich wurden Änderungen am Kernel vorgenommen, die als Kernel-based Virtual Machines (KVM) bezeichnet werden. Diese Änderung ermöglicht einen neuen Socket für den Benutzerbereich, der es anderen Betriebssystemen ermöglicht, auf dem KVM-fähigen Kernel zu laufen. Neben der Ausführung anderer Linux-Instanzen kann auch Microsoft Windows virtualisiert werden. Die einzige Einschränkung besteht darin, dass der zugrunde liegende Prozessor die neuen Virtualisierungsanweisungen unterstützen muss.
Viertens der Unterschied zwischen Linux-Architektur und Kernelstruktur
1. Auf die Frage nach der Linux-Architektur (also wie das Linux-System aufgebaut ist) können wir dies anhand des Bildes rechts beantworten: Im Großen und Ganzen lässt sich die Linux-Architektur in zwei Teile gliedern:
2. Der Grund, warum die Linux-Architektur in User Space und Kernel Space unterteilt ist:
1) Moderne CPUs implementieren im Allgemeinen unterschiedliche Arbeitsmodi,
Nehmen Sie ARM als Beispiel: ARM implementiert 7 Arbeitsmodi. In verschiedenen Modi sind die Anweisungen, die die CPU ausführen kann, oder die Register, auf die sie zugreift, unterschiedlich:
Nehmen Sie (2) X86 als Beispiel: X86 implementiert 4 verschiedene Berechtigungsstufen, Ring0-Ring3; Ring0 kann privilegierte Anweisungen ausführen und auf IO-Geräte zugreifen;
2) Daher teilt Linux aus Sicht der CPU das System in zwei Teile, um die Sicherheit des Kernels zu schützen3. Benutzerraum und Kernelraum sind zwei verschiedene Zustände der Programmausführung. Wir können die Übertragung vom Benutzerraum zum Kernelraum durch „Systemaufrufe“ und „Hardware-Interrupts“ abschließen
4. Linux-Kernel-Struktur (beachten Sie den Unterschied zwischen Linux-Architektur und Linux-Kernel-Struktur)
5. Linux-gesteuerter Plattformmechanismus
Im Vergleich zum herkömmlichen Gerätetreibermechanismus dieser Plattformtreibermechanismen von Linux besteht ein sehr wesentlicher Vorteil darin, dass der Plattformmechanismus seine eigenen Ressourcen im Kernel registriert und vom Kernel verwaltet wird. Bei Verwendung dieser Ressource im Treiber werden die bereitgestellten Standards verwendet von platform_device Bewerben Sie sich und verwenden Sie den Socket. Dies verbessert die Unabhängigkeit von Treibern und Ressourcenmanagement, bietet aber auch eine bessere Portabilität und Sicherheit. Das Folgende ist ein schematisches Diagramm der SPI-Treiberhierarchie. Der SPI-Bus in Linux kann als der vom SPI-Controller gezogene Bus verstanden werden:
Wie bei herkömmlichen Treibern ist auch der Plattformmechanismus in drei Schritte unterteilt:
1. Busregistrierungsphase:
Kernel_init()→do_basic_setup()→driver_init()→platform_bus_init()→bus_register(&platform_bus_type) in der Datei main.c registriert während der Kernel-Startinitialisierung einen Plattformbus (virtueller Bus, platform_bus).
2. Ausrüstungsstufe hinzufügen:
Bei der Registrierung eines Geräts: Platform_device_register()→platform_device_add()→(pdev→dev.bus=&platform_bus_type)→device_add(), wodurch das Gerät an den virtuellen Bus angeschlossen wird.
3. Fahrerregistrierungsphase:
Platform_driver_register()→driver_register()→bus_add_driver()→driver_attach()→bus_for_each_dev(), führen Sie __driver_attach()→driver_probe_device() für jedes Gerät aus, das an der virtuellen Plattform hängt, und bestimmen Sie drv→bus→match() Ob die Ausführung erfolgt Wenn es erfolgreich ist, führen Sie zu diesem Zeitpunkt platform_match→strncmp(pdev→name,drv→name,BUS_ID_SIZE) über den Überwachungszeiger aus. Wenn es übereinstimmt, rufen Sie wirklich_probe auf (führen Sie tatsächlich platform_driver→probe(platform_device) des entsprechenden Geräts aus), um zu starten die eigentliche Erkennung. Wenn die Prüfung erfolgreich ist, wird das Gerät an den Treiber gebunden.
Von innen ist ersichtlich, dass der Plattformmechanismus schließlich die drei Schlüsselfunktionen bus_register(), device_add() und drivers_register() aufruft.
Die Platform_device-Struktur beschreibt ein Plattformstrukturgerät, das die übliche Gerätestruktur structdevicedev enthält; die Geräteressourcenstruktur structresource*resource und den Gerätenamen constchar*name. (Beachten Sie, dass dieser Name mit dem vorherigen platform_driver.driverà-Namen identisch sein muss. Der Grund wird früher erläutert.)
Das Wichtigste in dieser Struktur ist die Ressourcenstruktur, weshalb der Plattformmechanismus eingeführt wird.
Der Grund, warum Namen gleich sein sollten:
Der darin erwähnte Treiber ruft bei der Registrierung die Funktion bus_for_each_dev() auf und führt für jedes am virtuellen Plattformbus hängende Gerät einen vorläufigen Test von dev und drv durch Beim Matching wird die Funktion aufgerufen, auf die drv->bus->match zeigt. In der Funktion platform_driver_register ist drv->driver.bus=&platform_bus_type, also ist drv->bus->match platform_bus_type→match, was der Funktion platform_match entspricht.
besteht darin, die Namen von dev und drv zu vergleichen. Wenn sie identisch sind, werden sie in die Funktion „wirklich_probe()“ übernommen, sodass sie in die von ihnen selbst geschriebene Sondenfunktion für einen weiteren Abgleich eintreten. Daher müssen dev→name und drivers→drv→name bei der Initialisierung auf die gleiche Weise gefüllt werden.
Verschiedene Treibertypen haben unterschiedliche Übereinstimmungsfunktionen. Der Treiber dieser Plattform vergleicht die Namen von dev und drv. Erinnern Sie sich an die Übereinstimmung im USB-Treiber? Es vergleicht ProductID und VendorID.
Persönliche Zusammenfassung der Vorteile des Plattformmechanismus:
1. Stellen Sie einen Bus vom Typ „Plattformbus“ bereit und fügen Sie diese SOC-Geräte vom Typ „Plattform“ zu diesem virtuellen Bus hinzu. Dadurch kann das Bus-Gerät-Treiber-Modell populär gemacht werden.
2. Stellen Sie Datenstrukturen vom Typ „platform_device“ und „platform_driver“ bereit, indem Sie herkömmliche Geräte- und Treiberdatenstrukturen darin einbetten, aber Ressourcenmitglieder hinzufügen, um eine einfache Integration mit neuen Bootloadern und Kerneln wie OpenFirmware zu ermöglichen, die Geräteressourcen dynamisch übertragen.
Sechs, Linux-Kernel-Architektur
Da der Linux-Kernel monolithisch ist, nimmt er den größten Platz ein und weist die höchste Komplexität auf als andere Kerneltypen. Dies ist ein Designmerkmal, das in den frühen Tagen von Linux für einige Kontroversen sorgte, aber immer noch einige der gleichen Designfehler aufweist, die einem einzelnen Kernel innewohnen.
Um diesen Fehler zu beheben, haben die Linux-Kernel-Entwickler Kernel-Module zur Laufzeit ladbar und entladbar gemacht, was bedeutet, dass Sie Kernel-Funktionen dynamisch hinzufügen oder entfernen können. Dies kann neben der Erweiterung des Kernels um Hardware-Fähigkeiten auch Module zur Ausführung von Serverprozessen wie Low-Level-Virtualisierung umfassen, aber auch den gesamten Kernel ersetzen, ohne dass im Einzelfall ein Neustart des Rechners erforderlich ist.
Stellen Sie sich vor, Sie könnten auf ein Windows Service Pack aktualisieren, ohne einen Neustart durchführen zu müssen ...
Sieben, Kernelmodul
Was ist, wenn unter Windows bereits alle verfügbaren Treiber installiert sind und Sie nur die benötigten aktivieren müssen? Dies ist im Wesentlichen das, was Kernel-Module für Linux tun. Kernelmodule, auch ladbare Kernelmodule (LKMs) genannt, sind erforderlich, damit der Kernel mit der gesamten Hardware funktioniert, ohne den gesamten verfügbaren Videospeicher zu verbrauchen.
Module fügen dem Basiskernel im Allgemeinen Funktionen wie Geräte, Dateisysteme und Systemaufrufe hinzu. Die Dateierweiterung von lkm ist .ko und wird im Allgemeinen im Verzeichnis /lib/modules gespeichert. Aufgrund der Eigenschaften des Moduls können Sie den Kernel einfach anpassen, indem Sie das Modul mit dem Befehl „menuconfig“ beim Start auf „Laden“ oder „Nichtladen“ einstellen, die Datei /boot/config bearbeiten oder das Modul mit dem Befehl „modprobe“ dynamisch laden und entladen.
In einigen Distributionen wie Ubuntu sind Module von Drittanbietern und Closed-Source-Module verfügbar, deren standardmäßige Installation möglicherweise schwierig ist, da der Quellcode solcher Module nicht verfügbar ist. Die Entwickler der Software (d. h. nVidia, ATI usw.) stellen keinen Quellcode zur Verfügung, sondern erstellen ihre eigenen Module und kompilieren die erforderlichen .ko-Dateien für die Verteilung. Tatsächlich sind solche Module kostenlos wie Bier, aber sie sind nicht frei wie Sprache und daher nicht in einigen Distributionen enthalten, weil die Betreuer der Meinung sind, dass sie den Kernel „verschmutzen“, indem sie unfreie Software bereitstellen.
Der Kernel ist nicht magisch, aber er ist für jeden ordnungsgemäß funktionierenden Computer unerlässlich. Der Linux-Kernel unterscheidet sich von OSX und Windows dadurch, dass er Treiber auf Kernel-Ebene enthält und dafür sorgt, dass viele Dinge sofort funktionieren. Hoffentlich erfahren Sie mehr darüber, wie Software und Hardware zusammenarbeiten und welche Dateien zum Starten Ihres Computers erforderlich sind.
Fazit: Die Macht des Interesses ist unendlich. Interesse kann Leidenschaft hervorrufen. Wenn Arbeit mit Interesse verbunden werden kann, entsteht Begeisterung für die Arbeit. Auf diese Weise ist Arbeit nicht nur Arbeit, sondern auch eine Art Vergnügen.
Das obige ist der detaillierte Inhalt vonVerstehen Sie die vorbereitende Arbeit des Linux-Kernels: Verstehen Sie die C-Sprache und ein wenig über das Betriebssystem. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!