Pamięć Wirtualna - Wstęp


Spis treści


Pamięć wirtualna - wprowadzenie

Na początku warto powiedzieć do czego potrzebna jest pamięć wirtualna. Być może jest ona niepotrzebna - w końcu istnieje wiele systemów operacyjnych, które nie używają pamięci wirtualnej, a mimo to działają prawidłowo. Na przykład MS-DOS nie wspiera pamięci wirtualnej, a jednak wciąż jest systemem mającym pewną pozycję na rynku.

Odwiecznym problemem dla informatyków zawsze były ograniczenia ilości dostępnej pamięci fizycznej. W ciągu wielu lat zostało wymyślonych wiele technik pozwalających na ominięcie problemu braku wymaganej ilości pamięci w różnych sytuacjach. Jednym z mechanizmów był tzw. "overlay", kiedy to program był dzielony na ukryte fragmenty, z których tylko jeden w danym momencie rezydował w pamięci. Za każdym razem kiedy inny fragment był wymagany, odczytywało się go i wpisywało do pamięci nadpisując wcześniejszą jej zawartość.

Mechanizmy pamięci wirtualnej posunęły ten trik o krok do przodu. Dzielą one całą pamięć na zbiór stron. Dzięki temu zamiast jednego nadpisywalnego rejonu, pamięć została podzielona na wiele takich nadpisywalnych części. Początkowo za cały proces wymiany pamięci był odpowiedzialny programista. Z czasem odpowiedzialność została zrzucona na system operacyjny i częściowo sprzętowe mechanizmy wspomagające zarządzanie pamięcią.

W trakcie ewolucji pamięci wirtualnej do postaci w jakiej ją teraz znamy, została dodana jeszcze jedna własność - pojęcie i implementacja przestrzeni adresowej. Niektóre systemy miały bardzo ograniczone możliwości adresownania. Na przykład szacowny PDP-11 posiadał 16-bitową przestrzeń adresową, co pozwalało mu zaadresować 64KB. Niektóre wersje PDP-11 podwajały tą przestrzeń przez rozróżnienie kodu programu od danych - dzięki temu przestrzeń adresowa zwiększała się do 128KB. Wciąż jednak aplikacje nie mogły być większe niż 64KB.

Ten problem został rozwiązany przez użycie standardowego triku programistycznego, a mianowicie dodania poziomu pośredniego adresowania, dzięki czemu system operacyjny mógł uporać się z wieloma różnymi przestrzeniami adresowymi. Oczywiście tylko jedna mogła być aktywna w danym czasie. Wykorzystywanie różnych przestrzeni adresowych miało jeszcze jedną zaletę - pamięć należąca do jednej z nich nie mogła byćmodyfikowana przez inną przestrzeń adresową. Na PDP-11 fizyczna przestrzeń adesowa systemu była znacznie większa niż wirtualna przestrzeń adresowa, więc możliwe było jednoczesne przebywanie wielu procesów w pamięci fizycznej jednocześnie.

Ostatnim problemem wywierającym głęboki wpływ na wygląd współczesnej pamięci wirtualnej był niedobór pamięci fizycznej zastępowanej przez wzrastające wykorzystanie tańszego, ale mniej wydajnego magazynowania danych. W celu zasymulowania systemu koputerowego z większą niż fizyczna ilością pamięci, dane mogły być kopiowane z pamięci na dysk i przywracane z dysku z powrotem do pamięci, w zależności od zapotrzebowania systemu.

Digital Equipment Corporation stworzyła zupełnie nową architekturę systemu wokół tych nowych koncepcji pamięci wirtualnej - The Virtual Address Extension System (VAX) został stworzony aby wspierać bardzo duże przestrzenie adresowe. Ten nowy system umożliwiał pojedynczej przestrzeni adresowej zawierać do 4GB pamięci wirtualnej. Niektóre systemy, jak Windows NT wciąż bazują na nieco zmienionej koncepcji pamięci zaproponowanej w VAX.

Współczesne implementacje VM (Virtual Memory) mają jeszcze inne cele do zralizowania, o których nie myśleli twórcy oryginalnego VAX-a. Odkąd systemy operacyjne stały się przenośne, architektura pamięci wirtualnej nie mogła się opierać na specyficznych właściwościach konkretnego sprzętu. Oczywiście znaczna część zarządzania VM spada na CPU. Na przykład procesory Intel posiadają wbudowaną jednostkę MMU (Memory Management Unit), która wspomaga segmentacyjny i stronicowy model pamięci. Digital AXP CPU ma wsparcie dla bardzo dużej (264 bajtów) wirtualnej przestrzeni adresowej. Warto zaznaczyć, że mimo tego adres fizyczny jest ograniczony do 48-bitowego. Nowoczesne systemy operacyjne muszą sobie wydajnie radzić z zarządzaniem pamięcią zarówno w sytuacjach, gdy posiadają dodatkowe wsparcie sprzętowe, jak i całkowicie niezależnie od platformy sprzętowej.

W tym momencie warto sobie odpowiedziećna pytanie: "Po co w ogóle wspierać pamięć wirtualną?". Wygląda na to, że jej implementacja jest dość skomplikowana - i tak jest w rzeczywistości, ale korzyści które otrzymujemy znacznie przewyższają jej wady:

Współczesne systemy operacyjne wspierają wszystkie wymienione funkcje i jeszcze więcej. Teraz możemy się zastanowić jak działa pamięć wirtualna?

Nowoczesne CPU wspierają zarządzanie pamięcią wirtualnąna poziomie sprzętowym. Również systemy operacyjne są projektowane tak, aby to sprzętowe wsparie wykorzystać w jak największym / najlepszym stopniu. Właściwie mimo teoretycznej możliwości zbudowania CPU bez wsparcia dla VM - uczyniłoby to go tak wolnym, że niezdatnym do użycia.

Za każdym razem kiedy CPU pracuje w trybie pamięci wirtualnej, adresy które otrzymuje CPU są adresami wirtualnymi, które są tłumaczone na adresy fizyczne. Mechanizm tłumaczenia adresu wirtualnego na rzeczywisty zależy w głównej mierze od architektury CPU. Na przykład na procesorze Intel Pentium Pro proces tłumaczenia adresu może być całkiem skomplikowany, ponieważ procesor ten wspiera pięć możliwych schematów adresowania.

Podstawy

Ten dokument opisuje mechanizmy sprzętowe wspomagające obsługę pamięci w procesorach Intel, (na podstawie starszych modeli, ale sam proces niewiele się zmienił, co najwyżej został rozszerzony). Niezależnie od systemu operacyjnego architektura x86 wspomaga sprzętowo proces zarządzania pamięcią. Poniżej znajduje się opis zarówno sprzętowego mechanizmu, jak i algorytmu tłumaczenia adresu wirtualnego na adres fizyczny.

Realizacja pamięci wirtualnej (logicznej) o wielkości większej niż rozmiar faktycznie zainstalowanej pamięci operacyjnej (czyli przypadek najbardziej interesujący) polega na uzupełnieniu pamięci operacyjnej przez pomocniczą pamięć masową (na ogół dysk) i na odpowiednim zarządzaniu przesyłaniem danych między tymi pamięciami. Pamięć dyskowa służy do przechowywania obrazów tych fragmentów pamięci (logicznej), które aktualnie nie mieszczą się w pamięci fizycznej. Niezbędne w trakcie wykonywania programu fragmenty (kod, dane) są odczytywane z dysku i umieszczane w pamięci operacyjnej (swap-in), z kolei niektóre fragmenty sposród obecnych w pamięci muszą być przenoszone na dysk w celu uzyskania wolnego miejsca (swap-out).

Zarządzaniem pamiecią wirtualną zajmuje się system operacyjny korzystając z mechanizmów wbudowanych w mikroprocesor - odbywa się to bez udziału programu (programisty tworzącego programy uzytkowe). Realizacja pamięci wirtualnej w systemach z mikroprocesorami 80286, 80386 i i486 jest ściśle związana z segmentacją i stronicowaniem - fragmenty pamięci wymieniane między pamięcią operacyjną a pamiecią pomocniczą odpowiadają bowiem segmentom lub stronom.

Tu należy wspomnieć o bitach związanych z implementacją pamięci wirtualnej, które występują w deskryptorze segmentów oraz w elementach katalogu tablic i elementach tablic stron. W przypadku deskryptorów segmentów są to: bit obecności P (Present) i bit A (Accessed) oznaczający segment użyty, zaś w odniesieniu do atrybutów elementów tablic związanych ze stronicowaniem - bity P (Present), A (Accessed) i bit zmiany D (Dirty).

W mikroprocesorze 80286 pamięć wirtualna może być zrealizowana jedynie z zastosowaniem segmentacji. Podczas ładowania selektora do rejestru segmentu procesor automatycznie odwołuje się do odpowiedniego deskryptora i sprawdza wartość bitu obecnosci P. Jeżeli P=1, po sprawdzeniu praw dostępu deskryptor jest umieszczany w ukrytym rejestrze deskryptora stowarzyszonym z rejestrem segmentu. Wartość P=0 oznacza, że segment opisywany przez deskryptor nie jest dostępny w pamięci operacyjnej i w takiej sytuacji procesor generuje wyjątek (exception). Procedura obsługi wyjątku związanego z nieobecnością segmentu w pamięci stanowi fragment systemu operacyjnego i jej zadaniem jest znalezienie miejsca w pamięci na brakujący segment, odczytanie segmentu z dysku, uaktualnienie deskryptora - tzn. wpisanie właściwych wartości adresu bazowego i ewentualnie wielkości oraz ustawienie bitu P. Po zakończeniu obsługi wyjątku następuje ponowne wykonanie instrukcji, która wyjątek spowodowała. Podczas tego ponownego wykonania nie nastąpi już zgłoszenie wyjątku braku segmentu.

Istotnym elementem implementacji pamięci wirtualnej, wpływającym na efektywność działania systemu, jest strategia usuwania segmentów z pamięci operacyjnej w celu uzyskania miejsca do wprowadzenia brakujących segmentów. Często stosowana jest strategia usuwania tych części pamięci, które były najdawniej używane (LRU - Least Recently Used). Strategia taka jest uzasadniona, gdyż ze względu na lokalność odwołań do pamięci w programie zakłada się, że w najbliższej przyszłości nie będzie również do nich odwołań. Inna stosowana strategia polega na usuwaniu z pamięci segmentów najrzadziej używanych (LFU - Least Frequently Used), przy czym w pierwszym rzędzie usuwa się segmenty nie modyfikowane, gdyż nie jest wówczas konieczne zapisywanie obrazów pamięci na dysku. Najprostszą strategią jest usuwanie tych segmentów, które zostały do pamięci załadowane jako pierwsze (FIFO - First In First Out). W celu zaimplementowania w systemie operacyjnym wybranej strategii usuwania segmentów można skorzystać z bitu A w deskryptorze segmentu. Bit ten jest ustawiany przez procesor zawsze przy ładowaniu selektora do rejestru segmentu i deskryptora do rejestru deskryptora (a nie przy odwołaniu do segmentu w operacji odczytu lub zapisu jak mogłaby sugerować nazwa bitu - Accessed). Bit A nie jest natomiast nigdy zerowany automatycznie przez procesor. System operacyjny może zbierać informacje o częstotliwości korzystania z poszczególnych segmentów przez systematyczne przeglądanie bitów A deskryptorów w tablicach GDT i LDT i jednoczesne zerowanie ustawionych bitów A. O podobnych strategiach możemy mówić w odniesieniu do mechanizmu stronicowania, z drobnymi różnicami wynikającymi z bezpośrednich różnic oby tych metod wirtualnych.

