1. Definicja
CMOS (ang: Complementary Metal Oxide Semiconductor), zwany także NVR (ang: Non-Volatile RAM) jest to układ pamięci BIOS przechowujący informacje o konfiguracji sprzętowej komputera oraz zawierający kalendarz i zegar czasu rzeczywistego.
Mówiąc o pamięci CMOS mamy zwykle na myśli nie tylko komórki pamięci, lecz również zespół układów, rejestry sterujące, port adresowy i port danych.
Zapisane w pamięci konfiguracyjnej dane o zainstalowanych elementach systemu są każdorazowo odczytywane podczas startu systemu w pamięci ROM procedury diagnostycznej POST i porównywane ze stanem faktycznym określonych układów.
Funkcję pamięci konfiguracyjnej i zegara czasu rzeczywistego pełni w PC/AT układ scalony MC146818 w którym CMOS-RAM jest 64-komórkową pamięcią o swobodnym dostępie.
Przyjęta nazwa CMOS pochodzi od rodzaju zastosowanej technologii o znikomym zużyciu energii lecz wolnym dostępie.
2. Organizacja pamięci CMOS
64 bajty pamięci CMOS zawierają następujące informacje:
| Offset | Bajt | Znaczenie |
|---|---|---|
| 0x00 | 0-7 | RTC - licznik sekund (BCD) |
| 0x01 | 0-7 | alarm RTC - licznik sekund (BCD) |
| 0x02 | 0-7 | RTC - licznik minut (BCD) |
| 0x03 | 0-7 | alarm RTC - licznik minut (BCD) |
| 0x04 | 0-7 | RTC - licznik godzin (BCD) |
| 0x05 | 0-7 | alarm RTC - licznik godzin (BCD) |
| 0x06 | 0-7 | RTC - dzień tygodnia (BCD) |
| 0x07 | 0-7 | RTC - dzień w miesiącu (BCD) |
| 0x08 | 0-7 | RTC - miesiąc (BCD) |
| 0x09 | 0-7 | RTC - rok (00-99) (BCD) |
| 0x0A | rejestr A - stan zegara, współczynniki czasu | |
| 0-3 | używany dzielnik częstotliwości zegara, współczynnik podziału czasu (T), standardowo = 0110 (1,024 kHz) | |
| 4-6 | używana częstotliwość taktowania zegara, podstawa czasu standardowo = 010 (32,768 kHz) | |
| 7 | dostępność zegara: 0-można odczytać, 1-trwa aktualizacja | |
| 0x0B | rejestr B - stan zegara | |
| 0 | czy korzysta się z czasu letniego | |
| 1 | tryb pracy zegara: 0 - 12h, 1 - 24 | |
| 2 | kodowanie liczb: 0 - binary, 1 - BCD | |
| 3 | generacja sygnału prostokątnego: 0 - zablokowana, 1 - aktywna | |
| 4 | generacja przerwania od cyklu aktualizowania: 0 - zablokowana, 1 - aktywna | |
| 5 | generacja przerwania od alarmu: 0 - zablokowana, 1 - aktywna | |
| 6 | generacja przerwania okresowego: 0 - zablokowana, 1 - aktywna | |
| 7 | cykle aktualizowania: 0-aktywne, 1-zablokowane | |
| 0x0C | rejestr C - stan zegara; znaczniki przerwania | |
| 0-3 | Zarezerwowane | |
| 4 | Źródłem IRQ jest przerwanie od alarmu; 0-nie, 1-tak | |
| 5 | Źródłem IRQ jest przerwanie od cyklu aktualizacji; 0-nie, 1-tak | |
| 6 | Źródłem IRQ jest przerwanie okresowe; 0-nie, 1-tak | |
| 7 | Żądanie IRQ od MC146818; 0-nie, 1-tak | |
| 0x0D | rejestr D | |
| 0-6 | Zarezerwowane | |
| 7 | Bit wiarygodności danych; 0-zbyt niski poziom napięcia baterii, dane niewiarygodne, 1-poziom napięcia beterii prawidłowy, dane wiarygodne | |
| 0x0E | rejestr E | |
| 0-1 | Zarezerwowane | |
| 2 | Czas zegara CMOS; 0-błędny, 1-wiarygodny | |
| 3 | Wynik inicjalizacji dysku twradego; 0-inicjalizacja prawidłowa, 1-błąd kontrolera lub błąd dysku | |
| 4 | Rzeczywisty rozmiar pamięci; 0-zgodny z deklarowanym w pamięci CMOS, 1-inny niż zadeklarowano w pamięci CMOS | |
| 5 | Rzeczywisty stan konfiguracji; 0-zgodny z zawartością pamięci CMOS, 1-niezgodny z zawartością pamięci CMOS | |
| 6 | Suma kontrolna danych przechowywanych w układzie; 0-nieprawidłowa, 1-prawidłowa | |
| 7 | Stan napięcia zasilającego układ MC146818; 0-nastąpiła przerwa w zasilaniu, 1-zasilanie ciągłe | |
| 0x0F | rejestr F - Przyczyna restartu systemu | |
| 0-7 |
| |
| 0x10 | Typy napędów dysków elastycznych | |
| 0-3 | Typ drugiego napędu dysków elastycznych (/dev/fd1),
| |
| 4-7 | Typ pierwszego napędu dysków elastycznych (/dev/fd0), kodowany jak powyżej | |
| 0x11 | 0-7 | Zarezerwowany |
| 0x12 | Typy dysków twardych | |
| 0-3 | Typ drugiego dysku twardego (/dev/hdb);
| |
| 4-7 | Typ pierwszego dysku twardego (/dev/hda); kodowany jak powyżej | |
| 0x13 | 0-7 | Zarewzerwowany |
| 0x14 | Bajt konfiguracji sprzętowej | |
| 0 | Obecność napędu dysków elastycznych; 0-brak napędów, 1-obecny co najmniej jeden napęd | |
| 1 | Koprocesor arytmetyczny; 0-brak, 1-obecny | |
| 2-3 | Zarezerwowane | |
| 4-5 | Typ karty graficznej (dziś tylko = 10) | |
| 6-7 | Liczba zainstalowanych napędów dysków elastycznych (gdy bit 0=1); 00-jeden napęd, 01-dwa napędy | |
| 0x15 | 0-7 | Rozmiar pamięci podstawowej w kB (LSB) |
| 0x16 | 0-7 | Rozmiar pamięci podstawowej w kB (MSB) |
| 0x17 | 0-7 | Rozmiar pamięci dodatkowej (Extended Memory) zgodnie z danymi z programu Setup, w kB (LSB) |
| 0x18 | 0-7 | Rozmiar pamięci dodatkowej zgodnie z danymi z pogramu Setup w kB (MSB) |
| 0x19 | 0-7 | Bajt dodatkowych informacji dotyczących pierwszego dysku twardego |
| 0x1A | 0-7 | Bajt dodatkowych informacji dotyczących drugiego dysku twardego |
| 0x1B-1F | Zarezerwowane | |
| 0x20-27 | Blok danych dysku twardego typu 47 | |
| 0x28-2D | Zarezerwowane | |
| 0x2E | 0-7 | Suma kontrolna (LSB) |
| 0x2F | 0-7 | Suma kontrolna (MSB) |
| 0x30-31 | 0-15 | [WORD] wielkość zainstalowanej pamięci powyżej 1 MB, (w kB) |
| 0x31 | 0-7 | Rozmiar pamięci dodatkowej określony przez procedury POST, w kB (MSB) |
| 0x32 | 0-7 | RTC - Stulecie (BCD) |
| 0x33 | 0-7 | Dane programu Setup |
| 0x34 | 0-7 | Zarezerwowane |
| 0x35-3C | Blok danych dysku twardego typu 48 | |
| 0x3D-3F | Zarezerwowane | |
3. Obsługa CMOS
Dostęp do pamięci CMOS możliwy jest poprzez porty 0x70 i 0x71. Pierwszy z nich ustawia przesunięcie bloku, a drugi dostęp.
unsigned char read_cmos(unsigned char index)
{
outb(index,0x70);
return inb(0x71);
};
void char write_cmos(unsigned char index, unsigned char what)
{
outb(index,0x70);
outb(what,0x71);
};