NVRAM-WakeUp, der automatische Wakeup für VDR

Version 0.1.2 vom 23.07.2004       Copyright © 2003, 2004: Hubertus Sandmann

1. Einleitung

2. Installation

3. Sonstiges


1. Einleitung

1.1 Vorwort

Für den Betrieb als Videorecorder wäre die Fähigkeit, dass die VDR-Box vor Beginn einer anstehenden Aufnahme selbstständig hochfährt, besonders praktisch. Auch für diesen Fall gibt es eine Lösung in Form des kleinen Programms namens nvram-wakeup. Es ist speziell für den VDR geschrieben worden.

http://sourceforge.net/projects/nvram-wakeup/

Hiermit lässt sich beim Herunterfahren des VDR-Rechners der Zeitpunkt für das automatische Hochfahren des Rechners im BIOS setzen.

1.2 Voraussetzungen

Natürlich ist das nur auf einem ATX-Motherboard möglich, in dessen Einstellungen des Powermanagements im BIOS sich ein entsprechender Menüpunkt zur Aktivierung wie z. B. "Automatic Power Up Control" oder auch "Resume by Alarm" mit den entsprechenden Einstellmöglichkeiten für Uhrzeit und ggf. Datum finden lässt. Ebenfalls ist ein aktueller Kernel der Version 2.4 Voraussetzung für diese Funktion. Es muss weiterhin im Kernel oder als Modul die Unterstützung für /dev/nvram, /dev/rtc und /dev/mem aktiviert sein. Beim Standardkernel einer SuSE-Distribution ist dies der Fall.

Auf Linux-Systemen ist es eigentlich üblich die RTC (Real Time Clock) im BIOS auf GMT/UTC eingestellt zu haben und den Zeitversatz zur lokalen Zeitzone (z. B. MEZ bzw. CET) von Linux-System berücksichtigen zu lassen. Für den hier vorliegenden Einsatzfall sollte man aber z. B. mit YaST bei einer SuSE-Distribution besser die lokale Zeit (z. B: "Berlin") als Basis für die Hardware-Clock im BIOS wählen. Das macht die folgenden Schritte deutlich übersichtlicher und weniger fehleranfällig. Man kann das aber problemlos nachträglich wieder umstellen, was den Vorteil hat, dass es dann auch mit der automatischen Umstellung auf die Sommerzeit klappt.


2. Installation

Die Installation des Programms beginnt beispielsweise aus dem Verzeichnis /usr/local/src/ heraus. Dabei wird das Binary für nvram-wakeup und einige weitere Tools erstellt.

    tar -xjvf nvram-wakeup-0.97.tar.bz2
    
    cd nvram-wakeup-0.97
    
    make
    
    make install
    
    

Bei der Installation wird das fertige Binary ins Verzeichnis /usr/local/bin installiert. Gleichzeitig wird dabei auch die beigefügte Beispieldatei vdrshutdown nach /usr/local/bin kopiert und ersetzt die ggf. vorhandene bisherige Datei mit dieser Bezeichnung. Der beim Beenden der VDR-Software übergebene Parameter zum Neustart in Form der Anzahl der Sekunden bis zur nächsten programmierten Aufnahme wird hierbei ausgewertet.

Ebenso kann man nach der Installation die Manual-Pages aufrufen.

    man nvram-wakeup
    
    man nvram-wakeup.conf
    
    


2.1 bekanntes Motherboard

Im einfachsten Fall sind die Daten für das eigene Motherboard bereits bekannt. Mit der aktuellen Version der Software werden die Werte anhand der DMI-Daten bei bereits erfassten Boards richtig erkannt. Ob dies beim eigenen Board der Fall ist kann man überprüfen mit:

    ./biosinfo
    
    ./nvram-wakeup --debug
    
    

Auf jeden Fall muss im Weiteren noch geklärt werden, ob evtl. Besonderheiten oder Änderungen im System erforderlich sind, wie etwa bei der Reboot-Problematik!


2.2 unbekanntes Motherboard

Um vom Betriebssystem aus die Werte für den Zeitpunkt zum automatischen Starten des Rechner aus setzen zu können, müssen zuallererst einmal die betroffenen Adressen im nicht-flüchtigen Speicher (NVRAM) des BIOS bekannt sein. Die entsprechenden Angaben müssen in der Datei nvram-wakeup-mb.c vorhanden sein. Bekannt sind die Werte bereits für so manche Boards, so dass nur noch in einigen Fällen die Angaben für das eigene Motherboard u. U. erst selbst ermittelt werden müssen. Näheres dazu findet sich in der Datei README.

Die prinzipielle Vorgehensweise dabei ist, dass nacheinander die betroffenen Werte im BIOS händisch eingetragen werden und daraufhin die Inhalte des Speicherbereichs ausgelesen werden. Durch Vergleiche ermittelt man dann die Positionen der gesuchten Speicheradressen im NVRAM. Ausgelesen werden die Inhalte über /dev/nvram bzw. /dev/rtc. Details werden in der Datei README.mb erläutert.

Prinzipiell gibt es dazu mehrere Möglichkeiten. Auf die Schilderung der umständlichen manuellen Methode mit bitweisem Vergleich der Werte, verzichte ich hier. Glücklicherweise steht das Hilfsprogramm guess-helper bereit um eine halbautomatische Auswertung der relevanten Daten des eigenen Motherboards zu ermöglichen. Um dieses Programm zu nutzen sind fest vorgegebene Eingaben im BIOS-Menü und mehrere aufeinander folgende Reboots durchzuführen. Zwischendurch ist jeweils der Inhalt des NVRAM auszulesen und in Dateien abzuspeichern.

Dies erfolgt in 4 festgelegten Schritten nach dem ersten Aufruf des Skripts als Systemadministrator root.

    /usr/local/sbin/guess-helper
    
    

  1. Im ersten Schritt sind im BIOS die Wakeup-Funktion zu aktivieren und für den Tag der Wert "31" sowie für die Stunde "23" und jeweils für Minute und Sekunde "59" als Maximalwerte einzutragen.
  2. Im Weiteren werden als Zwischenwerte für den Tag "11", die Stunde "12", die Minute "13" und die Sekunde "14" eingetragen.
  3. Danach sind die jeweiligen Minimalwerte mit "01" für den Tag und jeweils "00" für Stunde, Minute und Sekunde einzugeben.
  4. Im letzten Schritt sind diese Werte beizubehalten und die Wakeup-Funktion im BIOS wieder zu deaktivieren.
Das Skript wird nach jedem Reboot zwischen den einzelnen Schritten erneut aufgerufen. Am Ende der Prozedur steht die automatisch ermittelte Konfigurationsdatei für das bislang unbekannte Board bereit.

Grundsätzlich stehen in den Verzeichnissen /root/guess-directisa und /root/guess-nvram-module wahlweise 2 Dateien entweder für die Methode per direktem I/O-Zugriff oder über /dev/nvram auf die BIOS-Werte zur Verfügung. Hier beschreibe ich nur die universellere Methode mit direktem I/O-Zugriff. Dies vermeidet Probleme mit möglicherweise notwendigen Kernelpatches und nicht auslesbaren Bereichen des NVRAM, wenn die betreffenden Werte oberhalb von Byte 114 und unterhalb von Byte 128 liegen. Auch ist diese Methode die einzige Möglichkeit um bei neueren Boards die Bereiche zwischen Byte 128 und 256 anzusprechen. Hierbei muss man den jeweiligen Chipsatz des Motherboards bei der Option "upper_method" angeben. Es werden bislang aber nicht alle Chipsätze unterstützt.

Als entscheidender Nachteil dieser Methode ist allerdings zu beachten, dass bei gleichzeitigem Zugriff eines anderen Programms auf /dev/nvram oder /dev/rtc die Werte im BIOS verstellt werden können!

Im nächsten Schritt wird dann die dazu passende Vorlagedatei ins geeignete Verzeichnis /etc kopiert.

    cp /root/guess-directisa/nvram-wakeup.conf /etc
    
    

Die Datei und die zusätzliche Option muss dann zukünftig stets beim Aufruf des Programms mit angegeben werden.

    /usr/local/bin/nvram-wakeup -C /etc/nvram-wakeup.conf --directisa
    
    

Als "Trockenübung" für einen letzten Test lässt man nun die Inhalte der Speicherstellen ermitteln und ausgeben um einen programmierten Neustart des Rechners in 20 Minuten zu bewirken:

    /usr/local/bin/nvram-wakeup -C /etc/nvram-wakeup.conf --directisa -s $((`date +%s` + 20 * 60)) --nowrite
    
    

Hierbei wurden die Daten noch nicht wirklich geschrieben. Die Ausgabe des Aufrufs sollte man sich notieren und im BIOS händisch die gleichen Daten eintragen. Nach dem Reboot liest man dann die tatsächlichen Speicherinhalte nocheinmal aus und vergleicht diese mit den zuvor durch das Tool berechneten Werten. Hier sollten sich auf keinen Fall Differenzen ergeben. Ausserdem ist noch beim Vergleich zu beachten, dass der tatsächliche Zeitpunkt des Neustarts 5 Minuten vorverlegt ist um dem Rechner genügend Zeit zu geben den kompletten Bootvorgang zu durchlaufen. Ebenso wird unterstellt, dass der Rechner weitere 5 Minuten benötigt um ordnungsgemäß herunter zu fahren, sodass eine kürzere Zeit als 10 Minuten nicht akzeptiert wird.

War der Probelauf zufrieden stellend, kann man jetzt ernst machen. Man tätigt nun einen erneuten Aufruf und fährt dann den Rechner herunter mit:

    /usr/local/bin/nvram-wakeup -C /etc/nvram-wakeup.conf --directisa -s $((`date +%s` + 10 * 60))
    
    poweroff
    
    

Wenn der Rechner jetzt tatsächlich nach 5 Minuten selbständig mit dem Bootvorgang beginnt, hat man diesen Teil schon geschafft.


2.3 Reboot-Problematik

Grundsätzlich gibt es 2 Gründe für die Notwendigkeit eines zusätzlichen Reboots beim Herunterfahren des Rechners. Entweder werden die Werte bei Änderungen im BIOS erst nach einem Reboot des Rechners übernommen oder aber es liegt ein grundsätzliches Problem im Bereich des Powermanagements APM bzw. ACPI vor. Für diese verschiedenen Ursachen gibt es jeweils unterschiedliche Lösungsansätze, weil bei Problemen im Bereich Powermanagement Lösungen im Rahmen des Programms nvram-wakeup nicht greifen können. Zur Ermittlung der Art des Problems kann man 2 Kurztests heranziehen. Details dazu finden sich in der Datei README.reboot.


1. Kurztest

Der Einfachheit halber wird dieser Test zur vollen Stunde, beispielsweise 12:00 durchgeführt. Zunächst aktiviert man einen automatischen Neustart in 15 Minuten und rebootet den Rechner.

    nvram-wakeup -C /etc/nvram-wakeup.conf --directisa -s $((`date +%s` + 1200))
    
    shutdown -r now
    
    

Nachdem Hochfahren des Rechners wird um 12:05 der Neustart für 12:10 programmiert und der Rechner anschließend sofort heruntergefahren.

    nvram-wakeup -C /etc/nvram-wakeup.conf --directisa -s $((`date +%s` + 601))
    
    shutdown -h now
    
    

Fährt der Rechner dann nicht bis spätestens 12:20 hoch, liegt ein grundsätzliches Problem mit dem Powermanagement vor. In diesem Fall ist in der Datei /usr/local/bin/vdrshutdown der Teil "case 0)" zu löschen und der Teil "case 1)" durch "case 0,1)" mittels eines Editors zu ersetzen, damit zukünftig bei jedem Herunterfahren des VDR-Rechners ein einmaliger Reboot vor dem endgültigen Abschalten durchgeführt wird.

