Sei sulla pagina 1di 36

1 Einleitung

1.1 Sinn und Funktion von Betriebssystemen


The operating system is the one program running at all times on the computer - usually called
the kernel. Along with the kernel, there are two other types of programs: system programs,
which are associated with the operating system but are not necessarily part of the kernel, and
application programs, which include all programs not associated with the operation of the
system. Mobile operating systems often include not only a core kernel but also middleware -
a set of software frameworks that provide additional services to application developers.
• intermediary between the user/application programs of a computer and the computer
hardware
• provide an environment in which a user can execute programs in a convenient and effi-
cient manner
• software that manages the computer hardware
- hardware must provide appropriate mechanisms to ensure the correct operation of the
computer system and to prevent user programs from interfering with the proper operation
of the system
• Like a government, it performs no useful function by itself. It simply provides an envi-
ronment within which other programs can do useful work

1.2 Konzepte moderner Betriebssysteme


• Stabilität: Aufrechterhaltung des Systems bei Programmfehlern
• Fairness: Verhinderung der Monopolisierung von Ressourcen
• Abstraktion: Schaffung einheitlicher Hardware-Schnittstellen
• Schutz: Definition und Einhaltung von Sicherheitsrichtlinien
- Umsetzung durch Isolation (Abschottung)
- von Anwendungen untereinander
- von Anwendungen gegenüber dem Kernel

1.3 Computer-System Operation


• bootstrap program: initial program to run when the computer starts running - for in-
stance, when it is powered up or rebooted
- tends to be simple
- stored within the computer hardware in read-only memory ( ROM ) or electrically era-
sable programmable read-only memory ( EEPROM ) ⇒ firmware
- initializes all aspects of the system, from CPU registers to device controllers to memory
contents
- must know how to load the operating system and how to start executing that system

1
• once the kernel is loaded into memory and executing, it can start providing services to
the system and its users
- some services are provided outside of the kernel, by system programs that are loaded
into memory at boot time to become system processes, or system daemons that run the
entire time the kernel is running

2 Betriebssystemarchitektur
• ein Operationsprinzip für die Systemsoftware welches sich in der Rechnerbetriebsart ma-
nifestiert

• Struktur ihres Aufbaus aus den einzelnen Systemprogrammen

2.1 Architektur
Eine damit gemeinte Konstruktion ist auf drei Prinzipien begründet:

• venustas: Anmut, Schönheit, Wunsch

• firmitas: Solidität, Stabilität, Wesentlichkeit

• utilitas: Zweckmäßigkeit, Nützlichkeit, Funktion, Gut

Eine Betriebssystemarchitektur ist bestimmt durch ein Operationsprinzip für die Systemsoft-
ware und die Struktur ihres Aufbaus aus den einzelnen Systemprogrammen.

2.2 Nichtfunktionale Anforderungen


• Zuverlässigkeit, Leistung, Effizienz

• Betriebs-/Angriffssicherheit (safety/security)

• Portierbarkeit (Plattformunabhängigkeit), Übertragbarkeit

• Aussehen, Handhabung, Benutzbarkeit

2.3 Architekturformen
Monolithische Systeme allgemein
• als eine Menge von Prozeduren realisiert

• jede Prozedur kann von jeder anderen aufgerufen werden

• Struktur meist sehr einfach

• unaufwändige Kommunikation zwischen den einzelnen Teilen des Betriebssystems

2
Allgemeine Struktur des Aufbaus

• Ansatz: BS als Super-Programm, Kontrollinstanz


- Programme laufen unter der Kontrolle des Betriebssystems
- dadurch erstmals (sinnvoll) Mehrprozess-Systeme realisierbar

• Privilegiensystem
- Systemmodus ⇔ Anwendungsmodus
- Direkter Hardwarezugriff nur im Systemmodus ⇒ Gerätetreiber gehören zum System

Vorteile

• Effiziente Kommunikation und effizienter Datenzugriff innerhalb des Kerns


- Nur Betreten / Verlassen des Kerns ist teuer

• Privilegierte Befehle jederzeit ausführbar

Nachteile

• Keine interne Strukturierung (änderungsunfreundlich, fehleranfällig)


- Neukompilierung des ganzen Kernels nötig
- wenn ein beschissener Treiber verreckt verreckt das BS mit ihm
- Hinzufügen oder Abändern von Funktionalität betrifft oft mehr Module, als der Ent-
wickler vorhergesehen hat

• Gemeinsamer Adressraum aller Kernkomponenten


- kein Schutz zwischen Kernkomponenten (Problem: zugekaufte Treiber)

3
- keinen sicherer Speicherschutz, nur Anwendungen isoliert
- viele Komponenten laufen überflüssigerweise im Systemmodus

• Eingeschränkte Synchronisationsmechanismen
- oft nur ein ’Big Kernel Lock’, d. h. nur ein Prozess kann zur selben Zeit im Kernmodus
ausgeführt werden, alle anderen warten

Architektureigenschaften

• Isolationsmechanismus: Privilegebenen, Addressräume


- Pro Anwendung ein Addressraum, Kern läuft auf Systemebene

• Interaktionsmechanismus: Funktionsaufrufe, Traps - Anwendung → Kern durch Traps,


innerhalb des Kerns durch call / ret

• Unterbrechungsmechanismus: Bearbeitung im Kern

Monolithisches Betriebssystem

Ungetrennte Systemfunktionen

• einheitlicher Adressraum

• keine Fehlereingrenzung

• derselbe Arbeitsmodus: privilegiert

Bestenfalls schwache Modularität

• hohe räumliche Verflechtung

• unaufwändige Interaktion im System

• prozedur-/prozessorientierter Aufbau

4
Monolithisches schichtenstrukturiertes Betriebssystem

Ungetrennte Systemfunktionen

• einheitlicher Adressraum

• keine Fehlereingrenzung

• derselbe Arbeitsmodus: privilegiert

starke logische Modularität

• schwache räumliche Verflechtung

• unaufwändige Interaktion im System

• prozedur-/prozessorientierter Aufbau

wohldefinierte innere Struktur

• Programmhierarchie

• Benutzthierarchie

• funktionale Hierarchie
- nur Funktionen der nächsthöheren Schicht auf-
rufbar

Mikrokernbasierte Systeme allgemein


Prinzip des geringsten Privilegs

• Systemkomponenten müssen nur so viele Privilegien besitzen, wie zur Ausführung ihrer
Aufgabe erforderlich sind
– z.B. Treiber: Zugriff auf spezielle IO-Register, nicht auf die gesamte HW
– Speicherverwaltung: Pflege der Übersetzungstabellen, Programmierung der MMU;
jedoch nicht die Prozessein - und -auslagerung
– Prozessverwaltung: insbesondere Dispatching; nicht jedoch Scheduling
– Unterbrechungsbehandlung: Externe Unterbrechungsanforderungen werden vom
Mikrokern entgegengenommen und über IPC an den zuständigen Server-Prozess
(Treiber) weitergeleitet
– Interprozesskommunikation: normalerweise botschaftsorientiert oder über (lokal ge-
nutzte) RPCs, und Prozessynchronisation zwischen Server-Prozessen
– sowie Grundfunktionen zur Synchronisation

5
• alle weiteren Funktionen werden in privilegierte, sogenannte Server-Prozesse mit eige-
nen Adressräumen ausgelagert, die mit den nachfragenden Programmen (Client) kom-
munizieren, oder als Programmbibliothek, welche von den nachfragenden Programmen
eingebunden wird, im Benutzer-Modus implementiert.
– Speicherverwaltung inklusive Paging
– Dateisystemverwaltung
– Interprozesskommunikation und -synchronisation zwischen Anwendungsprozessen
– Realisierung von Scheduling-Strategien
– Netzdienste
– Graphikfunktionen
– sonstige Ein-/Ausgabe

• Nur der Mikrokern läuft im Systemmodus

Ziel: Reduktion der Trusted Computing Base (TCB)

• Minimierung der im privilegierten Modus ablaufenden Funktionalität

• BS-Komponenten als Server-Prozesse im nicht-privilegierten Modus

• Interaktion über Nachrichten (IPC, Inter Process Communication)

Vorteile

• Separierte Komponenten

6
– Flexibilität: Einzelne Bestandteile des Betriebssystems können beliebig ausgetauscht
werden, ohne dass dadurch andere Teile beeinträchtigt werden
– Der Absturz einer einzelnen Komponente führt nicht zwangsläufig zum Zusammen-
bruch des gesamten Systems
• Treiber im Benutzer-Modus
– Die Gerätetreiber laufen zusammen mit einem Anwendungsprogramm im Benutzer-
Modus – im Gegensatz zu Monolithischen Kerneln, bei denen alle Treiber im pri-
vilegierten Modus laufen. Dies hat den Vorteil, dass die Zugriffsrechte der Treiber
einzeln bestimmt werden können. Gerätetreiber brauchen nicht im Kernel zu sein
und sind meist so konzipiert, dass sie auch mit Benutzerrechten ausgeführt werden
können.
• Sicherheit:
– kleine Trusted Computing Base: Der Kernel-Code, dem ein Nutzer vertrauen muss,
ist im Vergleich zu monolithischen Betriebssystemen relativ klein und somit einfa-
cher zu verifizieren
– getrennte Adre Adressräume der Komponenten
• Gut geeignet für Verteilte Systeme: Leichte Verteilung von Betriebssystemdiensten auf
mehrere Rechner
• leichte Konfigurierbarkeit durch Abwahl nicht benötigter Komponenten
• Personalisierbarkeit durch mehrere koexistente API-Server, aber auch mehrere koexis-
tente Subsysteme
Nachteile
• Leistungsverluste: hoher Overhead für IPC-Operationen (Adressraumüberschreitung und
häufige Kontextwechsel)

• Synchronisation: viele einzelne Nutzer-Prozesse


• Komplexität: Gesamt-Betriebssystem wird komplizierter (dafür werden die Einzelkom-
ponenten eher überschaubarer)
• Hardware-Zugriff: ausgewählte Module wie der I/O-Treiber muessen im Kernel-Modus
betrieben werden ⇒ Aufweichen das Mikrokern-Konzepts
Architektureigenschaften
• Isolationsmechanismus: Adressräume
- Pro Anwendung ein Adressraum, ein Adressraum pro Systemkomponente
• Interaktionsmechanismus: IPC
- Anwendungen und Systemkomponenten interagieren über Nachrichten
• Unterbrechungsmechanismus: IPC an Server-Prozess
- Unterbrechungsbehandlung erfolgt durch Faden im Benutzermodus

7
Mikrokernbasiertes Betriebssystem

getrennte Systemfunktionen

• in separierten Adressräumen

• starke Fehlereingrenzung

• verschiedene Arbeitsmodi
- privilegierter Kern (dunkel)
- unprivilegierte Systemprozesse (hell)

starke reale und logische Modularität

• schwache räumliche Verpflechtung

• aufwändige Interaktion im System


- Prozesse IPC (hell)
- Kern Systemaufruf (dunkel)

mittelkörnige Struktur

• Granularität auf Adressraumebene

• Kernadressraum als Monolith

Makrokernbasiertes Betriebssystem allgemein


Auch Hybridkernel

• Kompromiss zwischen einem Mikrokernel und einem monolithischen Kernel


– enthält mehr Parts - wobei unbestimmt ist welche - im Kernel als ein reiner Mikro-
kernel (+ Leistung)
– besitzt nicht genügend Funktionen besitzt um als monolithischer Kernel zu gelten

• Vereint Vorteile von beidem


– nicht so fehleranfällig wie ein monolithischer Kernel, da zum Beispiel nicht alle
Treiber im privilegierten Modus laufen
– nicht so viele Kontextwechsel nebst Kommunikation nötig wie bei einem Mikro-
kernel

8
Makrokernbasiertes Betriebssystem

teils getrennte Systemfunktionen

• in separierten Adressräumen

• schwache Fehlereingrenzung

• verschiedene Arbeitsmodi
- privilegierter Hybridkern (dunkel)
- unprivilegierte Systemprozesse (hell)

eingeschränkte Modularität

• bedingte räumliche Verpflechtung

• unaufwändige Interaktion im System


- Prozesse IPC (hell und dunkel)
- Hybridkern Systemaufruf (dunkel)

grobkörnige Struktur

• Granularität auf Adressraumebene

• Hybridkernadressraum als Monolith

Exokernbasiertes Betriebssystem allgemein


Ziel: Leistungsverbesserung durch Reduktion
• Entfernung von Abstraktionsebenen
• Implementierung von Strategien (z.B. Scheduling) in der Anwendung
Extrem kleiner Kern, dieser implementiert nur
• Schutz
• Multiplexing von Ressourcen (CPU, Speicher, Disk-Blöcke, ...)
• ⇒ Hardwaremultiplexer
Trennung von Schutz und Verwaltung der Ressourcen
• Keine Implementierung von IPC-Mechanismen (Mikrokerne) oder weiterer Abstraktio-
nen (Monolithen)
• Anwendungen können die für sie idealen Abstraktionen, Komponenten und Strategien
verwenden

9
Exokernbasiertes Betriebssystem

Trennung von Belangen

• Betriebsmittelverwaltung
- durch Bibliotheksbetriebssysteme (hell)

• Betriebsmittelschutz
- durch den Exokern (dunkel)

konsequentes Freilegen

• von Betriebsmittelbindungen

• aller Betriebsmittelbelegungen

• der realen Betriebsmittelnamen

• des Widerrufs von Betriebsmitteln

drei Grundtechniken:

1. sichere Betriebsmittelbindung

2. sichtbarer Betriebsmittelwiderruf

3. imperativer Betriebsmittelentzug

10
2.4 Dualität: Betriebssystemstruktur
Nachrichtenorientiertes System

• im-/explizite Koordinierung der Systemprozesse durch die Exekutive

• kleine und relativ statische Anzahl grosser Prozesse

• expliziter Satz von Nachrichtenkanälen zwischen diesen Prozessen


– typischerweise langfristige Bindung
– Message Passing als Interaktionsmittel

• relativ begrenzter Umfang von direkt gemeinsam benutzten Daten


– im Haupt- oder Arbeitsspeicher

• eine Identifizierung von Adressraum oder Kontext mit den Prozessen


– jeder Prozess neigt dazu, in einem relativ statischen Kontext zu laufen
– Adressräume stehen in übereinstimmung mit den Prozessen
– Prozesse überschreiten Schutzgrenzen eher selten (Kern/Exekutive betreten)

• ⇒ als prägend zeigt sich, Prozesse mit Systemressourcen zu assoziieren

• ⇒ Anwendungsbedürfnisse erhält das System in Nachrichten kodiert

11
Prozedurorientiertes System

• i.d.R. explizite Koordinierung der Systemprozesse durch die Exekutive


– Systemprozesse rekrutieren sich implizit aus den Anwendungsprozessen

• große Anzahl sehr kleiner ((teil-)aufgabenspezifischer) Prozesse


– die mittels Prozeduraufrufe das ganze System durchstreifen

• kurzfristige/rasche Erzeugung und Beseitigung der Prozesse


– da keine expliziten Kommunikationskanäle auf-/abgebaut werden müssen

• Kommunikation über direkt gemeinsam benutzte Daten


– Verriegelung (interlocking) von Daten im Haupt-/Arbeitsspeicher
– Zugriff und Schutz globaler Daten über prozedurale Schnittstellen

• eine Identifizierung des Ausführungskontextes jeder Funktion


– genauer: die sich gerade in Ausführung befindet

• Systemressourcen repräsentieren sich als Datenstrukturen

• Anwendungen sind mit Prozessen assoziiert

12
Gegenüberstellung

3 Bindelader
3.1 Einleitung

13
shared memory segment
• explizite Text- und Datenverbünde ursprünglich getrennter Adressräume
- positionsabhängige/-unabhängige Mitbenutzung

• Verbünde erfordern einen passenden Zuschnitt der Text-/Datenbereiche


- Ausrichtung gemäß Granulatgröße: byte-, block-, seitenausgerichtet
- Bereichslänge ist Vielfaches der Länge einer Ausrichtungseinheit

• Text-/Datenverbünde haben statische/dynamische Systemeigenschaften


- eine Frage der Bindezeit von Symbol und Adresse: vor/zur Laufzeit

Übertragungstechniken
• Prozessadressraumerzeugung: COW

• Interprozesskommunikation: COW und COR

• Deduplizierung: COW

shared library
• Programmbibliothek im Textverbund (code sharing)

• Gemeinsamkeiten mit und Unterschiede zum dynamischen Binden


- von Bibliothek/sinhalt/en oder beliebigen symbolisch adressierten Entitäten

14
Programmbibliotheken
Bündel von Unterprogrammen oder Objekten, die von Programmen durch symbolische Adres-
sierung angefordert werden

• statische Bindung läuft ab vor Lade- oder Laufzeit des Programms


- ergibt große Programme, die alles Referenzierte eingebunden haben
- Folge ist ein großer Speicherplatzbedarf im Vorder- und Hintergrund
- für gebundene Programme sind Bibliotheksänderungen wirkungslos
→ Individualbibliothek, ist in Teilen mehrfach repliziert gespeichert
→ Symbolauflösung durch einen Binder (linkage editor, linker)

• dynamische Bindung läuft ab zur Lade- oder Laufzeit des Programms


- kleinere Programme im Hintergrund, da kleinere Lademodule (Datei)
- bedingt kleinerer Speicherplatzbedarf im Vordergrund: Art dyn. Bindung (komplette
Bibliothek oder nur einzelne Einträge/Unterprogramme)
- Programme profitieren von Bibliotheksänderungen insb. Fehlerkorrekturen
→ Gemeinschaftsbibliothek, ist im Arbeitsspeicher ggf. mehrfach repliziert
→ Symbolauflösung durch einen Bindelader (linking loader)

• Gemeinschaftsbibliotheken haben Einfluss auf das Adressraummodell

3.2 Background-Informationen
Objektdateien: nicht-ausführbare Binärdateien
• verschiebarer (relocatable) Maschinencode

• Symbole (bspw. Funktionsnamen, globale Datenstrukturen)

• ggf. Debug-Symbole (bspw. lokale Variablennamen)

• Stripping entfernt unnötige Symbole aus einer Binärdatei

Statisches vs dynamisches Linken


statisches Linken:

• Auflösung von Bibliotheksabhängigkeiten einmalig zur Link-Zeit


15
• selbstständig ausführbares Programm bestehend aus einer Datei

• Vorteile:
- schneller Programmstart, weil dynamisches Laden entfällt
- einfacher zu verteilen, da Bibliotheken nicht vorinstalliert sein müssten
Relocation / Rebasing
Verschiebung von Code ist notwendig, falls Bibliotheken dieselben virtuellen Adressen bean-
spruchen

• Link-Time Relocation: aufgelöst vom Linker (statisch)

• Load-Time Relocation: aufgelöst vom Loader (dynamisch)

16
Relocation vs PIC
Es existieren zwei Konzepte um Adresskollisionen beim Laden dynamischer Bibliotheken auf-
zulösen:

• Relocatable Code

– Code muss vom Lader beim Verschieben überarbeitet werden (Relocation)

– Verwendung: Windows DLLs


– zeitaufwendig beim Laden
- it will take some time to actually perform the relocations when the application is
loaded
- especially time-consuming, if a complex piece of software loads multiple large
shared libraries at start-up
– Code-Section der DLL ist nicht shared
- text section has to be modified at load-time to apply the relocations
- pro Relocation ist eine DLL-Kopie im RAM notwendig
- nur das Festplattenabbild der DLL ist shared
– Daher werden alle Windows System-DLLs an verschiedenen, festen Adressen ohne
Konflikte vorgeladen
– Moreover, having a writable text section (it must be kept writable, to allow the
dynamic loader to perform the relocations) poses a security risk, making it easier to
exploit the application.

• Position Independent Code


– Idea: add an additional level of indirection to all global data and function references
in the code
– Code kann von jeder Adresse aus ausgeführt werden
– Verwendung: Linux Shared Libraries
– Linker weiß relative Offsets der Segmente zu einander, die er ja selbst anordnet und
die jeweiligen Längen
– EIP bestimmt den Offset im Codesegment (call tmplabel; tmplabel: pop ebx)

– data addressing
- A GOT ( global offset table)is simply a table of addresses, residing in the data
section. Suppose some instruction in the code section wants to refer to a variable.
Instead of referring to it directly by absolute address (which would require a relo-
cation), it refers to an entry in the GOT. Since the GOT is in a known place in the
data section, this reference is relative and known to the linker. The GOT entry, in
turn, will contain the absolute address of the variable
- we’ve gotten rid of a relocation in the code section by redirecting variable refe-
rences through the GOT
- Relocation happens only to the data section, which is writable and not shared
between processes anyway, so adding relocations to it does no harm. Moving re-
17
locations from the code section, however, allows to make it read-only and share it
between processes.
– function calls
- The Procedure Linkage Table (PLT) allows lazy resolution of functions
- PLT[n] is called and jumps to the address pointed to in GOT[n]
Definition of Linker
• input: object code generated by the Assembler

• output: executable code for the program (⇒ loader)

• links library functions contained by the source program to the built-in libraries

• combining/linking all object modules to generate a single executable file of the source
program

• 2 types:
– Linkage Editor:
- generates the relocatable, executable module
– Dynamic Linker:
- defers/postpones the linkage of some external modules until the load module/exe-
cutable module is generated
- here, linking is done during load time or run time

• when the linker creates a shared library, it doesn’t know in advance where it might be
loaded
- his creates a problem for the data and code references within the library, which should
be somehow made to point to the correct memory locations.

18
Definition of Loader
The program that has to be executed currently must reside in the main memory of the computer

• a program in an operating system

• load the executable file/module of a program, generated by the linker, to the main memory
for execution

• allocates the memory space to the executable module in main memory

• 3 loading approaches:
– Absolute loading
- loads the executable file of a program into a same main memory location each
time (address mentioned in the binary image record)
- in case, the program is to be modified involving some insertion and deletion in the
program, then all the addresses of the program have to be altered
- simple to implement and efficient in execution
- the programmer must know and clearly specify to the translator (the assembler)
the address in the memory for inner-linking and loading of the programs → are
should take so that the addresses do not overlap
- for programs with multiple subroutines, the programmer must remember the abso-
lute address of each subroutine and use it explicitly in other subroutines to perform
linking
- if the subroutine is modified, the program has to assemble again from first to last.
– Relocatable loading
- the compiler or assembler does not produce actual main memory address but rela-
tive addresses
- The rel.dyn section of ELF is reserved for dynamic (load-time) relocations, to be
consumed by the dynamic loader
- faster than PIC
– Dynamic run-time loading
- the absolute address for a program is generated when an instruction of an exe-
cutable module is actually executed - very flexible, the loadable module/executable
module can be loaded into any region of main memory - the executing program
can be interrupted in between and can be swapped out to the disk and back to main
memory this time at a different main memory address

3.3 Shared Library

19
Gemeinschaftsbibliothek
Arbeitsteilung von Binder und Lader, um die Anzahl redundanter Programme zu reduzieren
und Speicherplatz zu sparen

• zur Bindezeit werden Symbole mit Adressen assoziiert


– der Binder (linker) sucht in den Bibliotheken nach Objektmodulen, die undefinierte
externe Symbole auflösen (d.h., exportieren)
– jedoch kopiert er die gefundenen Module nicht in die Ausgabedatei
- vielmehr vermerkt er, in welcher Bibliothek das Modul enthalten ist und
- hinterlässt eine Liste der Bibliotheken in dem Lademodul (executable)

• die Inbetriebsetzung (startup) der Bibliothek(en) erfolgt zur Ladezeit


- der Lader (loader) setzt für das Programm einen logischen Adressraum auf, gemäß den
Vorgaben im Lademodul
- anschließend durchläuft er eine Anlaufprozedur (startup code)
– die die Bibliotheken findet und in den Programmadressraum einblendet

• die Anlaufprozedur vollzieht die statische oder dynamische Bindung


- je nach den Einflussfaktoren für die Text-/Datenverbünde
- bevor das geladene Programm (durch main-Aufruf) eigentlich startet

4 Systemaufruf
4.1 Partielle Interpretation
Ein Betriebssystem implementiert die Maschinenprogrammebene, d.h., es übersetzt das für das
Betriebssystem kompilierte Anwendungsprogramm (das z.B. Systemaufrufe enthält) auf Be-
fehlssatzebene (das, was die CPU frisst). Dabei sind nur einzelne Eingriffe in den Programma-
blauf nötig (z.B. bei Traps, Interrupts oder Systemaufrufen); in der Regel läuft das Programm
selbstständig auf der CPU.
Der Rechner wird aufgefasst als eine abstrakte Maschine, die fortlaufend eine Sequenz von
Instruktionen abarbeitet. Die meisten dieser Instruktionen können direkt von der untersten
Schicht der Maschine (sprich dem Prozessor) verarbeitet werden - aber auch Betriebssyste-
moperationen wie z. B. write() werden als Instruktionen der abstrakten Maschine angesehen.
Der Prozessor stellt keine native Operation bereit, um den Inhalt eines Puffers in einen Da-
teideskriptor zu schreiben. Die write()-Instruktion muss also von einer Zwischenebene (sprich
dem Betriebssystem) interpretiert werden. Das geschieht dadurch, dass mithilfe eines Traps die
Kontrolle an das Betriebssystem abgegeben wird, das dann seinerseits eine Sequenz von Ma-
schineninstruktionen auslöst, die die gewünschte Operation erledigen. Danach geht die Kon-
trolle zurück an das Anwendungsprogramm, das die Ausführung seiner Instruktionssequenz
fortsetzt.
.
• partielle Interpretation = nur einzelne Teile des Programms werden vom Betriebssystem

20
Anlaufprozedur - Startup Code
• die Inbetriebsetzung der Bibliothek geschieht im Programmkontext:
1. sie ist Teil des Betriebssystems
2. des ablauffähigen Programms selbst, das gerade geladen wird

3. eines im Programmadressraum eingeblendeten dynamischen Binders oder

4. sie gestaltet sich als eine Kombination aus 1, 2 und 3

• zur Einlagerung in den realen Adressraum bestehen die Optionen:


– im Voraus
- vorgreifend (anticipatory), vor Programmstart
- bedingtes Laden 2 aller Objekte gebundener Symbole
– auf Anforderung
- bei Bedarf (on-demand), nach Programmstart
- speicherabgebildete Datei (memory-mapped file)
- typisch in Verbindung mit virtuellem Speicher

• die Einblendung in den (log.) Programmadressraum erfolgt


- im Voraus statische Gemeinschaftsbibliothek
- auf Anforderung dynamische Gemeinschaftsbibliothek

• mit Segmentattributen read-only, copy on reference oder copy on write

• positionsabhängig (statisch) oder -unabhängig (dynamisch)

interpretiert, der Rest läuft direkt auf der Hardware.

• Beispiel Fließkommaeinheit: Wenn die CPU nativ Fließkommabefehle unterstützt, wer-


den sie einfach direkt abgearbeitet. Wenn das nicht der Fall ist, gibt es einen Trap (un-
gültige Instruktion) und das Betriebssystem kann die betreffende Operation in Software
emulieren.

So ein Betriebssystemkern besteht aus mehreren Schichten und Komponenten. Einige davon
kümmern sich um Interrupts oder die Hardware. Diese laufen nativ und sind keiner partiellen
Interpretation unterworfen (durch was denn auch?). Wenn jetzt aber z.B. einer der genannten
Gerätetreiber eine Division durch Null auslöst, oder einen Page-Fault, dann werden die unteren
Schichten (Trap-Handler) des Betriebssystem sich darum kümmern müssen, ein Linux wird
davon nicht gleich komplett abstürzen. Die partielle Interpretation, die man von Anwendungs-
programmen kennt, findet also nur auf manchen Teilen des Betriebssystemcodes statt. Also:
Eingeschränkte (betrifft nicht den kompletten Teil des Betriebssystems) partielle Interpretati-
on.

21
Positionsabhängigkeit
Eigenschaft von Programmtext, der abhängig von seiner absoluten Lage in einem Adress-
raum ausführbar ist

• manifestiert in der Adressierungsart zum Zugriff auf Befehlsoperanden

• sprachlich artikuliert zur Programmier- oder Übersetzungszeit


- unveränderlich an Adressen gebunden zur Binde- oder Ladezeit

• verankert im Programmiermodell der Maschinenprogrammebene


- festgelegt durch das Adressraumkonzept und -modell des Betriebssystems (wenn es
z.B. Gemeinschaftssegmenten einen festen Adressbereich zuweist)

• beeinflusst durch die Hardware-Vorgaben der Befehlssatzebene

• eine Art von Ortstransparenz, jedoch problemspezifisch ausgelegt:


– Ladezeit:
- Moment der Einblendung in den logischen Adressraum
- zur Laufzeit können absolute Adressen gespeichert werden
→ Gemeinschaftsbibliothek, dynamisches Binden
– Laufzeit:
- Moment des Befehlsabrufs aus dem logischen Adressraum
- es dürfen nur relative Adressen gespeichert werden
→ Kompaktifizierung, Speicherbereinigung, Migration (Umzug)

• Umzugsfähigkeit von (dynamischen) Daten ist nicht vordergründig


– obgleich copy on write/reference damit uneingeschränkt nutzbar wird:
- wenn Nachrichteninhalte direkt auf Programmdatenstrukturen verweisen, die un-
arrangiert (uenmarshalled) und direkt übertragen werden sollen
- um dynamische Daten beliebig im Empfangsadressraum platzieren zu können
– ganz unabhängig von dynamisch gebundenem Programmtext

• positionsunabhängige dynamische Daten sind üblw. Quelltextmerkmal

.
• Teilinterpretation von Betriebssystemprogrammen = Wenn ein Teil des Betriebssystems
einen Trap auslöst, dann wird zum Trap-Handler gesprungen. Die den Trap auslösende
Instruktion ist also indirekt (da durch die Hardware umgesetzt) ein rekursiver Aufruf in
einen anderen Betriebssystemcodepfad.

22
Positionsunabhängigkeit
Motiv: Verwendung von absoluter Adressierung (Text) oder absoluten Adressen (Daten) legt
Programmbereiche fest

• Relokation zur Laufzeit ist zwar möglich, aber oft nicht praktikabel
– es müssen alle zu ändernden Programmadressen bekannt sein
- für Programmtext stehen diese in der Symboltabelle des Binders (Sofern nicht
mittels strip(1) aus dem Objekt-/Lademodul entfernt)
- für Programmdaten sind dynamische Datenstrukturen zu verfolgen
→ Programme werden dann nicht unverfälscht (pure) ablaufen können
– aber nicht alle Adressen eines Programms liegen wirklich offen

– z.B. dynamische Datenstrukturen des Laufzeitsystems (Halde, Stapel, ... )

• die Programme selbst müssten frei verschiebbar ausgelegt sein


– ausschließliche Verwendung der relativen Adressierung im Programmtext
- indizierte Adressierung mit Basisregister: Adressdistanz zu einem Basiswert
- Befehlszähler für Programmtext, Adressregister für Programmdaten

• Anweisungen von Hand oder durch den Kompilierer generieren

• → position-independent code (PIC): durchgängig indizierte Adressierung

• Performance -Rückgang bei Gemeinschaftsbibliotheken

– Ladezeit
- Verschiebung (relocation) der Bibliotheken
- Auflösung (resolution) von Programmsymbolen
– Laufzeit
- Entschleunigung durch Einsprungtabelle
- Mehraufwand durch Funktionsprolog
- Mehraufwand durch indirekte Datenreferenzen
- Verlangsamung durch reservierte Adressregister

4.2 Syscall
Syscalls in Linux
A system call is an entry point into the Linux kernel. Usually, system calls are not invoked
directly: instead, most system calls have corresponding C library wrapper functions which per-
form the steps required (e.g., trapping to kernel mode) in order to invoke the system call. Thus,
making a system call looks the same as invoking a normal library function.

23
Zusammenhang zur Gemeinschaftsbibliothek
Profiteur, wenn überhaupt, von positionsunabhängigem Kode ist die dynamische Gemein-
schaftsbibliothek (dynamic shared library)

• deren Symbole erst zur Laufzeit an Adressen gebunden werden


- durch einen bindenden Lader (linking loader) oder
- dem dynamischen Binder (dynamic linker)

• deren Verortung im logischen Adressraum nicht fest vorgegeben ist

Gegenstück dazu ist die - durch positionsunabhängigen Kode unnötig belastete - statische Ge-
meinschaftsbibliothek (static shared library)

• deren Symbole bereits vor Laufzeit an Adressen gebunden werden


- normalerweise durch den (statischen) Binder (linker)

• deren Verortung im logischen Adressraum damit fest vorgegeben ist

Gemeinsamkeit:
- der Programmtext wird zur Lade- oder Laufzeit eingeblendet

24

In many cases, the C library wrapper function does nothing more than:

• copying arguments and the unique system call number to the registers where the kernel
expects them;

• trapping to kernel mode, at which point the kernel does the real work of the system call;

• setting errno if the system call returns an error number when the kernel returns the CPU
to user mode.

However, in a few cases, a wrapper function may do rather more than this, for example,
performing some preprocessing of the arguments before trapping to kernel mode, or postpro-
cessing of values returned by the systemcall.

Stackframe nach int 0x80

Allgemein
• adressraumübergreifender Prozeduraufruf

• verlagert (shift) die weitere Prozedurausführung ins Betriebssystem

• synchrone Programmunterbrechung (trap)

• der Fokus liegt auf Moduswechsel: sysenter/syscall

25
Syscalls in Linux

Ortstransparenz
• für den Aufrufer durch den Auf-
rufstumpf

• für die Systemfunktion durch den Auf-


rufzuteiler

Entkopplung
• des Maschinenprogramms von Pro-
grammen des Betriebssystems

Zugriffstransparenz
• für den Aufrufzuteiler

• für die Systemfunktion

• Wertparameter: unmittelbar adressierte Operanden


Auswertung vor Laufzeit des Maschinenprogramms geschehen ist
lediglich sein Wert ist in den Befehlsstrom einzufügen

• Referenzparameter: direkt (absolut) adressierte Operanden


Auswertung zur Laufzeit
seine Adresse ist in den Befehlsstrom einzufügen

Betriebssystem-Befehlsart
Komplexbefehl (CISC-artig)

• Auswertung der direkten Operanden durch den Syscall-Dispatcher

• Ebenenwechsel durch Interrupt im Stub

• CPU sichert Prozessorstatus beim Interrupt auf den BS-Stack

• Rückgabewert oder Fehler in eax

• Parameter für Syscall im Befehlsstrom (Textsegment), Länge abhängig vom jeweiligen


Opcode opc

• Dispatcher muss Operanden aus Befehlsstrom lesen und den Befehlszähler des Maschi-
nenprogrammes P Cos inkrementieren
– Zugriff auf P Cos und damit auf Opcode und Operandenliegt mittels BS-Stack

26
– Überschreiben des auf dem BS-Stack liegenden Wertes von P Cos vor dem Return
– beim iret stellt die CPU ihren zuvor gesicherten Status wieder her (P Ccpu = P Cos
– muss Kenntnis darüber besitzen, welcher Operand wie zu adressieren ist (unmittel-
bar vs direkt)
• Möglichkeit 1: 2 unterschiedliche Syscalls
– Direkte Systemaufrufe verwenden die unmittelbare Adressierung, die Operanden
sind Teil des Systemaufrufbefehls und liegen im Textsegment. Indirekte System-
aufrufe geschehen durch zwei verknüpfte Systemaufrufbefehle. Der erste Befehl
(Textsegment) verwendet die direkte Adressierung, um einen Deskriptor für den
zweiten Befehl (Datensegment) zu referenzieren. Dieser Hauptbefehl hat den Ope-
rationskode mit Nummer 0 und veranlasst den Syscall-Dispatcher dazu, den direkt
adressierten und im Deskriptor kodierten Nebenbefehl, der die eigentlich zu star-
tende Systemfunktion identifiziert, zur Ausführung zu bringen. Die Auswertung
der somit durch einen Referenzparameter (nämlich der einzige Operand des Haupt-
befehls) adressierten Operanden des Nebenbefehls kann zur Laufzeit geschehen
• Möglichkeit 2: Einkodierung in den Opcode
– Angenommen, das den Operationskode tragende Argument (opc ) ist 32 Bits breit,
wovon der Operationskode die niederwertigen 8 Bits beansprucht. Dann bleiben
24 Bits zur Klassifizierung von bis zu 24 Operanden beispielsweise mit folgender
Bedeutung: 0 für unmittelbare und 1 für direkte Adressierung.
• ⇒ Operandenauswertung im Dispatcher (⇔ Primitivbefehl)
• Ein Nachteil liegt im Falle von strikt privat eingerichteten Adressräumen vor, da zum
Abruf des Systemaufrufbefehls und seiner Operanden durch den Syscall-Dispatcher der
Adressraum des jeweiligen Benutzerebenenprozesses erst zugänglich gemacht werden
muss. Die dafür notwendigen Schritte sind vergleichsweise zeitaufwändig und erhöhen
die Latenz für einen Syscall durchaus erheblich.
• Fehlererkennung mittels Zustandsmerker im Statusregister

sos ; s w i t c h t o o p e r a t i n g system : t r a p assumed , here


. l o n g opc ; o p e r a t i o n code f o r t h e o p e r a t i n g system
. l o n g op1 ; 1 s t operand
. l o n g op2 ; 2nd operand
...
. l o n g opn ; n t h operand
jc error ; i f e r r o r f l a g set , handle t h a t e r r o r ; else , c o n t i n u e

Listing 1: komplex command

Primitivbefehl (RISC-artig)

27
• Anzahl der zu sichernden nichtflüchtigen (callee-save) Register
• Hauptspeicher oder flüchtige (caller-save) Register als Sicherungspuffer
• stapel- oder registerbasierte Parameterübergabe
• rückkehrende oder rückkehrlose Interaktion mit dem Betriebssystem
• Auswertung der direkten Operanden durch den Systemaufrufstumpf (Benutzerebene)
– Speicherung entweder in Registern
oft feste Zuordnung zwischen Argument und Prozessorregister für alle Systemauf-
rufe (Effizienz)
Sicherung der Registerinhalte auf Benutzerebene im Stub
Einschränkung der Parameteranzahl (6)
Übergabe zusätzlicher Parameter (7-n) über Stack
– oder auf dem Stack (Indirekter Syscall)
Return-Address in edx (sysenter)
Stackpointer in ecx (sysenter)
kopieren der Argumente auf den BS-Stack
ähnlich Komplexbefehl, allerdings kopieren von Stacksegment, nicht Textsegment
– int num in eax
• Fehleranmerkung per Wertebereich über Rückgabewert
– zweigeteilte Zielmenge für den Rückgabewert
ok error
z }| { z }| {
k
N0 = {0; 1; 2; · · · ; n} ∪ {n + 1; · · · ; 2 − 1}
k = Wortbreite, n = 4096 (Linux)
betriebssystemseitig einfach, sofern alle Funktionsergebnisse dazu passen
• call by value: die Systemaufrufparameter sind ausnahmslos Wertparameter, die bei der
Operandenauswertung gewonnen und als Kopien an den Systemaufrufzuteiler in Prozes-
sorregistern übergeben werden
• Dispatcher kopiert Operanden auf BS-Stack ⇒ Aufruf der Systemfunktion als gewöhn-
liches Unterprogramm
– Opcode Index für Sprungvektor, welcher die Funktions-Adressen enthält
– Vektortabelle hat 2v Einträge, v = Anzahl Bits der Syscall-Nummer im Opcode
(z.B. 8 ermöglicht 256 Syscalls)
– ungenutzte Syscall-Nummern werfen den Fehlercode ENOSYS
– Platzhalter für den Fehlerkode (im Datensegment, .data): .long errno
• oder mittels Carry Flag im Statusregister
– Stackframe des Systemaufrufs so manipulieren, dass bei Rückkehr der Merker den
Ausnahme- (1) oder Normalfall (0) anzeigt

28
– betriebssystemseitig mit größerem Overhead verbunden

stub : ; ops on s t a c k
p u s h l %ebx , %edi , %e s i , %ebp ; backup c a l l e e − save r e g i s t e r

movl 40(%esp ) , %ebp ; 6 t h operand


movl 36(%esp ) , %e d i ; 5 t h operand
movl 32(%esp ) , %e s i ; 4 t h operand
movl 28(%esp ) , %edx ; 3 r d operand
movl 24(%esp ) , %ecx ; 2nd operand
movl 20(%esp ) , %ebx ; 1 s t operand
movl opc , %eax ; o p e r a t i o n code f o r t h e o p e r a t i n g system
; s w i t c h t o o p e r a t i n g system
i n t 42
cmpl $−4095, %eax ; i f e r r o r f l a g set , handle t h a t e r r o r ; else , c o n t i n u e
j b .end
neg %eax
movl %eax , e r r n o
movl $−1, %eax

.end :
p o p l %ebx , %edi , %e s i , %ebp ; r e s t o r e c a l l e e − save r e g i s t e r
ret

dispatcher :
p u s h l %ebp ; pass or just save 6th operand
p u s h l %e d i ; pass or just save 5th operand
p u s h l %e s i ; pass or just save 4th operand
p u s h l %edx ; pass or just save 3rd operand
p u s h l %ecx ; pass or just save 2nd operand
p u s h l %ebx ; pass or just save 1st operand

movzbl %a l , %eax ; i s o l a t e system−c a l l number , an a r r a y i n d e x


c a l l * v e c t o r ( ,%eax , 4 ) ; i n v o k e system f u n c t i o n

Listing 2: simple command

asmlinkage
Instruiert gcc, die Funktionsparameter auf dem Stapel zu erwarten und nicht in Prozessorregis-
tern.

29
Primitivbefehl, Werteübergabe mittels Register

Primitivbefehl, Werteübergabe mittels Stack

30
Primitivbefehl, Werteübergabe mittels Userstack

Primitivbefehl, Werteübergabe mittels Kontextdeskriptor

31
Komplexbefehl

Primitivbefehl vs Komplexbefehl

32
Ergänzend: Komplexbefehl
Im Gegensatz zum Primitivbefehl, bei dem die Operandenauswertung im Systemaufruf- stumpf
geschieht, erfolgt diese Auswertung für die hier betrachtete Variante im System- aufrufzutei-
ler. Wären Stumpf wie auch Zuteiler demselben Adressraum zugeordnet, ergäbe sich zwischen
beiden Varianten kaum ein Unterschied. Jedoch liegt zwischen diesen beiden Komponenten
nicht nur eine logische, sondern auch eine physische Grenze, die durch die Art der im Sys-
tem etablierten Adressraumisolation definiert ist. Folgt die Abkapselung eines Prozesses einem
Mehradressraummodell, bestimmt letztlich der Grad der den Prozessen 105damit gegebenen
Privatspähre, ob die Operandenauswertung auch für den Systemaufrufzu- teiler vergleichswei-
se einfach ist. Dies ist etwa der Fall, wenn die Adressräume für die auf Benutzerebene statt-
findenden Prozesse teilprivat und damit für Aktionen der Systemebe- ne, eben die Operanden-
auswertung im Systemaufrufzuteiler, direkt zugänglich sind (Linux, Windows NT). Im Falle
von strikt privat eingerichteten Adressräumen (UNIX V6, macOS) muss zum Abruf des Sys-
temaufrufbefehls und seiner Operanden durch den Systemaufruf- zuteiler der Adressraum des
jeweiligen Benutzerebenenprozesses erst zugänglich gemacht werden. Die dafür notwendigen
Schritte sind vergleichsweise zeitaufwändig und erhöhen die Latenz für einen Systemaufruf
durchaus erheblich

Der erste Maschinenbefehl nach der Operandenliste, deren Länge vom jeweiligen, durch den
Operationskode opc bestimmten Systemaufruf abhängt, prüft für gewöhnlich ab, ob während
der Durchführung des Systemaufrufs ein Fehler aufgetreten ist. Gegebenenfalls wird dann die
Fehlerbehandlung im Kontext des Maschinenprogramms eingeleitet. Diese Kodierungsform
impliziert einen Systemaufrufzuteiler, der zur Ausführung des Sys- temaufrufs die Operanden
aus den Befehlsstrom lesen und dabei den vom Betriebssystem verwalteten Befehlszähler des
Maschinenprogramms, P Cos , Schritt für Schritt weiterschal- ten muss, so dass bei Rückkehr
zur Benutzerebene der Maschinenbefehl zur Fehlerabfra- ge (jc) als nächster ausgeführt wird.
Damit ähnelt ein solcher Systemaufrufbefehl einem gewöhnlichen Maschinenbefehl, nur dass
er durch das Betriebssystem und nicht von der CPU interpretiert wird. Die für seine partielle
Interpretation erforderlichen Schritte folgen weitesgehend dem Befehlszyklus einer CPU, die
durch den von ihr verwalteten Befehlszähler, P Ccpu , auch zunächst den Operationskode lesen
und deuten muss, um so einerseits die Ope- ration und anderseits die Adressierungsart des oder
der Operanden zu identifzieren und nach Befehlsausführung im Statusregister die Zustandsan-
zeige (carry bit) in Bezug auf die durchgeführte Berechnung zu hinterlassen. Analog zur CPU,
die P Ccpu nach jeden dieser Abrufschritte implizit weiterschaltet, funktioniert der Systemauf-
rufzuteiler: schritt- weise setzt er den Zeiger automatisch weiter, so dass am Ende, wenn der
komplette System- aufrufbefehl gelesen wurde, der diesem Befehl nachfolgende Maschinen-
befehl (jc) adressiert wird.

Ergänzend: Primitvbefehl
Die für die hier betrachtete Art von Systemaufrufbefehl erfolgende Operandenauswertung auf
Benutzerebene bedeutet, dass nicht der Systemaufrufzuteiler, sondern der Systemauf- rufstumpf

33
den Abruf der Operanden bewerkstelligt. Durch die direkte Einbindung des Stump- fes in das
Maschinenprogramm und dem daraus resultierenden gemeinsamen Adressraum ist der Operan-
denzugriff sehr einfach. Die Systemaufrufparameter sind ausnahmslos Wert- parameter, die bei
der Operandenauswertung gewonnen und als Kopien an den Systemauf- rufzuteiler in Prozes-
sorregistern übergeben werden (call-by-value). Das Gegenstück im Systemaufrufzuteiler legt
nur die Inhalte der Prozessorregister auf dem Laufzeitstapel des Betriebssystems ab und kom-
plettiert damit praktisch die Parameterüber- gabe an die Systemfunktion, bevor diese als ge-
wöhnliches Unterprogramm aufgerufen wird. Dabei identifiziert der Operationskode, genauer
die in ihm enthaltene Systemaufrufnummer, letztlich die aufzurufende Systemfunktion. Die
Funktionsadresse steht in einem Sprungvek- tor, der mit der Systemaufrufnummer als Index
einem Zeigerfeld entnommen wird.

4.3 Schutzdomänenwechsel
reale Sicht: ursprünglicher Zweck von Systemaufrufen (um 1955)
• transiente Maschinenprogramme und residente Systemsoftware trennen

logische Sicht: Systemaufrufe aktivieren einen privilegierten Kontext


• Abschottung des Betriebssystemadressraums

• Erlaubnis zur (eingeschränkten) Durchführung bevorrechtigter Funktionen


- Speicher-/Geräteverwaltung, Ein-/Ausgabe, ... , Betriebssystemdienste
- allgemein: direkte Ausführung von Programmen der Befehlssatzebene

• Zusicherung eigener Softwarebetriebsmittel zur Programmausführung


– Stapelspeicher:
- (1:1) prozessbasiertes Betriebssystem: jeder mögliche Handlungsstrang in dem
System benötigt eine Prozessinkarnation, um stattzufinden, wobei jeder dieser Strän-
ge mit einem eigenen Laufzeitstapel versehen ist.
- (N:1) ereignisbasiertes Betriebssystem: jede anstehende Aufgabe wird zu der je-
weils für sie vorgegebenen (statischen/dynamischen) Priorität durchgeführt; alle
Handlungsstränge werden auf ein und demselben Laufzeitstapel ablaufen gelassen.
– Registersatz:
- Sicherung/Wiederherstellung oder Spiegelung

Abschottung und bevorrechtigte Ausführung


• ein Trap ist hinreichendes Mittel, aber auch vergleichsweise teuer
- Zustandssicherung
- Segmentierung
- Speicher- bzw. Tabellensuchen (table look-up)
– int 42
- Instruction Pointer setzen (aus IDT)

34
- Ring wechseln (aus IDT)
- Auf Kernel-Stack wechseln (Task State Segment, adressierbar über Deskriptor in
GDT)
- Zustand auf Stack sichern
– iret
- Kernel-Stack: ss, esp, eflags, cs, eip
- Rücksprungadresse vom Stack holen
- Flagregister rekonstruieren
- Auf Userspace-Stack zurückschalten
- Prioritätslevel wieder auf 3 setzen

• Systemaufrufbeschleunigung durch Spezialbefehle


– sysenter
- sichert keinen Zustand, auch kein eip/esp!
- setzt cs, eip und ss, esp auf systemspezifische Werte
- Model-specific registers (MSRs)
* cs: 0x174 (Basisindexregister in die Segmenttabelle)
* ss/ds: 0x174 + 8
* cs: 0x174 + 12
* esp: 0x175 (Update bei Taskwechsel)
* eip: 0x176
⇒ richtiges GDT-Layout wichtig!
- sperrt asynchrone Programmunterbrechungen (IRQ)
- aktiviert Schutzring 0
– sysexit
- setzt cs und ss auf prozesspezifische Werte
- setzt eip/esp auf die edx/ecx stehenden Werte (von Stub mitgegeben)
- aktiviert Schutzring 3 - nur von Ring 0 aus ausführbar - Model-specific registers
(MSRs)
* ss/ds: 0x174 + 24
⇒ Kontextsicherung liegt komplett in Hand des Benutzerprozesses

35
/ / syscalls with sysenter / sysexit
wrmsr ( MSR_IA32_SYSENTER_CS, KERNEL_CODE_SEGMENT * 8 , 0 ) ;
wrmsr ( MSR_IA32_SYSENTER_EIP , ( unsigned l o n g ) s y s e n t e r _ d i s p a t c h e r , 0 ) ;
wrmsr ( MSR_IA32_SYSENTER_ESP, s t a c k _ p t r , 0 ) ;

...

s t a t i c v o i d wrmsr ( u i n t 3 2 _ t i d , u i n t 6 4 _ t v a l ) {
asm v o l a t i l e ( ` ` wrmsr ` ` : : ` `A ` ` ( v a l ) , ` ` c ` ` ( i d ) : ` ` memory ` ` ) ;
}

Listing 3: initialize the msr registers

4.4 Resümee
Rekapitulation
• Maschinenprogramme werden durch Betriebssysteme teilinterpretiert

• Teilinterpretierung wird (insb. auch) durch Systemaufrufe ausgelöst

funktionale Hierarchie
• Systemaufrufstümpfe trennen Maschinenprogramm von Betriebssystem

• im Betriebssystem aktiviert ein Systemaufrufzuteiler die Systemfunktionen

• der Systemaufruf ist ein adressraumübergreifender Prozeduraufruf

Implementierung
• ein Systemaufruf ist als Primitiv- oder Komplexbefehl realisiert

• Primitivbefehle nutzen (ausschließlich) Register zur Parameterübergabe

• Komplexbefehle erlauben einen unverfälschten Zustandsabzug

• Fehler werden durch spezielle Rückgabewerte oder Merker signalisiert

• einem Systemaufruf ist ein Betriebssystemstapel 1 : 1 oder N : 1 zugeteilt

36

Potrebbero piacerti anche