Vývoj operačného systému/16-bitový („reálny“) mód

16-bitový alebo inak reálny mód (real mode) je základné prostredie, do ktorého sa procesor architektúry inštrukčnej sady x86 načíta hneď po zapnutí. V dnešnej dobe sa prakticky užívateľmi nepoužíva, no napriek tomu je logickou základňou pre načítavanie operačného systému. Reálny mód si môžete predstaviť ako podporu pre absolútne najzákladnejšie operácie (čítanie a zapisovanie dát na disky, vypisovanie znakov na obrazovku, zisťovanie veľkosti pamäti), ktorá sa dá neskôr rôznymi prvkami rozvinúť do prostredia aké chce sám programátor. Je podstatné ovládať princípy na ktorých reálny mód funguje, kedže sú základom pre ďalšie módy procesoru. Na internete sa môžete stretnúť aj s prezývkou "kamarát do dažďa". Predstavuje to, čo sa v procesore (a vlastne aj v počítači) vždy nachádza.

Zaujímavosť: nižšie uvedený obrázok formovania adresy v reálnom móde sa nachádza v originálnej príručke k procesorom 80386 z roku 1986, a rovnaký obrázok sa dá nájsť aj v aktuálnej príručke, čiže aj po skoro 30-tich rokoch.

Prostredie reálneho módu

upraviť

Inicializácia

upraviť

Medzi jednotlivými módmi, v ktorých procesor pracuje sa dá prechádzať. Na zmeny alebo zistenie aktuálneho módu slúžia špeciálne registre - riadiace registre (control registers, CRs) a modelovo-špecifické registre (model-specific registers, MSRs). Tieto registre majú samozrejme aj množstvo iných úloh. Zaujímavosti týchto registrov:

  • Nie je k nim poskytnutý priamy prístup. V prípade riadiacich registrov sa jedná o varianty inštrukcie MOV, a v prípade modelovo-špecifických registrov sa jedná o špeciálne inštrukcie (RDMSR - "read from model specific register", WRMSR - "write to model specific register").
  • Nemajú vplyv na príznaky procesora ((R|E)FLAGS)
  • Mimo nastavenia registra môžu manipulačné inštrukcie spustiť aj iné operácie. Príkladom je nastavenie hodnoty riadiaceho registra CR3, keď sa v procesorovej komponente TLB (translation lookaside buffer) zapíšu záznamy o preklade pamäti (address translation).

V prípade prestupu do reálneho módu netreba nastavovať žiaden register, no je nutné mať vynulované príznaky a nastavenia iných módov (to platí aj pri prestupe z iného módu naspäť do reálneho). BIOSy zvyknú spustiť kód bootloaderu v reálnom móde (je to štandard, no nie je to 100%-tné pravidlo).

Pamäť

upraviť

Z historických dôvodov poskytuje reálny mód veľkosťou obmedzené, ale výpočtovo flexibilné adresovanie.

V roku 1974 bol uvedený procesor Intel 8080, ktorý mal 8-bitovú dátovú zbernicu (Data bus) (a z toho dôvodu nepodporoval veľa operácií s 16-bitovými číslami) a 16-bitovú adresovú zbernicu (Address bus).

Poznámka: text poznámky.
Môže ležať aj na viacerých riadkoch

V roku 1977 bol uvedený procesor Intel 8085, ktorý mal rovnako 8-bitovú dátovú zbernicu a 16-bitovú adresovú zbernicu, podporujúc však vyššie frekvencie.

Na základe týchto dvoch procesorov bol v roku 1979 uvedený procesor Intel 8086, ktorý mal finálne 16-bitovú dátovú zbernicu a podporoval (cca) 1MB pamäte. Návrh tohoto procesoru sa po dlhý čas používal (a stále sa používa) v jeho potomkoch. Intel 8086 zaviedol taktiež systém 20-bitového adresovania. Tento systém spočíva v adresovaní nie jedným registrom alebo adresou, ale párom týchto prvkov. Tento pár má dva prvky: segment (segment) a odsadenie (offset). Zvyčajne sa spájajú dvojbodkou, čiže adresa zložená zo segmentu DS (data segment - register dátového segmentu) a odsadenia 0 sa zaznačí ako DS:0. Podobne adresa začiatku bootloadera (boot sektora, 0x7C00) sa dá zaznačiť ako 7C0:0 (hexadecimálna sústava je pri značení adries štandard).

Formovanie adresy v reálnom móde
Formovanie adresy v reálnom móde

Je podstatné vedieť, že odsadenie zaberá len 4 bity, aj keď je možné mať ho väčšie (ako 24-1 = 15) - procesor sa o jeho formovanie postará (vzorce nižšie). Niektoré funkcie (napríklad BIOSové) môžu byť priamo závislé od formy páru, a nemusia brať do úvahy presahujúce odsadenie. Kalkulácia je už ďalej jednoduchá:

 

Teoreticky by mohol tento systém podporovať 32-bitovú pamäť, ale v skutočnosti to tak nie je. Často sa však pri tomto formovaní adresy stáva, že ešte neformovaná adresa presahuje 220, teda ako 1MB. Miesto toho sa ráta (aj v oficiálnom manuáli) s pamäťou o veľkosti cca 1MB a 64KB.

 

Spätné formovanie absolútnej adresy do formy segment:odsadenie sú výsledok a zvyšok po celočíselnom delení:

 
 

Je však potrebné poznať rozdiel medzi čistým 16-bitovým módom a 16-bitovým adresovaním - nejedná sa o totožné pojmy. 16-bitové adresovanie popisuje procedúru formovania pamäte a používa sa aj v móde Virtual 8086, zatiaľ čo reálny mód zahŕňa celkový stav procesora. Ďalej je nutné podotknúť, že "bonusový" blok pamäte o veľkosti 64KB nemusí byť vôbec prístupný, pokým nie je povolené používať na adresovanie viac ako 20 bitov (takzv. brána A20 - A20 Gate ).

Funkcie

upraviť

Počas vykonávania BIOSového kódu sa v operačnom systéme nastaví vektorová tabuľka prerušení (Interrupt Vector Table - IVT). Táto tabuľka obsahuje 256 záznamov záchytných rutín prerušení po 4 bajty (=1KB).

Prerušenie (interrupt, skratka INT alebo int.) je udalosť, pri ktorej dostane procesor informáciu od vonkajšieho zariadenia, že je schopné dodať spracované dáta. Týmto zariadením môže byť pevný disk, klávesnica, myš alebo časovač. Pevný oznamuje žiada o prerušenie vtedy, keď má dáta načítané v dočasnej pamäti. Klávesnica žiada o prerušenie pri stlačení alebo uvoľnení (či držaní) nejakej klávesy.

Prerušenia

upraviť

Prečo existujú prerušenia?

upraviť

Pri návrhu procesoru mali vývojári dve možnosti. Mohli poskytnúť inštrukcie, ktoré by overovali či má zariadenie dáta spracované, alebo mohli nechať túto starosť na zariadenia. Prenechanie zodpovednosti za oznamovanie prerušení na zariadenia bolo logické, kedže dopytovanie (polling) by bolo príliš pomalé. Prerušenia sú neodmysliteľnou súčasťou moderných zariadení a nie sú špecifické len pre procesory od firmy Intel.

Hardvérové prerušenia

upraviť

Samozrejme, zariadení v počítači je nemálo, a tak bolo nutné dodať na základné dosky komponentu, ktorá by sa starala o správu prerušení, a podľa naprogramovaných podmienok by činnosť procesora prerušovala iba keby to bolo potrebné. Do počítačov sa v zmysle tejto komponenty pridal čip PIC (programmable interrupt controller - programovateľný radič prerušení), ktorý bol schopný spravovať 8 kontaktov prerušení. Po čase bolo ale 8 prerušení primálo na to, aby sa dokázali procesoru hlásiť všetky zariadenia, a tak sa vytvorilo takzv. master-slave prepojenie. Tým sa mohlo na procesor napájať 16 zariadení (resp. 14-15), ktorých polovica sa hlásila cez nadradený čip (prípadne nehlásila, ak bol nadradený čip naprogramovaný na ignorovanie). Hlásenie zariadení sa dalo prostredníctvom čipu PIC označiť za podstatné, zakázať alebo označiť za vyriadené. Do inštrukčnej sady procesoru sa dodali tri podstatné inštrukcie, ktoré slúžia na správu prerušení.

  • cli - nastaví bit IF (interrupt flag) v registri EFLAGS na 0, čím zakáže prerušovanie činnosti procesora. Pri každom prerušení si procesor najprv overí, či je tento bit nastavený. Ak tento bit nie je nastavený, procesor odmietne prerušenie a PIC si ho označí za oznámený, no nevykonaný.
  • sti - nastaví bit IF v registri (E)FLAGS na 1, čím povolí činnosť tých prerušení, ktoré sú mu nariadené. Ak je tento bit nastavený, procesor preruší aktuálny kontext vykonávania, zavolá rutinu na základe IVT a PIC si označí prerušenie za prijaté, no neskončené.
  • hlt - zastaví činnosť procesora pokým sa nezaznamená prerušenie. Po vyriadení prijatého prerušenia sa pokračuje vykonávaním ďalšej inštrukcie.

