Betriebssystembau (BSB)
2. Übung
https://ess.cs.tu-dortmund.de/DE/Teaching/WS2017/BSB/
Olaf Spinczyk
[email protected]://ess.cs.tu-dortmund.de/~os
AG Eingebettete SystemsoftwareInformatik 12, TU Dortmund
23. Okt 2017 Betriebssystembau: 2. Übung 2
Überblick● C++ Crashkurs (Teil 2)
● Aufgabe 1: Tastatur-Programmierung
● Aufgabe 2: Unterbrechungsbehandlung
23. Okt 2017 Betriebssystembau: 2. Übung 3
C++-Konzepte (Crashkurs Teil 2)● Übersetzungs- und Bindevorgang
● Präprozessor
● Vererbung und Mehrfachvererbung
● Virtuelle Funktionen
23. Okt 2017 Betriebssystembau: 2. Übung 4
C++ - Übersetzungsprozess
23. Okt 2017 Betriebssystembau: 2. Übung 5
Sourcecode - Präprozessor● Zwei Dateiendungen:
– .cc — C++ Source Code
– .h — „Header Files“ mit Definitionen von Datentypen, Konstanten, Präprozessor-Makros etc.
● Die Endungen sind Konvention, aber nicht zwingend– oft z.B. auch .cpp, .hpp o.ä.
● Header-Files werden mit Hilfe des Präprozessors textuell in .cc-Files integriert– #include-Direktive:
● #include <iostream> für System-Headerfiles● #include "device.h" für eigene Headerfiles
23. Okt 2017 Betriebssystembau: 2. Übung 6
Sourcecode - Präprozessor● Weitere Präprozessorfunktionen:
– Makrodefinition, z.B. für Konstanten:● ohne Semikolon am Ende!
– Bedingte Übersetzung:
● Der Präprozessor expandiert Makros im Source Code, fügt Header-Files ein und erzeugt eine neue Textdatei, die der Compiler vorgesetzt bekommt
#define pi 3.1415926#define VGA_BASE 0xb8000
#ifdef DEBUG…#endif
#ifndef VGA_BASE#define VGA_BASE 0xb8000#endif
23. Okt 2017 Betriebssystembau: 2. Übung 7
Sourcecode - Präprozessor● Wichtige Anwendung für #define und #ifndef:
– Verhindern von mehrfacher Inklusion von Header-Dateien● Header-Dateien dürfen wiederum Header-Dateien inkludieren →
Ringschluss …
#ifndef __cgastr_include__#define __cgastr_include__
#include "object/o_stream.h"#include "machine/cgascr.h"
class CGA_Stream /* Hier muesst ihr selbst Code vervollstaendigen */ {/* Hier muesst ihr selbst Code vervollstaendigen */ };#endif
23. Okt 2017 Betriebssystembau: 2. Übung 8
Sourcecode - Compiler● Erzeugt aus vom Präprozessor vorverarbeitetem Source Code
eine Objektdatei (.o)– Diese ist i.A. nicht direkt ausführbar, da noch Referenzen auf
Funktionen oder Variablen in anderen Objektdateien enthalten sein können
● Der Compiler überprüft den Source Code auf Syntaxfehler und erzeugt ggf.– Fehlermeldungen (errors)
– Warnungen (warnings)
● Eine Objektdatei wird nur bei fehlerfreier Übersetzung erzeugt– Warnungen führen nicht zum Abbruch des Übersetzungsvorgangs! Sie
sollten aber beachtet werden …
23. Okt 2017 Betriebssystembau: 2. Übung 9
Sourcecode - Linker● Fasst eine Menge an Objektdateien (.o) sowie ggf. Libraries
(.a, .so) zu einem ausführbaren Programm zusammen:– Auflösung von Referenzen
– Sortierung der einzelnen Teile der Objektdateien im Speicherabbild der ausführbaren Datei
● „Normalerweise“ gibt es zwei Link-Modi:– dynamisch: Libraries werden erst zur Zeit der Ausführung des
Programms zum Objektcode geladen und Referenzen darin aufgelöst
– statisch: Libraries werden zur Link-Zeit in ein komplett ausführbares Programm integriert
23. Okt 2017 Betriebssystembau: 2. Übung 10
Einfache Vererbung● Klasse keyboard_interrupt erbt von Klasse interrupt
● Vererbungsoperator “:” (entspricht “extends” in Java)
class interrupt { …};
#include "interrupt.h"
class keyboard_interrupt : public interrupt {public: keyboard_interrupt(); ~keyboard_interrupt();};
interrupt.h: keyboard_interrupt.h:
interrupt
keyboard_interrupt
23. Okt 2017 Betriebssystembau: 2. Übung 11
Mehrfachvererbung● Klasse keyboard_interrupt erbt von den
Klassen interrupt und keys:
interrupt
keyboard_interrupt
keys
#include "interrupt.h"
class keyboard_interrupt : public interrupt, public keys {public: keyboard_interrupt(); ~keyboard_interrupt();};
keyboard_interrupt.h:
23. Okt 2017 Betriebssystembau: 2. Übung 12
Virtuelle Funktionen● Virtuelle Funktionen sind Funktionen einer Basisklasse.
● Eine abgeleitete Klasse kann sie überschreiben und übernimmt damit die Ausführung der Funktion für ihre Klassenmitglieder. – das funktioniert auch mit nicht virtuellen Funktionen ...
● Das Besondere an virtuellen Funktionen ist, dass das Objekt selbst weiß, zu welcher abgeleiteten Klasse es gehört und seine zugehörige Klassenfunktion ruft.
● Nicht jede Funktion ist standardmäßig virtuell, es muss explizit das Schlüsselwort „virtual“ verwendet werden!(im Gegensatz zu Java)
23. Okt 2017 Betriebssystembau: 2. Übung 13
Virtuelle Funktionen
● Ausgabe:
„Derived“
● ohne das virtual vor void base::display():
„Base“
#include <iostream>
class base {public: virtual void display() { cout << ”Base”; }};
class derived : public base {public: void display() { cout << ”Derived”; }};
void main() { base *ptr = new derived; ptr->display();}
23. Okt 2017 Betriebssystembau: 2. Übung 14
Virtuelle Destruktoren● Es gibt eine Faustregel, die besagt, dass jede Klasse mit
virtuellen Funktionen auch einen virtuellen Destruktor haben soll.
● Da ein nicht virtueller Destruktor nicht gewährleistet, dass abgeleitete Klassen ordnungsgemäß abgebaut werden, kann ein nicht virtueller Destruktor sogar so interpretiert werden, dass der Autor ein Ableiten seiner Klasse nicht vorgesehen hat und wohl auch nicht empfiehlt.
23. Okt 2017 Betriebssystembau: 2. Übung 15
Überblick● C++ Crashkurs (Teil 2)● Aufgabe 1: Tastatur-Programmierung● Aufgabe 2: Unterbrechungsbehandlung
23. Okt 2017 Betriebssystembau: 2. Übung 16
PC-Tastatur● klassisch:
● moderner PC: USB-Tastatur– USB Legacy Support: Ansteuerung funktioniert immer noch zusätzlich
über den Tastaturcontroller (Rückwärtskompatibilität)
23. Okt 2017 Betriebssystembau: 2. Übung 17
Tastenkodierungen● Jede Taste hat eindeutigen Tastencode (Scan-Code)
– Scan-Code ist 7-Bit Zahl (max. 128 Tasten)
● Tastaturcontroller sendet zusätzliche Informationen– Make-Code beim Drücken / Halten einer Taste
– Break-Code beim Loslassen
Darstellung im Programm(und im CGA-Speicher!):Zeichencodes (ASCII)
Darstellung im Programm(und im CGA-Speicher!):Zeichencodes (ASCII)
Darstellung in der Hardware:Tastencodes
Darstellung in der Hardware:Tastencodes
23. Okt 2017 Betriebssystembau: 2. Übung 18
Make- und Break-Codes● Üblicherweise gilt
– Make-Code (Taste gedrückt) = Scan-Code
– Break-Code (Taste losgelassen) = Scan-Code + 128 (Bit 7)
● Einige Tasten senden jedoch mehrere Codes– z.B. Funktionstasten (F1-F12)
– aus historischen Gründen (XT-Tastatur)
– bis zu drei Make/Break-Codes pro Taste
● Eingebaute Wiederholungsfunktion– Hardware sendet zusätzliche Make-Codes,
wenn eine Taste länger gehalten wird
➔ Dekodierung ist mühsam– bei OOStuBS in der Vorgabe enthalten: bool key_decoded()
23. Okt 2017 Betriebssystembau: 2. Übung 19
Datenaustausch mit der Tastatur● Tastaturcontroller wird über zwei E/A-Ports angesprochen
– Ein-/Ausgaberegister (data_port) 0x60
– Steuerregister (ctrl_port) 0x64
data_port
ctrl_port
Keyboard_Controller set_led: LED ein-/ausset_speed: Wiederholungsrate
cpu_reset: Warmstart ...
Make-CodeBreak-Code
Status des Tastatur-Controllers
SchreibenLesen
23. Okt 2017 Betriebssystembau: 2. Übung 20
Status der Tastatur● Statusregister stellt folgende Informationen bereit:
23. Okt 2017 Betriebssystembau: 2. Übung 21
Status der Tastatur - Verwendung
● Aktive Tastaturabfrage (nicht durch Unterbrechungen):– Warten, bis outb in ctrl_port gesetzt ist– Make-/Break-Code vom data_port lesen (löscht ctrl_port.outb)
● Tastatur programmieren (set_led, set_speed)– Befehlsbyte in data_port schreiben– Tastatur antwortet mit ack (0xfa), ggfs. auf Antwort warten (s.o.)– Datenbyte in data_port schreiben (LED-Codes, Repeat-Rate)– Tastatur antwortet mit ack, ggfs. auf Antwort warten
23. Okt 2017 Betriebssystembau: 2. Übung 22
Tastatur programmieren● set_led 0xed, <led_mask> in data_port
● set_speed 0xf3, <config_byte> in data_port
Parameter für set_led Befehl: (led_mask)Parameter für set_led Befehl: (led_mask)
Parameter für set_speed Befehl: (config_byte)Parameter für set_speed Befehl: (config_byte)
23. Okt 2017 Betriebssystembau: 2. Übung 23
Überblick● C++ Crashkurs (Teil 2)● Aufgabe 1: Tastatur-Programmierung● Aufgabe 2: Unterbrechungsbehandlung
23. Okt 2017 Betriebssystembau: 2. Übung 24
Hardware-IRQs bei x86-CPUs● Bis einschließlich i486 hatten x86-CPUs nur einen
Interrupt-Eingang (INT) plus einen NMI-Eingang– INT kann mit dem IE-Bit im Statuswort maskiert werden
● cli-Befehl (clear interrupt enable) – Interruptverarbeitung sperren● sti-Befehl (set interrupt enable) – Interruptverarbeitung freigeben
– NMI kann auf der CPU nicht maskiert werden (sagt ja schon der Name)
● beim PC aber trotzdem durch externe Hardware …
● Externer Controller muss Nummer auf den Bus legen– Beim PC ist das der Programmable Interrupt Controller 8259A
– Datenaustausch zwischen CPU und PIC 8259A erfolgt nach einem festgelegtem Protokoll
23. Okt 2017 Betriebssystembau: 2. Übung 25
Ablauf eines Hardware-IRQ (mit PIC)PIC 8259A IDT Handler <n>CPU (i386)
<n> (8 Bit, Datenbus)
INTA-Pin
Applikation
INT-Pin
<interruption>
INTA-Pin
EOI-Befehl (konfigurationsabhängig)
IRET Befehl
<continue>
Softw
areH
ardw
are
23. Okt 2017 Betriebssystembau: 2. Übung 26
Kaskadierung im PC (15 Interrupts)
23. Okt 2017 Betriebssystembau: 2. Übung 27
x86_64-Interrupt-Deskriptortabelle
IDTRIDTR
● maximal 256 Einträge– Basisadresse und Größe in IDTR
● 16 Byte pro Eintrag (Gate)– Task-Gate (Hardwaretasks)
– Trap-Gate (Ausnahmehandler)
– Interrupt-Gate (Ausnahmehandler + cli)
23. Okt 2017 Betriebssystembau: 2. Übung 28
x86 IDT: Aufbau
Traps Hardware/Software IRQs
0 31 255
IDT
Number Description 0 Divide-by-zero 1 Debug exception 2 Non-Maskable Interrupt (NMI) 3 Breakpoint (INT 3) 4 Overflow 5 Bound exception 6 Invalid Opcode 7 FPU not available 8 Double Fault 9 Coprocessor Segment Overrun 10 Invalid TSS 11 Segment not present 12 Stack exception 13 General Protection 14 Page fault 15 Reserved 16 Floating-point error 17 Alignment Check 18 Machine Check 19-31 Reserved By Intel
– Einträge 0-31 für Traps (fest)
– Trap = Ausnahme, die synchronzum Kontrollfluss auftritt
● Division durch 0● Seitenfehler● Unterbrechungspunkt● ...
– Einträge 32-255 für IRQs (variabel)
● Software (INT <nummer>)● Hardware (INT-Pin der CPU
auf HIGH, Nummer auf Datenbus)
23. Okt 2017 Betriebssystembau: 2. Übung 29
Zustandssicherung● Wenn eine Unterbrechung eintritt, sichert die CPU automatisch einen
Teil des Zustands auf dem Stapel– Aktives Stacksegment (ss)
– Stapelzeiger (rsp)
– condition codes (rflags)
– Aktives Codesegment (cs)
– Rücksprungadresse (rip)
– Bei einer Exception zusätzlichein Fehler-Code Offsets +8!→
● Der automatisch gesicherte Zustand wird bei der Ausführung von iretq zurückgesetzt– verwendet der Handler weitere Register,
so muss er diese selber sichern!
rflags
cs
riprsp
esp + 8
esp + 0
esp + 16
rsp esp + 24
ss
rsp
esp + 32
23. Okt 2017 Betriebssystembau: 2. Übung 30
PIC 8259A – Interner Aufbau
höchste
niedrigste
23. Okt 2017 Betriebssystembau: 2. Übung 31
Zugriff auf die PICs über IO-Ports
Port 0x20
Port 0x21
Master
Port 0xa0
Port 0xa1
Slave
ICW1 (Initialisierung beginnen)OCW2 (EOI, ...)OCW3 (IRR lesen, ISR lesen, ...)
ICW2-4 (Initialisierungsdaten)OCW1 (= IMR)
IRRISROffset
IMR
● Jeder PIC hat zwei Ports, die gelesen/geschrieben werden können
● Schreibdaten: ICW1-4, OCW1-3– ICW = Initialization Control Word – Initialisierung des PICs
– OCW = Operation Control Word – Kommandos im Betrieb
● Lesedaten abhängig von KommandoSchreibenLesen
<wie Master><wie Master>
23. Okt 2017 Betriebssystembau: 2. Übung 32
Initialisierung der PICs – Teil 1OO-Stubs-Einstellung:
00010001
Master
00010001
Slave
OO-Stubs-Einstellung:
00100000
Master
00101000
Slave
23. Okt 2017 Betriebssystembau: 2. Übung 33
Mapping der HW-IRQs (OO-Stubs)
IRQ 0 System Timer IRQ 1 Tastatur (Keyboard) IRQ 2 PIC Kaskadierung IRQ 3 COM 2 IRQ 4 COM 1 IRQ 5 IRQ 6 Floppy IRQ 7 LPT 1 IRQ 8 CMOS Echtzeituhr IRQ 9 (HW-Mapping von IRQ 2) IRQ10 IRQ11 IRQ12 PS/2 IRQ13 numerischer Coprozessor IRQ14 1. IDE Port IRQ15 2. IDE Port
Traps <unbenutzt>
0 255
IDT HW
4732
Standard ATIRQ-BelegungStandard AT
IRQ-Belegung
23. Okt 2017 Betriebssystembau: 2. Übung 34
Initialisierung der PICs – Teil 2OO-Stubs-Einstellung:
00000100
Master
0000010
Slave
OO-Stubs-Einstellung:
00000011
Master
00000011
Slave
23. Okt 2017 Betriebssystembau: 2. Übung 35
Programmierung der PICsInterruptmaske (IMR)
● schreiben und lesen über Port 0x21 / 0xa1
Interruptmaske (IMR)● schreiben und lesen
über Port 0x21 / 0xa1
23. Okt 2017 Betriebssystembau: 2. Übung 36
Interrupthandler in OO-Stubs● Behandlung startet in der Funktion guardian()
– bekommt die IRQ-Nummer als Parameter:
void guardian( unsigned int slot ) { ... // IRQ-Handler (Gate) aktivieren}
– Interrupts sind während der Abarbeitung gesperrt● können mit sti manuell wieder zugelassen werden ● werden automatisch wieder zugelassen, wenn guardian() terminiert
● Die eigentlichen (spezifischen) IRQ-Handler– sind Instanzen der Klasse Gate
– werden an- und abgemeldet über die Klasse Plugbox
23. Okt 2017 Betriebssystembau: 2. Übung 37
Interrupthandler in OO-Stubs
Keyboard
Keyboard_Controller
Key
CPU
PIC Plugbox
guard
Gate
Panic
device
machine