Pierwsze kroki

Jak na razie dla wygody nasz system będziemy umieszczać na dyskietce. W końcu jak na razie pewnie nikt nie chce sobie zepsuć boot sektora, który jest na dysku twardym :P. A na początku póki nie opisze systemu plików (o tym będzie osobny art), zepsujemy cały system plików, który jest na dyskietce, albo inaczej „stworzymy własny system plików” – tak ładniej brzmi :]
Zanim zaczniemy pisać nasz pierwszy system operacyjny, musimy napisać boot loadera, który nam to jądro załaduje. No to zaczynamy:

Co to w ogóle jest boot loader?

Boot loader jest to mały program który ma za zadanie załadować i uruchomić system operacyjny.
Bios ładuje do ramu tak zwany boot sektor (inaczej MBR – Master Boot Record), czyli pierwszy sektor pod zerową głowicą i na zerowej ścieżce pierwszego ustawionego urządzenia bootującego, pod warunkiem, że znajduje się tam boot loader. Boot loader musi zajmować dokładnie 512 bajtów (czyli tyle ile jeden segment w trybie rzeczywistym) a dwa ostatnie bajty musza mieć wartość AA55h. Jeżeli nie ustawimy takiej ostatniej wartości to Bios uzna, że nie ma boot loadera. Jeżeli jednak wszystko pójdzie dobrze to w pamięci pod adresem 0000:7C00H będzie boot loader. Gdy bios oddaje kontrolę boot loaderowi wszystkie rejestry segmentowe są wyzerowane, a DL zawiera numer dysku, z którego pochodzi boot sektor (0 to dyskietka, 80h – pierwszy dysk twardy).

A oto przykład najprostszego boot loadera:
Boot.asm:

A teraz kompilujemy:

nasm boot.asm -o boot.bin

Teraz programem RawWrite kopiujemy nasz plik boot.bin na dyskietkę(traktujemy go jako obraz). No i uruchamiamy emulator i widzimy czarny ekran :] Czyli wszystko się udało, nasz pierwszy boot loader został załadowany bez żadnych błędów.

Wcześniej wspomniałem o „własnym formacie plików”, jest on bardzo prosty – w pierwszy sektorze będzie znajdował się boot loader a zaraz w drugim początek naszego kernela. Czyli teraz rozbudujemy boot loadera o to ze będzie wczytywał do pamięci drugi sektor i przekazywał mu kontrole. Do czytania użyjemy przerwania biosu 13h.

Kod na wczytanie drugiego sektora z dyskietki pod adres 0800h:

Aby teraz boot loader uruchomił to, co załadował do pamięci (czyli coś, co nazywamy kernelem) musimy wykonać skok do tego miejsca, czyli krótko i na temat:

I to już cały boot loader. A oto cały kod:

Aby sprawdzić czy nasz boot loader działa musimy jeszcze napisać jakiegoś przykładowego kernela. A oto on:

Kernel.asm:

Dobra, mamy boot loader i kernela, pozostaje tylko jedno pytanie jak skopiować na dyskietkę boot loadera do pierwszego sektora a kernela do drugiego?
Teraz napiszemy sobie w delphi prosty program, który połączy nam te dwa pliki w jeden (krótko mówiąc zrobimy sobie obraz dyskietki). Cały czas kompilujemy z linii poleceń, więc dla wygody napiszemy sobie tez taki programik, nie będziemy się tu bawić komponentami VCL, bo w tym przypadku to strata czasu.

A teraz kompilujemy całość:

nasm boot.asm -o boot.bin
nasm kernel.asm -o kernel.bin
zlacz boot.bin kernel.bin image.img

I teraz RawWritem nagrywamy plik image.img. Odpalamy emulator i widzimy naszego pierwszego kernela :]

Autor: Michał Ślaga (Blind)