Hat der Kernel eine main () Funktion? [geschlossen]


52

Ich lerne Gerätetreiber und Kernelprogrammierung. Laut Jonathan Corbets Buch gibt es main()in Gerätetreibern keine Funktion.

Also ich zwei Fragen:

  • Warum brauchen wir keine main()Funktion in Gerätetreibern?
  • Hat der Kernel selbst eine main()Funktion?

Kann mir das jemand erklären?


1
Vom selben Benutzer auch hier gefragt
Keith Thompson

@KeithThompson ... Ja ... Nur weil ich keine Antwort bekommen habe, was ich will, habe ich es hier gefragt.
Jemand

@ Shadur ... sowieso jetzt ist es zu schließen ... Und ich habe nicht das Privileg, das zu migrieren ...
jemand

Dies sollte umgekehrt geschlossen worden sein, dieses hat viel mehr Ansichten :-)
Ciro Santilli 新疆 18 改造. 六四 六四

Antworten:


82

In User-Space-Programmen main()ist dies der Einstiegspunkt für das Programm, das vom libc-Initialisierungscode aufgerufen wird, wenn die Binärdatei ausgeführt wird. Kernel-Code hat nicht den Luxus, sich auf libc zu verlassen, da libc selbst auf die Kernel-Syscall-Schnittstelle für Speicherzuweisung, E / A, Prozessverwaltung usw. angewiesen ist.

Das Äquivalent zu main()im Kernel enthaltenem Code ist start_kernel(), der vom Bootloader aufgerufen wird, nachdem das Kernel-Image geladen, in den Speicher dekomprimiert und wichtige Hardware und Speicherseiten eingerichtet wurde. start_kernel()Führt den größten Teil der Systemeinrichtung aus und startet schließlich den Init-Prozess.

Der Einstiegspunkt für Linux-Kernelmodule ist eine Init-Funktion, die durch Aufrufen des module_init()Makros beim Kernel registriert wird . Die registrierte Modulinitialisierungsfunktion wird dann durch den Kernelcode über die do_initcalls()Funktion während des Kernelstarts aufgerufen .


11
Vielen Dank, dass Sie den wahren Zweck der mainMethode in C erkannt haben . (Es ist ein allzu weit verbreitetes Missverständnis, dass das Betriebssystem direkt anruft main, was in C ++ nicht der Fall und noch weniger der Fall ist.) I ' Ich würde dir noch eine Gegenstimme geben, wenn ich nur dafür könnte.
einen Lebenslauf vom

1
@ Thomas ... Vielen Dank für diese hervorragende Antwort ....
jemand

17

Der Kernel hat keine mainFunktion. mainist ein Konzept der C-Sprache. Der Kernel ist in C und Assembly geschrieben. Der Eintrittscode des Kernels wird von der Assembly geschrieben.

Die Startsequenz ist wie folgt organisiert:

  1. Das BIOS lädt normalerweise einen Bootloader von einem Bootblock-Gerät. Ein beliebter Bootloader ist derzeit Grub.
  2. Grub lädt ein Kernel-Image in den RAM, möglich mit einem anfänglichen Root-Gerät ( initrd). Dann wird Code an irgendeiner Adresse ausgeführt.
  3. Das Kernel-Image enthält einige Kernel-Module, zum Beispiel: Dateisystem-Module, Gerätetreiber. Das Kernel-Image verwendet das Dateisystemmodul, um das Root-Dateisystem bereitzustellen. Jetzt kann der Kernel alle Kernelmodule von der Festplatte laden und ausführen.
  4. Der Kernel führt Initialisierungsaufgaben aus. Beispiel: Überqueren Sie den PCI-Bus und suchen Sie alle PCI-Geräte. Initialisieren Sie alle Gerätetreiber.
  5. Schließlich erstellt der Kernel den Prozess 0 und den Prozess 1 (den initProzess), schaltet den Kontext der CPU von Ring 0 auf Ring 3 um und startet den Init-Prozess (die Prozess-ID ist 1). Jetzt ist der Kernel-Boot fertig!
  6. Das initProgramm führt alle Init-Skripte aus. Alle Dienste werden gestartet. Shell heißt. Benutzer können sich anmelden.

Die mainFunktion ist eine C-Funktion. Tatsächlich ist die Hauptmethode nicht der Einstiegspunkt von C-Programmen. Die C-Laufzeit ruft viele Funktionen vorher auf main. GCC hat eine erweiterte Funktion: Konstruktoren. Als "Konstruktor" deklarierte Funktionen werden vorher aufgerufen main.

Zum Beispiel:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

Dieses Makro stammt aus dem qemu-Projekt.


Hauptmethode ist ac-Methode. Tatsächlich ist main-Methode nicht der Eintrag von c-Programm. C-Laufzeit hat viele Methoden vor main-Methode aufgerufen.
Edward Shen

Nun, BIOS lädt normalerweise einen Bootloader und dieser Bootloader lädt ein Kernel-Image (und möglicherweise eine initrd). Der Code des Kernels ist im Kernel-Image, nicht initrd
Stéphane Chazelas

GCC hat eine Erweiterungsfunktion: Konstruktor. Die Methodendeklaration "constructor" wird vor der Hauptmethode aufgerufen. Zum Beispiel: / * Dies sollte nicht direkt verwendet werden. Verwenden Sie stattdessen block_init etc. * / #define module_init (function, type) \ static void _attribute __ ((constructor)) do_qemu_init ## function (void) {\ register_module_init (function, type); \}
Edward Shen

1
initrd.img IST NICHT das Kernel-Image. Es ist eine Reihe von Modulen, die vom Kernel beim Booten geladen werden. Kernel-Images haben normalerweise Namen, die mit "vmlinuz" beginnen, unterscheiden sich jedoch von Distribution zu Distribution.
Goldlöckchen

3
Diese Antwort steckt voller "Alles ist ein PC / Linux / i86" und bootet auf diese Weise, und der Kernel ist auf diese Weise ... Warum glaubt jeder, dass dies der einzig mögliche Weg auf der Welt ist?
Jens

9

Es gibt z. B. eine main () - Funktion in arch / x86 / boot / main.c, um das System auf den Wechsel vom realen in den geschützten Modus vorzubereiten, aber andere Architekturen haben keinen solchen Code. Es gibt einen schönen Überblick darüber, wie das Booten des Linux-Kernels 2.6.x auf der x86-Plattform funktioniert. Es lohnt sich wirklich, es zu lesen.

Laut dem Dokument HOWTO do Linux Kernel Development handelt es sich um den Linux Kernel

Eine freistehende C-Umgebung, die nicht auf die Standard-C-Bibliothek angewiesen ist, sodass einige Teile des C-Standards nicht unterstützt werden.

Was bedeutet das nach dem C-Standard BTW?

Durch die Implementierung wird festgelegt, ob ein Programm in einer freistehenden Umgebung erforderlich ist, um eine Hauptfunktion zu definieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.