Použitie kombinácie inštrukcií cli a hlt bez iného vedľajšieho povoľovania prerušení (napríklad načítaním registru (E)FLAGS zo zásobníku - popf(d)) nastaví procesor do nekonečného čakania na prerušenie, ktoré nepríde.

Výnimky a chyby

upraviť

Prerušenia môžu byť zavolané okrem požiadavky zariadenia aj chybou spôsobenou programom. K volaniu chybového prerušenia dochádza vtedy, keď si už procesor nevie dať rady zo situáciou, ktorá nastala. Typickým príkladom je chyba pri delení nulou. Rovnako ako z matematického hľadiska to nie je možné ani v oblasti programovania. Kým vyššie jazyky túto chybu často objavia s predstihom, na úrovni inštrukcií je činnosť procesora surovo prerušená. Procesor nevie, ako by sa dala daná chyba opraviť, kedže nevie aký je očakávaný výsledok. Nula? A čo ak chce program vypočítať počet znakov, ktoré má vypísať na obrazovku? V tom prípade by nevypísal nič a užívateľ by sa nedozvedel o úplne ničom. V takýchto prípadoch nastupujú rutiny prerušení, ktoré na základe svojho kódu program zastavia a vypíšu chybovú hlášku. V tabuľke prerušení si Intel rezervoval prvých 32 prerušení. V dnešnej dobe je už 17 z nich zabraných, no 15 je stále voľných. Nižšie je uvedený ich zoznam.

Číslo prerušenia Označenie Opis Zdroj/dôvod
0 #DE Divide error - Chyba pri delení Inštrukcie DIV alebo IDIV, delenie nulou
1 #DB Debug - prerušenie programu za účelom cieleného odstraňovania chýb Ľubovoľné odkazovanie na kód alebo dáta
2 NMI Non-maskable interrupt - "nezakázateľné" prerušenie, ignoruje bit IF v registri (E)FLAGS (inštrukcie cli a sti nemajú účinok) "nezakázateľné" vonkajšie prerušenie kritickou chybou (neopraviteľná chyba čipovej sady, poškodenie pamäte)
3 #BP Breakpoint - prerušenie programu za účelom cieleného odstraňovania chýb (diagnostika situácie príslušným nástrojom). Inštrukcie INT3 a INT
4 #OF Overflow - pretečenie Inštrukcia INT, alebo použitie inštrukcie INT0 v prípade, keď je bit OF v registri (E)FLAGS nastavený na 1
5 #BR BOUND range exceeded - prekročenie rozsahu nastaveného inštrukciou BOUND Inštrukcia BOUND
6 #UD Undefined/Invalid Opcode - nedefinovaný/nevalidný kód operácie (inštrukcia) nesprávnym (z hľadiska manuálu rezervovaným) kódom operácie (prípadne jeho časti, napríklad použitím nepovoleného prefixu) alebo inštrukcie. Môže byť spôsobený aj inštrukciou UD2
7 #NM Device not avaible - zariadenie (math coprocessor) nie je prístupné Inštrukcie určené na prácu s číslami s pohyblivou desatinnou čiarkou (floating-point numbers), prípadne inštrukcie wait/fwait
8 #DF Double fault - dvojitá chyba Ľubovoľná inštrukcia schopná spôsobiť prerušenie, prerušenie NMI alebo prerušenie z pinu INTR
9 #MF Coprocessor segment overrun - v dnešnej dobe rezervovaná inštrukcia Inštrukcie určené na prácu s číslami s pohyblivou desatinnou čiarkou
10 #TS Invalid TSS - nevalidný/nedovolený obsah štruktúry TSS Striedanie úloh alebo prístup k štruktúre TSS
11 #NP Segment not present - segment nie je prítomný Načítavanie segmentového registru alebo prístup k systémovým segmentom
12 #SS Stack segment fault - chyba zásobníkového segmentu Zásobníkové operácie alebo manipulácia s registrom SS
13 #GP (alebo GPF) General protection (fault) - všeobecná ochranná chyba Ľubovoľné odkazovanie na pamäť a rôzne ochranné overovania
14 #PF Page fault - chyba stránkovania Ľubovoľné odkazovanie na pamäť
15 Rezervované
16 #MF Floating-point error (Math fault) - matematická chyba zariadenia na prácu s číslami s pohyblivou desatinnou čiarkou Inštrukcie určené na prácu s číslami s pohyblivou desatinnou čiarkou, prípadne inštrukcie wait/fwait
17 #AC Alignment check - overovanie zarovnania Ľubovoľné odkazovanie na dáta v pamäti
18 #MC Machine check - overenie stroja Závislé od modelu
19 #XM SIMD floating-point exception Chyba SIMD triedy architektúry pri práci s číslami s pohyblivou desatinnou čiarkou.
20-31 Rezervované
32-255 Voľne použiteľné BIOSom, zariadeniami alebo operačnými systémami externé zariadenia (cez pin INTR) alebo inštrukcia INT

Poznámka: k mnohým z týchto chýb v reálnom móde nedôjde, no sú tu napísané kvôli kompletnosti zoznamu.

Softvérové prerušenia

upraviť

Prerušenia môžu byť zavolané taktiež použitím inštrukciou INT, za ktorou nasleduje číslo prerušenia. Táto inštrukcia sa dá použiť na testovanie prerušení určených pre zariadenia, rovnako ako aj pre prerušenia definované programom len pre program. Tento spôsob je základným princípom fungovania štandardných BIOSových funkcií.

Zápisy v tabuľke IVT sú dosadzované inicializačnými programami v ROM pamätiach jednotlivých zariadení (program v ROM pamäti zariadenia na prácu grafikou nastaví (softvérové) prerušenia na prácu s obrazom, ďalší program prikladaný k úložným zariadeniam nastaví softvérové prerušenia na prácu s pevnými diskami a pod.). Volanie softvérového prerušenia sa podobá na normálne volanie funkcie v jazyku assembler - až na to, že namiesto adresy rutiny sa zavolá adresa uložená na konkrétnom indexe v tabuľke prerušení.

Jednotlivé BIOSy poskytujú relatívne štandardné usporiadanie záznamov v tabuľke prerušení. Pre zariadenia je typické toto umiestnenie:

Čip Umiestnenie
Master PIC 0x08 - 0x0F (8 - 15) - pri prechode do chráneného módu bývajú tieto umiestnenia v konflikte z umiestnením rutín na zachytávanie chýb
Slave PIC 0x70 - 0x77

Špecifickou vlastnosťou uloženia je súvislé uloženie ôsmych rutín v jednom slede (obmedzenie hardvéru). Programátori operačných systémov zvyknú tieto rutiny mapovať na okrúhle odsadenia (často okrúhle z pohľadu hexadecimálnej sústavy ;) )

Pre softvérové rutiny sú zase typické tieto umiestnenia:

Odsadenie (číslo prerušenia) Názov Popis
0 - 0xF Vynechávané Rezervované pre prerušenia a zariadenia
0x10 Video Services - služby grafiky Množstvo funkcií na prácu s módmi, znakmi, farbami, pixelmi alebo kurzorom a celkovo základnými schopnosťami grafiky.
0x11 Equipment check - overenie výbavy/informovanie o výbave Informuje o niektorých zariadeniach pripojených k počítaču a o ich základných nastaveniach. Výsledné dáta obsahujú informácie o nastavenom móde grafiky (rozlíšení v znakoch) počte diskiet/pevných diskoch alebo podpory vedľajšieho matematického zariadenia (math coprocessor). - dnes nepoužívané
0x12 Memory Avaible - dostupná pamäť Informuje o veľkosti dostupnej pamäte. - dnes nepoužívané
0x13 Low Level Disk Serices - nízkoúrovňové služby úložných zariadení (pevných diskov a diskiet) Poskytuje základné funkcie na obnovenie disku, vysunutie diskety, čítanie alebo zapisovanie sektorov prípadne na zisťovanie parametrov úložných jednotiek.
0x14 Serial port services - služby komunikácie cez (so) sériové porty Komunikácia so systémovými portmi (inicializácia, odoslania, prijatie a zistenie statusu)
0x15 Miscellaneous system services - zmiešané systémové služby Funkcie zaobstarávajúce čakanie, prácu so systémovými parametrami alebo mapu dostupnej pamäte.
0x16 Keyboard services - služby klávesnice Služby na prácu s klávesnicou (čítanie znakov, zisťovanie stavu/statusu, ukladanie znakov a pod.)
0x17 Printer services - služby tlačiarní Tlačenie, zisťovanie stavu a inicializácia - dnes nepoužívané
0x18 Execute Cassette BASIC v minulosti používané na vykonanie programu v jazyku BASIC uloženého v pamäti ROM - dnes nepoužívané
0x19 Printer services - služby tlačiarní Tlačenie, zisťovanie stavu a inicializácia - dnes nepoužívané
0x1A RTC and PCI services - funkcie čipu RTC (real-time clock) a busov PCI Umožňuje zistiť aktuálny dátum alebo čas, prípadne ho nastaviť. 0x21 Systémové volania operačného systému DOS Umožňovali prácu so súbormi, priečinkami, vstupom a výpisom alebo časom. - dnes nepoužívané, bez DOSu nefunkčné

Na rutiny označené ako dnes nepoužívané nie je dobré spoliehať pri systémovom programovaní. Poznámka: Dobrý spôsob na trénovanie/testovanie programovania v reálnom móde je použitie dnešných simulácií operačného systému DOS (napríklad DOSBox). Jedná sa o prostredie reálneho módu s podporou niektorých užitočných funkcií. Zároveň sa dajú účinky programu hneď overiť v prostredí operačného systému.

Jednotlivé softvérové rutiny majú svoje funkcie. Podľa pôvodného štandardu (zvyku?) sa číslo funkcie ukladá do registru AH, prípadne do celého registru AX (alebo EAX). Týmto spôsobom je možné, že jedno prerušenie zastrešuje dve úplne rozdielne úlohy (ako je to v prípade prerušenia 0x1A).

Niektoré záznamy v tabuľke IVT sa používajú aj ako ukazovatele a oblasti pamäti s informáciami. Tu je ich krátky zoznam:

Odsadnie (číslo prerušenia) Popis
0x1D Ukazovateľ na Video Parameter Table - štruktúru obsahujúcu informácie o video módoch (módoch grafiky)
0x1E Ukazovateľ na Diskette (Floppy) Parameter Table - štruktúru obsahujúcu informácie o disketových zariadeniach
0x1F Ukazovateľ na Video Graphics Character Table - zoznam dát pre znaky ASCII tabuľky v rozmedzí 128-255
0x41 Ukazovateľ na Fixed Disk Parameter Table - parametre prvého pevného disku
0x46 Ukazovateľ na Fixed Disk Parameter Table - parametre druhého pevného disku

Poznámka: označenia "prvý pevný disk" alebo "prvé zariadenie" (obecne) nemusia mať pevný štandard. V prípade pevných diskov nie je vždy jasné, či je zariadenie BIOSom označené ako "prvý pevný disk" master alebo slave zariadenie, alebo či je to zariadenie prvého alebo druhého busu (pripojenia). Predsalen sa jedná o naozaj staré prvky v oblasti počítačov, takže nie je na čo sa spoliehať.

Pôvodná špecifikácia BIOSu k IBM PC sa dnes dá dnes nájsť už len veľmi ťažko, a je dosť neaktuálna. Množstvo firiem sa vo vývoji vydalo vlastnou cestou a BIOSy už nedodržiavajú také usporiadanie ako v minulosti.

Mnoho informácií o fungovaní BIOSu vám môže poskytnúť aj štúdium zdrojového kódu otvorených BIOSov pre rôzne emulátory: