Wie wurde der Kernel geschrieben?

Wie wurde der Kernel geschrieben?

Das Ausführen eines Programms im Kernelmodus verbietet die Verwendung einer Standard-C-Bibliothek, da das einzige, womit Ihr Programm verknüpft ist, der Kernel selbst ist. Ich darf also im Kernel definierte Funktionen verwenden. Aber der Kernel selbst ist ein in C geschriebenes und für eine bestimmte Architektur kompiliertes Programm. Und es sollte weder die C-Standardbibliothek verwenden, noch sollte es irgendwelche Treiber verwenden, da Treiber ladbare Module sind. Meine Frage ist also, welche tatsächlichen C-Funktionen beim Schreiben eines Kernels verwendet werden. Wie können Sie mit Hardware interagieren, die nicht über den Kernel funktioniert? Sagen Sie mir nicht, ich solle mir die Quellen ansehen, das ist mir zu viel, danke.

Antwort1

Der Unix-Kernel umfasst traditionellmancheAssemblercode. Ich habe mir den Quellcode in letzter Zeit nicht angesehen, aber ich vermute, dass das immer noch der Fall ist.

SehenWie kommuniziert ein Treiber eigentlich mit einem Hardwaregerät? für einen Überblick über dieses Thema. Die Antworten auf diese Frage behandeln zwei Arten von Computerarchitekturen. Auf einem System, das Port-Mapping I/O (PMIO) verwendet, der Kernelmussteilweise in Assemblersprache geschrieben werden – obwohl Sie vielleicht mit ein paar sehr kurzen Routinen auskommen. Auf einem System, das Memory-Mapped I/O (MMIO) verwendet, können sogar Gerätetreiber vollständig in C geschrieben werden. Sie müssen lediglich einen Zeiger deklarieren, ihn auf die virtuelle Adresse des Geräts setzen und ihn dann verwenden, um das Gerät zu manipulieren, als würde es auf den Speicher zugreifen.

Antwort2

Nicht alle Treiber sind ladbare Module. Die Ladebarkeit ist lediglich eine Option. Einige wichtige Treiber werden jedoch nicht dynamisch geladen, sondern sind Teil des Kernels.

Antwort3

Der Kernel reproduziert einen Großteil der von libc bereitgestellten Funktionalität statisch in sich selbst.

Genau wie bei der C-Programmierung im Benutzermodus kann eine Funktion in einer Kompilierungseinheit definiert werden und eine andere Einheit kann einfach darauf verweisen (normalerweise über eine Header-Datei). Der Compiler macht daraus eine undefinierte Referenz und der Linker verknüpft sie mit der Kompilierungseinheit, die das Symbol tatsächlich bereitstellt.

Das Laden von Kernelmodulen funktioniert nach dem gleichen Prinzip wiedynamische Belastungund es wird hier beschrieben: http://www.tldp.org/LDP/tlk/modules/modules.html

verwandte Informationen