Betriebssystemtheorie/ Hardwaregrundlagen
Die Von-Neumann-Architektur
[Bearbeiten]Nach der Von-Neumann-Architektur besteht ein Computersystem aus dem Prozessor, welcher sich aus der ALU (Arithmetic Logic Unit) bzw. dem Rechenwerk und der Control Unit oder dem Steuerwerk zusammensetzt. Über den Systembus ist er mit dem Speicher und der I/O-Einheit, die für den Datenaustausch mit Hardwaregeräten und Schnittstellen benutzt wird, verbunden. (siehe Bild rechts)
Die meisten der heute gebräuchlichen Rechner sind nach der Von-Neumann-Architektur aufgebaut. Sie lässt sich gut beherrschen, da sie rein sequenziell arbeitet. Dadurch müssen keine Nebenläufigkeiten wie bei Parallelrechnern berücksichtigt werden. In der Praxis werden heute aus Leistungsgründen allerdings meistens erweiterte Von-Neumann-Architekturen eingesetzt, vor allem hat die Parallelverarbeitung durch mehrere Prozessoren bzw. mehrere Cores (SMP) Einzug gehalten. Dies ist zwar noch weit entfernt von einem echten Parallelrechner, wie er z.B. auf GPUs anzutreffen ist, jedoch müssen nun auch Nebenläufigkeiten beachtet werden.
Die Von-Neumann-Architektur zeichnet sich vor allem durch einen gemeinsamen Speicher für Programme und Daten aus. Dadurch unterscheidet sie sich z.B. von der Harvard-Architektur, in der für Programme und Daten unterschiedliche Speicher und Busse verwendet werden. Die Harvard-Architektur findet man Beispielsweise häufig in Microcontrollern, wo der Programmspeicher aus Flash-Speicher und der Datenspeicher aus RAM-Zellen besteht, oder bei DSPs.
Begriffsklärungen in der Wikipedia: Von-Neumann-Architektur, CPU, GPU
Speichertrennung
[Bearbeiten]Die erste benötigte Eigenschaft der Hardware ist die Speichertrennung. Hierbei muss es möglich sein, den physisch vorhandenen Arbeitsspeicher in disjunkte Teile zu zerlegen, wobei jedes ausgeführte Programm nur seinen Teil sieht. Jeder dieser Teile bildet einen virtuellen Speicheradressraum. Das einzige Programm, welches alle virtuellen Addressräume verwaltet und kontrolliert ist das Betriebssystem.
Diese Eigenschaft ist notwendig um zuverlässig verfügbare Systeme zu bauen.
Eingeschränkter CPU-Modus
[Bearbeiten]Eine CPU muss mindestens zwei Modi zur Verfügung stellen: einen Kernmodus, in dem alle Operationen ausgeführt werden dürfen und einen eingeschränkten Benutzermodus.
Der Kern des Betriebssystems läuft im Kernmodus. Er darf alle Prozessoranweisungen ausführen und auf alle Hardwaregeräte zugreifen.
Die Anwendungsprogramme werden im Benutzermodus ausgeführt. Dieser bringt einige Einschränkungen mit sich, um den sicheren Betrieb zu gewährleisten. Generell sind keine Aktionen gestattet, die den Zustand anderer Prozesse direkt beeinflussen können, so zum Beispiel:
- Keine Umschaltung zu anderen Prozessen, sogenannte Kontextwechsel
- Keine Änderungen am virtuellen Speicheraddressraum, weder am eigenen, noch am Addressraum anderer Prozesse
- Vor allem kein An- oder Abschalten der Interrupts
- Keine Änderungen an Interrupttabellen
- Keine Ausführung privilegierter Prozessorinstruktionen
Wechsel zwischen den Prozessormodi
[Bearbeiten]Syscalls
[Bearbeiten]Viele Programme müssen einige dieser Punkte verletzen, um ihre Aufgaben erfüllen zu können. Zwei Beispiele: Ein Gerätetreiber, der im Benutzermodus läuft, muss auf ein Hardwaregerät zugreifen. Wenn ein Programm einem anderen eine Nachricht senden will, muss es in dessen virtuellen Adressraum schreiben. Das Betriebssystem stellt dafür einen Mechanismus namens Syscalls zur Verfügung.
Durch Syscalls können Programme dem Kern mitteilen, welche Aktion sie durchführen wollen. Empfängt der Kern eine Mitteilung, führt er die gestellte Aufgabe wenn möglich aus.
Grundlegende Funktionsweise
[Bearbeiten]Zum Bauen von Syscalls benötigt man die zwei Prozessorinstruktionen syscall und sysret mit denen der Prozessormodus gewechselt werden kann.
Der Programmierer des Betriebssystems legt fest, welche Syscalls das Betriebssystem den Anwendungen anbieten soll. Jeder Syscall wird nun durch eine Nummer, die Parameter, die er übernimmt, und die Resultate, die er zurückgibt, definiert.
Ein Aufruf eines Syscalls läuft folgendermaßen ab:
- Die Parameter werden an definierte Stellen geschrieben, zum Beispiel auf den Stapel oder in festgelegte Prozessorregister.
- Die Nummer des Syscalls wird an eine definierte Stelle geschrieben.
- Die Anwendung ruft syscall auf. Es folgt ein Kerneintritt. Der Prozessor befindet sich nun im Kernmodus. Der Aufruf von syscall setzt den Instruktionszeiger des Prozessors auf eine Speicheradresse, die vorher vom Betriebssystem festgelegt wurde. An dieser Adresse befindet sich die Kernroutine, welche die Syscalls behandelt. Diese Routine wird von nun an ausgeführt.
- Der Kern liest die Nummer des Syscalls aus. Aus der Nummer kann die Anzahl und Position der Parameter im Speicher bestimmt werden. Falls sich diese Daten auf dem Stapel befinden, werden sie entfernt, da es sonst über kurz oder lang zu einem Stapelüberlauf kommen würde.
- Nun wird die gewünschte Funktion ausgeführt.
- Hinterlässt die Funktion einen Rückgabewert oder einen Fehler, wird dieser wiederum an eine definierte Stelle im Speicher geschrieben.
- Der Kern ruft nun sysret auf. Es kommt zum Kernaustritt. Der Prozessor wechselt in den Benutzermodus. Die Anwendung wird an der Stelle fortgesetzt, an der sie vorher unterbrochen wurde.
- Zum Abschluß des Syscalls muss die Anwendung nun noch den Rückgabewert auslesen und überprüfen, ob die gewünschte Operation erfolgreich war.
Typische Syscalls
[Bearbeiten]Interrupts
[Bearbeiten]Eine Unterbrechungsanforderung (Interrupt Request) ist eine Anfrage an die CPU, das gerade laufende Programm bzw. die Aufgabe, die sie momentan verrichtet, zu unterbrechen. Diese Unterbrechung ist meist so kurz, dass die Benutzung des Rechners davon nicht beeinträchtigt wird. Das Interrupt-Verfahren wurde entwickelt, um die unterschiedlichen Geschwindigkeiten, mit denen verschiedene Komponenten arbeiten, effizient auszugleichen.
Hardware-Interrupts
[Bearbeiten]Software-Interrupts
[Bearbeiten]IO Adressraum für Gerätezugriff
[Bearbeiten]Datenübertragung per DMA Modus
[Bearbeiten]DMA (Direct Memory Access) eröffnet die Möglichkeit, dass Hardwarekomponenten ohne Beteiligung der CPU Daten miteinander austauschen. Dieser direkte Speicherzugriff ermöglicht es der CPU in dieser Zeit ihre Rechenleistung für andere Aufgaben zu nutzen.