Wi­tam ponownie
Pró­buję zro­bić bo­o­t­lo­a­der i za­trzy­ma­łem się na kolejnym pro­b­le­mie.

Tworzę tablice translacji (mapowania) stron pamięci wirtualnej w 4-poziomowej hierarchii:

4-lvl-pg.png
4-lvl-pg.png

Odsyłacz do kodu C: https://github.com/overcq/boot/blob/main/fileloader.c#L292

Najpierw w kodzie asemblera tworzę tablice dla pamieci konwencjonalnej (pierwsze niecałe 640 KiB) umieszczone w tekście programu. Następnie w kodzie C tworzę tablice dla 64 MiB początkowej pamięci umieszczone w pobliżu wierzchołka pamięci konwencjonalnej. Następnie tworzę tablice dla 16 GiB początkowej pamięci umieszczone w pamięci rozszerzonej (od drugiego mibibajta pamięci).
Każdorazowo po utworzeniu tablic wpisuję adres tablicy 4. poziomu do rejestru cr3 i wtedy testuję zapis i odczyt na początku każdego mibibajta alokowanej pamięci.

I podczas alokacji tablic dla 16 GiB początkowej pamięci pojawiły się następujące problemy:

  1. Jeśli alokuję tablice od adresu 0x100000 (czyli drugiego mibibajta, początku pamięci rozszerzonej), to nie mogę przypisać wartości w tablicach dla niektórych zakresów adresów, jak widoczne w kodzie (wyjątki if, gdy zadeklarowano DEBUG), ponieważ pojawia się wyjątek.
  2. Jeśli alokuję tablice od adresu 0x200000 (czyli trzeciego mibibajta, 1 MiB po początku pamięci rozszerzonej), to nie mogę mieć ustawionej wartości dla zakresu większego niż 505 MiB, jak widoczne w kodzie (wyjątki if, gdy zadeklarowano DEBUG_2), ponieważ podczas wpisywania do rejestru cr3 (ustawiania translacji przy pomocy nowo utworzonych tablic) pojawia się wyjątek.
    W tym drugim przypadku wiem, że formalnie bity adresu w tablicy powyżej rozmiaru posiadanej pamięci rzeczywistej są zarezerwowane (powinny być 0), ale przecież nie żądam nigdy dostępu do tych obszarów pamięci.

Co może uniemożliwiać przypisanie do pewnych obszarów pamięci pomiędzy 2 a 3 mibibajtem (adresy 0x100000 do 0x200000) w pierwszym przypadku?
Co może powodować, że niemożliwe jest ustawienie translacji, gdy jest mapowanie powyżej pewnego adresu w drugim przypadku?
Jak w takim razie poznać rozmiar dostępnej w systemie pamięci rzeczywistej?
A może w kodzie jest gdzieś błąd?

Zaalokowałem tablice od adresu 0x300000 (czyli czwartego mibibajta) i działa, ale pytania nadal aktualne.