Realizacja pamięci wirtualnej w oparciu o mechanizm segmentacji może być stosowana w systemach z mikroprocesorem 80286 jak i 80386 (i486). W tym rozwiązaniu pojawiają się jednak problemy związane z faktem, że segmenty mają niejednakową długość. Często wprowadzenie nowego segmentu do pamięci operacyjnej wymaga usunięcia kilku mniejszych segmentów. Wielokrotne wykonanie operacji wymiany obrazów pamięci z dyskiem prowadzi do znacznego stopnia fragmentacji pamięci tzn. pojawia się wiele małych obszarów pamięci nie używanej (czasem stosuje się przesuwanie segmentów w celu uzyskania dużego spójnego obszaru wolnego). Ze względu na niejednakową długość segmentów również część oprogramowania systemowego związanego bezpośrednio z obsługą pomocniczej pamięci dyskowej jest znacznie bardziej rozbudowana. Pewną zaletą, jednak nie rekompensującą wymienionych wad, jest silny związek podziału na segmenty z logiczną strukturą programu, co na ogół zmniejsza liczbę koniecznych przesłań w porównaniu z przedstawioną niżej metodą korzystającą ze stronicowania.

W mikroprocesorach 80386 i i486 wbudowano mechanizmy umożliwiające efektywną realizację pamięci wirtualnej w oparciu o stronicowanie. Podobnie jak w przypadku segmentów, również i tu najwazniejszą rolę odgrywa bit opecności P w elementach katalogu tablic stron i samych tablic stron. W sytuacji, gdy następuje odwołanie do strony, dla której w odpowiednim elemencie tablicy stron bit P=0, mikroprocesor zgłasza wyjątek braku strony. Reakcja programu obsługi polega na przygotowaniu wolnego miejsca (strony) w pamięci operacyjnej, wprowadzeniu pożądanej strony i uaktualnieniu opisu strony w tablicy stron. Strategia wymiany stron może korzystać z bitu A, który jest ustawiany przez procesor w następujących okolicznościach: w elemencie tablicy stron - gdy następuje odwołanie do strony opisywanej przez ten element, w katalogu tablic stron - gdy następuje odwołanie do którejkolwiek ze stron opisanych w tablicy stron wskazywanej przez ten element katalogu. Bit ten nie jest nigdy samoczynnie zerowany przez procesor. Dodatkowe ułatwienie dla oprogramowania systemowego stanowi bit D. Jest on ustawiany przez procesor (jedynie w elementach tablicy stron), gdy odbywa się zapis do odwzorowywanej przez element strony. Na podstawie wartości tego bitu system operacyjny może określić, czy podczas usuwania z pamięci danej strony jest konieczne jej zapisanie na dysku, gdyż w trakcie jej obecności w pamięci nastąpiły zmiany, czy że obraz przechowywany na dysku jest właściwy, ponieważ nie było operacji zapisu na danej stronie. Przy realizacji pamięci wirtualnej w oparciu o stronicowanie unika się fragmentacji (wszystkie bloki mają jednakową długość). Upraszcza to również program obsługi pomocniczej pamięci dyskowej. W systemach z mikroprocesorem 80386 i i486 wskazana jest implementacja pamięci wirtualnej w oparciu o stronicowanie, zaś innych mechanizmów systemowych - z wykorzystaniem segmentacji lub łącznie: segmentacji i stronicowania.

Za pomoca 32 bitów można zaadresować 4GB pamięci (przy założeniu że strona ma rozmiar 4KB). Niedawno, w procesorach Intel Pentium Pro i lepszych, wprowadzono rozszerzenie zwane PAE (Phisical Address Extension), które pozwala na zaadresowanie na tych procesorach 64GB pamięci RAM za pomocą adresowania 36-bitowego. Jednak aby realizacja tego mechanizmu była skuteczna w 32-bitowych systemach operacyjnych (które go obsługują) posiadają one spacjalne mechanizmy umożliwiające jego używanie. Dla takich procesorów zmienił się również mechanizm stronicowania. Dla tych procesorów używa się trójpoziomowego stronicowania. Strona nadal ma 4KB, a tablice i katalogi stron zajmują jedną stronę. Długość pozycji w katalogach i tablicach stron wzrosła do 64 bitów (2 razy więcej niż przy adresowaniu 4GB). Trójpoziomowe stronicowanie zostało wprowadzone ponieważ każdy katalog i tablica stron powinny mieścić się na jednej stronie. Rozszerzenie to dotyczy tylko adresów fizycznych, adres liniowy wciąż jest 32 bitowy, przez co tylko 4GB pamięci mogą być ,,stale odwzorowane'' przez jądro. Dodatkowo - możliwe jest uzywanie bloków stronicowych w wielkości 2MB.


Architektura procesora x86

Mikroprocesor 80386 posiada wszystkie rejestry mikroprocesora 8086 oraz kilka dodatkowych. Wszystkie rejestry z wyjątkiem segmentowych są 32-bitowe.

Wyróżniamy więc 8 rejestrów ogólnego przeznaczenia:

Poza ogólnym zastosowaniem rejestry te pełnią szczególne funkcje podczas wykonywania pewnych rozkazów znane z 8086. Do 32-bitowych rejestrów zaliczamy jeszcze licznik rozkazów EIP i rejest flagowy EFLAGS. Młodsze słowo (bity 15..0) każdego z powyższych rejestrów to znane z procesora 8086 rejestry 16-bitowe: AX, BX, CX, DX, SI, DI, BP, SP oraz IP i FLAGS.

Oprócz czterech rejestrów segmentowych znanych z 8086: CS, DS, ES i SS mikroprocesor 80386 ma dodatkowe dwa rejestry segmentowe: FS i GS. Rejestry segmentowe są nadal 16-bitowe!

Dodatkowe rejestry mikroprocesora 80386:

Adresowanie pamięci.

Popatrzmy na ponizszy rysunek:

pic_i386_translating

Teraz trochę wyjaśnień:

Segmentacja i stronicowanie funkconują niezależnie od siebie.


Segmentacja

Przypomnijmy, że w trybie rzeczywistym zawartość rejestru segmentowego to tzw. adres segmentowy, czyli adres początku segmentu podzielony przez 16. Oznacza to, ze adres początku segmentu musi być liczbą podzielną przez 16. W trybie adresowania wirtualnego jest zupełnie inaczej.

Deskryptor segmentu pamięci

Jest to struktura danych zajmująca w pamięci 8 bajtów, opisująca własności segmentu pamięci. Na razie, nie wdając się w szczegóły, zauważmy, że składa się ona z trzech części:

32-bitowy adres bazowy oznacza, że początek segmentu może być ustalony z dokładnością do jednego bajtu (przy założeniu 4GB ograniczenia przestrzeni wirtualnej).

20-bitowa wielkość wcale nie oznacza, że maksymalna wielkość segmentu wynosi 220 bajtów = 1 MB. Dla segmentu powyżej 1 MB wielkość podawana jest w jednostkach 4-kilobajtowych co pozwala uzyskać wielkość segmentu do 4 GB.

Deskryptory umieszczone są w pamięci kolejno tworząc tablice deskryptorów. Selektor to wskaźnik do tej tablicy czyli numer deskryptora. Deskryptory numerowane są od zera. Zerowy deskryptor jest zarezerwowany. Podczas odwoływania się do pamięci selektor pobierany jest z rejestru segmentowego a przemieszczenie wyliczane zależnie od trybu adresownia, np. może być w rejestrze wskaźnikowym ESI.

Popatrzmy teraz jak procesor wylicza adrees liniowy:

