KIV/OS Flashcards
80186 a 80286
Oba - 1982
Oba - Instrukční sada x86-16 (16 bitový procesor)
80186 - sice se už nevyrábí, ale zato dodnes existují RISCové procesory, které mají x86-16 instrukční sadu
80286 - měl protected mode, procesor po zapnutí však startuje real-mode kvůli zpětné kompatibilitě (to ostatně dělají i dnešní x86-64)
80286 – vybrané registry (5x)
1) AX, BX, CX a DX – obecné 16-bitové registry, které se dále dělí na dvojice 8-bitových registrů
2) CS, DS, SS, ES – segmentové registry pro kód, data, zásobník a extra segmentový registr
3) SI, DI, BP, SP – indexové registry; source, destination, base, stack
4) Flags – stavový registr, výsledky operací
5) MSW (386+: CR0-4, atd.) – stav CPU (machine status word)
80286 – adresace
Adresa v paměti ji dána dvojicí registrů segment:index (např CS:IP)
Adresa má 20 bitů
- segment i index 16 bitů
- adresa = segment posunutý o 4 bity dolevo, bitové or s indexem
MS-DOS
- význam
- co poskytuje
- druhy
- Disk Operating System
- Jeden z nejvýznamnějších (tj. ne nutně nejlepších) operačních systémů
- Poskytuje konzoli a souborový systém
(konzole se myslí klávesnice pro standard input) - Existovalo mnoho DOSů
◦ MS-DOS, PC-DOS, DR-DOS, QDOS…
◦ MSDOS.SYS, IO.SYS a COMMAND.COM se pak jmenují jinak
◦ A dodnes aktivní FreeDOS
80286 – MS-DOS Bootstrap - od začátku až do nalezení MBR (tj. kroky 1 - 4)
1) Po zapnutí/hw resetu (tj. hot reset počítače) se procesor uvede do aktivního stavu a do režimu real-mode, tzn. má přístup pouze k 1MB paměti a kód může číst a zapisovat na libovolné místo v paměti
2) Registry CS:IP se nastaví na hodnoty F000:FFF0 a CPU začne vykonávat instrukce od této adresy
◦ Tj. skočí na první instrukci ROM-BIOSu, čímž spustí jeho kód – proto se této adrese říká reset vector
◦ Cold reset počítače: předání se řízení na adresu určenou reset vectorem; od 386 je to fyz. lineární adr. 0xFFFFFFF0
3) Podle nakonfigurovaného pořadí BIOS hledá disky
4) Při nalezení prvního disku BIOS načte do paměti, adresa 0x7c00, jeho první sektor, tj. prvních 512 bytů, předá řízení CPU na tuto adresu – tj. nastaví CS:IP
◦ První sektor se nazývá Master Boot Record (MBR)
80286 – MS-DOS Bootstrap - od nalezení MBR až po převzetí řízení IO.SYS (tj. kroky 4-7)
4) Při nalezení prvního disku BIOS načte do paměti, adresa 0x7c00, jeho první sektor, tj. prvních 512 bytů, předá řízení CPU na tuto adresu – tj. nastaví CS:IP
◦ První sektor se nazývá Master Boot Record (MBR)
5) Kód načtený z MBR má za úkol načíst zbytek zavaděče ze správného/aktivního/vybraného oddílu disku
◦ Může být zavaděč přímo operačního systému
◦ Anebo manažer, který dá vybrat, který OS se má zavést, je-li jich nainstalováno více
◦ Anebo to také může být vir, který infikuje počítač ještě před načtením OS
◦ MS-DOS startuje z FAT, active&bootable&primary oddílu
6) Poté, co kód z MBR identifikoval použitelný diskový oddíl, pokračuje s načítáním OS do paměti
◦ Jedná se o soubory IO.SYS a MSDOS.SYS, které musí být uloženy kontinuálně na začátku oddílu
7) Jakmile jsou sobory načteny, řízení převezme IO.SYS
◦ Rozhraní mezi DOSem a I/O subsystémem, které zpřístupní základní periferie
80286 – MS-DOS Bootstrap - od převzetí řízení IO.SYS až do konce (tj. kroky 7 - 12)
7) Jakmile jsou sobory načteny, řízení převezme IO.SYS
◦ Rozhraní mezi DOSem a I/O subsystémem, které zpřístupní základní periferie
8) IO.SYS předá řízení MSDOS.SYS
◦ Jádro OS, které poskytuje abstrakci od HW pomocí poskytovaných služeb
9) Pokud existuje, MSDOS.SYS načte a zparsuje CONFIG.SYS
◦ Zavede ovladače paměti (XMS, EMS), periferií (CDROM, Myš, zvuková karta, atd.)…
10) MS-DOS.SYS načte a spustí, tj. předá řízení, COMMAND.COM (interpret příkazů, aneb shell)
11) Pokud existuje, spustí se AUTOEXEC.BAT
◦ Dávkový soubor s příkazy pro COMMAND.COM
12) C:\ aneb Hotovo
Windows - 9X Bootstrap
- 16 bitové Windows se spouštěly příkazem win.com
◦ Zavaděč Windows/386 přepnul procesor do tzv. protected-mode - Windows 9x se zaváděly tak, že IO.SYS provedl konfiguraci počítače v real-mode a pak spustil win.com po dokončení AUTOEXEC.BAT
◦ Komplikované zavedení ovladačů, některá zařízení mají ovladače jen pro real-mode, zatímco Windows běží v protected-mode => potřeba virtualizace –V86 mode
Pozn:
O trochu komplikovanější
Méně pádů
Pády kvůli driverům
Problém jádra většího než 1MB
- CPU startuje v real-mode pouze s 20-bitovou adresou (2^20 = 10^6)
Jak zavést tak velké jádro?
1) 386+ procesory lze přepnout do tzv. unreal-mode, který zpřístupní dostupnou paměť jako 4GB flat address space
- > A pak lze načíst a spustit jádro větší než 1MB
2) Anebo máme UEFI – což nikdy nebyl případ MS-DOSu
- > Ale stále existuje např. FreeDOS
Unreal mode
- Není to oficiálně garantovaná vlastnost, ale existuje protože ji potřebuje System Management Mode
- Aby mohly programy běžet v protected-mode (32-bitová adresa, segmentace, stránkování, izolace procesů), je třeba vytvořit GDT a LDT
- Globální a lokální tabulky deskriptorů segmentů – organizace paměti
- Segmentům se nastaví maximální velikost (limity) a procesor se přepne zpět do real-mode
◦ Respektive do unreal-mode protože limity zůstanou zachovány
Problém příliš velkého programu (DOS)
Co když máme program pro real-mode, který ale
vyžaduje více paměti, než kolik jí je volné?
◦ XMS, EMS – paměťové manažery, které přepnuly procesor do protected mode a na rozdíl od unreal mode v něm zůstaly
◦ Real-mode programům, pak umožnily využít větší paměť po max 64kB velkých oknech, které kopírovaly mezi adresami nad a pod 1MB
Programy pak dynamicky překrývaly blok paměti různými částmi, moduly, svého kódu => tzv. overlays
Overlays
- Technika, která umožňuje spustit program, který je větší než velikost dostupné paměti
◦ Předchůdce virtuální paměti (příští přednáška)
◦ Stále se používá u vestavěných zařízení, kde virtuální paměť není k dispozici - Program se rozdělí do funkčních modulů, overlays, které mají stromovou strukturu
◦ V paměti mohou být zavedeny jenom moduly od na cestě kořene, tj. fce main, až k listům
◦ Návrh stromů a explicitní zavádění a uvolňování musí zařídit programátor
UEFI
- Unified Extensible Firmware Interface
- Nástupce BIOSu, který má řešit jeho nedostatky
- Nespoléhá se na boot (tj. první) sektor, ale definuje boot manager
◦ Umí zavádět pouze důvěryhodně podepsaný kód – což nejsou např. viry – BIOS uměl zamezit přepsání MBR
◦ Nicméně má legacy mode, ve kterém se chová jako BIOS - Umí přepnout procesor do cílového režimu, např. protected-mode – zavaděč OS to ale musí očekávat
UEFI boostrap - Stejná control flow jako MS-DOS
EFI executable
spustitelný soubor v UEFI bytecodu (ne Java bytecode)!
Guid Partition Table (GPT)
načisto udělaná tabulka diskových oddílů, tak aby se nemusel vláčet omezující balast z minulost (UEFI)
EFI System Partition
oddíl naformátovaný souborovým systémem FAT dle specifikace UEFI
MS-DOS API
Chce-li program zavolat službu operačního systému, de-facto volá požadovanou rutinu, která je už někde
v paměti – ale jak ji najde?
Řešením je, aby byla na předem známé adrese, kam se předá řízení procesoru nastavením CS:IP
Rutin implementujících jednotlivé služby může být mnoho => použije se další registr, např. ax na určení konkrétní služby
Volání:
Služba MS-DOS se zavolá pomocí přerušení 21h
◦ Tzn. adresa hlavní rutiny služeb OS je zapsána na 0x21. pozici tabulky vektorů přerušení
Příklad volání:
mov ah, 0x30h
int 21h
;po návratu jsou hlavní a vedlejší čísla verze v AL a AH
MS-DOS obsluha API
- Program nastaví příslušné registry vykoná int 21h
- Do zásobníku, na jehož vrchol ukazuje SS:SP, se uloží registry CS:IP (ukazující ve volajícím programu na další instrukci po int 21h) a registr Flags
◦ Provede procesor v rámci zpracování instrukce int 21h - Jádro OS získá kontrolu nad CPU a vidí všechny registry volajícího programu
- Jádro OS provede příslušnou akci a nastaví příslušní registry podle výsledku akce
EGA-BIOS
- Co když budeme chtít využít služeb, které neposkytuje BIOS, ale např. grafický adaptér?
- Např. budeme chtít změnit režim obrazovky na
320x200x256. Program vykoná následující instrukce
mov ah, 0 ;služba Změň videorežim
mov al, 13h ;režim 320x200 256 barev
int 10h
- Z hlediska procesoru se stane to samé jako při instrukci int 21h, pouze vykonávaný kód bude v paměti někde jinde
Zápis do video paměti (asi MS-DOS)
- Na adrese a000:0000 je první pixel právě nastaveného videorežimu, levý horní roh
Na každý pixel je jeden byte, byte je index do palety barev
Přímým zápisem do namapované videopaměti měníme barvy jednotlivých pixelů
V textovém režimu je znak v levém horním rohu na
b800:0000
◦ Má dva byty – 1. byte kód znaku, 2. byte atributy, např. barva
VESA - motivace
Videorežim 320x200x256 potřebuje méně než 64kB na uložení indexů pixelů do palety barev
Videorežim 640x480x16 také
Ale videorežim 640x480x256 už ne – navíc to dříve nebýval standardní režim, dokud se neobjevila specifikace VESA - SuperVGA
Před VESA sice bylo možné na některých kartách takový režim aktivovat, ale postup byl proprietární
Proto vznikl rezidentní software, který VESA emuloval
VESA - stránkování
Video režim 1280x1024 při 24-bitové barevné hloubce potřebuje více než 64kB paměti
Řešením bylo stránkování
◦ Obraz se rozdělil na několik stránek po 64kB
◦ 64kB od A000:0000 umožňovalo přímý zápis a čtení do aktivní stránky
Aktivní stránka se zvolí funkcí VESA BIOSu
◦ Buď pomocí int 10h – opakované volání int 10h je pomalé
◦ Anebo call na konkrétní adresu obslužné rutiny; adresu získáme přes int 10h – call je daleko rychlejší než int, který je potřeba pouze jednou
VESA – Linear Frame Buffer
I když je stránkování video paměti pomocí call rychlejší než pomocí int, je stále pomalé
Rychlejší je přímý přístup do video paměti, jako tomu bylo u videorežimů, kterým stačilo 64kB
VESA umožňuje získat adresu Linear Frame Buffer (LFB)
◦ Obdoba A000:0000 u EGA, ale adresa LFB není pevně daná
◦ Je třeba LFB „povolit“ a následně získat adresu od grafické karty
◦ Blok paměti, který nelze použít pro data a kód programů
Zřetězení obsluhy přerušení
Např. chceme-li sw emulovat VESA
1. Program si do vlastní proměnné načte adresu stávajícího vektoru přerušení – int 10h u sw VESA
2. Program zapíše do tabulky vektorů přerušení adresu své rutiny, která bude přerušení nově obsluhovat
◦ Např. u sw VESA obsluhuje služby s AH=4Fh (VESA extension)
◦ Nová rutina přerušení může, případně musí (např. int 08h hodiny), zavolat (už ne int!) předcházející obsluhu přerušení
3. Program skončí službou OS Terminate and Stay Resident (TSR)
Ukončení TSR
TSR program měl smysl pouze tehdy, pokud obsluhoval některé přerušení
V paměti mohl být načteno několik TSR obsluhujících stejné přerušení
Ale co když se měl jeden z nich ukončit, a nebyl to ten poslední?
◦ Byl to problém, protože neexistoval standardizovaný protokol, jak vyjmout ze zřetězeného seznamu obsluh přerušení někoho uprostřed
Interrupt request (IRQ)
Instrukce int je sw-vyvolané přerušení
Pokud přerušení vyvolá hw, pak se bavíme o IRQ
◦ Každé IRQ má svoji prioritu – Level aka IRQL
Při IRQ procesor zastaví vykonávání aktuálního programu, uloží Flags, CS a IP, a začne vykonávat příslušenou obsluhu přerušení dle tabulky vektorů přerušení
Programmable Interrupt Controller (PIC) mj. překládá číslo IRQ na index do tabulky vektorů přerušení
Časovač
Např. tik hodin je IRQ0 (nelze změnit ani maskovat)
a vyvolá obsluhu přerušení int 08h
◦ Proběhne každých 55ms
Na tomto přerušení závisí mnoho důležitých činností a je proto nutné, aby
a) Bylo co nejrychlejší
b) Zavolalo původní obsluhu přerušení
Pomocí časovače se implementuje preemptivní
multithreading (a následně multitasking)
Časovač - implementace
Nejprve se do proměnné oldVec8 uloží adresa původní
obsluhy přerušení, takže obsluha může vypadat následovně:
pushf;simulace volání obsluhy přerušení
call dword ptr cs:[oldVec8] ;pro původní obsluhu
… ;naše vlastní činnost
iret ;návrat do přerušeného programu
I/O Porty
Input/Ouput base address – adresa prvního portu
Periferie lze také ovládat pomocí portů – jedno zda blikáme s LED klávesnice, nebo programujeme PIC
◦ Zápis odešle příkaz; instrukce out
◦ Čtení čte stav nebo výsledek operace; instrukce in
Např. při obsluze časově závislých činností v int 08h je nutné poslat řadiči přerušení informaci, že přerušení již skončilo
mov al, 20h ;signál Konec přerušení
out 20h, al ;port řadiče přerušení 8259
Viry
MS-DOS umožnil ovládat počítač a jeho periferie
Ale špatně nebo záměrně napsaný program mohl číst
a přepisovat jeho vnitřní proměnné, a libovolně měnit činnost systému
◦ Např. na přerušení se mohl pověsit vir, který se spouštěl z infikovaného MBR disku a infikoval MBR disket, a díky zavedení před jádrem OS mohl utajit své soubory na disku filtrováním systémových volání
Antiviry musely skenovat paměť, což byla příležitost pro polymorfní viry, které měnily svůj kód v paměti za běhu
Režím jádra a uživatelský režim - motivace
..mohlo zároveň běžet několik procesů
..proces nemusel vědět, že zároveň s ním běží další procesy
..bylo jedno, kde v paměti běží který proces
..proces nemohl přistupovat do paměti jiného procesu či jádra
..výsledkem nebylo zpomalení počítače
..výsledkem bylo zefektivnění práce na počítači
Memory Management Unit
- Výše uvedené cíle (motivace režim jádra a uživatelský režim) implikují, že procesy budou pracovat se
svým formátem (tj. virtuální) adresy do paměti, která bude následně převedena na fyzickou adresu do paměti
Protože sw implementovaný převod by byl pomalý, převod virtuální na fyzickou adresu obstará hw
◦ Konkrétně Memory Management Unit (MMU)
◦ Detaily převodu zadá MMU přímo OS
CPU –(virutální)–> MMU –(fyzická)–> Paměť
x86 virtuální adresa
x86 pracuje s virtuální adresou ve formátu segment:offset
Z ní je třeba získat tzv. lineární adresu, a teprve tu lze převést na fyzickou adresu v režimu, ve kterém dokážeme od sebe izolovat jednotlivé procesy a jádro
CPU –(virutální/logická)–> MMU –(lineární)–> Stránkování –(fyzická)–> Paměť
Protected mode
V prvé řadě musíme zabránit uživatelským procesům, aby nemohly modifikovat kód a data jádra
Jelikož x86 adresuje pomocí segmentu a offsetu (vůči
segmentu), řešením bylo připojit dodatečné informace ke konkrétním segmentům
◦ => už nepracujeme se segmentem, ale se segment deskriptorem
◦ Procesor běží v tzv. Protected mode