Operating Systems I (Bachelor) |
Lab 2: Kernel Modul
Lernziele.
Funktionsweise der Systemschnittstelle in Linux
Bearbeitung eines Systemaufrufts im Linux-Kernel
User-level Code zum Auslösen eines Systemaufrufs
Parameter-Übergabe zwischen Userspace (Prozess) und Linux-Kernel
Aufgabe.
Einleitung:
Kernaufgabe eines Betriebssystem ist es u.a. Nutzern eine
Plattform zu bieten in denen sie Programme benutzen können und dabei die
Ausführdetails und den dafür benötigten Verwaltungsaufwand vom Nutzer fern zu
halten. Damit nun einzelne Nutzerprogramme nicht die Gesamtausführung des
Systems beeinflussen, wird strikt zwischen dem eigentlichen Betriebssystem,
(auch Systemkern oder Kernel) und ausgeführten Nutzerprozessen unterschieden.
Diese Trennung entscheidet darüber, welche Rechte die zur Zeit ausgeführte
Software hat und wird bis runter auf die Hardware vollzogen (siehe
CPU Ringe).
Dies hat zur Folge, dass das Betriebssystem als Programm alle verfügbaren
Rechte hat. Es darf z.B. von der Festplatte lesen bzw. auf diese schreiben oder
Grafik auf dem Display ausgeben. Nutzerprogramme hingegen dürfen dies nicht.
Wenn ein Nutzerprogramm solch eine höher privilegierte Aufgabe durchführen
möchte, muss es das Betriebssystem bitten, diese stellvertretend zu übernehmen.
Solche eine Anfrage nennt man Systemaufruf bzw. System Call.
Damit wird sichergestellt, dass alle wichtigen Aktionen stets vom Betriebssystem
kontrolliert und korrekt ausgeführt werden und somit das System im Kern immer in
einem definierten Zustand und verfügbar bleibt.
In der folgenden Aufgabe sollen Sie verschiedene Varianten kennenlernen, solch
einen System Call zu realisieren. Die wahrscheinlich offensichtlichste ist
dabei, den Quelltext des Betriebssystems um Ihren eigenen Systemaufruf zu
erweitern, dieses neu zu kompilieren und dann den neu erstellten
Betriebssystemkernel zu booten. Dies erfordert allerdings mitunter Aufwand,
welcher nicht proportional zur Größe des zu lösenden Problems ist. Eine weitere
Variante die sie daher umsetzen sollen ist, nur ein einzelnes Kernelmodul zu
erstellen, welches dann in das schon laufende Betriebssystem integriert werden
und über das sog. Proc-Filesystem angesprochen werden kann. Beim Proc-FS handelt
es sich um ein virtuelles
Dateisystem. Die über das Proc-FS angezeigte Dateien sind keine wirklichen
Dateien. Sie dienen viel mehr als Kommunikationsschnittstelle und erlauben es
mit den gängigen Fileoperationen wie read() und write() Daten zwischen Userspace
und Kernelspace auszutauschen. Um Ihnen eine noch leichtgewichtigere aber
dementsprechend auch im Umfang nicht ganz so mächtige
Kommunikationsschnittstelle zu zeigen, sollen Sie im letzten Teil der Aufgabe
das sog. Sys-Control, kurz "sysctl", Interface nutzen. Dies ist eigentlich dafür
vorgesehen kleinere Konfigurationen am System zur Laufzeit vorzunehmen, kann
aber auch als Kommunikationsschnittstelle verwendet werden.
Wenn Sie alle hier dargestellten Möglichkeiten implementiert haben, sollten Sie
sie über ausreichende Auswahl an Systemaufrufrealisierungen verfügen, welche es
Ihnen erlaubt, die passende für das jeweilige Problem auszuwählen.
Aufgabenstellung:
Installieren Sie Qemu und laden Sie sich das Qemu-Image für das Praktikum von der Webseite. Beachten Sie dabei die Hinweise auf unserer Webseite.
Implementieren Sie ein Modul sarlkm.ko, welches ein Pseudo-File /proc/sarlkm bereitstellt nachdem es geladen wurde. Das File soll Folgendes enthalten:
<Prompt>, <Praktikumsgruppe>, <Anzahl Sekunden seit Systemstart>
Durch Schreiben in das Pseudo-File /proc/sarlkm soll sich der Prompt ändern lassen:
cat "foobar" > /proc/sarlkm
setzt den Prompt auf "foobar".
Implementieren Sie einen System-Call (sysctl: kernel.prompt), der den Prompt der vorangegangenen Teilaufgabe setzen kann und den Wert des alten Prompts zurückliefert. Erweitern Sie das Modul um einen Modulparameter "prompt_param" mit welchem der Prompt schon beim Laden des Moduls gesetzt werden kann.
Schreiben Sie ein Programm hostnamesysctl, das über die Kommandozeile einen Parameter entgegennimmt und den Hostnamen des Rechners mittels sysctl setzt. Wenn das Programm hostnamesysctl ohne Parameter aufgerufen wird, so soll der Hostname mittels sysctl ermittelt und mit printf ausgegeben werden.
Nutzen Sie sowohl für das Kernelmodul als auch für das Programm hostnamesysctl die Vorlage lab-2.tar. Diese enthält die folgenden Dateien:
Makefile: Makefile zum bauen und starten
hostnamesysctl.c: Vorlage für das Programm hostnamesysctl
sar.c: Vorlage für das Modul sarlkm.ko
test.sh: Testscript zum Testen des Moduls und von hostnamesysctl
Das Makefile enthält folgende Ziele:
sarlkm: baut das Modul
tools: baut das Programm hostnamesysctl
clean: löscht die Binärdateien und das Modul
pack: erstellt ein tar-file für die Abgabe über Goya
Zusatzaufgaben.
Die Bearbeitung eines System Calls durch den Kernel soll möglichst kurz gehalten werden. Bei komplexen Aufgaben (z.B. Netzwerkfilter) sollte die Aufgabe also möglichst an einen Userspaceprozess ausgelagert werden.
1. Implementieren Sie ein Userspace-Programm und einen entsprechenden System-Call, welcher die Bearbeitung des System-Calls an das Userspace-Programm weiterreicht.
2. Das Kopieren der Daten vom Userspace in den Kernelspace und zurück ist recht auswendig. Versuchen Sie die Kopiervorgänge zu reduzieren ("Zerocopy").
Abgabe der Lösung.
Quelltexte als .tar-Datei
Hinweise.
Verwenden Sie den PC-Emulator Qemu zum Ausprobieren Ihres modifizierten Betriebssystems. Hinweise zur Bearbeitung finden Sie in den Folien zur Übung.
Ressourcen.
Folien aus der Übung.