NVRAM WakeUP - Autoaccensione del PC

Da VDR-Italia.

NVRAM WakeUP - Autoaccensione del PCmodifica

Avviso che il presente manuale va a scrivere dati nel BIOS, per cui anche se il rischio è minimo è sempre presente. L'autore e tutta la comunità non si assumono nessuna responsabilità per qualsiasi danno causato dall'uso proprio o improprio del manuale.


Indice

Introduzione

Con l'aumento del costo dell'energia elettrica l'idea di lasciare un PC acceso 24 ore su 24 è una cosa quasi impensabile, sempre che non si è abbastanza ricchi da potersi permettere di buttare i soldi. Però nel tenerlo spento c'è anche il problema che quando siamo assenti non abbiamo la possibilità di registrare degli eventi, cosa per cui è nato VDR. Tre questi due problemi si tratta di trovare un compromesso, e questo si chiama NVRAM WakeUP. In poche parole, il PC ad una data ora si accende da solo, registra e poi si spegne, risolvendo tutti i problemi sopra elencati.

Il kernel

Per prima cosa dobbiamo attivare dei device nel kernel (/dev/rtc, /dev/mem e /dev/nvram), che probabilmente in molte distribuzioni saranno già presenti come moduli. Facciamo un controllo per vedere se sono presenti, in questo modo:

ls /dev/rtc /dev/mem /dev/nvram

Nel mio caso per esempio (Suse 10.0) manca il device nvram che carico così:

modprobe nvram

Nel caso mancassero pure i moduli, ci tocca ricompilare il kernel, cosa complessa ma nemmeno tanto per un utente non proprio alle prime armi. La cosa che ci interessa è abilitare queste opzioni nel menu:

Device Drivers  --->
  Character devices  --->
    <*> /dev/nvram support
    <*> Enhanced Real Time Clock Support 

ed infine ricompilate il tutto. Se avete dei problemi potere seguire questa guida sulla compilazione del kernel: Guida alla compilazione del kernel. Riavviate il sistema e ripetete l'operazione di controllo per vedere se i device esistono. Se avete a che fare con un modulo, ricordatevi di includere un comando che al boot lo carichi.

Installazione delle utility

Per iniziare dobbiamo trovare qualcosa per gestire la lettura/scrittura del BIOS. La soluzione migliore è usare qualcosa che è stato fatto apposta per questo, NVRAM-WakeUP. Lo possiamo trovare a questo URL. Scompattiamo i sorgenti ed infime li compiliamo:

#> tar -jxvf nvram-wakeup-0.97.tar.bz2
#> cd nvram-wakeup-0.97
#> make
#> make install

Nella compilazione di questi sorgenti non ho mai avuto errori, vi auguro di trovarmi nella mia stessa situazione.

Configurazione

Rilevamento dati scheda madre

Per prima cosa controlliamo se la scheda madre è supportata dal programma:

#> nvram-wakeup

e... tanto per cambiare scopro che la mia non è supportata, come potete vedere:

nvram-wakeup: Your mainboard is currently not supported.
nvram-wakeup: Please try determining the addresses and sending the following
nvram-wakeup: information back to the maintainers:
nvram-wakeup:  - The addresses you found out (read README.mb)
nvram-wakeup:  - Mainboard vendor:   ASUSTeK Computer Inc.
nvram-wakeup:  - Mainboard type:     P4P800
nvram-wakeup:  - Mainboard revision: Rev 1.xx
nvram-wakeup:  - BIOS vendor:        American Megatrends Inc.
nvram-wakeup:  - BIOS version:       1019.005
nvram-wakeup:  - BIOS release:       10/14/2004

Non c'è da preoccuparsi comunque, esiste un altra possibilità, rilevare 'quasi' manualmente le posizioni di memoria dove il BIOS salva l'orario di accensione.

Per rilevare le posizioni di memoria nel BIOS si deve usare il programma guess-helper presente sempre nel pacchetto che abbiamo compilato prima, e se abbiamo dato il make install essere installato nel nostro sistema. Lanciato il programma dobbiamo seguire attentamente le sue istruzioni, che saranno di questo tipo:

# lanciare il programma e leggere le istruzioni
# riavviare
# Modificare il contenuto del BIOS in base alle istruzioni ricevute
# Tornare al punto 1

Questa sequenza di dovrà fare un pò di volte, e nel mio caso è stata così, per fare un esempio:

-- Sequenza 1 Sequenza 2 Sequenza 3 Sequenza 4
Giorno 31 11 01 01
Ora 23 12 00 00
Minuti 59 13 00 00
Secondi 59 14 00 00
Abilitato yes yes yes no

Alla fine nella directory /root/guess-directisa/ mi sono trovato dei files che corrispondono all'immagine di uno spazio di memoria del BIOS per ogni sequenza. Comunque l'unico file che ci interessa è quello chiamato nvram-wakeup.conf che in pratica nel mio caso contiene questo, nel vostro ovviamente le posizioni di memoria saranno sicuramente diverse.

################################################
##  Mainboard autodetection information:
##
##    - Mainboard vendor:   "ASUSTeK Computer Inc."
##    - Mainboard type:     "P4P800"
##    - Mainboard revision: "Rev 1.xx"
##    - BIOS vendor:        "American Megatrends Inc."
##    - BIOS version:       "1019.005"
##    - BIOS release:       "10/14/2004"

addr_stat        = 0x9B
shift_stat       = 4
addr_day         = 0x9C
addr_hour        = 0x9D
addr_min         = 0x9E
addr_sec         = 0x9F
addr_chk_h       = 0x30   # guessed
addr_chk_l       = 0x31

upper_method = INTEL

Copiamo il file nella directory /etc.

Spegnimento del sistema

Per lo spegnimento del sistema non basta un semplice shutdown -h now ma prima di fare questo serve scrivere nel BIOS l'orario di accensione. Per fare questo utilizziamo questo script:

#!/bin/sh

# NVRamWakeUp v0.0.4
# By Lukkino, 12/05/2007

# HISTORY
# --------------------------------------
# 0.0.4
# * Corretti alcuni bugs
#
# 0.0.3
# * Aggiunto lo spegnimento automatico
# --------------------------------------

# File timers.conf di VDR
FILE_TIMERS="/etc/vdr/timers.conf"

# File di configurazione di nvram-wakeup
FILE_NVRAM_WAKEUP="/etc/nvram-wakeup.conf"

# Valore di avvio per GRUB
GRUB_ID="1"

# Directory configurazione di nvram
DIR_CONF="/"

# Nome file registrazioni
FILE_REC=".nvram.rec"

# Nome file tipo di programmazione
FILE_TYPE=".nvram.type"

# Nome file ora di programmazione
FILE_TIMER=".nvram.timer"


########### Inizio programma ##########

# Funzione di creazione dei file di base
function init_nvram()
{
  echo -n "0" > $DIR_CONF/$FILE_REC
  echo -n "manual" > $DIR_CONF/$FILE_TYPE
  echo -n "0" > $DIR_CONF/$FILE_TIMER
}

# Inizializzo il sistema se necessario
if [ ! -e "$DIR_CONF/$FILE_REC" ]
then
  init_nvram
fi

if [ ! -e "$DIR_CONF/$FILE_TYPE" ]
then
  init_nvram
fi

if [ ! -e "$DIR_CONF/$FILE_TIMER" ]
then
  init_nvram
fi

# Ora corrente del sistema
NOW="`date +%s`"

# Ora corrente più 15 minuti
AFTER="`date --date="+15 min" +%s`"

# Numero di registrazioni attive
RECS="`cat $DIR_CONF/$FILE_REC`"

# Tipo di avvio della vdrbox
TYPE="`cat $DIR_CONF/$FILE_TYPE`"

# Ora di avvio programmata
TIMER="`cat $DIR_CONF/$FILE_TIMER`"

# Funzione di avvio della vdrbox
function start_vdr()
{
  # Calcolo la differenza tra il timer impostato e l'ora corrente
  let DIFF=${TIMER}-${NOW}
  
  # Imposto il valore di default del tipo di programmazione
  TYPE="manual"
  
  # Se la differenza è maggiore di 0 e minore di 300 secondi,
  # imposto il tipo di programmazione a "auto"
  if [ "$DIFF" -gt "0" ]
  then
    if [ "$DIFF" -lt "300" ]
    then
      TYPE="auto"
    fi
  fi
  
  # Scrivo il tipo di programmazione nel file
  echo -n "$TYPE" > $DIR_CONF/$FILE_TYPE
}

# Funzione di spegnimento della vdrbox
function stop_vdr()
{
  # Se il numero di registrazioni attive è maggiore di 0, esco dal programma
  if [ "$RECS" -gt "0" ]
  then
    return
  fi
  
  # Azzero l'ora di programmazione
  TIMER="$NOW"
  
  # Leggo il file timers.conf
  while read TIMER_CONF
  do
    TIME="`echo "$TIMER_CONF" | awk '{ split( $0, VALUE, ":" ); print VALUE[3] " " substr( VALUE[4], 1, 2 ) ":" substr( VALUE[4], 3, 2 ); }'`"
    TIME="`date -d "$TIME" +%s`"

    if [ $TIME -gt $NOW ] ; then
    
        # Ricavo il timer con maggior precedenza
        if [ "$TIMER" -eq "$NOW" ] ; then
          TIMER="$TIME"
        fi
        
        if [ "$TIMER" -gt "$TIME" ] ; then
          TIMER="$TIME"
        fi
    
    fi
    
  done < "$FILE_TIMERS"
  
  # Se il timer ricavato ha una differenza di tempo minore di 15
  # rispetto all'ora corrente azzerro il timer
  if [ "$TIMER" -lt "$AFTER" ]
  then
    TIMER="0"
  fi
  
  # Programmo l'orologio del bios
  nvram-wakeup -A -C "$FILE_NVRAM_WAKEUP" -s "$TIMER"
  
  # Scrivo il valore del timer nel file ora di programmazione
  echo -n "$TIMER" > $DIR_CONF/$FILE_TIMER
  
  # Scrivo il valore "manual" nel file tipo di programmazione
  TYPE="manual"
  echo -n "$TYPE" > $DIR_CONF/$FILE_TYPE
  
  # Scrivo il default di avvio di grub
  grub-set-default "$GRUB_ID"
  
  # Spengo la vdrbox
  #(riavvio sempre per memorizzare il valore nel timer del bios)
  reboot
}

# Funzione inizio registrazione
function before_recording()
{
  # Incremento la variabile RECS e scrivo su file
  let RECS=${RECS}+1
  echo -n "$RECS" > $DIR_CONF/$FILE_REC
}

# Funzione fine registrazione
function after_recording()
{
  # Decremento la variabile RECS e scrivo su file
  let RECS=${RECS}-1
  echo -n "$RECS" > $DIR_CONF/$FILE_REC
  
  # Se la vdrbox si è avviata in "auto" eseguo la funzione stop_vdr
  if [ "$TYPE" == "auto" ]
  then
    stop_vdr
  fi
}


# Opzioni di avvio
case "$1" in
  start)
    # Funzione eseguita all'avvio della vdrbox
    start_vdr
    ;;
    
  stop)
    # Funzione eseguita allo spegnimento della vdrbox
    stop_vdr
    ;;
    
  before)
    # Funzione eseguita all'inizio di una registrazione programmata
    before_recording
    ;;
    
  after)
    # Funzione eseguita al termine di una registrazione programmata
    after_recording
    ;;
esac

exit 0

Ricordatevi di impostare le variabili dello script adattandole al vostro sistema.

Avvio di VDR

Nello script di avvio di VDR, dovremo adesso specificare quale script usare per spegnere la macchina quando si preme il pulsante POWER del telecomando. Questo programma è lo script presente sopra, per cui, aggiungiamo questa opzioni alla riga che avvia VDR:

--shutdown='/vdr/.scripts/nvram.sh stop'
--record='/vdr/.scripts/nvram.sh'

Ovviamente le dovrete adattare mettendo il path esatto di dove si trova lo script. La prima opzione (shutdown) dice a vdr che usare per spegnere la macchina, mentre la seconda (record) dice che programma eseguire quando si avvia e si ferma una registrazione. Nel nostro caso, quest'ultima spegne la vdrbox a registrazione ultimata. Ancora prima di avviare VDR, nello script dobbiamo avviare lo script per fargli controllare se il PC è stato avviato manualmente o in automatico, in questo modo:

/vdr/.scripts/nvram.sh start

Per essere più chiaro faccio un esempio della riga esatta, come dovrebbe apparire utilizzando i path presenti nella mia vdrbox:

#!/bin/sh
/vdr/.scripts/nvram.sh start
/vdr/v-1.4.5-1/vdr --shutdown='/vdr/.scripts/nvram.sh stop' --record='/vdr/.scripts/nvram.sh'

Modifica di grub.conf

Adesso siamo agli sgoccioli, non rimane altro che impostare grub.conf ed il lavoro dovrebbe essere finito. Dobbiamo dire a grub che se esistono dei timers, prima di spegnere definitivamente il PC, lo riavvii, cosa richiesta da alcuni BIOS. Nel mio caso non serve, ma lo implemento ugualmente per evitare problemi. In questo caso non vi posso postare il file pronto per l'uso perché ogni sistema ne ha uno personalizzato, ma un esempio posso farvelo:

# Script /boot/grub/grub.conf
timeout 0

default saved

color green/black light-green/black

title VDRBOX
root (hd0,0)
kernel (hd0,0)/vmlinuz-2.6.14 real_root=/dev/hda3 video=vesafb:ywrap,mtrr vga=0x31A
savedefault 0

title VDRBOX PowerOff
savedefault 0
halt

In poche parole, in presenza di un Timer, al momento dello spegnimento, viene eseguito VDRBOX che poi reimposta grub per eseguire di default il title VDRBOX PowerOff. Quest'ultimo reimposta di default il precedente e poi spegne la VDRBox. In pratica il reboot non riavvia linux, ma appena carica grub, il PC si spegne.

Ricordatevi di attivare la funzione RTC nel BIOS.

A questo punto non vi rimane che testare il tutto sperando che vada.

Conclusione

Se ci sono problemi di riavvi automatici, potete cancellare il file .nvram creato dallo script e dovrebbe tornare tutto a posto.

Eventuali problemi

Alcune schede non supportano il WakeUp, anche se sono una minima parte. In questo caso ci sono delle schede che oltre ad altre utili funzioni, fanno anche questo, ma costano abbastanza.

Strumenti personali