pic_i386_segmentation

Algorytm tłumaczenia adresu logicznego na liniowy:

Kiedy proces odwołuje się do pamięci z odpowiedniego rejestru segmentowego (CS, SS, DS, ED, FS, GS) pobierany jest selektor segmentu (patrz niżej). Na jego podstawie odnajdowany jest odpowiadający mu deskryptor: wartość w polu TI określa tablicę, numer deskryptora jest indeksem w tej tablicy, a wartość RPL musi być mniejsza lub równa od numeru uprawnienia wskazywanego przez selektor (wpp. generowane jest przerwanie wewnętrzne). Z deskryptora pobierany jest adres bazowy i dodawany do przesunięcia - w ten sposób wyliczony zostasje adres liniowy.

Jednostka segmentacji korzysta ze specjalnych struktur danych. Są to:

Adres GDT jest przechowywany w specjalnym rejestrze procesora (GDTR). Adresy LDT są przechowywane jako deskryptory w tablicy GDT.

Pytanie: Do czego służy w deskryptorze segmentu "wielkość" - przecież nie bierze udziału podczas wyliczania adresu liniowego?
Odpowiedź: Służy do kontroli, czy przemieszczenie wskazuje adres wewnątrz segmentu a tym samym ochrony zawartości pamięci spoza segmentu przed niewłaściwym dostępem. Stąd ten tryb pracy procesora nosi nazwe: wirtualny z ochroną (Virtual Protected Mode).

Deskryptor jest ośmiobajtowym rekordem umieszczonym w tablicy GDT lub LDT. Popatrzmy teraz na szczegółową budowę deskryptora segmentu pamieci:

15                             0
LIMIT (0-15)
31                             16
BASE (0-15)
47 46 45 44 43     40 39             32
P DPL S TYPE BASE (16-23)
63             56 55 54 53 52 51     48
BASE (24-31) G B/D O AVL LIMIT (16-19)
Adres bazowy jest .

Trzy bity typu segmentu oznaczają:

Można stwierdzić, że najstarszy z tych trzech bitów rozróznia czy segment zawiera dane (0) czy kod programu (1).
Najmłodszy dla segmentu danych zezwala na zapis a dla segmentu kodu zezwala na odczyt. Wartość 0 tego bitu oznacza, że z segmentu danych można tylko czytać a program w segmencie kodu można tylko wykonywać (czyli pobierać z takiego segmentu tylko do licznika rozkazów EIP).

Selektor

Do odnajdywania odpowiednich deskryptorów segmentu służy 16-bitowy selektor segmentu. Składa się on z:

15                       3 2 1 0
numer deskryptora TI RPL

Stronicowanie

Adres liniowy, katalogi stron i tablice stron

Stronicowanie jest całkowicie niezależne od segmentacji. Oznacza to, że adresy tablic deskryptorów dotyczą liniowej przestrzeni adresowej. Zarówno liniowa jak i fizyczna przestrzeń adresowa obejmuje obszar 4 GB. Stronicowanie polega na podzieleniu obu tych przestrzeni na bloki (strony) po 4 KB każdy. 32-bitowy adres liniowy można więc podzielić na dwie części: bity 31..12 (20 bitów) stanowią numer strony, bity 11..0 (12 bitów) określają położenie wewnątrz strony. 20 bitów numeru strony oznacza, że cała przestrzeń adresowa zawiera 220 stron = 1 M stron.

Mechanizm stronicowania korzysta z tablic rozmieszczenia stron. Można sobie wyobrazić jedną tablicę 220 elementowa, w której poszczególne elementy będą numerami stron pamięci fizycznej. Na jedną pozycję tablicy przeznaczono 32 bity ze względu na łatwość dostępu do pamieci (20 bitów to numer strony a pozostałe 12 jest wykorzystane do innych celów bądź zarezerwowane). Taka tablica wymagałaby 4 MB ciągłego obszaru pamięci fizycznej.

