BIOS

(ang. Basic Input-Output System - Podstawowy System Wejścia-Wyjścia)


Wstęp :: BIOS Data Area :: CMOS :: POST :: Proces bootowania :: Przerwania
Literatura :: Linki :: Autorzy

CMOS


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
  • 0x00 - "gorący restart" - [CTRL]+[ALT]+[DEL]
  • 0x01 - restart programowy po wyznaczeniu rozmiaru pamięci
  • 0x02 - restart programowy po wykonaniu testu pamięci
  • 0x03 - restart po błędzie parzystości pamięci
  • 0x04 - restart programowy przez skok do adresu 0xFFFF0
  • 0x05 - restart po zgłoszeniu sygnału EOI do kontrolera przerwań, wyzerowanie klawiatury i daleki skok pod adres wskazywany przez wektor 0040:0067
  • 0x06 - restart po poprawnym wykonaniu testu trybu chronionego
  • 0x07 - restart po błędzie testu trybu chronionego
  • 0x08 - jak w 0x07
  • 0x09 - restart po przemieszczeniu bloku pamięci dodatkowej funkcją 0x87 dla INT 0x15
  • 0x0A - daleki skok pod adres wskazany wektorem 0040:0067 bez sygnału EOI
  • 0x0B - wykonanie instrukcji IRET z adresem powrotu pod wektorem 0040:0067
  • 0x0C - wykonanie instrukcji RETF z adresem powrotu pod wektorem 0040:0067
0x10 Typy napędów dysków elastycznych
0-3 Typ drugiego napędu dysków elastycznych (/dev/fd1),
  • 0000 - brak
  • 0001 - 5.25 cala, 360 kB
  • 0010 - 5.25 cala, 1.2 MB
  • 0011 - 3.5 cala, 720 kB
  • 0100 - 3.5 cala, 1.44 MB
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);
  • 0000 - brak
  • 0001-1110 - standardowe typy numerowane 1-14
  • 1111 - typ jest zapisany w polu 25 CMOS RAM
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);
};