32-bitowy model pamięci / SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE
Na wielu forach można często spotkad pytania, dlaczego system operacyjny (nawet Windows 2003 Enterprise Edition) widzi tylko ~3,7 GB pamięci RAM, skoro w serwerze znajduje się np. 8 GB RAM. Wiele osób nie rozumie przyczyny tego zjawiska. Postaram się to ostatecznie wyjaśnid!
Dla uproszczenia środowisko Windows definiuje dwa pojęcia pamięci, często przez użytkowników mylone. Mówimy o pamięci fizycznej (pamięci RAM zainstalowanej w komputerze/serwerze) oraz o pamięci widzianej przez daną aplikację (proces) –
między innymi przez 32 czy 64-bitowy system operacyjny. W tabeli poniższej
przedstawiamy zestawienie wielkości obsługiwanej pamięci fizycznej i dostępnej dla danej aplikacji w zależności od systemu operacyjnego, jego wersji oraz obsługi
specjalnych trybów adresowania pamięci (jak PSE czy PAE).
Tryby pracy procesora
Podobnie jak jego poprzednik (czyli 80286) 80386, i486, Pentium i późniejsze mogą pracowad w dwóch trybach pracy: rzeczywistym i wirtualnym. W trybie wirtualnym potrafią adresowad do 4 GB pamięci fizycznej (RAM).
W procesorze i386 usunięto najważniejsze ograniczenie procesora 80286 dotyczące ograniczenia wielkości segmentu danych do 64 KB. Teraz każdy segment danych (kodu lub stosu) może byd umieszczony w dowolnym miejscu przestrzeni adresowej i mied wielkośd do 4 GB każdy. Ponadto od i386 dostępny jest dodatkowy tryb pracy zwany trybem wirtualnym 8086 (ang. Virtual-8086 mode). Tryb ten pozwala na wykonywanie programów napisanych dla procesora 8086 bez konieczności ich modyfikacji.
Tryb rzeczywisty – Real Mode
W momencie startu lub resetu procesora przechodzi on w tryb rzeczywisty
adresowania. W tym trybie procesor korzysta z rejestrów 16-bitowych (tryb zgodności z 8086) i może zaadresowad 1 MB pamięci operacyjnej.
W tym trybie adres fizyczny pamięci operacyjnej tworzony jest poprzez dodanie do 20 bitowego adresu bazowego segmentu, 16 bitowego przemieszczenia. Adres bazowy jest tworzony poprzez pomnożenie przez 16 wartości odpowiedniego rejestru
segmentowego (przesunięcie w lewo o 4 bity). Dla segmentu kodu – rejestr CS,
danych – DS, stosu – SS, segmentu dodatkowego - ES. W większości przypadków tak utworzony adres będzie liczbą 20-bitową. Jeżeli powstały adres byłby jednak większy to w procesorach do modelu 188 nadwyżka (czyli 21 bit) jest ucinana; dla modeli
80286 i wyższych wyposażonych w więcej niż 20 linii adresowych pojawia się na linii A20.
W tym trybie można zaadresowad 1MB + 64KB - 16 Bajtów. Obszar ten powyżej 1 MB nazywa się HMA (ang. High Memory Area) i często był wykorzystywany w systemach operacyjnych MS-DOS w komputerach PC, aby zwolnid częśd wykorzystywanej
pamięci pomiędzy 0-640 KB.
Adres fizyczny pamięci operacyjnej, pojawiający się na wyprowadzeniach adresowych procesora (32 bity dla i386, i486, Pentium) powstaje w wyniku przetworzenia -
translacji adresu logicznego widzianego przez program (aplikację, proces). Wszystkie procesory rodziny x86 adresują przestrzeo dwuwymiarowo.
W 16-bitowym trybie rzeczywistym i 32-bitowym trybie chronionym (inne określenie - tryb z ochroną) do adresowania wykorzystuje się specjalne rejestry segmentowe (a dla trybu 32-bitowego - specjalne deskryptory – inaczej specjalne rejestry opisowe) określające dany adres w postaci – adres początkowy aplikacji w zakresie 0…4 GB oraz przesunięcie w stosunku do początku aplikacji. W sumie umożliwia to określenie
rzeczywistej wielkości pamięci przypisanej dla danej aplikacji. Tak utworzony adres nazywa się adresem liniowym. A sam proces tworzenia adresu – od wykorzystanych rejestrów segmentowych – tzw. adresowaniem segmentowym lub segmentacją.
Segmentacja ma dodatkowe zastosowanie – jej celem jest ochrona danego regionu pamięci przed dostępem (zapisem lub odczytem) przez inną aplikację (tzw. ochrona na poziomie segmentu).
Dla trybu 16-bitowego rzeczywistego
Adres logiczny jest reprezentowany przez parę liczb. Pierwsza nosi nazwę selektora (ang. Selector) i określa numer segmentu, druga przemieszczenie (ang. Offset)
wewnątrz segmentu. W każdej chwili procesor ma dostęp do 6 segmentów poprzez (16-bitowe) rejestry segmentowe CS, DS, ES, FS, GS i SS. Taki sposób adresowania pozwala na adresowanie większej ilości pamięci RAM niż wynika to z 16-bitowego trybu pracy.
Dla trybu 32-bitowego chronionego
Rejestry segmentowe są skojarzone z niewidocznymi dla programisty rejestrami deskryptorów (ang. Shadow register, lub segment descriptor cache register), w
których to przechowywana jest informacja o sposobie tłumaczenia wartości selektora wpisanego do danego rejestru segmentowego.
32-bitowy adres komórki pamięci w obrębie danej aplikacji - zostaje zamieniony na adres liniowy (również 32-bitowy) w obrębie pamięci fizycznej obsługiwanej przez dany procesor. Takie podejście pozwala na umieszczenie i jednoczesną obsługę wielu aplikacji 32-bitowych w obrębie dostępnej dla procesora pamięci fizycznej RAM.
Często wspólne dla wielu aplikacji biblioteki dynamiczne .dll mogą byd współdzielone przez wiele różnych aplikacji, co oznacza dostęp do tego samego regionu pamięci RAM przez wiele aplikacji umożliwiając zmniejszenie zapotrzebowania na pamięd przez wiele uruchomionych jednocześnie aplikacji.
Dodatkowo od modelu i386 wprowadzono dodatkowy mechanizm o nazwie stronicowanie (ang. Paging), który tłumaczy adres liniowy na adres fizyczny.
Stronicowanie pozwala na umieszczenie strony o wielkości 4 KB (lub 4 MB lub 2 MB) pod dowolnym adresem będącym wielokrotnością 4 KB (lub 4MB lub 2 MB) w pamięci fizycznej.
Sposób określania wielkości strony zostanie przedstawiony w dalszych częściach.
Mechanizm segmentacji jest niezależny od stronicowania. Stronicowanie można wykorzystad do zarządzania pamięcią operacyjną, segmentację do realizacji
wielozadaniowości i ochrony zadao. Systemy z serii Windows NT (4/5/6) wykorzystują do swej pracy tryb wirtualny procesora, do jego cech należy możliwośd pracy
wielozadaniowej (poprzez przełączanie się pomiędzy zadaniami (ang. Task switching).
Postawmy sobie pytanie. Dlaczego architekci firmy INTEL wprowadzili, aż tak skomplikowane mechanizmy zarządzania pamięcią?
Za takim rozwiązaniem stały pierwotnie trzy (teraz już cztery) założenia (prawie całkowicie ze sobą sprzeczne), które udało się jednak projektantom procesorów z rodziny Intel IA32, ze sobą pogodzid:
Założenie 1. KOMPATYBILNOŚĆ wsteczna - utrzymywana, aż do dziś, z procesorami INTEL 8088/8086, 80286.
Założenie 2. Wiele komputerów nie dysponowało w ówczesnym czasie (rok 1985 – prezentacja procesora i386) dużą ilością pamięci RAM, aby przydzielid jej
wystarczająco dla całości systemu i aplikacji.
Założenie 3. Systemy serwerowe (32-bitowe) posiadające po kilkadziesiąt GB pamięci RAM, nie były w stanie adresowad powyżej 4 GB pamięci RAM.
Założenie 4. Zgodnośd procesora 64-bitowego z procesorem 32-bitowym. Tryb pracy EM-64T. Zwany również IA-32e.
Zaproponowano, zatem następujące mechanizmy. Wykorzystanie pamięci masowej (dysku twardego), jako uzupełnienie dostępnej dla procesora pamięci fizycznej – tworząc pojęcie pamięci wirtualnej (RAM+SWAP). Dodatkowo projektanci
architektury procesorów INTEL IA-32 wprowadzili specjalne mechanizmy pozwalającą (32-bitowemu) systemowi operacyjnemu wykorzystad pamięd RAM z zakresu ponad 4 GB. Te specjalne tryby adresowania to PSE i PAE. Na koniec, rozszerzając wielkośd
rejestrów zarówno ogólnego przeznaczenia, oraz rejestrów związanych z
adresowaniem pamięci z 32 do 64-bitów, zapewnili możliwośd bezpośredniego wykorzystywania liczb 64-bitowych, co przyczyniło się do otwarcia drogi do 64-
bitowych systemów operacyjnych opartych o architekturę IA-32 (inaczej x86), zwaną teraz popularnie x64.
Mechanizm stronicowania
Podobnie jak segmentacja, stronicowanie posługuje się w procesie translacji tablicami systemowymi zawartymi w pamięci. Stronicowanie jest procesem całkowicie
niezależnym od segmentacji i przeznaczonym do realizacji innych zadao związanych z dostępem i zarządzaniem pamięcią.
Stronicowanie domyślne
Zarówno liniowa jak i fizyczna przestrzeo adresowa obejmuje ciągły obszar 4 GB.
Stronicowanie polega na wyróżnieniu w obu tych przestrzeniach bloków pamięci – tzw. stron (ang. pages) – o określonej wielkości każda, rozmieszczonych sekwencyjnie począwszy od adresu 0 i przyporządkowaniu stronom w przestrzeni liniowej - stron fizycznych.
Zaproponowano wielkośd strony o wartości 4 KB każda. (4 KB to 2^12 bajtów).
Zatem 2^32 /2^12 = 2^20 = 1 MB stron (1 048 576 stron). Położenie 4 KB strony da się jednoznacznie określid za pomocą jej 20–bitowego adresu. Dokonując translacji
adresu liniowego na fizyczny mamy 20-bitowy numer strony oraz 12 bitową resztę niepodlegającą translacji (adres wewnątrz strony).
Uwaga
Ze względu na koniecznośd wykorzystywania dodatkowych informacji, każde pole w tablicy numerów stron ma wymiar 32 bitów (4 bajtów) a nie 20 bitów, jak wynika za wyliczeo powyższych, zatem tablica translacji z wyliczeo musiałaby zajmowad ciągły obszar 4 MB. Jest to nie do zaakceptowania.
Projektanci w firmie INTEL zauważyli ten problem i zastosowano inne podejście.
Zrealizowano dwupoziomową strukturę tablic translacji. Są dwa rodzaje tablic:
- katalogi tablic stron PDE (ang. Page Directories Entries) – każdy element katalogu wskazuje na właściwą tablicę stron
- tablice stron PTE (ang. Page Tables Entries) – zawierające numery stron w fizycznej przestrzeni adresowej
Całkowita ilośd stron = 1024 elementy w PDE * 1024 elementy w PTE.
Domyślny tryb adresowania – 32-bitowy, strona 4 KB
Domyślnie system Windows korzysta z mechanizmu dwupoziomowego do budowania tablicy stron pamięci – z 32-bitowego adresowania z wykorzystaniem strony o
wielkości 4KB. Mechanizm ten omawiany był w części 3 (stronicowanie domyślne).
Przypominamy rysunek – prezentujący mechanizm odpowiadający za wybór danej 4 KB strony za pomocą elementów PDE i PTE.
Wybieramy za pomocą adresu 10-bitowego – z katalogu stron (ang. Page Directory Index) daną tabelę stron (Element PDE – ang. Page Directory Entry). Katalog stron ma pojemnośd 2^10 czyli 1024 pozycje.
Teraz z wybranej za pomocą elementu PDE tabeli stron (ang. Page Table Index) wybieramy interesującą stronę (adres 10-bitowy) (Element PTE – ang. Page Table Entry) – identycznie daje to 1024 pozycje numeru strony.
1024*1024 = 1048576 (1 MB) stron pamięci. Ponieważ maksymalnie możemy
zaadresowad dla aplikacji 4 GB pamięci otrzymujemy 4 GB/1 MB = 4 KB. Co oznacza że
strona ma domyślną wielkośd 4 KB. Aby teraz uzyskad adres wewnątrz danej strony został nam parametr oznaczony jako - przesunięcie w obrębie strony (12 bitowy) = czyli adres w obrębie 4 KB strony z dokładnością do bajta. Każdy 32-bitowy proces (aplikacja) – związany jest z jednym wpisem w katalogu stron PDE. Wpis ten tworzony jest przez Menadżera Pamięci w celu mapowania wszystkich stron pamięci
związanych z daną aplikacją. Adres w pamięci wirtualnej, w którym umieszczony jest katalog stron umieszczony jest w bloku procesów mikrojądra (KPROCESS), ale de facto jest również automatycznie mapowany na adres 0xC0300000h dla systemów
zgodnych z x86 systems (0xC0600000h dla systemów z włączoną funkcją PAE).
Procesor zna lokalizację katalogu tabel stron. Został, bowiem wyposażony w specjalny rejestr o nazwie CR3, który ładowany jest odpowiednią wartością przez system
operacyjny. Wartośd ta wskazuje, bowiem na adres katalogu tabel stron (ang. Page Directory) w pamięci wirtualnej. Za każdym razem w przypadku przełączenia
procesora na obsługę innego wątku innego procesu niż aktualnie wykonywany, rejestr ten ładowany jest wartością pochodzącą z bloku KPROCESS procesu, do którego
następuje przełączenie, za pomocą mechanizmu context-switch w jądrze systemu.
Przełączanie wątków wewnątrz procesu nie powoduje załadowania rejestru nową wartością, ponieważ wątki wewnątrz procesu współdzielą tą samą liniową przestrzeo adresową.