Hlavní navigace

Píšeme operační systém: boot

Daniel Sedláček 20. 1. 2006

Chtěli jste si někdy napsat vlastní operační systém? Nebo jste alespoň chtěli vědět, jak se to dělá? V následujícím článku si popíšeme jednoduchý postup, jak vytvořit boot disketu.

Operační Systém

Začnu tím, že se pokusím definovat pojem operační systém. Kdysi „dávno” před osobními počítači, kdy byly počítače velké jako tělocvičny a neexistovaly OS, program se nadírkoval (nahrál) a když skončil, nadírkoval se další. Ale počítačový čas byl moc drahý na takové plýtvání, a tak vznikly první OS, a to jako programy, které jen postupně pouští ostatní programy. Bylo také velmi nepraktické, že každý program musel mít vlastní ovladače k hardwaru a skoro každý prvek hardwaru byl unikátní, takže přenositelnost programů byla minimální. Takže se do OS začalo integrovat jednotné rozhraní mezi programy a periferiemi (ovladač).

Postupným vývojem jsme se dostali až k dnešní podobě, kdy, díky hardwarové podpoře CPU multitaskingu a multiprocesingu, může dnešní OS střídat běžící programy tak, že slyšíme hudbu, stahujeme soubory a zároveň třeba programujeme. Co ale tedy je operační systém? Je to program, který přiděluje programům paměť a hlavně je „pouští” na procesor. Nedílnou součástí je jednotný přístup k periferiím, sítím, diskům, souborovým systémům. Dnešní OS obsahují i širokou škálu vnitřních nástrojů jako sdílené knihovny nebo komunikaci mezi jednotlivými programy (tzv. systém zpráv). Je to tedy program, který je správce (hardwarových) prostředků.

CPU

Při každém novém procesoru se v minulosti také skoro vždy změnila architektura, buď změnou registrů, nebo se jednoduše přešlo z 4 bitů na 8 bitů. To znamenalo, že se každý program, OS nevyjímaje, musel přepsat, ne-li napsat zcela znovu, což bylo velice nákladné a brzdilo rozvoj.

Intel & x86

V roce 1978 firma Intel přišla na trh z procesorem Intel 8086. Byl zpětně kompatibilní s 8b procesory. Byl 16 bitový, ale adresovací sběrnici měl 20 bitovou, mohl tedy adresovat 1 MB fyzické paměti, pracoval v reálném režimu (real mode). Každý program mohl přistupovat do celé paměti, takže bezpečnost a separovatelnost programů byla na minimální úrovni. Podporoval přerušení jak hardwarové, tak i softwarové, které známe třeba z programování pod dosem. Důležité ale je, že od roku 1978 mluvíme o architektuře x86.

Dalším milníkem se stal procesor Intel 386, který byl 32b. A podporoval chráněný režim (protected mode), což je systém správy paměti, který umožňuje alokovat 4GB fyzické paměti, podporuje tzv. stránkování a virtuální paměť, kde může OS oddělit jednotlivé programy od sebe a simulovat větší paměť ukládáním stránek na disk (swap). Chráněný režim také napomáhá operačnímu systému s multitaskingem. Není ale zpětně kompatibilní s reálným režimem, což nám ale i386 vynahrazuje virtuálním režimem, který simuluje reálný. A tak můžeme programy psané pro reálný režim za kooperace OS pouštět i v chráněném. Chráněný režim podporoval už procesor Intel 286, který byl ale ještě 16bitový.

Budeme se zabývat pouze procesory x86 kompatibilními, což je asi nejpoužívanější architektura osobních počítačů. Důležité je, že každý procesor po startu (restartu) pracuje v 16 bitovém reálném adresovacím režimu a nezáleží na tom, jestli to je „stařičká” i386 nebo nejnovější 64bitový procesor architektury ia64. Je už jen na operačním systému, aby se přepnul do jiných režimů.

Boot systému

Jak tedy probíhá boot samotného systému? Po startu se nahraje do paměti BIOS a pustí se. My si nastavíme bootování z disketové mechaniky. BIOS vezme náš označený (poslední dva Byte mají speciální hodnotu) boot sector, což je první sector na disketě. Nahraje ho do paměti na místo 0000:7c00h a spustí ho.

Reálný režim

Teď si více osvětlíme reálný režim, ať víme, jak náš boot sector napsat. K dispozici máme 14 16-bitových registrů. Všeobecné: AX, BX, CX, DX, indexové a ukazatelové: SP, BP, SI, DI, segmentové: CS, DS, SS, ES a dále: IP a FLAGS. Důležitý je vztah segmentových registrů. Jak již víme, adresa je tvořena 20bity, ale registry máme 16 bitové. Adresa se tedy vytváří sečtením jednoho ze segmentových registrů posunutého o 4 bity (a vynásobeného 16) a zbytku adresy, tzv. offsetu. Adresa = segment * 16 + offset. Zapisujeme: „segment:offset”. 12 bitů se překrývá, neboli jednu adresu můžeme zapsat několika způsoby, třeba 0000:7c00h = 07c0:0000h = 00c0:7000h. Podle následujícího schematu se implicitně používají segmentové registry: SS:SP, SS:BP, DS:BX, DS:SI, DS:DI, ES:DI (řetězcové operace). Explicitní přiřazení v intel syntaxi vypadá následovně:

mov ah,es:[ukazatel]
mov ah,es:offset 

Příklady

Ukážeme si příklad boot sectoru:

; boot_sector1.asm

org 0x7c00  ;nastaveni segmentu

jmp main

;promene

boot_msg db 'Muj prvni OS...',13,10,0
klav_msg db 'Stisknete jakoukoliv klavesu k restartu',13,10,0

bootdev db 0

zprava:   ;funkce na vypis na obrazovku
lodsb
or al,al
jz short zprava_konec
mov ah,0eh
mov bx,0007h
int 10h
jmp zprava
zprava_konec:
ret

klavesa:        ;funkce na stisk klavesy
mov ah,00h
int 16h
ret

main:
cli
mov ax,9000h
mov ss,ax
mov sp,0xffff     ;nastaveni zasobniku
sti

mov [bootdev],dl  ;dl = zarizeni ze ktereho je bootovano

mov si,boot_msg   ;vypis boot zpravy
call zprava

mov si,klav_msg
call zprava
call klavesa
jmp 0xffff:0000h        ;restart

times 510-($-$) db 90h   ;sector musi byt dlouhy 512B

dw 0xaa55         ;oznaceni boot sectoru 

Program přeložíme do výstupního formátu: plain binary file a nahrajeme na disketu:

nasm -o boot_sector.asm -f bin boot_sector.bin
dd if=boot_sector.bin of=/dev/fd0 bs=512 

Pokud se budeme chtít podívat, jak soubor formátu plain binary vypadá po přeložení:

ndisasm -b 16 boot_sector.bin 

První direktiva programu (org 0×7c00) říká překladači, aby každému skoku na návěstí (call zprava), popřípadě adresaci proměnné (mov si,boot_msg) přičetl danou hodnotu, a to z důvodu umístění programu v paměti. Program se začne vykonávat prvním bytem souboru, a proto nesmí být začátek souboru datový, ale instrukční, bohatě však postačí, když nás jednoduše první instrukce přesune do těla programu ( main ) a hned potom následuje datová část. Hned na začátku těla programu nastavíme zásobník, abychom mohli volat funkce. Dále si uložíme hodnotu registru DL uchovávající driver, z nějž je bootováno. Zbytek je už na vaší fantazii. V celém programu můžeme užívat pouze funkce (přerušení) BIOSu, nikoliv DOSu, protože dos se vůbec nenahraje. Dále adresa ffff:0000h je adresou, kde začíná procesor po startu vykonávat první instrukci, proto nám k restartu stačí skočit na tuto adresu. Na konci zdrojového kódu musíme uvést direktivu, která nastaví soubor na délku 512 B a na konec přidá hodnotu ( AA55h ), která označuje boot sector.

Při bootu se z diskety nahraje pouze jeden sector dlouhý 512 B, což není nijak moc, ale bohatě stačí na program, který nahraje další sectory z diskety a spustí je.

Příklad takového boot sectoru:

;boot_sector2.asm

org 0x7c00

jmp main

;promene

boot_msg db 'Muj prvni OS...',13,10,0
load_msg db 'Zavadim jadro ...',13,10,0
bootdev db 0

zprava:
lodsb
or al,al
jz short zprava_konec
mov ah,0eh
mov bx,0007h
int 10h
jmp zprava
zprava_konec:
ret

reset_dev:      ;reset driveru
mov ah,00h
mov dl,[bootdev]
int 13h
ret

load_image:
mov ax,0h
mov es,ax
mov ah,02h
mov dl,[bootdev]
mov dh,0h
mov cx,2
mov al,1   ;pocet sectoru k nahrani
mov bx,8000h
int 13h

ret

main:
cli
mov ax,9000h
mov ss,ax
mov sp,0xffff
sti

mov [bootdev],dl

mov si,boot_msg
call zprava
mov si,load_msg
call zprava

call reset_dev
call load_image

jmp 0000:8000h ;skok do pameti k nahranemu programu

smycka:
jmp smycka

times 510-($-$) db 90h

dw 0xaa55 

Tento program nahraje druhý sector z diskety do paměti na adresu 0000:8000h a spustí jej. Můžeme dokonce nahrát více sectorů naráz, a to změnou hodnoty registru CX, ve funkci: load_image. Takže nahrávaný program nemusí mít pouze 512 B. Program může být libovolný, stejně jako u boot sectoru, musí být na začátku instrukce. Zásobník je již nastaven. A na konci kódu již nemusíme soubor zarovnávat na délku dělitelnou 512 B.

Ukázka:

; jadro.asm

org 8000h

jmp main

;promnene

wel_msg db 'Jadro nahrano.',13,10,0
end_msg db 'Stisknete jakoukoliv klavesu k restartu',13,10,0

zprava:
lodsb
or al,al
jz short zprava_konec
mov ah,0eh
mov bx,0007h
int 10h
jmp zprava
zprava_konec:
ret

klavesa:
mov ah,00h
int 16h
ret

main:

mov si,wel_msg
call zprava
mov si,end_msg
call zprava
call klavesa

jmp 0xffff:0000h 

Pokud máme tyto dva soubory, musíme je spojit v jeden image soubor, a to následovně:

; image.asm

incbin 'boot_sector.bin'
incbin 'jadro.bin' 

Boot sector a druhý program nahrajeme na disketu následovně:

nasm -o boot_sector.asm -f bin boot_sector.bin
    nasm -o jadro.asm -f bin jadro.bin
    nasm -o image.asm -f bin image.bin
    dd if=image.bin of=/dev/fd0 bs=512 
Našli jste v článku chybu?

20. 1. 2006 15:06

Ja vim :-), myslel jsem to tak, ze se z puvodniho colorForthu to (pro me) problemove rozlozeni klaves odstrani a ponecha se standardni QWERTY. Z toho puvodniho zdrojaku pro x86 je to docela lehce odstranitelne...

20. 1. 2006 9:01

O OS se nebudu vyjadrovat, ale k tomu assembleru: vzhledem k tomu, ze mezi assemblerem a vyssimi programovacimi jazyky (vcetne cecka) je dost velka semanticka mezera, tak je nekdy pouziti assembleru nevyhnutelne. Samozrejme to neznamena psat cele aplikace v assembleru (pokud to neni pro zabavu), ale nektere kriticke casti ano. A to nemluvim o jinych platformach, treba dneska popularnich PICech, rade 8051, 68HC11 atd. K nim sice existuji i ceckovske nebo skoroceckovske prekladace, ale pri vetsim …
Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: Nejenom EET, začaly platit další zákony

Nejenom EET, začaly platit další zákony

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

DigiZone.cz: Flix TV má set-top box s HEVC

Flix TV má set-top box s HEVC

Vitalia.cz: Manželka je bio, ale na sex moc není

Manželka je bio, ale na sex moc není

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Vitalia.cz: Co pomáhá dítěti při zácpě?

Co pomáhá dítěti při zácpě?

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Lupa.cz: UX přestává pro firmy být magie

UX přestává pro firmy být magie