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).
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ť.
Zdroje
upraviť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.
- Systémové volania DOSu
- Vydarený a obsiahly zoznam prerušení s popismi funkcií
- BIOS na Wikipédii
- Zoznam BIOSových volaní na anglickej Wikipédii
- Intel® 64 and IA-32 Architectures Software Developer Manuals
- Volume 1, 6-10
- Volume 3A, Chapter 6
- Volume 3A, Chapter 2
- Intel 80386 Programmer's Reference Manual - manuál z roku 1986, stále použiteľný
- Chapter 9 - množstvo jednoducho podaných informácií o prerušeniach a chybách/výnimkách
- Chapter 14 - informácie o reálnom móde (vhodné si prečítať)
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: