hank1
asked on
cmos access
We use pcs running NT4 to control industrial machines and it is important
that any pc power management options be disabled.
Before shipping a perl script checks the pc configuration. Is there
anyway to read the CMOS? Presently the technicians are
instructed to incept the boot and check these power mgnt
options via the bios setup utility.
Thanks for any ideas.
that any pc power management options be disabled.
Before shipping a perl script checks the pc configuration. Is there
anyway to read the CMOS? Presently the technicians are
instructed to incept the boot and check these power mgnt
options via the bios setup utility.
Thanks for any ideas.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You could create a DOS based boot floppy disk and write a DOS based (remember them) application to update the BIOS whilst under DOS.
You would have to locate the address and format of the APM areas of the BIOS as I do not believe there is any standard for these values and it may well vary from BIOS to BIOS.
You will alos probably have to recalculate the BIOS checksum.
If it is of any interest I have attached some code snippets from a (very) old program I wrote to disable floppy access to PCs at work. If any of the code is helpful you are welcome it. Just be aware that this code was set up to talk to the particular BIOS in our machines at the time (486DX2 DECs from memory)
#include <conio.h>
#include <stdio.h>
#include "rtc.h"
#include <process.h>
void main (void) {
int x,y,Loc,Data;
printf ("\n%33s\n\n ", "CMOS RAM Dump");
for (x = 0; x < 0x10; x++)
printf (" %2X", x);
puts ("\n---------------------- ---------- ---------- --------") ;
for (x = 0; x < 4; x++) {
printf ("%X ", x);
for (y = 0; y < 0x10; y++) {
Loc = (x << 4) + y;
Data = ReadCMOS (Loc);
printf (" %02X", Data);
}
printf ("\n");
}
printf ("\nOld value at location 10h = %02X\n", ReadCMOS (0x10));
WriteCMOS (0x10,0x00);
NewCMOSChecksum ();
printf ("\nNew value at location 10h = %02X\n", ReadCMOS (0x10));
printf ("\n\n%33s\n\n ", "CMOS RAM Dump");
for (x = 0; x < 0x10; x++)
printf (" %2X", x);
puts ("\n---------------------- ---------- ---------- --------") ;
for (x = 0; x < 4; x++) {
printf ("%X ", x);
for (y = 0; y < 0x10; y++) {
Loc = (x << 4) + y;
Data = ReadCMOS (Loc);
printf (" %02X", Data);
}
printf ("\n");
}
printf("System will now reboot to remove floppy disks from equipment\n");
printf("Press any key to reboot ...........\n");
getch();
execl("WARMBOOT","WARMBOOT ");
}
#include "global.h"
#include <stdio.h>
#include <dos.h>
#include "rtc.h"
/* Loop until "Update in Progress" bit is clear */
static void WaitForUpdate (void) {
while (ReadCMOS (SRA) & UIP)
;
}
/* Read Value from CMOS RAM */
int ReadCMOS (int Addr) {
int ch;
asm pushf /* save interrupt flag */
disable ();
if (Addr < SRA) WaitForUpdate ();
outportb (CMOS_Control, Addr);
ch = inportb (CMOS_Data);
asm popf /* restore interrupt flag */
return ch;
} /* ReadCMOS */
/* Write Value to CMOS RAM */
void WriteCMOS (char Addr, char Value) {
asm pushf /* save interrupt flag */
disable ();
if (Addr < SRA) WaitForUpdate ();
outportb (CMOS_Control, Addr);
outportb (CMOS_Data, Value);
asm popf /* restore interrupt flag */
} /* WriteCMOS */
/* Compute and store new CMOS checksum */
void NewCMOSChecksum (void) {
int Loc, CheckSum = 0;
for (Loc = 0x10; Loc < 0x2E; Loc++)
CheckSum += ReadCMOS (Loc);
WriteCMOS (0x2E, (CheckSum >> 8));
WriteCMOS (0x2F, (CheckSum & 0xFF));
}
/* RTC.H -- Symbols and function prototypes for RTCHDW.C */
#define PIC1data 0x20 /* PIC 1 data register */
#define PIC1ctrl 0x21 /* PIC 1 control register */
#define PIC2data 0xa0 /* PIC 2 data register */
#define PIC2ctrl 0xa1 /* PIC 2 control register */
#define EOI 0x20 /* "End of Interrupt" value */
#define ALARMINT 0x4A /* User Alarm Interrupt number */
#define RTCINT 0x70 /* RTC interrupt */
#define CMOS_Control 0x70 /* CMOS RAM control port */
#define CMOS_Data 0x71 /* CMOS RAM data port */
#define SRA 0x0a /* Status Register A */
#define SRB 0x0b /* Status Register B */
#define SRC 0x0c /* Status Register C */
#define SRD 0x0d /* Status Register D */
/* Status Register A flag masks */
#define UIP 0x80 /* Update in Progress */
/* Status Register B flag masks */
#define SET 0x80 /* Halt update flag */
#define PIE 0x40 /* Periodic Interrupt Enable */
#define AIE 0x20 /* Alarm Interrupt Enable */
#define UIE 0x10 /* Update-ended Interrupt Enable */
#define SQWE 0x08 /* Square Wave Enable */
#define DM 0x04 /* Data Mode */
#define AMPM 0x02 /* 24/12 Switch */
#define DSE 0x01 /* Daylight Savings Enable */
/* Status Register C flag masks */
#define IRQF 0x80 /* Interrupt Request */
#define PF 0x40 /* Periodic Interrupt */
#define AF 0x20 /* Alarm Interrupt */
#define UF 0x10 /* Update-ended Interrupt */
/* Status Register D flag masks */
#define VRT 0x80 /* Valid RAM & Time */
/* Time structure used by SetAlarmInt */
struct RTCTIME {
unsigned int Hour;
unsigned int Min;
unsigned int Sec;
unsigned int Daylight;
};
int ReadCMOS (int Addr);
void WriteCMOS (char Loc, char Data);
void NewCMOSChecksum (void);
int SetPeriodicInt (int Freq, void far (*isr)());
int SetUpdateInt (void far (*isr)());
int SetAlarmInt (struct RTCTIME *Time, void far (*isr)());
void EnableRTCint (int Which);
void DisableRTCint (int Which);
void ResetRTCint (int Which);
void TimerOn (void);
void TimerOff (void);
Cheers - Gavin
You would have to locate the address and format of the APM areas of the BIOS as I do not believe there is any standard for these values and it may well vary from BIOS to BIOS.
You will alos probably have to recalculate the BIOS checksum.
If it is of any interest I have attached some code snippets from a (very) old program I wrote to disable floppy access to PCs at work. If any of the code is helpful you are welcome it. Just be aware that this code was set up to talk to the particular BIOS in our machines at the time (486DX2 DECs from memory)
#include <conio.h>
#include <stdio.h>
#include "rtc.h"
#include <process.h>
void main (void) {
int x,y,Loc,Data;
printf ("\n%33s\n\n ", "CMOS RAM Dump");
for (x = 0; x < 0x10; x++)
printf (" %2X", x);
puts ("\n----------------------
for (x = 0; x < 4; x++) {
printf ("%X ", x);
for (y = 0; y < 0x10; y++) {
Loc = (x << 4) + y;
Data = ReadCMOS (Loc);
printf (" %02X", Data);
}
printf ("\n");
}
printf ("\nOld value at location 10h = %02X\n", ReadCMOS (0x10));
WriteCMOS (0x10,0x00);
NewCMOSChecksum ();
printf ("\nNew value at location 10h = %02X\n", ReadCMOS (0x10));
printf ("\n\n%33s\n\n ", "CMOS RAM Dump");
for (x = 0; x < 0x10; x++)
printf (" %2X", x);
puts ("\n----------------------
for (x = 0; x < 4; x++) {
printf ("%X ", x);
for (y = 0; y < 0x10; y++) {
Loc = (x << 4) + y;
Data = ReadCMOS (Loc);
printf (" %02X", Data);
}
printf ("\n");
}
printf("System will now reboot to remove floppy disks from equipment\n");
printf("Press any key to reboot ...........\n");
getch();
execl("WARMBOOT","WARMBOOT
}
#include "global.h"
#include <stdio.h>
#include <dos.h>
#include "rtc.h"
/* Loop until "Update in Progress" bit is clear */
static void WaitForUpdate (void) {
while (ReadCMOS (SRA) & UIP)
;
}
/* Read Value from CMOS RAM */
int ReadCMOS (int Addr) {
int ch;
asm pushf /* save interrupt flag */
disable ();
if (Addr < SRA) WaitForUpdate ();
outportb (CMOS_Control, Addr);
ch = inportb (CMOS_Data);
asm popf /* restore interrupt flag */
return ch;
} /* ReadCMOS */
/* Write Value to CMOS RAM */
void WriteCMOS (char Addr, char Value) {
asm pushf /* save interrupt flag */
disable ();
if (Addr < SRA) WaitForUpdate ();
outportb (CMOS_Control, Addr);
outportb (CMOS_Data, Value);
asm popf /* restore interrupt flag */
} /* WriteCMOS */
/* Compute and store new CMOS checksum */
void NewCMOSChecksum (void) {
int Loc, CheckSum = 0;
for (Loc = 0x10; Loc < 0x2E; Loc++)
CheckSum += ReadCMOS (Loc);
WriteCMOS (0x2E, (CheckSum >> 8));
WriteCMOS (0x2F, (CheckSum & 0xFF));
}
/* RTC.H -- Symbols and function prototypes for RTCHDW.C */
#define PIC1data 0x20 /* PIC 1 data register */
#define PIC1ctrl 0x21 /* PIC 1 control register */
#define PIC2data 0xa0 /* PIC 2 data register */
#define PIC2ctrl 0xa1 /* PIC 2 control register */
#define EOI 0x20 /* "End of Interrupt" value */
#define ALARMINT 0x4A /* User Alarm Interrupt number */
#define RTCINT 0x70 /* RTC interrupt */
#define CMOS_Control 0x70 /* CMOS RAM control port */
#define CMOS_Data 0x71 /* CMOS RAM data port */
#define SRA 0x0a /* Status Register A */
#define SRB 0x0b /* Status Register B */
#define SRC 0x0c /* Status Register C */
#define SRD 0x0d /* Status Register D */
/* Status Register A flag masks */
#define UIP 0x80 /* Update in Progress */
/* Status Register B flag masks */
#define SET 0x80 /* Halt update flag */
#define PIE 0x40 /* Periodic Interrupt Enable */
#define AIE 0x20 /* Alarm Interrupt Enable */
#define UIE 0x10 /* Update-ended Interrupt Enable */
#define SQWE 0x08 /* Square Wave Enable */
#define DM 0x04 /* Data Mode */
#define AMPM 0x02 /* 24/12 Switch */
#define DSE 0x01 /* Daylight Savings Enable */
/* Status Register C flag masks */
#define IRQF 0x80 /* Interrupt Request */
#define PF 0x40 /* Periodic Interrupt */
#define AF 0x20 /* Alarm Interrupt */
#define UF 0x10 /* Update-ended Interrupt */
/* Status Register D flag masks */
#define VRT 0x80 /* Valid RAM & Time */
/* Time structure used by SetAlarmInt */
struct RTCTIME {
unsigned int Hour;
unsigned int Min;
unsigned int Sec;
unsigned int Daylight;
};
int ReadCMOS (int Addr);
void WriteCMOS (char Loc, char Data);
void NewCMOSChecksum (void);
int SetPeriodicInt (int Freq, void far (*isr)());
int SetUpdateInt (void far (*isr)());
int SetAlarmInt (struct RTCTIME *Time, void far (*isr)());
void EnableRTCint (int Which);
void DisableRTCint (int Which);
void ResetRTCint (int Which);
void TimerOn (void);
void TimerOff (void);
Cheers - Gavin
ASKER
looks like you've been there.... let me digest this.
Thanks.
Thanks.
ASKER
Could find no driver and the mfg do not support this. Can't be done like you said. Thanks everyone.
ASKER