Was ist der Unterschied zwischen dem Kernel-Space und dem User-Space?


Antworten:


116

Die wirklich vereinfachte Antwort lautet, dass der Kernel im Kernelbereich und normale Programme im Benutzerbereich ausgeführt werden. Der Benutzerbereich ist im Grunde eine Form des Sandboxing - er schränkt Benutzerprogramme ein, damit sie nicht mit dem Speicher (und anderen Ressourcen) anderer Programme oder des Betriebssystemkerns in Konflikt geraten können. Dies schränkt ihre Fähigkeit ein, schlechte Dinge wie einen Absturz der Maschine zu tun (beseitigt sie jedoch normalerweise nicht vollständig).

Der Kernel ist der Kern des Betriebssystems. Normalerweise hat es vollen Zugriff auf alle Speicher- und Maschinenhardware (und alles andere auf der Maschine). Um den Computer so stabil wie möglich zu halten, möchten Sie normalerweise, dass nur der vertrauenswürdigste und am besten getestete Code im Kernelmodus / Kernelspeicher ausgeführt wird.

Der Stapel ist nur ein weiterer Teil des Speichers, daher ist er natürlich zusammen mit dem Rest des Speichers getrennt.


3
Sagen Sie also, wenn ich 10 Prozesse in meinem System habe. Hat jeder Prozess einen eigenen Stapel, der in einen Benutzerstapel und einen Kernelstapel unterteilt ist, ODER teilen sich alle Prozesse einen einzelnen Kernelstapel?
kc3

10
@ kc3: Das hängt zumindest teilweise vom Betriebssystem ab, aber ich glaube, die meisten haben einen Kernel-Modus-Stack für jeden Prozess, der verwendet wird, wenn der Kernel Dinge für einen Prozess ausführt (z. B. E / A), und mindestens einen weiteren Kernel-Stack, der ausschließlich für den internen Gebrauch durch den Kernel bestimmt ist (z. B. für die Planung).
Jerry Coffin

2
Gibt es Existenzen von Kernelprozessen und wie ist die Beziehung oder der Unterschied zu den fraglichen Userspace-Prozessen?
Victor Choy

Also per se, um einen User-Space- Prozess auszuführen , muss er dem Kernel-Space zugeordnet werden ?
Roottraveller

@roottraveller: Ich bin nicht sicher, was dich auf diese Idee gebracht hat, aber nein, überhaupt nicht. Zur gleichen Zeit, ein User-Space - Prozess wird normalerweise einig (mehr oder weniger versteckt) Kernel-Space - Speicher, so (zum Beispiel) Ihr Prozess wird einen User-Space - Stack und einen Kernel-Space - Stack, der verwendet wird, wenn Sie Führen Sie Betriebssystemaufrufe durch, die im Kernelmodus ausgeführt werden müssen.
Jerry Coffin

63

Der Direktzugriffsspeicher (RAM) kann logisch in zwei unterschiedliche Bereiche unterteilt werden, nämlich den Kernelraum und den Benutzerraum. ( Die physischen Adressen des RAM sind nicht nur die virtuellen Adressen , die alle von der MMU implementiert werden. )

Der Kernel läuft in dem Teil des Speichers, der dazu berechtigt ist. Auf diesen Teil des Speichers können die Prozesse der normalen Benutzer nicht direkt zugreifen, während der Kernel auf alle Teile des Speichers zugreifen kann. Um einen Teil des Kernels zugreifen, müssen die Benutzerprozesse die vordefinierte Systemaufrufe , dh verwenden open, read, writeetc. Auch die CBibliotheksfunktionen wie printfAnruf der Systemaufruf writewiederum.

Die Systemaufrufe fungieren als Schnittstelle zwischen den Benutzerprozessen und den Kernelprozessen. Die Zugriffsrechte werden auf den Kernelbereich gelegt, um zu verhindern, dass die Benutzer unwissentlich mit dem Kernel herumspielen.

Wenn also ein Systemaufruf auftritt, wird ein Software-Interrupt an den Kernel gesendet. Die CPU kann die Steuerung vorübergehend an die zugehörige Interrupt-Handler-Routine übergeben. Der durch den Interrupt angehaltene Kernelprozess wird fortgesetzt, nachdem die Interrupt-Handler-Routine ihren Job beendet hat.


2
Der erste Teil dieser Antwort ist falsch. RAM ist nicht in Kernel und Benutzerbereich aufgeteilt. Virtueller Speicher ist. Ich habe versucht, die Antwort zu bearbeiten, aber die Bearbeitungswarteschlange ist seit Tagen voll. Bitte repariere. Weitere Informationen finden Sie in Varuns Antwort unten.
MeLikeyCode

1
@MeLikeyCode Ist das nicht eine berechtigte Vereinfachung im Zusammenhang mit dem Versuch, eine allgemein verständliche Antwort zu geben?
Problemoffizier

2
@problemofficer, ich denke, dass eine große Vereinfachung ein falsches Grundverständnis liefern kann. Jeder sollte herausfinden, dass der physische Speicher nicht in Benutzer- und Kernelbereich unterteilt ist, sondern dass der Kernel eine Abstraktion des virtuellen Speichers bereitstellt, die in Kernel und Benutzerbereich unterteilt und später einem physischen Speicher zugeordnet wird.
dshil

22

Kernel Space & Virtual Space sind Konzepte des virtuellen Speichers. Dies bedeutet nicht, dass Ram (Ihr tatsächlicher Speicher) in Kernel & User Space unterteilt ist. Jeder Prozess erhält einen virtuellen Speicher, der in Kernel und Benutzerbereich unterteilt ist.

So heißt es: "Der Direktzugriffsspeicher (RAM) kann in zwei verschiedene Bereiche unterteilt werden, nämlich den Kernelraum und den Benutzerraum." ist falsch.

& in Bezug auf "Kernel Space vs User Space" Sache

Wenn ein Prozess erstellt wird und sein virtueller Speicher in einen Benutzerbereich und einen Kernelbereich unterteilt ist, enthält der Benutzerbereich Daten, Code, Stapel, Heap des Prozesses und der Kernelbereich enthält beispielsweise die Seitentabelle für den Prozess , Kernel-Datenstrukturen und Kernel-Code usw. Um den Kernel-Space-Code auszuführen, muss die Steuerung in den Kernel-Modus wechseln (unter Verwendung eines 0x80-Software-Interrupts für Systemaufrufe). Der Kernel-Stack wird grundsätzlich von allen Prozessen gemeinsam genutzt, die derzeit im Kernel-Space ausgeführt werden.


1
Ein gemeinsamer Prozess hat seinen eigenen Kernel- und Benutzerraum?
Victor Choy

@ VictorChoy, ein Prozess wird in zwei Modi ausgeführt: Benutzer und Kernel. Die Erinnerung, die der Prozess sieht, ist einzigartig für ihn. Für alle Prozesse, die im Kernelmodus ausgeführt werden (Kernelcode ausführen), gibt es jedoch nur einen Speicherplatz - den Kernelbereich.
dshil

Beachten Sie außerdem, dass der virtuelle Speicher eines Prozesses beim Erstellen in zwei Teile (Benutzer und Kernel) unterteilt ist, wobei ein Teil der virtuellen Adressen für den Benutzermodus und ein anderer Teil für den Kernelmodus reserviert ist.
dshil

19

CPU-Ringe sind die klarste Unterscheidung

Im x86-geschützten Modus befindet sich die CPU immer in einem von 4 Ringen. Der Linux-Kernel verwendet nur 0 und 3:

  • 0 für Kernel
  • 3 für Benutzer

Dies ist die schwierigste und schnellste Definition von Kernel vs. Userland.

Warum verwendet Linux die Ringe 1 und 2 nicht: CPU-Berechtigungsringe: Warum werden die Ringe 1 und 2 nicht verwendet?

Wie wird der aktuelle Ring ermittelt?

Der aktuelle Ring wird durch eine Kombination von:

  • Globale Deskriptortabelle: Eine speicherinterne Tabelle mit GDT-Einträgen, und jeder Eintrag verfügt über ein Feld Privl , das den Ring codiert.

    Der LGDT-Befehl setzt die Adresse auf die aktuelle Deskriptortabelle.

    Siehe auch: http://wiki.osdev.org/Global_Descriptor_Table

  • Das Segment registriert CS, DS usw., die auf den Index eines Eintrags in der GDT verweisen.

    CS = 0Dies bedeutet beispielsweise, dass der erste Eintrag des GDT derzeit für den ausführenden Code aktiv ist.

Was kann jeder Ring?

Der CPU-Chip ist physisch so aufgebaut, dass:

  • Ring 0 kann alles

  • Ring 3 kann nicht mehrere Anweisungen ausführen und in mehrere Register schreiben, insbesondere:

    • kann seinen eigenen Ring nicht ändern! Andernfalls könnte es sich auf Ring 0 setzen und Ringe wären nutzlos.

      Mit anderen Worten, der aktuelle Segmentdeskriptor , der den aktuellen Ring bestimmt , kann nicht geändert werden .

    • Die Seitentabellen können nicht geändert werden: Wie funktioniert x86-Paging?

      Mit anderen Worten, das CR3-Register kann nicht geändert werden, und das Paging selbst verhindert das Ändern der Seitentabellen.

      Dies verhindert, dass ein Prozess aus Sicherheits- / Programmiergründen den Speicher anderer Prozesse sieht.

    • Interrupt-Handler können nicht registriert werden. Diese werden durch Schreiben in Speicherorte konfiguriert, was auch durch Paging verhindert wird.

      Handler werden in Ring 0 ausgeführt und würden das Sicherheitsmodell beschädigen.

      Mit anderen Worten, kann die LGDT- und LIDT-Anweisungen nicht verwenden.

    • kann keine E / A-Anweisungen wie inund ausführen und outverfügt daher über beliebige Hardwarezugriffe.

      Andernfalls wären beispielsweise Dateiberechtigungen nutzlos, wenn ein Programm direkt von der Festplatte lesen könnte.

      Genauer gesagt dank Michael Petch : Es ist dem Betriebssystem tatsächlich möglich, E / A-Anweisungen auf Ring 3 zuzulassen, dies wird tatsächlich vom Task- Statussegment gesteuert .

      Was nicht möglich ist, ist, dass sich Ring 3 die Erlaubnis dazu gibt, wenn er es überhaupt nicht hatte.

      Linux verbietet es immer. Siehe auch: Warum verwendet Linux den Hardware-Kontextschalter nicht über das TSS?

Wie wechseln Programme und Betriebssysteme zwischen Ringen?

  • Wenn die CPU eingeschaltet ist, startet sie das erste Programm in Ring 0 (gut, aber es ist eine gute Annäherung). Sie können sich dieses anfängliche Programm als den Kernel vorstellen (aber normalerweise ist es ein Bootloader, der den Kernel dann noch in Ring 0 aufruft ).

  • Wenn ein Userland-Prozess möchte, dass der Kernel etwas dafür tut, z. B. in eine Datei schreiben, verwendet er eine Anweisung, die einen Interrupt generiert, z. B. int 0x80odersyscall um den Kernel zu signalisieren. x86-64 Linux Syscall Hallo Welt Beispiel:

    .data
    hello_world:
        .ascii "hello world\n"
        hello_world_len = . - hello_world
    .text
    .global _start
    _start:
        /* write */
        mov $1, %rax
        mov $1, %rdi
        mov $hello_world, %rsi
        mov $hello_world_len, %rdx
        syscall
    
        /* exit */
        mov $60, %rax
        mov $0, %rdi
        syscall
    

    kompilieren und ausführen:

    as -o hello_world.o hello_world.S
    ld -o hello_world.out hello_world.o
    ./hello_world.out
    

    GitHub stromaufwärts .

    In diesem Fall ruft die CPU einen Interrupt-Callback-Handler auf, den der Kernel beim Booten registriert hat. Hier ist ein konkretes Baremetall-Beispiel, das einen Handler registriert und verwendet .

    Dieser Handler wird in Ring 0 ausgeführt, der entscheidet, ob der Kernel diese Aktion zulässt, die Aktion ausführt und das Userland-Programm in Ring 3 neu startet. X86_64

  • Wenn der execSystemaufruf verwendet wird (oder wenn der Kernel gestartet wird/init ), bereitet der Kernel die Register und den Speicher des neuen Userland-Prozesses vor, springt dann zum Einstiegspunkt und schaltet die CPU auf Ring 3

  • Wenn das Programm versucht, etwas Unartiges wie das Schreiben in ein verbotenes Register oder eine Speicheradresse (wegen Paging) zu tun, ruft die CPU auch einen Kernel-Callback-Handler in Ring 0 auf.

    Aber da das Benutzerland ungezogen war, könnte der Kernel den Prozess dieses Mal beenden oder ihm eine Warnung mit einem Signal geben.

  • Wenn der Kernel startet, richtet er eine Hardware-Uhr mit einer festen Frequenz ein, die regelmäßig Interrupts erzeugt.

    Diese Hardware-Uhr generiert Interrupts, die Ring 0 ausführen, und ermöglicht es ihr, zu planen, welche Userland-Prozesse aufgeweckt werden sollen.

    Auf diese Weise kann die Planung auch dann erfolgen, wenn die Prozesse keine Systemaufrufe ausführen.

Was bringt es, mehrere Ringe zu haben?

Die Trennung von Kernel und Userland bietet zwei Hauptvorteile:

  • Es ist einfacher, Programme zu erstellen, da Sie sicherer sind, dass eines das andere nicht stört. Beispielsweise muss sich ein Userland-Prozess nicht darum kümmern, den Speicher eines anderen Programms aufgrund von Paging zu überschreiben oder die Hardware für einen anderen Prozess in einen ungültigen Zustand zu versetzen.
  • es ist sicherer. Beispielsweise können Dateiberechtigungen und Speichertrennung verhindern, dass eine Hacking-App Ihre Bankdaten liest. Dies setzt natürlich voraus, dass Sie dem Kernel vertrauen.

Wie kann man damit herumspielen?

Ich habe ein Bare-Metal-Setup erstellt, mit dem sich Ringe direkt manipulieren lassen: https://github.com/cirosantilli/x86-bare-metal-examples

Ich hatte leider nicht die Geduld, ein Userland-Beispiel zu erstellen, aber ich ging so weit wie das Paging-Setup, sodass Userland machbar sein sollte. Ich würde gerne eine Pull-Anfrage sehen.

Alternativ werden Linux-Kernelmodule in Ring 0 ausgeführt, sodass Sie sie zum Ausprobieren privilegierter Operationen verwenden können, z. B. zum Lesen der Steuerregister: Wie kann man von einem Programm aus auf die Steuerregister cr0, cr2, cr3 zugreifen? Segmentierungsfehler erhalten

Hier ist ein praktisches QEMU + Buildroot-Setup mit dem Sie es ausprobieren können, ohne Ihren Host zu töten.

Der Nachteil von Kernelmodulen ist, dass andere kthreads ausgeführt werden und Ihre Experimente beeinträchtigen können. Theoretisch können Sie jedoch alle Interrupt-Handler mit Ihrem Kernelmodul übernehmen und das System besitzen, das wäre eigentlich ein interessantes Projekt.

Negative Ringe

Während im Intel-Handbuch nicht auf negative Ringe verwiesen wird, gibt es tatsächlich CPU-Modi, die über weitere Funktionen als Ring 0 selbst verfügen und daher gut zum Namen "negativer Ring" passen.

Ein Beispiel ist der in der Virtualisierung verwendete Hypervisor-Modus.

Für weitere Details siehe:

ARM

In ARM werden die Ringe stattdessen als Ausnahmeebenen bezeichnet, aber die Hauptideen bleiben dieselben.

In ARMv8 gibt es 4 Ausnahmestufen, die häufig verwendet werden als:

  • EL0: Benutzerland

  • EL1: Kernel ("Supervisor" in der ARM-Terminologie).

    Eingetragen mit der svcAnweisung (SuperVisor Call), die zuvor als swi vor der einheitlichen Assembly bekannt war. Diese Anweisung wird zum Ausführen von Linux-Systemaufrufen verwendet. Hallo Welt ARMv8 Beispiel:

    hallo.S

    .text
    .global _start
    _start:
        /* write */
        mov x0, 1
        ldr x1, =msg
        ldr x2, =len
        mov x8, 64
        svc 0
    
        /* exit */
        mov x0, 0
        mov x8, 93
        svc 0
    msg:
        .ascii "hello syscall v8\n"
    len = . - msg
    

    GitHub stromaufwärts .

    Testen Sie es mit QEMU unter Ubuntu 16.04:

    sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
    arm-linux-gnueabihf-as -o hello.o hello.S
    arm-linux-gnueabihf-ld -o hello hello.o
    qemu-arm hello
    

    Hier ist ein konkretes Baremetall-Beispiel, das einen SVC-Handler registriert und einen SVC-Aufruf ausführt .

  • EL2: Hypervisoren , zum Beispiel Xen .

    Eingetragen mit der hvcAnweisung (HyperVisor Call).

    Ein Hypervisor ist für ein Betriebssystem, was ein Betriebssystem für Userland ist.

    Mit Xen können Sie beispielsweise mehrere Betriebssysteme wie Linux oder Windows gleichzeitig auf demselben System ausführen und die Betriebssysteme aus Sicherheits- und Debug-Gründen voneinander isolieren, genau wie Linux dies für Userland-Programme tut.

    Hypervisoren sind ein wichtiger Bestandteil der heutigen Cloud-Infrastruktur: Sie ermöglichen die Ausführung mehrerer Server auf einer einzigen Hardware, halten die Hardware-Auslastung immer nahe 100% und sparen viel Geld.

    AWS beispielsweise verwendete Xen bis 2017, als der Wechsel zu KVM die Nachricht verbreitete .

  • EL3: noch ein Level. TODO Beispiel.

    Eingetragen mit der smcAnweisung (Secure Mode Call)

Das Referenzmodell für die ARMv8-Architektur DDI 0487C.a - Kapitel D1 - Das Programmierermodell auf AArch64-Systemebene - Abbildung D1-1 veranschaulicht dies auf wunderbare Weise:

Geben Sie hier die Bildbeschreibung ein

Die ARM-Situation hat sich mit dem Aufkommen von ARMv8.1 Virtualization Host Extensions (VHE) ein wenig geändert . Mit dieser Erweiterung kann der Kernel effizient in EL2 ausgeführt werden:

Geben Sie hier die Bildbeschreibung ein

VHE wurde entwickelt, weil In-Linux-Kernel-Virtualisierungslösungen wie KVM gegenüber Xen an Boden gewonnen haben (siehe z. B. die oben erwähnte Umstellung von AWS auf KVM), da die meisten Clients nur Linux-VMs benötigen und, wie Sie sich vorstellen können, alles in einem einzigen sind Projekt ist KVM einfacher und möglicherweise effizienter als Xen. In diesen Fällen fungiert nun der Linux-Kernel des Hosts als Hypervisor.

Beachten Sie, dass ARM, möglicherweise aufgrund des Vorteils der Rückschau, eine bessere Namenskonvention für die Berechtigungsstufen als x86 hat, ohne dass negative Stufen erforderlich sind: 0 ist die niedrigere und 3 die höchste. Höhere Ebenen werden in der Regel häufiger erstellt als niedrigere.

Die aktuelle EL kann mit folgender MRSAnweisung abgefragt werden : Was ist der aktuelle Ausführungsmodus / Ausnahmestufe usw.?

ARM erfordert nicht, dass alle Ausnahmestufen vorhanden sind, um Implementierungen zu ermöglichen, bei denen die Funktion zum Speichern des Chipbereichs nicht erforderlich ist. ARMv8 "Ausnahmestufen" sagt:

Eine Implementierung enthält möglicherweise nicht alle Ausnahmestufen. Alle Implementierungen müssen EL0 und EL1 enthalten. EL2 und EL3 sind optional.

QEMU zum Beispiel ist standardmäßig EL1, aber EL2 und EL3 können mit Befehlszeilenoptionen aktiviert werden: qemu-system-aarch64 gibt el1 ein, wenn a53 eingeschaltet wird

Code-Snippets, die unter Ubuntu 18.10 getestet wurden.


11

Kernel Space und User Space ist die Trennung der privilegierten Betriebssystemfunktionen und der eingeschränkten Benutzeranwendungen. Die Trennung ist erforderlich, um zu verhindern, dass Benutzeranwendungen Ihren Computer durchsuchen. Es wäre eine schlechte Sache, wenn ein altes Benutzerprogramm zufällige Daten auf Ihre Festplatte schreiben oder Speicher aus dem Speicher eines anderen Benutzerprogramms lesen könnte.

User Space-Programme können nicht direkt auf Systemressourcen zugreifen, sodass der Zugriff im Namen des Programms vom Betriebssystemkernel ausgeführt wird. Die User-Space-Programme stellen solche Anforderungen normalerweise über Systemaufrufe an das Betriebssystem.

Kernel-Threads, Prozesse und Stacks bedeuten nicht dasselbe. Sie sind analoge Konstrukte für den Kernelraum als ihre Gegenstücke im Benutzerraum.


8

Jeder Prozess verfügt über einen eigenen virtuellen Speicher von 4 GB, der über Seitentabellen dem physischen Speicher zugeordnet wird. Der virtuelle Speicher besteht hauptsächlich aus zwei Teilen: 3 GB für die Verwendung des Prozesses und 1 GB für die Verwendung des Kernels. Die meisten von Ihnen erstellten Variablen befinden sich im ersten Teil des Adressraums. Dieser Teil wird als Benutzerbereich bezeichnet. Im letzten Teil befindet sich der Kernel und ist für alle Prozesse gleich. Dies wird als Kernel-Speicherplatz bezeichnet, und der größte Teil dieses Speicherplatzes wird den Startpositionen des physischen Speichers zugeordnet, an denen das Kernel-Image beim Booten geladen wird.


1
Ihre Antwort ist spezifisch für Windows. Sie sollten das klarstellen.
Matthew

1
Sie sagen, dass für jeden Prozess aus 4 GB virtuellem Speicher 1 GB Kernel-Speicherplatz ist, der für jeden Prozess gleich ist und nur die Zuordnung enthält. Ich kann nicht verstehen, warum !!, warum 1 GB nur für die Zuordnung zum Startspeicherort erforderlich ist?
VISHAL DAGA

5

Die maximale Größe des Adressraums hängt von der Länge des Adressregisters auf der CPU ab.

Auf Systemen mit 32-Bit-Adressregistern beträgt die maximale Größe des Adressraums 2 32 Byte oder 4 GiB. In ähnlicher Weise können auf 64-Bit-Systemen 2 64 Bytes adressiert werden.

Ein solcher Adressraum wird als virtueller Speicher oder virtueller Adressraum bezeichnet . Es hängt nicht wirklich mit der physischen RAM-Größe zusammen.

Auf Linux-Plattformen ist der virtuelle Adressraum in Kernelraum und Benutzerraum unterteilt.

Eine architekturspezifische Konstante, die als Taskgrößenbeschränkung bezeichnet wird , oder TASK_SIZEmarkiert die Position, an der die Aufteilung erfolgt:

  • Der Adressbereich von 0 bis TASK_SIZE-1 wird dem Benutzerraum zugewiesen.

  • Der Rest von TASK_SIZEbis zu 2 32 -1 (oder 2 64 -1) wird dem Kernelraum zugewiesen.

Auf einem bestimmten 32-Bit-System könnten beispielsweise 3 GiB für den Benutzerraum und 1 GiB für den Kernelraum belegt sein.

Jede Anwendung / jedes Programm in einem Unix-ähnlichen Betriebssystem ist ein Prozess. Jeder von ihnen hat eine eindeutige Kennung, die als Prozesskennung (oder einfach als Prozess-ID , dh PID) bezeichnet wird. Linux bietet zwei Mechanismen zum Erstellen eines Prozesses: 1. den fork()Systemaufruf oder 2. denexec() Aufruf.

Ein Kernel-Thread ist ein einfacher Prozess und auch ein Programm, das gerade ausgeführt wird. Ein einzelner Prozess kann aus mehreren Threads bestehen, die dieselben Daten und Ressourcen gemeinsam nutzen, jedoch unterschiedliche Pfade durch den Programmcode nehmen. Linux bietet einen clone()Systemaufruf zum Generieren von Threads.

Beispielanwendungen von Kernel-Threads sind: Datensynchronisation des RAM, Unterstützung des Schedulers bei der Verteilung von Prozessen auf CPUs usw.


4

Kurz gesagt: Der Kernel wird im Kernel Space ausgeführt. Der Kernel Space hat vollen Zugriff auf den gesamten Speicher und die Ressourcen. Sie können sagen, dass der Speicher in zwei Teile unterteilt ist: Teil für Kernel und Teil für benutzereigenen Prozess. (User Space) führt normale Programme aus Der Speicherplatz kann nicht direkt auf den Kernelspeicherplatz zugreifen, sodass der Kernel die Verwendung von Ressourcen anfordert. per syscall (vordefinierter Systemaufruf in glibc)

Es gibt eine Aussage, die die verschiedenen " User Space ist nur eine Testlast für den Kernel " vereinfacht ...

Um es ganz klar auszudrücken: Die Prozessorarchitektur ermöglicht es der CPU, im Zwei-Modus, dem Kernel-Modus und dem Benutzermodus , zu arbeiten. Der Hardware-Befehl ermöglicht das Umschalten von einem Modus in den anderen.

Speicher kann als Teil des Benutzer- oder Kernelbereichs markiert werden.

Wenn die CPU im Benutzermodus ausgeführt wird, kann die CPU nur auf Speicher zugreifen, der sich im Benutzerbereich befindet, während die CPU versucht, auf den Speicher im Kernelbereich zuzugreifen. Das Ergebnis ist eine "Hardware-Ausnahme". Wenn die CPU im Kernelmodus ausgeführt wird, kann die CPU direkt darauf zugreifen sowohl zum Kernel-Space als auch zum User-Space ...


2

Der Kernelraum bedeutet, dass ein Speicherraum nur vom Kernel berührt werden kann. Unter 32-Bit-Linux ist es 1G (von 0xC0000000 bis 0xffffffff als virtuelle Speicheradresse). Jeder vom Kernel erstellte Prozess ist auch ein Kernel-Thread. Für einen Prozess gibt es also zwei Stapel: einen Stapel im Benutzerbereich für diesen Prozess und einen anderen im Kernel Platz für Kernel-Thread.

Der Kernel-Stack belegte 2 Seiten (8 KB unter 32-Bit-Linux), enthielt einen task_struct (ca. 1 KB) und den realen Stack (ca. 7 KB). Letzteres wird verwendet, um einige automatische Variablen oder Funktionsaufrufparameter oder Funktionsadressen in Kernelfunktionen zu speichern. Hier ist der Code (Processor.h (linux \ include \ asm-i386)):

#define THREAD_SIZE (2*PAGE_SIZE)
#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
#define free_task_struct(p) free_pages((unsigned long) (p), 1)

__get_free_pages (GFP_KERNEL, 1)) bedeutet, Speicher als 2 ^ 1 = 2 Seiten zuzuweisen.

Aber der Prozessstapel ist eine andere Sache, seine Adresse ist nur unter 0xC0000000 (32-Bit-Linux), die Größe kann ziemlich größer sein und wird für die Funktionsaufrufe des Benutzerraums verwendet.

Hier ist also eine Frage für den Systemaufruf: Er wird im Kernel ausgeführt, wurde aber vom Prozess im Benutzerbereich aufgerufen. Wie funktioniert er? Wird Linux seine Parameter und Funktionsadresse in den Kernel-Stack oder den Prozess-Stack stellen? Linux-Lösung: Alle Systemaufrufe werden durch Software-Unterbrechung INT 0x80 ausgelöst. In entry.S (linux \ arch \ i386 \ kernel) definiert, sind hier einige Zeilen zum Beispiel:

ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall)   /* 0  -  old "setup()" system call*/
.long SYMBOL_NAME(sys_exit)
.long SYMBOL_NAME(sys_fork)
.long SYMBOL_NAME(sys_read)
.long SYMBOL_NAME(sys_write)
.long SYMBOL_NAME(sys_open)     /* 5 */
.long SYMBOL_NAME(sys_close)

Die letzte Frage ist sehr gut, die Sie gestellt haben. Aber nur Software-Unterbrechung INT 0x80 , und dann? Es ist keine gute Erklärung für mich. Können Sie detailliert erklären, wie die Lösung für die von Ihnen selbst gestellte Frage funktioniert?
Victor Choy

2

Von Sunil Yadav auf Quora:

Der Linux-Kernel bezieht sich auf alles, was im Kernel-Modus ausgeführt wird und aus mehreren unterschiedlichen Ebenen besteht. Auf der untersten Ebene interagiert der Kernel über die HAL mit der Hardware. Auf der mittleren Ebene ist der UNIX-Kernel in vier verschiedene Bereiche unterteilt. Der erste der vier Bereiche befasst sich mit Zeichengeräten, rohem und gekochtem TTY und Terminal-Handling. Der zweite Bereich behandelt Netzwerkgerätetreiber, Routing-Protokolle und Sockets. Der dritte Bereich behandelt Festplattengerätetreiber, Seiten- und Puffercaches, Dateisystem, virtuellen Speicher, Dateinamen und Zuordnung. Der vierte und letzte Bereich befasst sich mit der Prozessverteilung, -planung, -erstellung und -beendigung sowie der Signalverarbeitung. Vor allem haben wir die oberste Ebene des Kernels, die Systemaufrufe, Interrupts und Traps enthält. Diese Ebene dient als Schnittstelle zu jeder der Funktionen der unteren Ebene. Ein Programmierer verwendet die verschiedenen Systemaufrufe und Interrupts, um mit den Funktionen des Betriebssystems zu interagieren.



1

Ich versuche eine sehr vereinfachte Erklärung zu geben

Der virtuelle Speicher ist in den Kernelbereich und den Benutzerbereich unterteilt. Der Kernelbereich ist der Bereich des virtuellen Speichers, in dem Kernelprozesse ausgeführt werden, und der Benutzerbereich ist der Bereich des virtuellen Speichers, in dem Benutzerprozesse ausgeführt werden.

Diese Unterteilung ist für den Speicherzugriffsschutz erforderlich.

Wenn ein Bootloader einen Kernel startet, nachdem er an einen Speicherort im RAM geladen wurde (normalerweise auf einem ARM-basierten Controller), muss er sicherstellen, dass sich der Controller im Supervisor-Modus befindet und FIQs und IRQs deaktiviert sind.


1

Kernel Space und User Space sind logische Räume.

Die meisten modernen Prozessoren sind so konzipiert, dass sie in verschiedenen privilegierten Modi ausgeführt werden. x86-Computer können in 4 verschiedenen privilegierten Modi ausgeführt werden. Geben Sie hier die Bildbeschreibung ein

Und eine bestimmte Maschinenanweisung kann ausgeführt werden, wenn sie sich in / über einem bestimmten privilegierten Modus befindet.

Aufgrund dieses Designs bieten Sie einen Systemschutz oder Sandboxing für die Ausführungsumgebung.

Der Kernel ist ein Code, der Ihre Hardware verwaltet und die Systemabstraktion bereitstellt. Es muss also Zugriff auf alle Maschinenanweisungen haben. Und es ist die vertrauenswürdigste Software. Also sollte ich mit dem höchsten Privileg hingerichtet werden. Und Ring Level 0 ist der privilegierteste Modus. Daher wird Ring Level 0 auch als Kernel-Modus bezeichnet .

Benutzeranwendungen sind Software, die von Drittanbietern stammt und denen Sie nicht vollständig vertrauen können. Jemand mit böswilliger Absicht kann einen Code zum Absturz Ihres Systems schreiben, wenn er vollständigen Zugriff auf alle Maschinenanweisungen hat. Daher sollte der Anwendung Zugriff auf begrenzte Anweisungen gewährt werden. Und Ring Level 3 ist der am wenigsten privilegierte Modus. Ihre gesamte Anwendung wird also in diesem Modus ausgeführt. Daher wird dieser Ring Level 3 auch als Benutzermodus bezeichnet .

Hinweis: Ich erhalte keine Ringstufen 1 und 2. Es handelt sich im Grunde genommen um Modi mit Zwischenberechtigungen. Möglicherweise werden Gerätetreibercodes mit diesem Privileg ausgeführt. AFAIK, Linux verwendet nur Ring Level 0 und 3 für die Kernel-Code-Ausführung bzw. die Benutzeranwendung.

Daher kann jede Operation, die im Kernelmodus ausgeführt wird, als Kernelraum betrachtet werden. Und jede Operation, die im Benutzermodus ausgeführt wird, kann als Benutzerbereich betrachtet werden.


0

Die richtige Antwort lautet: Es gibt keinen Kernel- und Benutzerbereich. Der Prozessorbefehlssatz verfügt über spezielle Berechtigungen zum Festlegen destruktiver Elemente wie dem Stammverzeichnis der Seitentabellenzuordnung oder dem Zugriff auf den Speicher des Hardwaregeräts usw.

Kernel-Code hat die höchsten Berechtigungen und Benutzercode die niedrigsten. Dies verhindert, dass Benutzercode das System zum Absturz bringt, andere Programme ändert usw.

Im Allgemeinen wird der Kernelcode unter einer anderen Speicherzuordnung als der Benutzercode gespeichert (genauso wie Benutzerbereiche in anderen Speicherzuordnungen als die anderen gespeichert werden). Hierher kommen die Begriffe "Kernel Space" und "User Space". Aber das ist keine feste Regel. Da der x86 beispielsweise indirekt erfordert, dass seine Interrupt- / Trap-Handler jederzeit zugeordnet werden, muss ein Teil (oder einige Betriebssysteme alle) des Kernels dem Benutzerbereich zugeordnet werden. Dies bedeutet wiederum nicht, dass dieser Code über Benutzerrechte verfügt.

Warum ist die Trennung zwischen Kernel und Benutzer notwendig? Einige Designer sind sich nicht einig, dass dies tatsächlich notwendig ist. Die Mikrokernel-Architektur basiert auf der Idee, dass die Codeabschnitte mit den höchsten Berechtigungen so klein wie möglich sein sollten, wobei alle wichtigen Vorgänge im Code mit Benutzerberechtigungen ausgeführt werden sollten. Sie müssten untersuchen, warum dies eine gute Idee sein könnte, es ist kein einfaches Konzept (und es ist berühmt dafür, Vor- und Nachteile zu haben).


0

Das Gedächtnis wird in zwei verschiedene Bereiche unterteilt:

  • Der Benutzerbereich, bei dem es sich um eine Reihe von Speicherorten handelt, an denen normale Benutzerprozesse ausgeführt werden (dh alles andere als der Kernel). Die Rolle des Kernels besteht darin, die in diesem Bereich ausgeführten Anwendungen so zu verwalten, dass sie nicht miteinander und mit dem Computer in Konflikt geraten.
  • Der Kernelbereich, in dem der Code des Kernels gespeichert ist und unter dem ausgeführt wird.

Prozesse, die unter dem Benutzerbereich ausgeführt werden, haben nur Zugriff auf einen begrenzten Teil des Speichers, während der Kernel Zugriff auf den gesamten Speicher hat. Prozesse, die im Benutzerbereich ausgeführt werden, haben auch keinen Zugriff auf den Kernelbereich. User Space-Prozesse können nur über eine vom Kernel bereitgestellte Schnittstelle - die Systemaufrufe - auf einen kleinen Teil des Kernels zugreifen. Wenn ein Prozess einen Systemaufruf ausführt, wird ein Software-Interrupt an den Kernel gesendet, der dann den entsprechenden Interrupt-Handler sendet und fortfährt seine Arbeit, nachdem der Handler beendet ist.


-7

Unter Linux gibt es zwei Leerzeichen: 1. ist Benutzerbereich und ein anderer ist Kernraum. Der Benutzerbereich besteht nur aus der Benutzeranwendung, die Sie ausführen möchten. Als kernaler Dienst gibt es Prozessverwaltung, Dateiverwaltung, Signalverarbeitung, Speicherverwaltung, Threadverwaltung und so viele Dienste sind dort vorhanden. Wenn Sie die Anwendung über den Benutzerbereich ausführen, interagiert diese Anwendung nur mit dem Kernal-Dienst. und dieser Dienst interagiert mit dem Gerätetreiber, der zwischen Hardware und Kern vorhanden ist. Der Hauptvorteil der Trennung von Kernraum und Benutzerraum besteht darin, dass wir durch die virus.bcaz eine Sicherheit aller im Benutzerraum vorhandenen Benutzeranwendungen erreichen können und der Dienst im Kernraum vorhanden ist. Deshalb wirkt sich Linux nicht auf den Virus aus.


5
Abgesehen von der Tatsache, dass es sich um "Kernel" und nicht um "Kernel" handelt, ist Ihre Antwort nicht ganz richtig. Moderne Viren (und mit modern meine ich alles nach Windows 98) interagieren überhaupt nicht mit dem "Kernel-Dienst", alles wird im Benutzerbereich erledigt. Die Tatsache, dass Linux nicht viele Viren hat (es gibt natürlich Viren für Linux), ist, dass es ein ziemlich gutes Berechtigungsmanagement hat und - die wichtigste Tatsache - die meisten Linux-Benutzer sind nicht diese: "omaigosh JustinBieber.NewSong.exe! Ich muss es hören NAO !!! 1111 "Benutzer, die klicken und alles ohne Anhaltspunkt installieren.
Alexclooze

3
Außerdem wird Linux nicht so häufig verwendet wie Windows - das Schreiben von Viren würde nicht so viel Schaden anrichten, wie die Autoren von Viren erreichen möchten. User Space-Anwendungen kommunizieren nicht mit dem Kernel-Dienst, sondern rufen spezielle Funktionen auf, die vom Kernel bereitgestellt werden und als syscalls bezeichnet werden.
Alexclooze
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.