Next: Linux als Mehrbenutzersystem
Up: Systemverwaltung
Previous: Prozeßordnung
Die wesentliche Qualität der Zeit, in einer von relativistischen Verzerrungen freien Welt, besteht im unaufhaltsam konstanten Verstreichen; jeder Zeitpunkt ist eindeutig und einmalig.
Um die zeitliche Dimension der realen Welt in der virtuellen Welt von Linux zu modellieren, benutzt das Betriebssystem den Timer-Chip als Uhr. Diese Uhr soll eine möglichst synchrone Zuordnung aller digitalen Ereignisse zu der realen Zeit ihres Auftretens vornehmen.
Das Betriebssystem ordnet jedem Ticken der Systemuhr ein Datum zu, das der Uhrzeit und dem Kalendertag der realen Welt entsprechen soll. Der Timer-Chip zählt mit einer Frequenz von 1,19318MHz, kann also die Zeit mit einer Auflösung im Mikrosekundenbereich messen.
Wenn die Systemuhr Zeitdifferenzen von wenigen Mikrosekunden feststellen kann, drängt sich die Frage nach der Genauigkeit dieser Uhr auf. Die Beantwortung dieser Frage zerfällt in zwei Teile:
Die NTP-Zeitfunktionen sind im Kernel enthalten, damit kann Linux höchste Ansprüche an Zeitsynchronisation und Genauigkeit erfüllen. Mit dem Systemcall adjtimex läßt sich die Systemuhr ``ruckfrei'' einstellen. Durch eine vom Kernel emulierte Nachlaufsynchronisation (Phase Locked Loop) kann die Geschwindigkeit der Systemuhr automatisch an eine externe Zeitreferenz angepaßt werden.
Eine externe Referenzzeit kann beispielsweise von einer DCF77-Funkuhr über die serielle Schnittstelle in den Rechner eingespeist werden. Wenn die Zeitmarke, die vom Sekundensignal der Funkuhr erzeugt wird, durch eine spezielle Interruptroutine gespeichert und von geeigneter Software ausgewertet wird, läßt sich die Systemzeit mit dem externen Signal in einem Fehlerintervall von einer Millisekunde synchronisieren.Eine geeignete Funkuhr gibt es für weniger als 80,-DM, Treiber und zusätzliche Informationen finden Sie in den Unterlagen zu dem Vortrag, den Harald König zu diesem Thema auf dem zweiten Linux-Kongreß gehalten hat (http://www.lunetix.de/kongress95/slides/koenig/).
Bei Internet-Systemen kann die externe Referenzzeit aus dem Netz bezogen werden. Das Client-Server-System xntp bietet sehr umfangreiche Funktionalität zu diesem Zweck. Sie finden die aktuelle Version beispielsweise auf ftp.informatik.hu-berlin.de im Verzeichnis /pub/os/linux/sources/kernel/net-source/tools. Dieses Paket enthält außer den Sourcen noch jede Menge Information zum Thema Zeitsynchronisation von Computern.Die Internet-Funktionalität von Linux stellt höhere Anforderungen an die Datumsfunktionen, als das bei einem isolierten Arbeitsplatzrechner der Fall ist. Stellen Sie sich zum Beispiel vor, daß Sie sich von einem Linux-Rechner in Berlin aus mit einem Rechner in Boston, USA, verbinden und von dort eine Datei auf den lokalen Rechner kopieren. In Berlin ist es 10 Uhr vormittags (Sommerzeit), am MIT in Boston ist es 4 Uhr morgens. Sie dürfen erwarten, daß die Datei auf dem Weg von Boston nach Berlin nicht um 6 Stunden gealtert ist.
Um die Zeit auf allen Rechnern im Internet vergleichen zu können, sind alle Systemuhren auf Universal Time Coordinated (UTC, ehemals GMT) eingestellt. Die Umrechnung der Systemzeit in die lokale Zonenzeit wird erst bei der Datumsausgabe durch die Funktionen der C-Bibliothek vorgenommen.
Die Zeitzone des lokalen Systems wird durch die Datei /usr/lib/zoneinfo/localtime bestimmt. Diese Datei sollte für alle Systeme mit Mitteleuropäischer Zeit ein symbolischer Link auf die Zeitzonenbeschreibung MET in dem gleichen Verzeichnis sein.
Jeder User kann die Datumsfunktionen auf eine andere Zeitzone umstellen, indem er in der Umgebungsvariablen TZ den Dateinamen der entsprechenden Zonenbeschreibung angibt.
Der Timer-Chip, mit dem die Systemzeit gemessen wird, ist bei abgeschaltetem Rechner außer Betrieb. Damit die Systemzeit beim nächsten Einschalten wieder aktuell ist, haben alle PCs eine batteriegepufferte Uhr, die das Datum und die Uhrzeit auch ohne Netzspannung weiterzählt.
Diese Uhr wird gelegentlich als Echtzeituhr bezeichnet. Weil sie im gleichen Baustein wie das CMOS-RAM (Non-Volatile-RAM) untergebracht ist und die Zeit in dessen Speicherbereich schreibt, wird sie in diesem Buch durchgängig als CMOS-Uhr bezeichnet.
Der Kernel liest gleich zu Beginn der zweiten Initialisierungsphase, noch vor der Initialisierung der Geräte, die Zeit aus der CMOS-Uhr und stellt die Systemzeit entsprechend ein. Dabei wartet der Kernel beim Auslesen der Uhr genau den Zeitpunkt ab, an dem das im Sekundentakt stattfindende Update der CMOS-Zeit abgeschlossen ist, also gerade eine neue Sekunde beginnt. Auf diese Weise kann der Kernel die Systemzeit, mit einer Abweichung im Bereich von Mikrosekunden, genau auf die CMOS-Uhr synchronisieren, obwohl diese Uhr die Zeit nur mit einer Auflösung von ganzen Sekunden anzeigen kann.
Diese Methode zum Stellen der Systemzeit führt nur dann zu einer korrekten Einstellung, wenn die CMOS-Uhr auf Universal Time Coordinated (oder auch Greenwich Mean Time) eingestellt ist. Wenn Sie die CMOS-Uhr aus irgendwelchen Gründen auf die lokale Zonenzeit eingestellt lassen müssen, können Sie die Systemzeit in einem der Initialisierungsscripts mit dem Programm clock erneut stellen und dabei die Zeitzone berücksichtgen.
Wenn Sie Wert auf eine exakte Systemzeit legen, aber über keine externe Zeitreferenz verfügen, sind Sie auf die CMOS-Uhr angewiesen. Da der Hersteller Ihres PC mit Sicherheit keinen temperaturstabilisierten, geeichten Qualitätsquarz als Taktgeber für die CMOS-Uhr eingebaut hat, müssen Sie mit einem Fehler von einigen Sekunden pro Tag rechnen. Durch Beobachtung über mehrere Tage können Sie diesen Fehler auch ohne aufwendige Messgeräte sehr gut bestimmen. Das Systemprogramm clock ermöglicht es Ihnen, den so bestimmten Fehler zu korrigieren.Um die CMOS-Uhr zu ``justieren'', werden in der Datei /etc/adjtime die tägliche Abweichung und das Datum der letzten Korrektur eingetragen. Jedes Mal, wenn das Programm clock zum Justieren der CMOS-Uhr aufgerufen wird, errechnet es aus dem Datum der letzten Korrektur und dem Fehlerfaktor die aktuelle Abweichung und korrigiert sowohl die Systemzeit als auch die CMOS-Uhr, sobald der Fehler mehr als eine Sekunde beträgt. Außerdem wird in der Datei /etc/adjtime die Zeitmarke der letzten Korrektur aktualisiert und der nicht korrigierte Rest zur vollen Sekunde als dritter Wert eingetragen.
Wenn Sie zum Beispiel festgestellt haben, daß die CMOS-Uhr Ihres Rechners innerhalb von zwei Tagen um 23 Sekunden vorgeht, können Sie das System zur Korrektur folgendermaßen installieren:
[01] # echo "0.0 0 0.0" > /etc/adjtime [02] # clock -au [03] # date -s "Thu Aug 29 15:59:00 MET DST 1996" Thu Aug 29 15:59:00 MET DST 1996 [04] # clock -wu [05] # cat /etc/adjtime 0.000000 841345408 0.000000 [06] # echo "-11.500000 841345408 0.000000" > /etc/adjtime [07] # _
Mit dem ersten Kommando wird die Datei /etc/adjtime neu erzeugt, durch das zweite Kommando wird der aktuelle Zeitstempel in die soeben erzeugte Datei eingetragen. Im dritten Kommando wird die Systemzeit ``von Hand'' mit der höchsten Genauigkeit gestellt. Durch das vierte Kommando wird die CMOS-Uhr mit der gerade eingestellten Systemzeit synchronisiert.
Für die Beispielrechnung beträgt der Fehler 23 Sekunden in zwei Tagen, das sind 11,5 Sekunden pro Tag. Das sechste Kommando zeigt, wie dieser Korrekturfaktor in die Datei adjtime eingetragen werden kann. Es ist wichtig, die beim zweiten Kommando erzeugte Zeitmarke (im Beispiel 841345408) dabei nicht zu verändern.
Wenn Sie jetzt das zweite Kommando oben in einem Initialisierungsscript beim Booten aufrufen, werden CMOS-Uhr und Systemzeit automatisch bei jedem Systemstart korrigiert.
Wenn die Systemuhr mit einer externen Zeitreferenz synchronisiert ist, wird die CMOS-Uhr automatisch alle 11 Minuten nachgestellt. Wenn Sie den während der Betriebspause aufgelaufenen Fehler beim Booten durch die oben beschriebene Methode korrigieren möchten, müssen Sie beim Shutdown dafür sorgen, daß die Zeitmarke in /etc/adjtime in etwa mit dem Datum des letzten Update der CMOS-Uhr vor dem Herunterfahren des Systems übereinstimmt.Die beeindruckende Genauigkeit, mit der die Systemuhr von Linux synchronisiert werden kann, hat wenig mit Echtzeitfähigkeit zu tun. Bei einem Echtzeitsystem muß die Antwortzeit auf ein Ereignis in engen Grenzen vorhersagbar sein.
Der Scheduler von Linux unterstützt diese Funktionalität nicht. Das Scheduling wird spätestens durch einen Clocktick vom Timer ausgelöst. Bei einer Frequenz von 100Hz sind Verzögerungen bis zu 10 Millisekunden nicht zu vermeiden. Durch Interrupts, Prozesse mit höherer Priorität und Swapping kann es noch wesentlich länger dauern, bis ein Prozeß tatsächlich ausgeführt wird.
Weil Linux im Sourcecode vorliegt, läßt sich natürlich für spezielle Anwendungen eine Lösung programmieren. Beispielsweise kann der Scheduler modifiziert werden, oder eine zeitkritische Funktion wird als Interruptroutine in den Kernel integriert.
Das Linux Anwenderhandbuch