Im Falle eines selbstständigen Starts um 12:15 bedeutet dies, dass bei Änderungen der Wakeup-Zeiten auf dem verwendeten Board zunächst ein zusätzlicher Reboot notwendig ist. Es ist dann eine entsprechende Ergänzung in der /etc/nvram-wakeup.conf zu machen:

...
need_reboot      = ON_ANY_CHANGE


2. Kurztest

Auch für den Fall, dass der Rechner um 12:10 hochfährt, gibt es immer noch die Möglichkeit, dass beim Aktivieren oder Deaktivieren der Wakeup-Funktionalität ein zusätzlicher Reboot notwendig wird. Dies überprüft man mit dem folgenden Kurztest, indem man beispielsweise um 12:30 eine Wakeup-Zeit für 12:45 programmiert und den Rechner rebootet.

    nvram-wakeup -C /etc/nvram-wakeup.conf --directisa -s $((`date +%s` + 1200))
    
    shutdown -r now
    
    

Nach dem Hochfahren wird um 12:35 die Wakeup-Funktion deaktivert und der Rechner heruntergefahren.

    nvram-wakeup -C /etc/nvram-wakeup.conf -d
    
    shutdown -h now
    
    

Sollte der Rechner trotzdem um 12:45 wieder hochfahren, ist in solch einem Fall in der /etc/nvram-wakeup.conf folgende Zeile einzufügen.

...
need_reboot      = ON_STAT

Hat man nach dem zweiten Kurztest festgestellt, dass der Rechner bis 12:50 überhaupt nicht hochgefahren ist und damit keine Reboot-Problematik vorliegt, sind hier keine weiteren Maßnahmen nötig.


In allen anderen Problemfällen ist zusätzlich zu den erwähnten Änderungen in den Dateien vdrshutdown bzw. nvram-wakeup.conf im Boot-Manager für den zusätzlichen Reboot eine neue Boot-Option für den Boot-Manager im System einzustellen. Hierfür gibt es mehrere Möglichkeiten. Ich behandele hier nur die einfachste Alternative, bei der auf die Installation eines speziellen Kernelimages verzichtet wird.

In diesem Fall wird die Datei /etc/lilo.conf mit dem zusätzlichen Eintrag zu versehen, bei der einfach nur der Teil für die standardmäßig eingestellte Boot-Option mittels eines beliebigen Editors kopiert und unter der neuen Bezeichnung "PowerOff" mit einer zusätzlichen Append-Zeile versehen wird.

boot = /dev/hda
read-only
lba32
default = linux

image = /boot/vmlinuz
    label = linux
    root = /dev/hda2
    initrd = /boot/initrd
    append = "enableapic vga=0x0314 splash=silent desktop hdc=ide-scsi hdclun=0"

## Ergänzung für VDR-WakeUp
image = /boot/vmlinuz
    label = PowerOff
    root = /dev/hda2
    initrd = /boot/initrd
    append = "0"

Abschließend muss die Änderung noch durch einen erneuten Aufruf von Lilo wirksam gemacht werden:

    lilo
    
    

Bleibt noch zu erwähnen, dass diese einfache und elegante Methode nur mit dem Bootmanager Lilo möglich ist. Bei der Verwendung Grub, wie dies bei aktuelleren Distributionen der Fall ist, ist das ungleich komplexer. Ich habe daher bei mir einfach auf Lilo umgestellt.


2.4 vdrshutdown

Mit der Installation des Programms nvram-wakeup wird gleichzeitig das ggf. vorhandene Skript /usr/local/bin/vdrshutdown gegen das mitgelieferte Skript ausgetauscht. Normalerweise sind hierin keine Änderungen nötig. In meinem Fall wird das Skript jedoch mit den beschränkten Rechten des Users vdr aus der VDR-Sofware heraus aufgerufen. Programme mit direktem Zugriff auf systemnahe Funktionen benötigen jedoch Root-Rechte zur Ausführung. Dies wird per sudo-Kommando realisiert und dazu die Datei vdrshutdown entsprechend angepasst.

#!/bin/bash
# $Id: vdrshutdown,v 1.20 2004/07/21 08:41:10 bistr-o-math Exp $

NVRAMCMD=/usr/local/bin/nvram-wakeup
SVDRPCMD=/usr/local/src/VDR/svdrpsend.pl
CHECKSCRIPT=/path/to/the/script

...

# Add here needed options like --configfile=...
# (read 'man nvram-wakeup' and 'man nvram-wakeup.conf' for more details)
sudo $NVRAMCMD --configfile=/etc/nvram-wakeup.conf --directisa --syslog --settime $1

# if you are going to use the set_timer script instead of nvram-wakeup,
# comment out the line above and uncomment the following line.
# (read the comments inside the script for more details)
# $PATH_TO_SET_TIMER/set_timer $1 $2


case $PIPESTATUS in
     0) # all went ok - new date and time set
        sudo /sbin/shutdown -h now
        EXITSTATUS=0
        ;;
     1) # all went ok - new date and time set.
        #
        # *** but we need to reboot. ***
        #
        # for some boards this is needed after every change.
        #
        # for some other boards, we only need this after changing the
        # status flag, i.e. from enabled to disabled or the other way.


        # For plan A - (Plan A is not supported anymore---see README)
        #
        # For plan B - (don't forget to install the modified kernel image first)
        #

        sudo /sbin/lilo -R PowerOff

        sudo /sbin/shutdown -r now
        EXITSTATUS=0
        ;;
     2) # something went wrong
        # don't do anything - just exit with status 1
        EXITSTATUS=1
        ;;
esac

# exit with 0 if everything went ok.
# exit with 1 if something went wrong.
exit $EXITSTATUS

Ebenso muss noch die Datei /etc/sudoers editiert werden mit:

    visudo
    

Es ist die entsprechende Zeile zu ergänzen.

...
# User privilege specification
root    ALL=(ALL) ALL
vdr     ALL=(ALL) NOPASSWD: /usr/local/bin/nvram-wakeup, /sbin/shutdown, /sbin/lilo

Bei dem hierbei aufgerufenen Editor vi gelangt man mit der Taste "i" in den Einfügemodus und mit [ESC] wieder zurück. Abgespeichert wird mit ":wq" und beendet wird mit ":q".


3. Sonstiges

3.1 Warnung

An dieser Stelle sei noch einmal ausdrücklich auf die Warnung des Programmautors verwiesen. Werden falsche Werte übergeben oder nicht die richtigen Speicherstellen angesprochen, kann dies dazu führen, dass der Rechner überhaupt nicht mehr hochfährt! Normalerweise wird bei einem Fehler in der Checksumme das BIOS automatisch wieder mit den Default-Werten geladen ohne bleibenden Schaden zu hinterlassen.


3.2 Aktualisierungen

Zum Schluss noch die Bitte, dass die selbst ermittelten Werte für bislang undokumentierte Boards, wie in der README-Datei beschrieben, weitergegeben werden, damit es zukünftige Generationen etwas einfacher haben. Dazu ist die selbst erstellte Datei /etc/nvram-wakeup.conf und die vollständige Ausgabe von biosinfo nötig. Die jeweils aktuellste Datei nvram-wakeup-mb.c mit den zwischenzeitlich neu aufgenommenen Motherboards gibt es hier:

http://svn.sourceforge.net/viewvc/*checkout*/nvram-wakeup/trunk/nvram-wakeup/nvram-wakeup-mb.c

3.3 Dank

Ich möchte nicht unerwähnt lassen, dass diese Beschreibung mit aktiver Unterstützung des Programmautors Sergei Haller <Sergei.Haller@math.uni-giessen.de> entstanden ist.