Rozruch i komunikacja

https://chacker.pl/

Aby uruchomić jądro, użyjemy GRUB, aby uniknąć kłopotów z pisaniem własnego bootloadera. Zazwyczaj hypervisory obsługują rozruch BIOS-u i/lub UEFI. Na szczęście narzędzie grub-mkrescue4 pozwala nam wygenerować nośnik ISO do rozruchu z obu. Nasz obraz jądra będzie plikiem ELF z nagłówkiem Multiboot25 umieszczonym na początku sekcji kodu. Gdy GRUB uruchamia obraz, środowisko, w którym nas pozostawia, to 32-bitowy tryb chroniony; chcemy używać wszystkich dostępnych funkcji procesora, więc musimy przełączyć się na tryb długi. Zacznijmy naszą implementację od kodu bootstrap, który emituje nagłówek Multiboot2, a następnie przełącza się na tryb długi:

Sekcja .text zaczyna się od dyrektyw, aby wyemitować minimalny nagłówek Multiboot2 (1). W punkcie wejścia (2) ustawiany jest stos 8 KB i tworzone jest mapowanie 1:1 pierwszych 4 GB pamięci (3). Kolejne kroki obejmują ustawienie flagi Long Mode Enable w rejestrze EFER (4), załadowanie 64-bitowego GDT (5), włączenie stronicowania (6) i przejście do trybu długiego (7). Kod kończy się wywołaniem niezaimplementowanej jeszcze funkcji kmain. Do komunikacji między naszym jądrem a światem zewnętrznym możemy użyć prostego i powszechnie dostępnego urządzenia: portu szeregowego. Większość hiperwizorów implementuje emulację portu szeregowego i zwykle pozwalają one na przekazywanie jej do mechanizmów IPC w hoście, takich jak gniazda lub potoki. Weźmy się do roboty i dodajmy podstawową obsługę portu szeregowego do naszego jądra:

Najpierw piszemy parę wrapperów dla OUTB (1) i INB (2), potrzebnych reszcie kodu. Funkcji setup_serial (3) można użyć do zainicjowania portu szeregowego przy typowej prędkości transmisji 115200 bodów. Implementujemy write_serial (4), aby przesłać strumień danych z pamięci, i implementujemy read_serial (5), aby go odebrać. Nasza implementacja ma pewne braki, takie jak spinwait na gotowość portu szeregowego, ale zachowajmy prostotę. Teraz możemy zaimplementować kmain, aby przetestować nasze jądro:

Po zbudowaniu jądra przeprowadzimy testy w QEMU/KVM. Jeśli wszystko pójdzie dobrze, powinniśmy zobaczyć komunikat „Hello world!”:

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *