Übung zur Vorlesung Grundlagen Betriebssysteme und Systemsoftware (Prof. Dr. J. Schlichter, WS 2011 / 2012) Übungsleitung: Dr. Wolfgang Wörndl (gbs-ws11@mailschlichter.informatik.tu-muenchen.de) http://www11.in.tum.de/veranstaltungen/grundlagenbetriebssystemeundsystemsoftwarews1112 http://www11.in.tum.de/veranstaltungen/uebung-gbs-ws11 Übungsblatt 2 Abgabe der Hausaufgaben vor der nächsten Tutorübung (KW: 46-14-18.11) per E-Mail an den Tutor der eigenen Gruppe. Der Betreff der Mail sollte folgendem Schema genügen: GBS Abgabe HA: Übungsblattnummer; Übungsgruppennummer Musterlösungen Tutoraufgaben: ab 11.11.2011 (18 Uhr), auf der Download. Übungswebseite zum Musterlösungen Hausaufgaben: Download. ab 18.11.2011 (18 Uhr), auf der Übungswebseite zum Stoff Es wird empfohlen folgende Literatur durchzuarbeiten: Skript zur Vorlesung: Kapitel 1 und 2 Tanenbaum Modern Operating Systems : Kapitel 1 Introduction Siegert, Baumgarten Betriebssysteme : Kapitel 1 Einführung Das Gnu C-Programming Tutorial (Burgess, Hale-Evans) (als pdf zum Download von der Übungs-Webseite oder http://www.crasseux.com/books/ctutorial/). Hierbei sind wichtig: Kapitel 9, 14, 17, 20, 21. Völlig weglassen kann man Kapitel 16, 22, 23.
1 Pointer und Arrays in C, Pointerarithmetik (Tutoraufgabe) Lernziel Das Konzept der Pointer in C soll weiter geübt und die Kenntnisse an Beispielen vertieft werden. Insbesondere soll das Zusammenspiel von Arrays und Pointern verdeutlicht werden. Für das Verständnis und die Implementierung von Betriebssystemen ist das systemnahe Pointer- Konzept, das in modernen höheren Sprachen oft nicht mehr vorkommt bzw. nur implizit verwendet wird, recht hilfreich. Aufgabe Es sollen an einer Reihe vorgegebener C Programmstücke die beteiligten Entitäten untersucht und interpretiert werden. Folgende Deklarationen und Initialisierungen seien gegeben: int arrayxyz[10]; //allocates memory for 10 int variables int i; int *pi; int intvar; for(i=0;i<10;i++) arrayxyz[i]=i; Keine Abgabe Die Aufgabe wird in den Tutorübungen gemeinsam erarbeitet. Die Aufgabe soll NICHT abgegeben werden. 1.1 Deklarationen Wie sind die folgenden Anweisungen zu interpretieren? pi = &arrayxyz[7]; pi = &arrayxyz[0]; Sind die zweite und die dritte Zuweisung äquivalent? 1.2 Code interpretieren Zusätzlich zu den Deklarationen aus der Aufgabenstellung ist nun folgendes Code-Stück gegeben: intvar = arrayxyz[8]; intvar = *(arrayxyz+8);
*(pi + 12) = 178; pi[12] = 178; Sind die erste und die zweite Anweisung äquivalent? Sind die vierte und die fünfte Anweisung äquivalent? Was ist das Problem bei den Anweisungen vier und fünf? Wenn die Deklarationen aus der Aufgabenstellung mit Hilfe von double Variablen, Arrays und Pointern formuliert worden wären: Hätte man dann in der dritten Anweisung *(pi + 4*12) schreiben müssen? 1.3 Korrektheit von Code Welche der folgenden Anweisungen sind mit den Deklarationen aus der Aufgabenstellung korrekt? pi++; arrayxyz++; arrayxyz = pi; 1.4 Unterschiede von Deklarationen Interpretieren Sie die folgenden Deklarationen! Wo sind die Unterschiede? int (*arrayxyz)[10]; int *(arrayxyz[10]); int *arrayxyz[10]; 1.5 Bewertung von Code In welcher Hinsicht ist int *arrayxyz[10]; for(i=0;i<10;i++) array[i]=(int *)malloc(10*sizeof(int)); flexibler als int arrayxyz[10][10];
2 POTATOES - First Steps (Tutoraufgabe) Lernziele POTATOES (Practical Oriented TeAching Tool, Operating (and) Educating System) ist ein einfach verständliches open-source Betriebsystem für Lehr- bzw. Lernzwecke. Es entstand im Rahmen des Praktikums Technische Informatik an der TUM. Lauffähig ist das System auf x86-rechnern, programmiert wurde es hauptsächlich in C und zu kleinen Teilen in Assembler. In der GBS-Übung soll es die Möglichkeit bieten, auch einmal praktische Erfahrungen in der Betriebssystementwicklung zu sammeln. Außerdem dient es als Plattform für eigene Experimente im Bereich Betriebssysteme und hardwarenahe Programmierung. Für die Arbeit mit POTATOES wird eine vorkonfigurierte Virtuelle Maschine zur Verfügung gestellt, um für alle Studenten eine einheitliche Entwicklungsumgebung zu garantieren. Diese Tutoraufgabe dient der Einführung con POTATOES und zeigt die Installation, Ausführung und Nutzung dieses Systems. Aufgabe Laden Sie sich das Einführungsdokument zu POTATOES (Anleitung Studenten.pdf)herunter und machen Sie sich mit POTATOES vertraut. Die Aufgaben auf diesem Übungsblatt entsprechen weitgehend der Einführung. Diese und sämtliche Ressourcen finden Sie unter: http://www11.in.tum.de/veranstaltungen/uebung-gbs-ws11 Abgabe Diese Aufgabe wird in der Tutorübung bearbeitet. Eine Abgabe ist NICHT notwendig. 2.1 Installation von POTATOES POTATOES läuft in einer virtuellen Maschine, um Plattformunabhängigkeit zu ermöglichen. Installieren Sie die virtuelle Maschine des POTATOES Hostsystems in Virtualbox von Sun und starten Sie POTATOES aus dieser virtuellen Maschine heraus. 2.2 POTATOES benutzen Machen Sie sich mit den Funktionen von POTATOES vertraut: Starten Sie neue Konsolen und wechseln Sie zwischen diesen. Machen Sie sich mit dem Dateisystem vertraut. Legen Sie eine neue Datei an, geben diese aus und löschen Sie sie wieder.
2.3 POTATOES programmieren Starten Sie die Eclipse Entwicklungsumgebung in der virtuellen Maschine und suchen Sie im Quellcode den Welcome to POTATOES String. Ändern Sie diesen in Welcome to POTA- TOES in GBS at TUM, kompilieren Sie POTATOES neu und führen es aus. Sie sollten nun diese Änderungen sehen. Starten Sie das Skript Export and Compress in der virtuellen Maschine, um den gesamten Quellcode von POTATOES in ein ZIP-Archiv zu packen. Exportieren Sie dieses Archiv gemäß der Anleitung aus der virtuellen Maschine heraus. Bei der Abgabe zukünftigtiger Potatos- Aufgabe ist diese Vorgehensweise zu verfolgen. 2.4 Änderungen verwerfen Machen Sie Ihre Änderungen rückgängig, indem Sie das Revert code changes Script ausführen. 3 C-Programmierung (Hausaufgabe) Lernziel Es soll der Umgang mit C am Beispiel exemplarisch ausprobiert werden, insbesondere der Umgang mit Zeigern, Referenzen und Dynamic Memory-Allocation. Es soll ein binärer Baum in C implementiert werden. Verwenden Sie am besten ein Unix / Linux System und gcc als C Compiler. Falls Sie auf Ihrem Rechner nur Windows verwenden, empfiehlt sich eine Linux Live CD (z.b. Knoppix, die komplett von CD / DVD lauffähig ist http://www.knoppix.org). Alternativ können Sie diese Aufgabe auch in der Rechnerhalle persönlich oder per SSH-Zugang lösen. Abgabe Als Abgabe ist ein (getestetes) Gesamt-.c-File, das alle Teilaufgaben umfasst, ausreichend. 3.1 Datenstrukturen Implementieren Sie mit Hilfe von struct eine Datenstruktur Node, die je einen Zeiger auf den Elternknoten, sowie auf den linken und rechten Kindknoten enthält. Außerdem soll die Datenstruktur eine double Variable nodevalue zur Speicherung von Nutzdaten enthalten. 3.2 Implementierung Implementieren Sie eine Funktion makerandomtree, die als Eingabe-Parameter eine Integer-Zahl numberofnodes nimmt und als return-parameter einen Zeiger auf Node liefert. Die Funktion soll mit Hilfe von dynamischer Speicher-Allokation einen binären Suchbaum mit numberofnodes Knoten aufbauen, deren nodevalue eine (Pseudo-)Zufallszahl in [0, 1] ist. Hierbei sind folgende Aspekte interessant:
Wie kann man das zur Instantiierung von Objekten aus Klassen verwendete new in Java in gewissem Sinn analoge dynamische Neu-Erzeugen von struct Instanzen mit Hilfe von malloc realisieren? Welchen Vorteil hat dynamic memory allocation gegenüber static memory allocation (static Variablen) und automatic memory allocation ((Block-)lokale Variablen)? Wie ist der dynamisch allozierte Speicher organisiert im Vergleich zu den anderen Varianten? Wie kann man Pseudo-Zufallszahlen in C erzeugen? Welche Präprozessor-Includes muss man in den Header schreiben? Muss man die zugehörige Bibliothek beim Kompilieren extra hinzu linken? 3.3 Implementierung Implementieren Sie eine Funktion inordertraversal, die einen binären Baum in order traversiert. Bearbeiten des Knotens soll in der Ausgabe von nodevalue bestehen. 3.4 Implementierung Implementieren Sie eine main Funktion, die einen binären Suchbaum mit 100 Knoten erzeugt, diesen inorder traversiert und dabei den Sinus der enthaltenen nodevalues (mal 2π) berechnet, den Wert in nodevalue schreibt und ausgibt. Implementieren Sie hierzu eine zweite Variante inordertraversaltwo der Traversierfunktion inordertraversal aus Aufgabe 3.3. Hierbei sind folgende Aspekte interessant: Welche Präprozessor-Includes muss man jetzt in den Header schreiben? Muss man jetzt die zugehörige Bibliothek beim Compilen extra hinzu linken? 4 POTATOES-Konsolenanwendungen (Hausaufgabe) Lernziel Diese Aufgabe vermittelt einen ersten Einblick in die Funktionsweise von POTATOES. Es soll eine einfache Konsolenapplikation programmiert werden, die aus der Shell von POTATOES aufrufbar ist. Abgabe Abzugeben ist der modifizierte Quellcode von Potatos als ZIP-Archiv (vgl. Aufgabe 2.3).
Aufgabe In dieser Aufgabe soll ein einfaches Shellkommando hello implementiert werden. Die Applikation benötigt genau zwei Argumente: Einen Bezeichner und eine Nummer, die angibt wie oft der Bezeichner ausgegeben werden soll. Es soll soll also [number] mal der Text [lineno]: Hello, [name]. auf der Konsole erscheinen, wobei [lineno] die Anzahl der bereits ausgegebenen Zeilen darstellt. Bei Aufruf des Befehls mit weniger als zwei Argumenten soll der Hilfetext Usage: hello [name] [number] ausgegeben werden. Beispiel: Aufruf von hello POTATOES 5 liefert: 1: Hello, POTATOES. 2: Hello, POTATOES. 3: Hello, POTATOES. 4: Hello, POTATOES. 5: Hello, POTATOES. Zu bearbeitende Dateien: src/apps/shell cmds.c 4.1 Vorbereitung Starten sie die Eclipse-Entwicklungsumgebung und öffnen sie die Datei src/apps/shell cmds.c. Legen sie nach der Funktion void shell cmd kill() die Funktion void shell cmd hello(int argc, char *argv[]) an. Der Funktionsrumpf bleibt zunächst leer. Um den Shellbefehl für Benutzer verfügbar zu machen, muss er im Array shell cmds[] registriert werden. Fügen sie ihre Definition, analog zu den bereits vorhandenen Einträgen, vor dem Terminatoreintrag hinzu. 4.2 Argumente entgegennehmen Nun soll der Codepfad für den Aufruf des hello-befehls mit weniger als zwei Argumenten programmiert werden. Der Funktionsparameter argc gibt die Anzahl der Befehlsargumente an, wobei das erste Argument stets der Name des aufgerufenen Befehls ist. Wird also hello POTA- TOES 5 aufgerufen, so ist argc gleich drei. Überprüfen sie, ob weniger als zwei Argumente übergeben wurden und geben sie in diesem Fall mit der Funktion printf() einen Hilfetext aus. 4.3 Applikation implementieren Implementieren sie die oben beschriebene Funktionalität des hello-befehls. Das Array *argv[] enthält alle dem Befehl übergebenen Argumente in Stringform (z. B. argv[0] = hello ). Zum Konvertieren von Strings in int-zahlen können sie die Bibliotheksfunktion int atoi(char*) verwenden.