One can access the CMOS memory via ports 0x70 and 0x71. One writes the address of the CMOS memory location you want to read to port 0x70 and then read the contents via a read of port 0x70. I implemented this as follows:
..I was not 100% sure of a small port delay was required between the write to port 0x70 and the read of data on port 0x71, but I added one in by writing to port 0x80 just in case. The ioperm() calls are required to get access to the I/O ports, and one needs to run this code with root privileges otherwise you will get a segmentation fault.
unsigned char cmos_read(int offset)
unsigned char value;
ioperm(0x70, 0x2, 1);
ioperm(0x80, 0x1, 1);
outb(0, 0x80); /* Small delay */
value = inb(0x71);
ioperm(0x80, 0x1, 0);
ioperm(0x70, 0x2, 0);
Then it is a case of reading 128 bytes or so of CMOS memory using this function. The next step is decoding this raw data. Web-pages such as http://www.bioscentral.com/misc/cmosmap.htm contain CMOS memory maps, but it does tend to vary from machine to machine. With data from several memory map descriptions that I found on the Web I have figured out some common across different BIOS implementations and written some code to annotate the contents of the CMOS memory. There are a bunch of fields that need a little more decoding, but that's work in progress...
My aim is to add this into the Firmware Test Suite for 11.04 as part of a diagnostic feature.