|
Appunti informatica |
|
Visite: 1360 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:Le variabiliLe variabili E' il momento di ripescare CIAO.C e complicarlo un poco. #include I device driverI device driver Sempre più difficile: dopo avere affrontato i TSR (pag. 169) Problemi di mutua esclusione nel modello a memoria comuneProblemi di mutua esclusione nel modello a memoria comune VI) Scrivere una |
Le macchine dotate di processore Intel 80286 o superiore dispongono di 64 byte (o 128, a seconda dei modelli) di memoria CMOS, permanentemente alimentata da una batteria, nella quale sono memorizzate, oltre alla data e ora, lo shutdown byte e le informazioni relative alla configurazione hardware
L'accesso alla memoria CMOS è possibile attraverso operazioni di lettura e scrittura sulle porte hardware 70h e 71h.
BARNINGA_Z! - 1991
READCMOS.C - readcmos()
unsigned char cdecl readcmos(int off);
int off; l'offset, nel CMOS, del byte da leggere.
Restituisce: il byte letto nel CMOS all'offset specificato.
COMPILABILE CON TURBO C++ 2.0
tcc -O -d -c -k- -mx readcmos.c
dove -mx puo' essere -mt -ms -mc -mm -ml -mh
#pragma inline
#pragma option -k-
unsigned char cdecl readcmos(int off)
return(_AL);
Il listato della readcmos() è estremamente semplice; l'unica particolarità è rappresentata dall'istruzione JMP $+2, ininfluente dal punto di vista del flusso di esecuzione : essa ha solamente lo scopo di introdurre un piccolo ritardo tra le due operazioni sulle porte, in modo tale che prima della seconda trascorrano i cicli di clock necessari al completamento della prima.
La scrittura di un byte nel CMOS avviene in maniera analoga:
BARNINGA_Z! - 1991
WRITCMOS.C - writcmos()
void cdecl readcmos(int off, unsigned char val);
int off; l'offset, nel CMOS, del byte da scrivere.
unsigned char val; il byte da scrivere nel CMOS.
Restituisce: nulla.
COMPILABILE CON TURBO C++ 2.0
tcc -O -d -c -k- -mx writcmos.c
dove -mx puo' essere -mt -ms -mc -mm -ml -mh
#pragma inline
#pragma option -k-
void cdecl writcmos(int off,unsigned char val)
Nella writcmos() la presenza dell'istruzione MOV AL,VAL tra le due operazioni di scrittura sulle porte elimina la necessità di inserire un'istruzione JMP $+2
Di seguito presentiamo un programma che utilizza le due funzioni testè commentate per effettuare un salvataggio su file del contenuto del CMOS, nonché il suo eventuale ripristino. Chi abbia intenzione di sperimentare l'effetto di modifiche alla configurazione hardware del proprio personal computer pasticciando con le routine di setup del BIOS intuisce al volo quanto possa essere prezioso un backup dei dati originali. Si ricordi inoltre che la batteria di alimentazione del CMOS, come tutte le batterie, ha il pessimo vizio di scaricarsi, più o meno lentamente: può accadere a chiunque, un brutto giorno, di ritrovarsi nella necessità di ricostrure a memoria tutta la configurazione dopo avere sostituito la batteria ormai esausta.
Barninga_Z! - 09/08/93
CMOSBKP.C - Se richiesta opzione -S (SAVE), crea una copia del CMOS nel file
CMOSBKP.SAV nella stessa directory dalla quale e' stato lanciato (sono
copiati i byte da offset 0x10 a 0x7F; in pratica NON vengono copiati i
bytes usati dall'orologio e dalla diagnostica). Se viene richiesta
opzione -r oppure -R (RESTORE), copia nel CMOS (a partire da offset 0x10)
il contenuto del file CMOSBKP.SAV precedentemente creato (-r NON
ripristina i bytes ad offset CMOS da 40h a 4Fh). Se richiesta opzione -o
oppure -O confronta il contenuto del CMOS con il contenuto del file
CMOSBKP.SAV (o non confronta i bytes ad offset CMOS da 40h a 4Fh). Se
richiesta opzione -c effettua un test sul byte del CMOS usato dalla
diagnostica del bootstrap e visualizza i risultati.
Il nome di file puo' essere specificato sulla command line se si vuole
che esso non sia CMOSBKP.SAV.
Compilato con BORLAND C++ 3.1:
bcc -O -d -rd -mt -lt cmosbkp.c
#pragma inline // per readcmos() e writcmos()
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK 0x0E /* byte diagnostico nel CMOS */
#define START 0x10 /* primo byte da gestire nel CMOS */
#define OFF1 0x40 /* inizio intervallo da saltare se richiesto */
#define OFF2 0x50 /* byte successivo a fine intervallo saltato */
#define END 0x7F /* ultimo byte da gestire nel CMOS */
#define BYTES (END-START+1) /* numero di bytes da gestire nel CMOS */
#define NAME 'CMOSBKP' /* nome del programma */
#define EXT 'SAV' /* estensione del file dati */
#define REL '1.5' /* versione */
#define OK 'O.K.' /* messaggio per diagnostica tutto OK */
#define SW '-' /* switch per le opzioni */
int pascal __IOerror(int dosErr);
int main(int argc,char **argv);
void checkcmos(void);
int compcmos(char *datafile,unsigned cod);
int handlecmos(char *opt,char *datafile);
unsigned char cdecl readcmos(int off);
int readfile(char *datafile,unsigned char *cmos);
int restcmos(char *datafile,unsigned cod);
int savecmos(char *datafile);
void writcmos(int off,unsigned char val);
struct CMOSCHK chk[] = ,
,
,
,
,
,
char errmsg[] = '
%s: syntax: %s option [filename]nn
option is one of the following:n
-c check CMOS statusn
-O compare CMOS with filen
-o compare CMOS with file but offsets 40h to 4Fhn
-R restore CMOS from filen
-r restore CMOS from file but offsets 40h to 4Fhn
-S save CMOS to file but offsets 00h to 0Fhn
// main() gestisce una prima analisi della command line per decidere quale
// funzione invocare
int main(int argc,char **argv)
return(errno);
// checkcmos() legge dal CMOS il byte di checksum, poi effettua la somma dei bytes
// di cui quello e' a sua volta la somma e confronta i valori trovati.
void checkcmos(void)
// compcmos() confronta il contenuto del CMOS con il contenuto di un file per vedere
// se questo e' una copia della configurazione attuale
int compcmos(char *datafile,unsigned cod)
// handlecmos() analizza le opzioni della command line e invoca la funzione
// corrispondente
int handlecmos(char *opt,char *datafile)
return(cod);
// readcmos() legge un byte dal CMOS
unsigned char readcmos(int off)
return(_AL);
// readfile() legge in un buffer il contenuto di un file contenente una
// configurazione di CMOS
int readfile(char *datafile,unsigned char *cmos)
// restcmos() scrive nel CMOS il contenuto del buffer riempito con i bytes letti
// da file da readfile()
int restcmos(char *datafile,unsigned cod)
// savecmos() scrive il contenuto del CMOS in un buffer e poi scrive questo in un
// file, generando cosi' una copia di backup del CMOS
int savecmos(char *datafile)
// writcmos() scrive un byte nel CMOS
void writcmos(int off,unsigned char val)
Come si vede, CMOSBKP si compone di poche funzioni, ciascuna dedicata ad una operazione elementare di gestione dei dati del CMOS: non sembra necessario, pertanto, dilungarsi in una loro approfondita descrizione; tuttavia va osservato che il programma potrebbe essere perfezionato eliminando la handlecmos() ed utilizzando, in luogo, gli strumenti di gestione delle opzioni della riga di comando descritti a pag. e seguenti. Ciò consentirebbe, inoltre, di razionalizzare la struttura di main()
Concludiamo queste scarne note in tema di CMOS con un consiglio da amico: è buona norma predisporre un dischetto autopartente e copiare sul medesimo, oltre alle indispensabili componenti del DOS, CMOSBKP.EXE e un file di backup del CMOS da questo generato. Può sempre servire.
Lo shutdown byte è utilizzato per il rientro in real mode da protected mode mediante reset del processore.
Delle macchine che dispongono di 128 byte di CMOS, molte utilizzano i 64 byte aggiuntivi per la memorizzazione di parametri non standard di configurazione.
Appunti su: |
|