Kernthreads und virtuelle Adresse bearbeiten

567
seifdean

Wenn der Kernel als Threads erzeugt wird und sich im Speicher befindet, wie könnte der psBefehl sie dann identifizieren, wenn dies kein normaler Prozess ist, und ich Ihnen hier weitere Informationen gibt:

root 2 0 0 févr.04 ? 00:00:00 [kthreadd] root 3 2 0 févr.04 ? 00:00:01 [ksoftirqd/0] root 5 2 0 févr.04 ? 00:00:00 [kworker/0:0H] 

Wie wir sehen, haben diese Kernel-Threads die gleichen Informationen wie die untergeordnete Linux-Prozess-ID, die übergeordnete ID (die 0 ist) und der Besitzer des Benutzers (der root)

Bitte erkläre das.

Wenn diese Threads auf unterschiedliche Art und Weise ausgeführt werden, wie könnte die CPU also den Unterschied zwischen einem Kernel-Thread und der ausführbaren Datei des linux-Prozess-elf oder einer Bibliothek im Speicher erkennen, muss ich dies bitte wissen.

Eine andere Frage: Wenn der Compiler die ausführbare Datei erstellt, erstellt er eine vma (virtuelle Speicheradresse), die dann von der CPU zum Zuweisen von Speicherplatz verwendet wird. Wie kann der Compiler diese Adressen generieren?

Danke Jungs.

0

1 Antwort auf die Frage

0
Jamie Hanrahan

Ich kann die Frage "Kernelthreads" für Linux nicht definitiv beantworten. Für Windows kann ich Ihnen sagen, dass die "Kernel-Threads" einfach Threads sind, die aus einer anderen Kernel-Modus-Routine erstellt wurden und Prozeduren ausführen, die niemals in den Benutzermodus wechseln. Wenn der Scheduler einen Thread zur Ausführung auswählt, nimmt er seinen vorherigen Status wieder (Benutzer oder Kernel, was auch immer das war). Die CPU muss nicht "den Unterschied erkennen". Der Thread wird im Kernel-Modus ausgeführt, weil er das letzte Mal ausgeführt hat.

In Windows werden diese normalerweise mit dem sogenannten "System" -Prozess als übergeordnetem Element erstellt, sie können jedoch tatsächlich in einem beliebigen Prozess erstellt werden. In Unix können sie also eine übergeordnete ID von Null haben? dh zu keinem Prozess gehören? Dies spielt eigentlich keine Rolle, wenn der Thread nicht versucht, Ressourcen auf Prozessebene zu verwenden.

Was die vom Compiler zugewiesenen Adressen angeht ... Es gibt einige Möglichkeiten, darüber nachzudenken. Ein Teil davon ist, dass der Compiler wirklich keine Adressen für viel von allem auswählt ; Fast alles, was ein Compiler (in einer modernen Umgebung) erzeugt, bezieht sich auf Offsets. Eine gegebene lokale Variable ist etwas versetzt von dem Ort, an dem sich der Stapelzeiger befindet, wenn die Routine instanziiert wird. (Beachten Sie, dass Stacks selbst dynamisch zugewiesene Adressen haben, genau wie Heap-Zuweisungen.) Ein Routine-Einstiegspunkt ist etwas versetzt vom Anfang des Codeabschnitts, in dem er sich befindet. Etc.

Der zweite Teil der Antwort ist, dass Adressen, wie sie sind, vom Linker zugewiesen werden, nicht vom Compiler. Was die Frage wirklich aufschiebt - wie kann das gemacht werden? Womit meinen Sie, wie wissen Sie, welche Adressen zur Laufzeit verfügbar sein werden? Die Antwort lautet "praktisch alle".

Denken Sie daran, dass jeder Prozess als fast völlig leere Tabelle beginnt und der Adressraum im Benutzermodus neu erstellt wird. Beispielsweise hat jeder Prozess eine eigene Instanz von 0x10000. Abgesehen davon, dass Sie einige Dinge vermeiden müssen, die an bekannten Stellen (für den Linker sowieso) in jedem Prozess auf der Plattform vorhanden sind, kann der Linker die Dinge dort platzieren, wo er sie in den Adressraum des Prozesses legen möchte. Es muss nicht wissen oder kümmern, wo noch etwas ist.

Der dritte Teil ist, dass fast alles (außer den vom Betriebssystem definierten Dingen, die sich an bekannten Adressen befinden) zur Laufzeit an andere Adressen verschoben werden kann, da die Adressraum-Layout-Randomisierung sowohl unter Windows als auch unter Linux (von Linux freigegeben) verfügbar ist erstens tatsächlich). Es ist also eigentlich egal, wo der Linker Sachen legt.