Niedogodność tą rozwiązano tak, że wprowadzono dwa rodzaje tablic: tablice stron i katalogi tablic stron. Wyliczanie adresu fizycznego następuje zatem dwustopniowo, a adres liniowy ma postać:

31                 22 21                 12 11                     0
numer tablicy stron numer strony przesunięcie

Jako że każda z tablic zawiera 210 elementów a każdy element to 4 bajty, więc każda z tablic a także katalog tablic ma wielkość 4 kB czyli dokładnie zajmuje jedną stronę pamięci fizycznej.

UWAGA: numer strony (fizyczny) zawierającej katalog stron zapisany jest w rejestrze kontrolnym CR3. Oto jego format:

31                                     12 11 10 9 8 7 6 5 4 3 2 1 0
numer strony zawierającej katalog 0 0 0 0 0 0 0 PCD PWT 0 0 0

Każda pozycja w katalogu ston i tablicy stron ma rozmiar 32 bitów. Format elementu katalogu i tablic stron:

15     12 11   9 8 7 6 5 4 3 2 1 0
adres bazowy (0-3) AVL   PS D A PCD PWT US RW P
31                             16
adres bazowy (4-19)

UWAGA:
Znaczniki A i D są automatycznie ustawiane (na 1) przez mikroprocesor. Ich wyczyszczenie (na 0) musi być przeprowadzone przez system operacyjny.
Kiedy bit P jest wyczyszczony, czyli strona nie jest w pamięci, wartości pozostałych bitów są z punktu wiedzenia procesora nieokreślone i mogą być wykorzystane przez system operacyjeny do własnych celów.
Adres bazowy po uzupełnieniu go o 12 zer na najmniej znaczących pozycjach jest adresem fizycznym początku ramki, w której umieszczona jest tablica stron lub strona. Do zapamiętania adresu bazowego wystarczy 20 bitów ponieważ wiadomo, że adresy fizyczne początków ramek mają 12 zer na najmniej znaczących pozycjach.

Tłumaczenie adresu liniowego

A tak można przedstawić dwupoziomowy mechanizm stronicowania:

pic_i386_paging

Algorytm tłumaczenia adresu:


Intel PAE

PAE (Physical Address Extention) - Intelowska metoda adresowania pamięci została po raz pierwszy zaimplementowana w procesorze Intel Pentium Pro i obecnie jest szeroko stosowana we współczesnych systemach operacyjnych. PAE umożliwia zaadresowanie do 64GB pamięci za pomocą 32-bitowego wirtualnego adresu liniowego, przy wykorzystaniu 4KB-owej lub 2MB wielkości stony.

Aby cała operacja była możliwa, wpisy w katalogach stron i tablicach stron zostały rozszerzone do 8 bajtów (poprzednio 4 bajty). Dzięki temu adres bazowy katalogu stron i ramek może być rozszerzony do 24 bitów (z 20 bitów). Właśnie stąd biorą się dodatkowe 4 bity potrzebne do adresowania pełnych 64GB (236 bitów) fizycznego adresu.

Algorytm wyznaczania tego adresu jest również nieco inny od opisywanego powyżej. Adres liniowy pozostał 32-bitowy, ale zmienił się trochę jego podział. W przypadku PAE wygląda to następująco (odpowiednio dla 2MB i 4KB wielkości strony):

Strona 2MB:

Strona 4KB:

Algorytm stronicowania trójpoziomowego

  1. Odczytujemy adres odpowiedniego katalogu stron z globalnego wskaźnika na katalogi stron na podstawie zawartości rejestru CR3 i bitów 30-31 adresu liniowego.
  2. W zależności od rozmiaru strony:
  3. Do otrzymanego adresu fizycznego dodajemy przesunięcie (bity 0-11 lub 0-20 w zależności od rozmiaru strony.

Tak ten proces wygląda na obrazku:

pic_i586_paging

Autor: Piotr Jędrzejewski