OOStuBS/MPStuBS
|
$ ssh and.tanenbaum@lab.sra.uni-hannover.de -p 2205 # für Lab-PC 5
$ tmux -S /tmp/my-shared-tmux new # tmux session erstellen $ setfacl -m "u:and.tanenbaum:rw" /tmp/my-shared-tmux # Andrew Tanenbaum Zugriff geben $ tmux -S /tmp/my-shared-tmux attach # auf die Session verbinden (von beiden auszuführen)
$ apt install nasm qemu qemu-system-x86 qemu-kvm build-essential binutils gcc-multilib g++ g++-multilib
Für die Bearbeitung der Rechnerübungsaufgaben (und damit für die Entwicklung von OOStuBS und MPStuBS) sind alle benötigten Werkzeuge im Labor vorinstalliert. Die Laborrechner sind über SSH und VNC erreichbar. Die Einrichtungsdetails finden sich weiter unten. Alternativ findet ihr unter ubuntu.ova ein VirtualBox-Image, in dem ebenfalls alle benötigten Werkzeuge vorinstalliert sind. Ihr könnt die Aufgaben natürlich auch zu Hause bearbeiten, wir empfehlen hierzu den Einsatz von Linux. Weiter unten finden sich einige Hinweise, wie ihr euren Linux-Rechner entsprechend konfigurieren könnt.
Da sich bei der Betriebssystementwicklung ab und zu auch Fehler einschleichen können, müsst ihr eure Lösungen testen, bevor ihr sie abgebt. Wir benutzen hierzu einen Emulator (QEMU
bzw. KVM
). Bei der Abgabe benutzen wir immer das QEMU
und KVM
auf dem Labor, um eure Lösung zu kontrollieren. Ihr solltet deshalb immer auch zumindest einmal im Labor testen, das ist die Referenzplattform!
Die Laborrechner erreicht man über SSH. VNC kann dann als zweiter Schritt über SSH getunnelt werden.
Um SSH zu verwenden braucht ihr eine Rechnernummer. Nehmt dazu eure Gruppennummer modulo 10 (um ein bisschen Loadbalancing hinzubekommen). Geht dann auf
$ ssh <euer_login_name>@lab.sra.uni-hannover.de -p 22<rechnernummer>
D.h., für Andrew Tanenbaum wäre der Login für Rechner 5:
$ ssh and.tanenbaum@lab.sra.uni-hannover.de -p 2205
Der Phabricator verbietet den anonymen Zugriff auf euer Repository. Auch eine normale Anmeldung, wie manchmal bei GitHub üblich ist auf den Repositories nicht möglich. Daher müsst ihr ein Schlüsselpaar erzeugen und dem Phabricator den öffentlichen Schlüssel zur Verfügung stellen zur Authentifizierung.
Entweder wird unter (Profilbild) -> Settings; dann unter Authentication -> SSH Public Keys ein Schlüsselpaar erstellt, oder ein eigener öffentlicher Schlüssel eingefügt. Soll das Schlüsselpaar lokal erzeugt werden, wird ssh-keygen
zur Schlüsselgenerierung verwendet:
$ ssh-keygen -t rsa -b 4096
Entweder der Schlüssel wird als ~/.ssh/id_rsa
also in eurem Home im versteckten Verzeichnis .ssh
abgelegt, oder ihr gebt ihm einen anderen Namen. id_rsa
wird standardmäßig von ssh angeboten, alle anderen Namen existieren für ssh zunächst nicht. Alle anderen Schlüsseldateien könnt ihr dem ssh-agent
bekanntmachen, indem ihr:
$ eval $(ssh-agent) # ssh-agent starten $ ssh-add ~/.ssh/phabricator # den Key in der Daten phabricator bekanntmachen
Beim zweiten Schritt werdet ihr u.U. nach dem Passwort gefragt, was ihr bei der Key-Erzeugung angegeben habt.
Ab dem Zeitpunkt (wenn ihr den öffentlichen Schlüssel dem Phabricator bekannt gemacht habt), könnt ihr einfach alle git-Kommandos ausführen. Die Authentifizierung läuft ab dann implizit über die Schlüssel und ihr müsst keine Passworte (mehr) eingeben.
VNC ist eine Technik, um eine Desktopoberfläche über Fernzugriff zu benutzen. Das braucht ihr vor allem, da QEMU und KVM ein Fenster öffnen. VNC greift im Normalfall auf eine laufende Session zu. Diese ist im Labor für euren Nutzer aber nicht vorhanden. Folglich müsst ihr zusätzlich zu dem VNC-Server auch noch eine Session starten. Dazu legt ihr ein Shellscript ~/.vnc/xstartup
an (über die Kommandozeile geht das z.B. mit dem Editor nano
gut). In dem Shellscript startet ihr eure Session, z.B. (nur eine der Zeilen sollte einkommentiert sein!):
#!/bin/sh /usr/bin/startkde & # KDE #/usr/bin/gnome-session & # GNOME #/usr/bin/startxfce4 & # XFCE4
Der VNC-Server wird dann diese Datei benutzen, um eine neue Session zu starten. Anschließend könnt ihr auch schon direkt den VNC-Server starten:
$ tigervncserver -useold -localhost
Der Server fragt dann nach einem Passwort (das schützt eure Session) und gibt nach dem Start eine Desktopnummer aus, die ihr später zum Verbinden braucht. Um die Session wieder zu schließen, reicht der Befehl:
$ tigervncserver -kill :<desktopnummer>
Bitte geht dabei verantwortungsbewusst mit den Ressourcen um. Unter Linux ist die Verbindung mit dem VNC-Servier z.B. mit dem VNCViewer möglich:
$ xtigervncviewer -passwd <password-file> -via <ssh-kennung> localhost:<bildschirmnummer>
<ssh-kennung>
muss dabei ein Eintrag aus der SSH-Config sein. Technisch müsst ihr einen SSH-Tunnel zum VNC-Port aufbauen und euch dann mit dem Server verbinden. Dieser VNC-Port unterscheidet sich pro gestarteter Instanz. Ihr könnt ihn per netstat -tulpen
nachschauen (Der standard ist 5900). Das -via
Argument macht das alles implizit. Die Passwort-Datei (.vnc/passwd
) muss dabei auf den Client-PC kopiert werden. Unter manchen Distributionen wird der xtigervncviewer auch als vncviewer ausgeliefert. Bspw.:
$ xtigervncviewer -SecurityTypes VncAuth -passwd /home/and.tanenbaum/.vnc/passwd -via lab-pc01 localhost:2
Die SSH-Config (Datei .ssh/config
) sieht dann so aus:
VNC erlaubt es, die Session zu teilen. Das ist allerdings eine Option des Clients. Beim xtigervncviewer heißen die Optionen z.B. -Shared
(Sehen und Bearbeiten) bzw. -ViewOnly
(nur Sehen). Außerdem ist die Option -RemoteResize=0
sinnvoll, um das automatische Anpassen an die Fenstergröße zu verhindern.
Für das gemeinsame Arbeiten kann man tmux verwenden, um eine TTY-Session mit einem anderen Benutzer zu teilen. Die beiden Benutzer können dann erst einmal dasselbe Terminal sehen und bearbeiten. Außerdem arbeitet tmux sessionbasiert, d.h. man teilt nicht nur ein Terminal, sondern eine ganze Session, konkret beliebig viele Terminals und ihren Zustand und Layout.
Zur Einrichtung erstellt man eine tmux -Session unter Angabe eines Sockets (-S
/ -L
):
$ tmux -S /tmp/my-shared-tmux new
Damit wird ein tmux-Server erzeugt, falls noch keiner auf dem Socket lauscht. (Der Socket-Name my-shared-tmux
sollte durch einen eigenen Namen ersetzt werden)
Mit der Option -s session-name
(hinter new
) kann der Session auch noch ein eigener Name zugewiesen werden (Standard: „0“).
Nun können weitere Nutzer bzw. tmux-Instanzen mit der Session verbunden werden:
$ tmux -S /tmp/my-shared-tmux attach
Gegebenenfalls muss mit der Option -t session-name
die Session identifiziert werden. Ein detach
wird mit der Tastenfolge Ctrl-b d
gemacht.
Damit ein anderer Benutzer ein attach
durchführen kann, muss er entsprechende Rechte am Socket haben, was mittels ACLs bewerkstelligt werden kann:
$ setfacl -m "u:and.tanenbaum:rw" /tmp/my-shared-tmux
(Wobei other.user
mit dem Usernamen des Partners ersetzt wird.)
Bitte seid bei der Erteilung der Rechte vorsichtig und verwendet dafür im Labor keine UNIX-Gruppenberechtigungen. Bedenkt, dass jeder in einer solchen Gruppe dann vollen Zugriff auf eure tmux-Session hat.
Für weitere Informationen siehe die offizielle tmux-Doku oder die Manpage von tmux.
Zum Kompilieren wird wie im Makefile vorgegeben g++
verwendet, zum Assemblieren des Startup-Codes und der hardwarenahen Teilprogramme der Netwide Assembler (nasm
). Der x86-Emulator QEMU
eignet sich zum vorläufigen Testen und, durch einen eingebauten GDB-Stub, auch zum Debuggen mit dem GNU Debugger
. Im Laborraum ist die entsprechende Umgebung vorhanden; wer das Ganze zu Hause machen will, muss sich die genannte Software entsprechend einrichten. Bei Problemen könnt ihr uns gerne fragen.
Zu Aufgabe 1 gibt es je eine Vorgabe für OOStuBS (https://scm.sra.uni-hannover.de/source/v_bsb_vorgabe_oostubs/) und MPStuBS (https://scm.sra.uni-hannover.de/source/v_bsb_vorgabe_mpstubs/). Die Vorgaben sind Git Repositories auf dem SRA Phabricator, in die wir die Vorgaben für die einzelnen Aufgaben sukkessive einchecken.
Wir werden für eure Gruppen Repositories im Phabricator anlegen und ihr könnt euch beim Übungsleiter zu diesen Gruppen zuweisen lassen. In der Beschreibung des Gruppenrepositories ist beschrieben, wie ihr die Vorlage (entweder OOStuBS oder MPStuBS) in eurer Repository integrieren könnt.
make
im Lösungsverzeichnis. Alle .cc
- und .asm
-Dateien im Lösungsverzeichnis werden daraufhin mit den entsprechenden Tools (Compiler bzw. Assembler) übersetzt und als bootbares Systemimage zusammengebunden. Anschließend stehen euch die Befehle make {kvm,qemu}{,-gdb,-ddd}{,-noopt}
zum Testen und Debuggen zur Verfügung (mehr dazu im nächsten Abschnitt).Als schnellsten und einfachsten Test eurer Implementierung könnt ihr mit make kvm euer Systemimage in QEMU mit Hardware-Virtualisierung ausführen:\
dietrich@obelix:~/oostubs$ make kvm
Dabei wird QEMU standardmäßig so konfiguriert, dass er ein System mit vier Prozessoren emuliert. Für die Entwicklung von OOStuBS stört dies nicht weiter, da die zusätzlichen CPUs ohne weiteres Zutun einfach „links liegen“ gelassen werden. Für die MPStuBS-Bastler gilt: durch den KVM-Modus wird euer System echt parallel auf mehreren Kernen ausgeführt. Dieser Test kommt daher im Hinblick auf Race-Conditions und fehlerhafter Synchronisation dem Test auf der echten Hardware schon relativ nahe.
make kvm
oder auf echter Hardware auftreten.Wer bei der Fehlersuche mit einfachem „printf
-Debugging“ nicht weiterkommt, der kann den in QEMU integrierten GDB-Stub verwenden, um sich mit einem Debugger (gdb
) zu der Emulation zu verbinden. Auf diese Weise könnt ihr euren Betriebssystemcode bequem schrittweise ausführen, um den Grund etwaiger Abstürze oder ungewünschten Verhaltens herauszufinden. Dafür stellen wir im Makefile das Target gdb bereit:
dietrich@obelix:~/oostubs$ make gdb
In dieser Konfiguration wartet der GDB-Stub im Emulator auf eine Socket-Verbindung, über die sich ein gdb
mit dem Emulator verbinden kann, um das System zu debuggen. Der Start des Debuggers wird bereits im Makefile erledigt, so dass der gdb
-Prompt unmittelbar nach dem Start von QEMU im Terminal erscheint.
Eine knappe Referenz der GDB-Funktionen könnt ihr hier finden. Wollt ihr detailierte Hinweise, wie ein bestimmter GDB-Befehl zu verwenden ist, so könnt ihr die in GDB eingebaute Hilfefunktion nutzen:
(gdb) help <Befehlsname>
Hinweis: Da durch den Emulator QEMU bei Verwendung des GDB-Stubs das Betriebssystem pausiert wird, darf man im GDB/DDD die Programmausführung nicht mit run
neu anstoßen, sondern muss sie stattdessen mit continue
fortführen.
Für einen schnelleren Überblick der Register- und Stackinhalte empfiehlt sich außerdem, diese gdbinit-Datei unter dem Namen .gdbinit
im eigenen Home-Verzeichnis abzulegen. Diverse Ansichtsoptionen am Anfang der Datei können ganz nach dem eigenen Geschmack geändert werden.
Das Arbeiten von Zuhause geht am einfachsten über eine SSH-Verbindung. Von alleine könnt ihr auf dieser Verbindung aber kein Fenster starten. QEMU ist aber in der Lage, den CGA-Screen im Textmodus vollständig mit NCurses auf ein Terminal zu mappen. Wir haben euch darum Targets eingerichtet, welche QEMU/KVM mit curses starten und auf von SSH aus funktionieren.
dietrich@obelix:~/oostubs$ make qemu-curses dietrich@obelix:~/oostubs$ make kvm-curses
Auch das GDB-Target braucht ein Fenster. Es ist aber möglich, GDB separat zu starten und QEMU anzuweisen, auf GDB zu warten. Letzeres geht, wenn ihr die vorhanden Targets mit dem -gdb
-Suffix startet. Ersteres geht, wenn ihr das spezielle Target connect-gdb
verwendet. D.h., um einen QEMU mit eurem System zu starten und zu debuggen, öffnet ihr zwei Terminals über SSH und gebt in dem einen ein:
dietrich@obelix:~/oostubs$ make qemu-curses-gdb
und in dem anderem:
dietrich@obelix:~/oostubs$ make connect-gdb
dietrich@obelix:~/oostubs$ make gdb-noopt
dietrich@obelix:~/oostubs$ make help
Wie bereits erwähnt, ist die Vorlage zu OOStuBS bzw. MPStuBS im SRA Phabricator zu finden. Wir haben dort jeder Übungsgruppe ein Repository angelegt, welches ihr zur gemeinsamen Arbeit nutzen sollt.
Eine kurze Übersicht der Git-Befehle findet ihr hier. Als tieferen Einstieg in die verteilte Quellcodeverwaltung empfehlen wir das Pro Git Buch, welches als Creative Commons verfügbar ist.