Menu

Budowa systemu

Budowa komputera

Przykładowe systemy

Programowanie

Linki



Współpraca z GRUB

GNU GRUB (GRand Unified Bootloader) jest prawdopodobnie najpopularniejszym obecnie bootloaderem. Jest używany zarówno z systemami uniksopodobnymi (FreeBSD, Linux), jak również do uruchamiania hobbystycznych systemów operacyjnych. Wymaga on jednak wprowadzenia pewnych modyfikacji do jądra systemu, co postaram się przedstawić w tym artykule.

Modyfikacje te wprowadzają zgodność jądra systemowego ze standardem Multiboot, opracowanym przez zespół zajmujący się tworzeniem GRUB'a. Określa on format obrazu jądra systemowego, umożliwiający załadowanie go przez bootloader. Multiboot dostarcza także cennych informacji na temat stanu komputera, w jakim znajduje się on po wczytaniu kernela do pamięci. Więcej informacji na ten temat pod adresem [1].

Aby zapewnić zgodność systemu ze standardem Multiboot, kernel powinien zawierać specjalny obszar zwany Multiboot Header (nagłówek Multiboot). W przypadku jądra zapisanego w formacie ELF (format ten polecam, innymi nie będę się zajmował z powodu utrudnień z nimi związanych) przedstawia się on następująco:

Offset Typ Nazwa
0 u32 magic
4 u32 flags
8 u32 checksum

Można to zapisać w składni assemblera NASM w postaci:

align 4

multiboot_header:
    ;magic
        dd 0x1BADB002
    ;flags
        dd 3
    ;checksum
        dd 0x0E4524FFB

Wartość pola magic jest ściśle ustalona i wynosi 0x1BADB002. Na jej podstawie bootloader wykrywa, że jest to system zgodny z Multiboot. W polu flags ustalone są parametry ładowania jądra systemu. Znaczenie bitów pola flags:

bit 0 ustawiony:
- ładuj system i wszystkie jego moduły na granicy stron, przydaje się, kiedy system używa stronnicowania
bit 1 ustawiony:
- dostarcz informacje na temat dostępnej pamięci operacyjnej przez Multiboot Information Structure
bit 2 ustawiony:
- dostarcz informacje na temat dostępnych trybów wideo (tekstowych i graficznych)
bit 16 ustawiony:
- używany z formatami innymi niż ELF, oznacza użycie rozszerzonego Multiboot Header zawierającego dodatkowe informacje na temat systemu

Na początek polecam wartość 3 dla pola flags. Pole checksum musi zawierać taką wartość, aby po dodaniu do niej wartości pola flags oraz pola magic wynikiem było zero.

Nagłówek Multiboot musi znajdować się w pierwszych 8 kilobajtach jądra systemu i znajdować się pod offsetem podzielnym przez 4, co zapewnione jest użyciem słowa kluczowego align 4.

Taki kod źródłowy (zawierający tylko dane) należy uzupełnić o kod wykonywalny. Trzeba dodać funkcję od której wykonanie ma się zacząć oraz kod wywołujący właściwy kod jądra systemu. Nie można  także zapomnieć o wyeksportowaniu danej funkcji:

global _kpreboot ;Wyeksportowanie funkcji _kpreboot
extern kmain ;Funkcja kmain nie znajduje się w tym pliku

_kpreboot:
       jmp exec_kmain

[...kod definiujacy naglowek Multiboot]

exec_kmain:
        call kmain

Gotowy program należy zassemblować i zlinkować z kernelem, pamiętając o zmianie procedury początkowej systemu(entry point) na _kpreboot. Otrzymany obraz jądra systemu można ładować za pomocą bootloadera GRUB, ze stacji dyskietek lub dysku twardego.

Kompletny kod źródłowy:

multiboot.asm - Do zlinkowania z kernelem

Stan komputera przygotowany przez GRUB

GRUB przed załadowaniem i wykonaniem jądra systemu przygotowuje w miarę pewne środowisko. Należy do niego:

1. Odblokowanie linii adresowej A20 (zdjęcie ograniczenia adresowania do 20 bitów)
2. Przejście do trybu chronionego procesora
3. Ustawienie odpowiednich początkowych deskryptorów pamięci
4. Zablokowanie przerwań
5. Dostarczenie systemowi specjalnej struktury Multiboot Information Structure

Dokumentacja

 [1] Dokumentacja standardu Multiboot 



Valid XHTML 1.1 License Poprawny CSS!
© 2007 by Tomek Figa na licencji Creative Commons Uznanie autorstwa-Użycie niekomercyjne 2.5 Polska.