Betriebssystembau (BSB)

Ähnliche Dokumente
Betriebssystembau. 3. Übung. Michael Engel Arbeitsgruppe Eingebettete Systemsoftware. Lehrstuhl für Informatik 12 TU Dortmund

Übung zu Betriebssystembau (Ü BS)

Betriebssystembau (BSB)

Betriebssysteme BS-V SS Hans-Georg Eßer. Foliensatz V: Ulix: Interrupts und Faults Ulix: System Calls. Dipl.-Math., Dipl.-Inform.

Betriebssysteme (BS) Unterbrechungen - Synchronisation - Überblick: Vorlesungen. Agenda. Agenda. Anwendung(en) Hardware. Motivation / Problem

Vorlesung 5: Interrupts

Software ubiquitärer Systeme

Assembler - Einleitung

Assembler - Adressierungsarten

Übung 1 - Betriebssysteme I

Hinweise 80x86-Architektur

Betriebssystembau. 7. Übung. Michael Engel Arbeitsgruppe Eingebettete Systemsoftware. Lehrstuhl für Informatik 12 TU Dortmund

Assembler Unterprogramme

2. Aufgabenblatt Musterlösung

Aufgabe 1 Entwicklung einer Virtuellen Maschine

Aufgabe 2 - Erweiterung um PIC und Interrupts

3.2 Prozessumschaltung

GCC 3.x Stack Layout. Auswirkungen auf Stack-basierte Exploit-Techniken. Tobias Klein, 2003 Version 1.0

Karlsruher Institut für Technologie

Assembler - Variablen

Systeme 1. Kapitel 9.2. Interaktion von Hardware und Betriebssystem Linux-Kernel und x86 Systeme

Kap.2 Befehlsschnittstelle. Prozessoren, externe Sicht

Übungen zur Vorlesung Systemsicherheit

Aufgabe 2 - Erweiterung um PIC und Interrupts

Einführung. Übungen zur Vorlesung Virtuelle Maschinen. Stefan Potyra. SoSe 2009

Name: ES2 Klausur Thema: ARM Name: Punkte: Note:

Prozesse vs. Threads

Interrupts. Funktionsprinzip. Funktionsprinzip. Beispiel in C

Intel x86 Bootstrapping

x86 Assembler Praktische Einführung Sebastian Lackner Michael Müller 3. Juni 2013

Betriebssysteme Übung 2. Tutorium System Calls & Multiprogramming

Einführung in (Intel) 80x86 Assembler. Einführung in (Intel) 80x86 Assembler Wintersemester 2008/09 1 / 26

Mikrocomputertechnik. 6. Exceptionhandling ( Ausnahmebearbeitung)

Systemprogrammierung

System Monitoring mit strace. Systemcall tracing

Grundlagen der Informatik III Wintersemester 2010/2011

Hobby-Betriebssysteme unter Linux entwickeln

Betriebssysteme. Interruptverarbeitung in Betriebssystemen. Sommersemester 2014 Prof. Dr. Peter Mandl. Prof. Dr. Peter Mandl Seite 1.

Hardware-Programmierung mit Linux/NASM

Embedded-Linux-Seminare. Linux als Betriebssystem

Betriebssysteme (BS) IA-32. Überblick. das Programmiermodell der Intel Architektur. Historie der Intel x86 Prozessoren. 8086: Programmiermodell

U5 Fortgeschrittene AVR-Programmierung

x86 Open Source Virtualisierungstechniken Thomas Glanzmann

Inhaltsverzeichnis. 1 Einleitung 2

Betriebssystembau (BSB)

Grundlagen der Informatik III Wintersemester 2010/ Vorlesung Dr.-Ing. Wolfgang Heenes

ARM Cortex-M Prozessoren. Referat von Peter Voser Embedded Development GmbH

Multiprozessoren. Dr.-Ing. Volkmar Sieh. Institut für Informatik 3: Rechnerarchitektur Friedrich-Alexander-Universität Erlangen-Nürnberg SS 2011

Einführung in die technische Informatik

PThreads. Pthreads. Jeder Hersteller hatte eine eigene Implementierung von Threads oder light weight processes

2

Effizientes Memory Debugging in C/C++

Betriebssystembau (BSB)

Technische Informatik 1 Übung 5: Eingabe/Ausgabe (Computerübung) Georgia Giannopoulou, ETZ G & 18.

DHBW Stuttgart Mikrocomputertechnik Labor KEIL Entwicklungsumgebung. Projektstruktur

Compiler: Vom Code zum Maschinen-Code. C Programmierung - Vorlesung 2 Hochschule Regensburg Universitätsstraße 31, Regensburg

Betriebssysteme (BS)

Daniel Betz Wintersemester 2011/12

Kompatibilitätsmodi: Real Mode: - Segmentregister*16+Offset => Adresse - Keine Segmentdeskriptoren, kein Paging, - ~ 1 MB Adressraum.

Beispiel 2a Die eigenen ersten Schritte mit dem Gnu-Debugger GDB für Remote-Debugging

Tafelübung zu BSRvS 1 6. Sicherheit

11: Echtzeitbetriebssystem ucos-ii

Datenstrukturen, Alignment Stack Prozeduraufruf, Parameterübergabe und -rückgabe (Calling Conventions) Leaf procedures

Einführung in die Informatik Jumping into Java

B1 Stapelspeicher (stack)

Ein Laufzeitsystem für hochgradig parallele Simulationen

Betriebssysteme KU - Einführungstutorium

U5-2 Register beim AVR-µC

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2012 / Vorlesung 9, Dienstag 18.

Hardware-basierte Virtualisierung

Debuggen mit GDB (Gnu DeBugger) unter Eclipse

Hardware-basierte Virtualisierung

Einleitung Die Pins alphabetisch Kapitel 1 Programmierung des ATmega8 und des ATmega

Deklarationen in C. Prof. Dr. Margarita Esponda

GdI2 - Systemnahe Programmierung in C Übungen Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4, 2006 U4.fm

Welche Informatik-Kenntnisse bringen Sie mit?

Technische Informatik 1

8. Referenzen und Zeiger

TIn 1: Feedback Laboratories. Lecture 4 Data transfer. Question: What is the IP? Institut für Embedded Systems. Institut für Embedded Systems

Metaprogrammierung 372

Programmierung mit C Zeiger

Dateien, die nicht in das Projekt eingebunden sind, werden ohne Syntax highlight dargestellt. MiCoWi und µvision Seite 1 Uwe Wittenfeld

1.7 Assembler Programmierung

Programmunterbrechungen

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Sicheres C Programmieren in Embedded Systemen ARM II (ARM7TMDI [1] ) Wintersemester

7 Ein einfacher CISC-Prozessor

C++ Teil 5. Sven Groß. 13. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 18

Microcontroller Praktikum SS2010 Dipl. Ing. R. Reisch

Grundlagen der Informatik III Wintersemester 2010/2011

Rechnerorganisation 2 TOY. Karl C. Posch. co1.ro_2003. Karl.Posch@iaik.tugraz.at

1 Organisatorisches. 2 Compilezeit- und Laufzeitfehler. 3 Exceptions. 4 Try-Catch-Finally

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Heute nur MIPS-Praxis (4 Aufgaben)

C++ Teil 6. Sven Groß. 27. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 14

Grundlagen zur Assemblerprogrammierung unter SPIM im Sommersemester Lorenz Schauer Mobile & Verteilte Systeme

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Aufgaben zur IA32-Assembler-Programmierung

Transkript:

Betriebssystembau (BSB) 3. Übung http://ess.cs.tu-dortmund.de/de/teaching/ws2012/bsb/ Olaf Spinczyk olaf.spinczyk@tu-dortmund.de http://ess.cs.tu-dortmund.de/~os AG Eingebettete Systemsoftware Informatik 12, TU Dortmund

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 2

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 3

Interrupts und Traps Interrupts durch Hardware ausgelöste Ereignisse asynchron zum Programmablauf nicht vorhersagbar unterbrochener Programmablauf wird nach Bearbeitung wieder aufgenommen Traps durch Instruktion (direkt oder indirekt) ausgelöst synchron zum Programmablauf unterbrochener Programmablauf kann wieder aufgenommen oder auch abgebrochen werden 30.10.12 Betriebssystembau: 3. Übung 4

Traps Überblick Traps werden von der CPU ausgelöst, wenn während der Ausführung der aktuellen Instruktion ein Problem festgestellt wird... Division durch Null Busfehler d.h., ein Programm generiert ungültige Adresse Betriebssystem-Eingriff erforderlich (z.b. Seitenfehler) ungültige Instruktion...oder aber auch, wenn die ausgeführte Instruktion direkt einen Trap hervorrufen soll int 0x80 syscall / sysenter 30.10.12 Betriebssystembau: 3. Übung 5

(nochmal) i386 IDT: Aufbau 0 31 255 IDT Traps Hardware/Software IRQs Einträge 0-31 für Traps (fest) Number Description 0 Divide-by-zero Trap = Ausnahme, die synchron 1 Debug exception 2 Non-Maskable Interrupt (NMI) zum Kontrollfluss auftritt 3 Breakpoint (INT 3) 4 Overflow Division durch 0 5 Bound exception Seitenfehler 6 Invalid Opcode 7 FPU not available Unterbrechungspunkt 8 Double Fault 9 Coprocessor Segment Overrun... 10 Invalid TSS 11 Segment not present 12 Stack exception Einträge 32-255 für 13 General Protection IRQs (variabel) 14 Page fault 15 Reserved Software (INT <nummer>) 16 Floating-point error 17 Alignment Check Hardware (INT-Pin der CPU 18 Machine Check auf HIGH, Nummer auf 30.10.12 19-31 Reserved By Intel Betriebssystembau: 2. Übung 6 Datenbus)

Traps Beispiele Division durch Null 1 int main() { 2 int i, j; 3 4 i=3; 5 j=0; 6 7 return i/j; 8 } $ gdb./divnull (gdb) run Program received signal SIGFPE, Arithmetic exception. 0x0804836b in main () at divnull.c:7 7 return i/j; main: leal andl pushl pushl movl pushl subl movl movl movl movl sarl idivl addl popl popl leal ret 4(%esp), %ecx $-16, %esp -4(%ecx) %ebp %esp, %ebp %ecx $16, %esp $3, -12(%ebp) $0, -8(%ebp) -12(%ebp), %edx %edx, %eax $31, %edx -8(%ebp) $16, %esp %ecx %ebp -4(%ecx), %esp 30.10.12 Betriebssystembau: 3. Übung 7

Traps Beispiele Schutzverletzung 1 int main() { 2 int *p; 3 4 p = (int *)0; 5 6 return *p; 7 } $ gdb./segfault (gdb) run Program received signal SIGSEGV, Segmentation fault. 0x0804835f in main () at segfault.c:6 6 return *p; main: leal andl pushl pushl movl pushl subl movl movl movl addl popl popl leal ret 4(%esp), %ecx $-16, %esp -4(%ecx) %ebp %esp, %ebp %ecx $16, %esp $0, -8(%ebp) -8(%ebp), %eax (%eax), %eax $16, %esp %ecx %ebp -4(%ecx), %esp 30.10.12 Betriebssystembau: 3. Übung 8

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 9

Race Conditions Wikipedia: A race condition [...] is a flaw in a system or process whereby the output of the process is unexpectedly and critically dependent on the sequence or timing of other events. [http://en.wikipedia.org/wiki/race_condition] Ursprung des Begriffs im Elektronikentwurf 30.10.12 Betriebssystembau: 3. Übung 10

Race Conditions in Software Parallel ablaufende Vorgänge (Prozesse, Threads) verwenden gemeinsamen Status Beispiel: zwei gleichzeitig ablaufende Prozesse wollen den (ASCII-)Wert eines Zeichens im Bildschirmspeicher erhöhen. Die Prozesse sehen beide wie folgt aus: 1 int main(void) { 2 volatile unsigned char *p; 3 4 p = (unsigned char *)0xb8000; 5 6 (*p)++; 7 return 0; 8 }??? 30.10.12 Betriebssystembau: 3. Übung 11

Race Conditions in Software Parallel ablaufende Vorgänge (Prozesse, Threads) verwenden gemeinsamen Status Beispiel: zwei gleichzeitig ablaufende Prozesse wollen den (ASCII-)Wert eines Zeichens im Bildschirmspeicher erhöhen. Die Prozesse sehen beide wie folgt aus: 1 int main(void) { 2 volatile unsigned char *p; 3 4 p = (unsigned char *)0xb8000; 5 6 (*p)++;!!! 7 return 0; 8 } 30.10.12 Betriebssystembau: 3. Übung 12

Race Conditions in Software Die harmlos aussehende Instruktion *p++ ist nicht atomar! In Assembler sieht das wie folgt aus: main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $16, %esp movl $753664, -8(%ebp) movl -8(%ebp), %eax 4 p = (...)0xb8000; movzbl (%eax), %eax leal 1(%eax), %edx 6 *p++; movl -8(%ebp), %eax movb %dl, (%eax) [...] popl %ecx popl %ebp leal -4(%ecx), %esp ret 30.10.12 Betriebssystembau: 3. Übung 13 Interrupt und Kontextwechsel

Race Conditions in Software movl $753664, -8(%ebp) movl -8(%ebp), %eax movzbl (%eax), %eax leal 1(%eax), %edx movl movb Interrupt, führt zu Kontextwechsel -8(%ebp), %eax %dl, (%eax) 'A' = 0x41 'B' = 0x42 'B' = 0x42 movl $753664, -8(%ebp) movl -8(%ebp), %eax 'A' = 0x41 movzbl (%eax), %eax leal 1(%eax), %edx 'B' = 0x42 movl -8(%ebp), %eax movb %dl, (%eax) Das Resultat ist falsch (erwartet: 'C' = 0x43), weil der Compiler das Zeichen im Bildschirmspeicher in einem Register zwischengespeichert hat. Jeder Prozess ist dann von diesem Wert als aktuell ausgegangen. Wäre der Interrupt zwei Instruktionen vorher oder später aufgetreten, wäre das Ergebnis korrekt! Race Conditions sind schwer zu finden und zu debuggen! 30.10.12 Betriebssystembau: 3. Übung 14

Konsistenzprobleme bei Interrupts Beispiel 1: Systemzeit hier schlummert möglicherweise ein Fehler... das Lesen von global_time erfolgt nicht notwendigerweise atomar! Beispiele aus der letzten Vorlesung 32-Bit-CPU: mov global_time, %eax 16-Bit-CPU (little endian): mov global_time, %r0; lo lo mov global_time+2, %r1; hi hi kritisch ist eine Unterbrechung zwischen den beiden Leseinstruktionen bei der 16-Bit-CPU Instruktion global_time Resultat hi hi // lo lo r1 r1 // r0 r0? 002A FFFF?? mov global_time, %r0 002A FFFF? FFFF /* /* Inkrementierung */ */ 002B 0000? FFFF mov global_time+2, %r1 002B 0000 002B FFFF Beispiel 2: Ringpuffer auch die Pufferimplementierung ist kritisch... Ausführung Zustand 'a' 'a'?? 1 1 0 char consume() { buf buf [0] [0] [1] [1] [2] [2] occ. occ. nextin nextin nextout int int elements = occupied; // // 1 if if (elements == == 0) 0) return 0; 0; char result = buf[nextout]; //'a' 'a' 'a'?? 1 1 0 nextout++; nextout %= %= SIZE; buf buf [0] [0] [1] [1] [2] [2] occ. occ. nextin nextin nextout void produce(char data) { // // 'b' 'b' int int elements = occupied; // // 1! 1! if if (elements == == SIZE) return; buf[nextin] = data; 'a' 'a' 'b' 'b'? 2 2 0 nextin++; nextin %= %= SIZE; occupied = elements + 1; 1; // // 2 buf buf [0] [0] [1] [1] [2] [2] occ. occ. nextin nextin nextout } occupied = elements 1; 1; // // 0 'a' 'a' 'b' 'b'? 0 2 0 return result; // // 'a' 'a' buf buf [0] [0] [1] [1] [2] [2] occ. occ. nextin nextin nextout } 30.10.12 Betriebssystembau: 3. Übung 15

Ursache Anwendungskontrollfluss (A) Kontrollflüsse...... von oben... main() Wir müssen (irgendwie) die Konsistenz sicherstellen. BS-Kern consume() buf[...] produce()... begegnen sich im Kern. handler()...und von unten... Unterbrechungsbehandlung (UB) 30.10.12 Betriebssystembau: 3. Übung 16

Naiver Lösungsansatz Zweiseitige Synchronisation Zweiseitige Synchronisation funktioniert natürlich nicht! gegenseitiger Ausschluss durch Schlossvariable (Mutex, Spin-Lock,...) wie zwischen zwei Prozessen Anwendungskontrollfluss (A) main() BS-Kern consume() handler() buf[...] produce() Unterbrechungsbehandlung (UB) char consume() { mutex.lock();... char result = buf[nextout++];... mutex.unlock(); return result; } void produce(char data) { mutex.lock();... buf[nextin++] = data;... mutex.unlock(); } 30.10.12 Betriebssystembau: 3. Übung 17

Besserer Lösungsansatz Einseitige Synchronisation Mit einseitiger Synchronisation funktioniert es... [warum eigentlich?] Unterdrückung der Unterbrechungsbehandlung im Verbraucher Operationen disable_interrupts() / enable_interrupts() (im Folgenden o.b.d.a. in Intel -Schreibweise: cli() / sti()) Anwendungskontrollfluss (A) main() BS-Kern consume() handler() buf[...] produce() Unterbrechungsbehandlung (UB) char consume() { cli();... char result = buf[nextout++];... sti(); return result; } void produce(char data) { // hier nichts zu tun... buf[nextin++] = data;... // hier nichts zu tun } 30.10.12 Betriebssystembau: 3. Übung 18

Erstes Fazit Konsistenzsicherung zwischen Anwendungskontrollfluss (A) und Unterbrechungsbehandlung (UB) muss anders erfolgen als zwischen Prozessen. Die Beziehung zwischen A und UB ist asymmetrisch Es handelt sich um verschiedene Arten von Kontrollflüssen UB unterbricht Anwendungskontrollfluss implizit, an beliebiger Stelle hat immer Priorität, läuft durch (run-to-completion) A kann UB unterdrücken (besser: verzögern) explizit, mit cli / sti (Grundannahme 5 aus der letzten Vorlesung) Synchronisation / Konsistenzsicherung erfolgt einseitig Diese Tatsachen müssen wir beachten! 30.10.12 (Das heißt aber Betriebssystembau: auch: Wir können sie 3. Übung ausnutzen) 19

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 20

i386 Interrupt-Deskriptortabelle (IDT) maximal 256 Einträge Basisadresse und Größe in IDTR 8 Byte pro Eintrag (Gate) Task-Gate (Hardwaretasks) Trap-Gate (Ausnahmehandler) Interrupt-Gate (Ausnahmehandler + cli) IDTR 30.10.12 Betriebssystembau: 3. Übung 21

i386 Interrupt-Deskriptortabelle (IDT) maximal 256 Einträge [SECTION.data] ; 'interrupt Basisadresse descriptor und Größe table' in IDTR mit 256 Eintraegen. 8 Byte pro Eintrag (Gate) idt: %macro idt_entry Task-Gate (Hardwaretasks) 1 Trap-Gate dw (wrapper_%1 (Ausnahmehandler) - wrapper_0) & 0xffff dw 0x0008 Interrupt-Gate dw 0x8e00 (Ausnahmehandler + cli) dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 %endmacro ;... wird automatisch erzeugt. %assign i 0 %rep 256 idt_entry i %assign i i+1 %endrep IDTR idt_descr: dw 256*8-1 ; idt enthaelt 256 Eintraege 30.10.12 dd idt Betriebssystembau: 3. Übung 22

i386 Interrupt-Deskriptortabelle (IDT) maximal 256 Einträge [SECTION.data] ; 'interrupt Basisadresse descriptor und Größe table' in IDTR mit 256 Eintraegen. 8 Byte pro Eintrag (Gate) idt: %macro idt_entry Task-Gate (Hardwaretasks) 1 Trap-Gate dw (wrapper_%1 (Ausnahmehandler) - wrapper_0) & 0xffff dw 0x0008 Interrupt-Gate dw 0x8e00 (Ausnahmehandler + cli) dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 %endmacro setup_idt: mov eax,wrapper_0 ; ax: niederwertige 16 Bit ;... wird automatisch erzeugt. mov ebx,eax shr ebx,16 ; bx: hoeherwertige 16 Bit %assign i 0 mov ecx,256 ; Zaehler %rep 256.loop: add [idt+8*ecx+0],ax idt_entry i adc [idt+8*ecx+6],bx %assign i i+1 IDTR dec ecx %endrep jge.loop idt_descr: lidt [idt_descr] dw 256*8-1 ; idt enthaelt 256 Eintraege ret dd idt 30.10.12 Betriebssystembau: 3. Übung 23

Zustandssicherung Jede CPU besitzt einen internen Status, der nur einmal vorhanden ist repräsentiert als Registerinhalte Bei x86-prozessoren sieht dieser wie folgt aus: Komplette Sicherung (Stack): 14 Register == 56 Bytes! 30.10.12 Betriebssystembau: 3. Übung 24

Beispiel (Linux arch/i386/kernel/entry.s) Implementation als Makro... wird häufiger benötigt :-) RESTORE_ALL entsprechend 87 #define SAVE_ALL \ 88 cld; \ 89 pushl %es; \ 90 pushl %ds; \ 91 pushl %eax; \ 92 pushl %ebp; \ 93 pushl %edi; \ 94 pushl %esi; \ 95 pushl %edx; \ 96 pushl %ecx; \ 97 pushl %ebx; \ 98 movl $( KERNEL_DS),%edx; \ 99 movl %edx,%ds; \ 100 movl %edx,%es; 30.10.12 Betriebssystembau: 3. Übung 25

Beispiel (Linux arch/i386/kernel/entry.s) Verwendung z.b. im NMI-Handler: 332 ENTRY(nmi) 333 pushl %eax 334 SAVE_ALL 335 movl %esp,%edx 336 pushl $0 337 pushl %edx 338 call SYMBOL_NAME(do_nmi) 339 addl $8,%esp 340 RESTORE_ALL 30.10.12 Betriebssystembau: 3. Übung 26

Kontextsicherung: Wer macht was? Kontextsicherung: eflags, cs und eip wurden bereits von der CPU gesichert alle weiteren Register müssen vom IRQ-Handler gesichert werden entweder im Assembler-Teil oder der Compiler generiert bereits entsprechenden Code Kontextsicherung beim Aufruf von Funktionen Lösung 1: Aufrufende Funktion sichert alle Register, die sie später noch braucht Lösung 2: Aufgerufene Funktion sichert alle Register, die sie verändert Lösung 3: Ein Teil der Register wird vom Aufrufer, ein anderer Teil vom Aufgerufenen gesichert 30.10.12 Betriebssystembau: 3. Übung 27

Kontextsicherung in Hochsprachen In der Praxis wird Lösung 3 verwendet Grundsätzlich hängt das natürlich vom Compiler ab CPU-Hersteller definiert jedoch Konventionen, damit Interoperabilität auf Binärcodeebene sichergestellt ist Register werden in 2 Subsets aufgeteilt Flüchtige Register ( scratch registers ) Compiler geht davon aus, dass Unterprogramm den Inhalt verändert Aufrufer muss Inhalt gegebenenfalls sichern bei x86 sind eax, ecx, edx und eflags als flüchtig definiert Nichtflüchtige Register ( non-scratch registers ) Compiler geht davon aus, dass der Inhalt nicht verändert wird Aufgerufene Funktion muss Inhalt gegebenenfalls sichern bei x86 sind alle sonstigen Register als nicht-flüchtig definiert Interrupt-Handler müssen auch flüchtige Register sichern! 30.10.12 Betriebssystembau: 3. Übung 28

Zustandssicherung im Wrapper ; Spezifischer Kopf der Unterbrechungsbehandlungsroutinen %macro wrapper 1 wrapper_%1: push eax mov al,%1 jmp wrapper_body %endmacro ;... wird automatisch erzeugt. %assign i 0 %rep 256 wrapper i %assign i i+1 %endrep ; Gemeinsamer Rumpf wrapper_body: cld ; das erwartet der gcc so. push ecx ; Sichern der fluechtigen Register push edx and eax,0xff ; Der generierte Wrapper liefert nur 8 Bits push eax ; Nummer der Unterbrechung uebergeben call guardian add esp,4 ; Parameter vom Stack entfernen pop edx ; fluechtige Register wieder herstellen pop ecx 30.10.12 pop eax iret Betriebssystembau: ; fertig! 3. Übung 29

Initialisierung der PICs Teil 1 OO-Stubs Einstellung: Master Slave 00010001 00010001 OO-Stubs Einstellung: Master Slave 00100000 00101000 30.10.12 Betriebssystembau: 3. Übung 30

Initialisierung der PICs Teil 1 OO-Stubs Einstellung: Master Slave ; Neuprogrammierung der PICs (Programmierbare 00010001 Interrupt-Controller), 00010001 ; damit alle 15 Hardware-Interrupts nacheinander in der idt liegen. reprogram_pics: mov al,0x11 ; ICW1: 8086 Modus mit ICW4 out 0x20,al call delay out 0xa0,al call delay OO-Stubs Einstellung: mov al,0x20 ; ICW2 Master: IRQ Master # Offset (32) Slave out 0x21,al call delay 00100000 00101000 mov al,0x28 ; ICW2 Slave: IRQ # Offset (40) out 0xa1,al call delay 30.10.12 Betriebssystembau: 3. Übung 31

Mapping der HW-IRQs (OO-Stubs) 0 32 47 255 IDT Traps HW <unbenutzt> Standard AT IRQ-Belegung IRQ 0 IRQ 1 IRQ 2 System Timer IRQ 3 COM 2 IRQ 4 COM 1 IRQ 5 Tastatur (Keyboard) PIC Kaskadierung IRQ 6 Floppy IRQ 7 LPT 1 IRQ 8 CMOS Echtzeituhr IRQ 9 (HW-Mapping von IRQ 2) IRQ10 IRQ11 IRQ12 IRQ13 numerischer Coprozessor IRQ14 1. IDE Port 30.10.12 Betriebssystembau: 2. Übung 32 IRQ15 2. IDE Port PS/2

Initialisierung der PICs Teil 2 OO-Stubs Einstellung: Master Slave 00000100 0000010 OO-Stubs Einstellung: Master Slave 00000011 00000011 30.10.12 Betriebssystembau: 2. Übung 33

Initialisierung der PICs Teil 2 OO-Stubs Einstellung: Master Slave... mov al,0x04 ; ICW3 Master: Slaves 00000100 an IRQs 0000010 out 0x21,al call delay mov al,0x02 ; ICW3 Slave: Verbunden mit IRQ2 des Masters out 0xa1,al call delay mov al,0x03 ; ICW4: 8086 Modus und automatischer EIO out 0x21,al call delay OO-Stubs Einstellung: out 0xa1,al Master Slave call delay... 00000011 00000011 30.10.12 Betriebssystembau: 2. Übung 34

Programmierung der PICs Interruptmaske (IMR) schreiben und lesen über Port 0x21 / 0xa1 30.10.12 Betriebssystembau: 2. Übung 35

Programmierung der PICs Interruptmaske (IMR) schreiben und lesen über Port 0x21 / 0xa1... mov al,0xff ; Hardware-Interrupts durch PICs out 0xa1,al ; ausmaskieren. Nur der Interrupt 2, call delay ; der der Kaskadierung der beiden mov al,0xfb ; PICs dient, ist erlaubt. out 0x21,al ret 30.10.12 Betriebssystembau: 2. Übung 36

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 37

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 38

Interrupthandler in OO-Stubs // ASSIGN: Einstoepseln einer Behandlungsroutine, die in Form eines Gate- // Objekts angegeben wird. void assign (unsigned int slot, Gate& gate); // REPORT: Abfrage eines eingetragenen Gate Objekts. Gate& report (unsigned int slot); 30.10.12 Betriebssystembau: 3. Übung 39

Was sind C++ Referenzen? Sprachlich: Aliase für Objekte Technisch: Initialisierte und unveränderliche Zeiger Wenn eine Referenz initialisiert wird, wird automatisch die Adresse des Initialisierers gebildet. Wenn eine Referenz in einem Ausdruck benutzt wird, wird automatisch das referenzierte Objekte benutzt. int v1; int &ref = v1; int v2 = ref; int &f(int &refarg) { refarg = 42; return refarg; } int v1; int *ref = &v1; int v2 = *ref; int *f(int *refarg) { *refarg = 42; return &*refarg; } int v3 = f(v2); int v3 = *f(&v2); technisch äquivalent 30.10.12 Betriebssystembau: 3. Übung 40

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 41

Aufgabe 3: Pro-/Epilog-Modell Die Hauptarbeit steckt in Guard Das Modell wird ausführlich in der kommenden Vorlesung besprochen. 30.10.12 Betriebssystembau: 3. Übung 42

Knifflige Zeiger: Queue in Aufgabe 3 Queue-Elemente erben von Chain Sie erben damit auch einen Zeiger auf das nächste Element Ein Queue-Objekte enthält class Chain { public: Chain* next; }; einen Zeiger auf das erste Element einen Zeiger auf einen Zeiger namens 'tail'!? class Queue { Chain* head; Chain** tail; public: Queue () { head = 0; tail = &head; } void enqueue (Chain* item); Chain* dequeue (); void remove (Chain*); }; 30.10.12 Betriebssystembau: 3. Übung 43

Knifflige Zeiger: Queue in Aufgabe 3 'tail' ist ein Zeiger auf den 'next' Zeiger im letzten Element Das macht das Anhängen (enqueue) sehr einfach: q.enqueue(&e1) item->next = NULL; q NULL e1 'a' NULL e2 'b'? *tail = item; 'a' NULL 'b'? tail = &item->next; 'a' NULL 'b'? q.enqueue(&e2)... item->next = NULL; *tail = item; tail = &item->next; 30.10.12 Betriebssystembau: 3. Übung 44 'a' 'b' NULL

Agenda Traps Unterbrechungssynchronisation Aufgabe 2 Was macht startup.asm für uns? Was soll in Teil c) und d) passieren? Wiederholung: Referenzen in C++ Plugbox und Gate Aufgabe 3 Vielen Dank für die Aufmerksamkeit! Vorstellung Wiederholung: Zeiger in C++ Die (komische?) Queue-Klasse 30.10.12 Betriebssystembau: 3. Übung 45