Vývoj operačného systému/Bootloader po druhé - práca s diskovými jednotkami

Práca s diskovými jednotkami je v dnešnej dobe najdôležitejšia súčasť BIOSu. Cieľom bootloaderu je načítať ďalšie časti operačného systému v slede procesu "bootovania", a to ide bez pomoci BIOSu len zložito a hlavne neprehľadne či neprenosne (medzi rôznymi typmi diskov).

Hierarchia disku upraviť

V minulosti nebol z praktického hľadiska v štruktúre pevného disku a diskety taký veľký rozdiel. Disková jednotka bola rozdelená

  • z fyzického hľadiska do "dosiek/tanierov" (plates)
  • z logického hľadiska do "hláv" (head), "stôp/cylindrov" (track/cylinder) a "sektorov" (sector) - hierarchia (od hora), pričom počet jednotlivých prvkov v jednom nadradenom prvku bol jednotný pre jeden disk, ale rozdielny pre rôzne typy
Logická štruktúra disku

Na každý "tanier" v zariadení (disketa mala jeden 1, pevné disky viac) sa dá zapisovať z dvoch strán. Každá jedna strana teda symbolizuje jednu "hlavu". Na jednotlivých "hlavách" sú zasadené stopy (alebo inak aj cylindre, kedže n-tá stopa sa nachádza na n-tej hlave na rovnakom mieste). Každá stopa obsahuje fixný počet sektorov z ktorých každý obsahuje fixný počet bajtov.

Pri čítaní z disku sa vsunul každý tanier medzi čítacie ihlice (alebo aj inak čítacie "ruky" (arm) či čítacie hlavy), čím sa dospelo k stavu v ktorom mala každá "hlava" svoju ihlicu. Mechanizmus na posúvanie ihlíc je spoločný pre všetky "hlavy", čo znamená že ak sa musí otočiť jedna ihlica, otočia sa všetky. Z toho dôvodu sa jednotlivé stopy nezapisujú lineárne na jednu stranu taniera, ale striedavo na obidve strany, čím sa minimalizuje potreba posúvania hlavy a celý proces je rýchlejší. Táto hierarchia sa preto niekedy označuje aj v poradí cylinder-hlava-sektor.

Hlavy a stopy sa číslujú číslami od 0 vyššie. Sektory sa však adresujú od 1 (zaužívaný postup, uvedený môžno kvôli rýchlejšiemu násobeniu pri vypočítavaní odsadenia v bajtoch).

Na základe týchto informácii si vieme urobiť vzorec na vypočítanie veľkosti disku, lineárnej adresy...

  • počet sektorov:
  • veľkosť disku (v bajtoch): alebo
  • lineárna adresa:

... a vzorce na vypočítanie CHS (cylinder-hlava-sektor) adresy

Poznámka: konštanta je vo vzorcoch používaná ako premenná vyjadrujúca počet hláv na jednom disku. Fyzicky nie je možné, aby mal tanier viac ako 2 strany, avšak jednotlivé čipy alebo virtuálne zariadenia si môžu s číslami pracovať ako chcú (jednotlivé umiestnenie hláv nemusí zodpovedať realite).

Diskety upraviť

V histórii klasických diskiet sú známe dva druhy:

  • 5.25" - Veľkosť medzi 360KB - 1.2MB
  • 3.5" - Veľkosť medzi 730 - 1.44MB

V tejto príručke sa pracuje hlavne s disketou 3.5", uvediem teda niektoré jej parametre (platia pri dosadení do vzorcov vyššie):

  • počet bajtov na sektor: alebo
  • počet sektorov na stopu:
  • počet stôp na hlavu:
  • počet hláv:
  • veľkosť:
  • maxmálna hodnota adresy LBA:

Adresovanie LBA upraviť

Adresa LBA je aktuálne všeobecne používaná pre adresovanie na diskoch (vo vzorcoch vyššie uvedená ako lineárna adresa alebo ). Na rozdiel od adresovania CHS sa v prípade LBA používa len jedno číslo (začínajúce od nuly, viď vzorce vyššie). Pre súborové systémy (rovnako ako aj pre disky samotné) je jednoduchšie (a úspornejšie) držať len jedno číslo. Pre diskové jednotky sú známe dva formáty:

  • LBA28: (3.5 bajtu), maximálny počet sektorov (pri veľkosti sektoru 512 bajtov je to 128GB dát)
  • LBA48: (6 bajtov), maximálny počet sektorov (pri veľkosti sektoru 512 bajtov je to 128PB (1PB = 1024TB) dát)

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

Je taktiež nutné poznamenať že veľkosť diskov sa často neudáva v mocninách čísla 2, ale v mocninách čísla 10, čím je disk na pohľad väčší. Preto môže mať USB o veľkosti 4GB () v skutočnosti len okolo 3.73GB () oproti očakávaným B. Čím väčší disk kupujete, tým prekvapenejší môžete byť. Množstvo bajtov v programátorskom značení pre

kde bude zastupovať multiplikáciu stupňa umocňovania (kB = 1, MB = 2, GB = 3, TB = 4 ...), môžeme vyjadriť ako

a tak teda môžeme vyjadriť stratu spôsobenú rozdielnym značením ako

pričom stále počítame hodnoty v rámci platnosti . Do presnej hodnoty v bajtoch sa dá výsledné číslo (v mocnine čísla ) preniesť týmto vzorcom:

a spätne (pre vstupné hodnoty) ako

Nárast straty sa dá vyjadriť ako derivácia , čiže

Percentuálne sa dá strata pre mocninu čísla vyjadriť ako

pre konkrétne .

Funkcie BIOSu upraviť

Na prácu s diskovými jednotkami sa používa prerušenie 19 (0x13) patriace BIOSu. Toto prerušenie poskytuje nízkoúrovňový prístup k disku využitím funkcií jednotných pre viacero druhov zariadení. Pôvodné verzie BIOSu podporovali len okolo 504MB pamäte (adresovanie v tejto veľkosti sa zvykne označovať aj ako fyzické CHS). Samotné pôvodné (štandardné) adresovanie CHS poskytuje má tieto obmedzenia:

Časť adresy Bitová šírka Max. hodnota Max. reálny počet prvkov
Hlavy 8 255 256
Cylindre 10 1023 1024
Sektory 6 63 63 [1]
Veľkosť jedného sektoru - - 512
Spolu 24 bitov ~8024.6557MB 8064MB
  1. Kým pri ostatných častiach adresy sa označujú prvky od 0 (ako je to zvykom), pri sektoroch začína 1. Preto je maximálna hodnota zároveň limitom počtu prvkov. Pri práci so zariadeniami ATA(IDE) je možné získať limity vo formáte CHS rovnako ako v LBA. Môže sa však stať, že zariadenie bude rátať s existenciou nultého sektoru. Preto sa viac oplatí používať adresovanie LBA, kde taktiež netreba zabudnúť na nultý sektor.

Tieto hodnoty pre adresovanie samozrejme nestačili pokryť rýchly vývoj v oblasti úložných zariadení, a tak sa do BIOSu pridali nové funkcie (známe aj ako rozšírenia prerušenia 19 - INT 13h Extensions). Rozšírené funkcie používajú adresovanie LBA, čím sa značne navýšili viaceré limity zariadení.

Úložné zariadenia majú v celom BIOSe jednoduché (a zároveň momentálne ťažko prakticky využiteľné) označenie, ktoré sa ukladá do jedného 8-bitového čísla (ktoré sa často/zvyčajne nachádza v registri DL). V dnešnej dobe je ťažké doplniť doň nové druhy zariadení, a preto sa tento formát v dnešných operačných systémoch nepoužíva.

Hodnota Zariadenie
0x00 Prvé disketové zariadenie ('A:')
0x02 Druhé disketové zariadenie ('B:')
0x80 Prvý pevný disk
0x81 Druhý pevný disk

Poznámka: Označenia prvý a druhý pevný disk nemajú pevné prepojenie so zariadeniami ATA. Môže sa jednať o CD-ROM, prvý a druhý pevný disk, alebo ich podzariadenia (slaves).

Základné funkcie prerušenia 19 sú usporiadané logicky.

Hodnota (hex) Funkcia Vstup Výstup
00 Reštartuje konkrétne zariadenie (zo zariadení známych pre BIOS) DL = BIOSové označenie zariadenia CF = v prípade chyby 1; inak 0
01 Získa stav poslednej operácie vykonanej na zariadení DL=zariadenie CF = v prípade chyby 1; inak 0,

AL = kód chyby

Hodnota (hex) Stav
00 Úspech
01 Neprávny (nepovolený) príkaz
03 Pokus o zápis na disk chránený proti zápisu
04 Sektor nenájdený
05 Reštartovanie zlyhalo
0A Zistený (nájdený) chybný sektor (bad sector)
0B Zistený (nájdený) chybný cylinder/stopa (bad cylinder)
0D Nesprávny (nedovolený) počet sektorov
20 Chyba radiča
40 Chyba pri presúvaní kurzoru (ihlice, seek failure)
80 alebo AA Zariadenie nepripravené
BB Neznáma chyba
CC Chyba pri zápise
E0 Chyba stavu (status error)
02 Čítanie sektorov zo zariadenia AL = počet sektorov na čítanie,

DL = zariadenie, DH = číslo "hlavy",

ES:BX = adresa uloženia prečítaných dát v pamäti, CX[0-5] = sektor,

CX[6-15] = stopa/cylinder

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01),

AL = počet prečítaných sektorov

03 Zápis sektorov na zariadenie AL = počet sektorov na zápis,

DL = zariadenie,

DH = číslo "hlavy",

ES:BX = adresa dát na zápis,

CX[0:5] = sektor,

CX[6:15] = stopa/cylinder

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01),

AL = počet zapísaných sektorov

04 Overenie sektorov na disku (hľadanie chýb). S dátami v pamäti sa nepracuje. Pri výskyte chyby by mal program niekoľkokrát overiť (a reštartovať), či sa disketa nachádza v zariadení. AL = počet sektorov na overenie,

DL = zariadenie,

DH = číslo "hlavy",

ES:BX, CX[0:5] = sektor,

CX[6:15] = stopa/cylinder

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01),

AL = počet (úspešne[neoverené] ) overených sektorov

08 Získa parametre zariadenia DL = zariadenie,

[ES:DI = niekedy vyžadovaná hodnota 0 na niektorých BIOSoch]

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01),

DL = počet (pevných?[1]) diskov,

DH = posledná (maximálna) "hlava" [2],

CX[0:5] = počet sektorov na stope,

CX[6:15] = posledná (maximálna) stopa/cylinder[2],

ES:DI = adresa tabuľky parametrov diskety [1],

BL = typ diskety podľa tabuľky

Hodnota Typ
01 5.25 palcová disketa, 360KB a 40 stôp/cylindrov
02 5.25 palcová disketa, 1.2MB a 80 stôp/cylindrov
03 3.5 palcová disketa, 720KB a 80 stôp/cylindrov
04 3.5 palcová disketa, 1440KB a 80 stôp/cylindrov
42 Rozšírené čítanie sektorov zo zariadenia, funguje na princípe paketov a používa adresovanie LBA DL = zariadenie, DS:SI = adresa na DAP (Disk Address Packet - paket diskovej addresy) CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01)

43 Rozšírený zápis sektorov zo zariadenia, funguje na princípe paketov a používa adresovanie LBA DL = zariadenie,

DS:SI = adresa na DAP,

AL = nastavenia zápisu

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01)

46 Vysunutie konkrétneho média DL = zariadenie, AL = 00 (rezerovované[neoverené]

)

CF = v prípade chyby 1; inak 0,

AH = kód stavu (ako pre funkciu 01)

  1. 1,0 1,1 Rôzne zdroje uvádzajú rôzne informácie, nemusí sa jednať len o diskety.
  2. 2,0 2,1 Z dôvodu číslovania "hláv" od 0 je nutné pripočítať 1 na zistenie počtu hláv

Použitie funkcii upraviť

Funkcie 00 a 01 upraviť

Kedže je reštartovanie disku jednou z jeho funkcií (00), je možné overiť si úspech tejto operácie použitím funkcie 01. Zároveň sa odporúča overiť (reálne[1]) zariadenie niekoľkokrát (asi 3x).

BITS 16
	xor cl, cl		;počítadlo = 0
	xor dl, dl		;zariadenie = 0 = prvá disketa ('A:')

	.again:
	inc cl			;počítadlo+1
	cmp cl, 5		;ak počítadlo 3+1
	jz .fatal		;disketa naozaj nefunguje

	xor ah, ah		;funkcia 00: reštartovanie zariadenia
	int 0x13		;prerušenie 0x13: práca s úložnými zariadeniami
	mov ah, 01		;funkcia 01: získanie stavu poslednej operácie
	int 0x13		;rerušenie 0x13
	test ah, ah		;ak AH=0 (stav = 0, úspech)
	jnz .again		;pokračuj, inak vyskúšaj overenie zariadenia ešte raz

	.fatal:			;informuj o výskyte chyby

Kódové ukážky uvedené nižšie budú funkčne zanedbávať AH ako návratovú hodnotu v prípade chyby.

Funkcie 02 a 03 upraviť

Úložné zariadenia ani BIOS neposkytujú možnosť kopírovania sektorov z jedného miesta na druhé[2]. Preto je nutné využiť na tento účel funkcie ktoré poskytujú (čítanie 02 a zápis 03) a dáta dočasne ukladať v pamäti RAM.

V nasledujúcom kóde sú informácie o zdroji a cieli kopírovania uložené v pamäti a do funkcie sa dodáva len ich adresa (+ počet sektorov na kopírovanie, rátajúc s tým že jeden sektor má 512 bajtov). Štruktúra zdroja a cieľa v pamäti pre tento prípad vyzerá asi takto[3]:

Odsadenie (od zač. štruktúry) Veľkosť (v bajtoch) Použitie Zodpovedajúci register
0 1 BIOSové označenie zariadenia, umožňuje kopírovať z/do rozdielnych zariadení DL
1 1 Hlava (head) z CHS adresy DH
2 2 [0:5] = sektor z CHS adresy, [6:15] = stopy/cylinder z CHS adresy CX
BITS 16
;VSTUP:	[ES:SI] = štruktúra pre zdrojové zariadenie, [ES:DI] = štruktúra pre cieľové zariadenie
;		ES:BX = pamäť pre buffer, AL = počet sektorov na čítanie (nemal by byť prekročený limit segmentu)
kopiruj:
	mov dl, byte [es:di]	;načítaj číslo cieľového zariadenia
	call reset				;procedúra reštartujúca zariadenie a overujúca stavový kód poslednej operácie
	mov dx, word [es:si]	;načítaj číslo zdrojového zariadenia + 'hlavu' začiatku
	call reset				;reštartuj

	mov cx, word [es:si+2]
	mov ah, 02
	int 0x13
	jc .error
	mov dx, word [es:di]
	mov cx, word [es:di+2]
	int 0x13
	jc .error
	jmp .end

	.error:
	mov si, chyba
	call vypis

	.end:
	ret
chyba: db "Vyskytla sa chyba pri kopirovani, skontrolujte register AH", 0x0D, 0x0A, 0

Funkcia 04 upraviť

Ukážka kódu vytvorená pre túto funkciu využije štruktúru uvedenú vyššie a poslúži ako nástroj na overovanie zdroja a destinácie pred kopírovaním. Funkcia prijíma adresy štruktúr a počet sektorov na kontrolu.

;VSTUP:	[ES:SI] = štruktúra pre zdrojové zariadenie, [ES:DI] = štruktúra pre cieľové zariadenie
;		ES:BX = pamäť pre buffer, vlastne ani nie potrebný parameter, AL = počet sektorov na overenie
kontrola:
	mov dx, word [es:si]
	mov cx, word [es:si+2]
	mov ah, 04
	int 0x13
	jc .error

	mov dx, word [es:di]
	mov cx, word [es:di+2]
	mov ah, 04
	int 0x13
	jc .error

	jmp .end

	.error:
	mov si, chyba
	call vypis

	.end:
	ret
chyba: db "Vyskytla sa chyba pri kontrole, pouzite register AH na diagnostiku", 0x0D, 0x0A, 0

Funkcia 08 upraviť

Tento kód získa informácie o zariadení a vráti ich[4] v štruktúre vytvorenej v ukážke pre funkcie 02 a 03.

;VSTUP:	DS:DI = štruktúra pre zariadenie,
;		DL = BIOSové označenie zariadenia
;VÝSTUP:[DS:DI] = štruktúra pre zariadenie,
;		BL = BIOSové označenie typu diskety
ziskaj_parametre:
	mov ah, 08
	int 0x13
	jc .error
	mov word [ds:di], dx
	mov word [ds:di+2], cx
	jmp .end

	.error:
	mov si, chyba
	call vypis

	.end:
	ret
chyba: db "Vyskytla sa chyba pri ziskavani parametrov, overte hodnotu AH", 0x0D, 0x0A, 0

Na základe vzorcov uvedených vo vyššej časti článku a pripomienok v tabuľke môžete vypočítať veľkosť zariadenia v bajtoch.

Poznámky upraviť

  1. Na virtuálnych zariadeniach sa tento problém pochopiteľne veľmi nevyskytuje
  2. Vo všeobecnosti taká operácia v oblasti pamäte nie je možná vôbec (teda ak nerátame rôzne čipy schopné podržať informácie kým sa spracujú)
  3. V skutočnosti majú rôzne kompilátory rôzne možnosti poskytujúce rýchlu tvorbu a návrh štruktúr, no takto je to možno aj prehľadnejšie.
  4. v prípade že sa nevyskytne chyba

Podrobné zdroje upraviť

Hoci je isté, že sa smer kódov BIOSu výrazne zmenil, je nutné poznamenať, že na rozdiel od iných oblastí ktorými sa BIOS zaoberá sa v tomto prípade v mnohom zmenili aj vlastnosti úložísk (pričom sa napríklad PS/2 a VGA až tak nezmenili). Nikdy nie je dobré spoliehať sa na BIOS v plnej miere, a pre zariadenia na ukladanie dát to platí dvojnásobne. Nižšie je uvedený zoznam celkom podrobných zdrojov na prácu s BIOSom s ohľadom na tento druh zariadení.