Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Hauptstudiumsprüfungen » Lehrstuhl 4 » Betriebssystem (Übersicht)
Inhaltsverzeichnis
Betriebssystem
Prüfer: Daniel Lohmann
Beisitzer: Daniel Danner
Themengebiete: Betriebssysteme (MPStubs + Übung, 7.5 ECTS)
Datum: April 2013
Papier + Stift bereitgestellt; Daniel Lohmann hat einiges von dem was ich erklärt hat aufgemalt und dann ggf. vertiefende Fragen gestellt und erweitert.
Prüfer P, Student S.
Fragen
P: Was ist ein Betriebssystem?
S: Definition ist schwer, kommt auch auf die Anwendung an. Bibliothek, Monolithen, Exokernel genannt und grob erklärt.
P: Was zeichnet einen Monolithen aus?
S: Benutzer-/Systemmodus, Speicherschutz, mehrere Anwendungen, getrennte Adressräume. (Hat etwas gedauert bis ich genau auf den Unterschied kam, hatte da vorher nicht genau drüber nachgedacht.)
P: Was zeichnet einen Mikrokern aus?
S: Minimierung der Trusted Code Base, möglichst viel aus dem Kernel auslagern. Dispatcher muss in den Kernel wegen Adressraumwechsel, Scheduler aber nicht.
P: Kann ein Bibliothekssystem auch mehrere Anwendung unterstützen (also Scheduling)?
S: (War zuerst etwas verwirrt weil das in der Vorlesung nicht explizit genannt war.) Ja, kann man implementieren.
P: Was ist MPStubS?
S: (Mit Hilfe.) Bibliothekssystem, da kein Speicherschutz bzw. Benutzer-/Systemmodus, alles wird zusammen gelinkt.
P: Wie funktioniert toc_switch() zum Koroutinenwechsel?
S: Erklärt (siehe Übung/Vorlesung), nicht-flüchtige Register tauschen, dann ret auf dem neuen Stack.
P: Benötigt das spezielle Rechte?
S: Nein, geht auch im Benutzermodus.
P: Was ist das ideale Betriebssystem?
S: Das die spezifische Anwendung möglichst effizient ausführt. Eierlegende Wollmilchsau gibt es nicht.
P: Sie sind Betriebssystemsentwickler und sollten für folgende Anwendung ein Betriebssystem erstellen, was brauchen sie?
main() { printf("Hallo, Welt!"); }
S:
- Bootloader
- Ausgabetreiber für den Monitor
- Startup-Code der main() aufruft und auch den Stack aufsetzt (den hab ich zuerst vergessen)
- nach der main() im Startup-Code ein hlt, damit der Prozessor nicht weiter läuft
P: Der Kunde will noch ein getch(). Wie muss das System erweitert werden?
S:
- Treiber für die Tastatur
- Pollen des Register im Tastatur-Controller im Loop bis ein Zeichen gelesen wurde
P: Kunde merkt das der Lüfter immer an ist, wie kann man das beheben?
S:
- aktives Warten ist schlecht, Interrupts verwenden
- Interrupt-Handler speichert Zeichen in Buffer, getch() liest aus (kurz I/O-APIC, IDT, Interrupt-Routine erklärt)
- sleep in getch()-Loop
P: Braucht man den Loop noch?
S:
Prinzipiell nein, da immer ein Zeichen geschrieben wurde. Aber wegen Spurious Interrupts ist es sinnvoll.
P: Wo ist das Problem im Loop?
S: Lost-Wakeup zwischen Überprüfung ob ein Zeichen gelesen wurde und sleep().
P: Wie behebt man das?
S: Interrupts vorher sperren; sti und sleep() müssen aber atomar sein (sti; hlt sind atomar auf x86).
P: Wo ist ein weiteres Problem?
S: Gemeinsamer Zustand (Buffer Index) in Interrupt-Handler und getch().
P: Wie behebt man das?
S:
- hart synchronisieren: Interrupts vorher sperren, einseitige Synchronisation da der Interruptkontrollfluss nicht vom Anwendungskontrollfluss unterbrochen werden kann
- weich synchronisieren: unterbrechungstransparenter Algorithmus
P: Wie könnte ein naiver Algorithmus aussehen?
S: interrupted flag im Handler setzen und im Loop in getch() prüfen, falls true Zeichen erneut auslesen (vgl. Time-Code in der Vorlesung).
P: Der Sohn des Auftraggebers hat dem Vater von Multiprozessorsystemen erzählt. Keyboard-Interrupts werden nur an die zweite CPU geschickt. Was müssen wir tun?
S:
- Startup-Code muss main_ap() auf zweiter CPU starten
- main_ap() einfach while(1) { hlt; }
- IPI im Interrupt-Handler um Interrupt bei Keyboard-Interrupt an die erste CPU zu schicken und diese zu wecken
P: Gibt es bei der main_ap() ein Lost-Wakeup?
S: Nein. Denn Lost-Wakeup hat immer eine Test-Handle-Wettlaufsituation, in main_ap() wird nichts geprüft.
P: Was geht jetzt in getch() kaputt?
S: getch() kann jederzeit unterbrochen werden, einseitige Synchronisation reicht nicht mehr aus.
P: Wie löst man das?
S: Spinlock, lock()/unlock() um den kritischen Abschnitt.
P: Wo gibt es da ein Problem mit Interrupts?
S: Interrupts vor lock() sperren sonst gibt es Deadlock wenn getch() lock() macht und dann ein Interrupt kommt.
[Noch 2-3 Minuten Zeit.]
P: Wie implementiert man ein Spinlock?
S:
lock() { while(TAS(&x, 1) == 1) ; } unlock() { x = 0; }
[Die folgenden Fragen gingen über den Stoff hinaus und waren stofflich nicht Teil der Prüfung.]
P: Weißt du wie man TAS auf der Hardware implementiert?
S: So grob. Über das Cache-Kohärenz Protokoll.
P: Wo ist das Problem damit? Wann wird eine Cache-Zeile ungültig?
S: Beim Schreiben bzw. wenn eine andere CPU den geänderten Wert lesen will? Also bei diesem TAS bei jedem Schleifendurchlauf.
P: Wie könnte man das mit CAS besser lösen? Hinweis, CAS vergleicht und tauscht dann.
S: CAS schreibt nur wenn der Lock nicht belegt ist, reduziert damit also das Cache-Trashing deutlich.
Fazit
Atmosphäre sehr angenehm, Fragen kamen nur von Daniel Lohmann. Note: sehr gut
Ich hab bei einigen Fragen etwas zu lange gezögert und kam nicht gleich auf die Antwort. Es lohnt sich, die „Programm“-Entwicklung schon zu Hause genau durchzugehen.