Windows Server 2008     Zarządzanie pamięcią w 32 i 64-bitowych systemach Windows, cz. II

Zarządzanie pamięcią w 32 i 64-bitowych systemach Windows, cz. I Udostępnij na: Facebook

Windows 2000/XP/2003/Vista/2008

Autor: Jacek Światowiak

Opublikowano: 6 grudnia 2007

Zawartość strony
Wprowadzenie  Wprowadzenie
Wstęp  Wstęp
Przeznaczenie rejestrów procesora  Przeznaczenie rejestrów procesora
Rejestr znaczników/flag  Rejestr znaczników/flag
Rejestr CR0  Rejestr CR0
Rejestr CR4  Rejestr CR4
Tryby pracy procesora  Tryby pracy procesora
Tryb rzeczywisty – Real Mode  Tryb rzeczywisty – Real Mode
Przeczytaj pozostałe części tego artykułu  Przeczytaj pozostałe części tego artykułu

Wprowadzenie

Pracując, jako MCT (ang. Microsoft Certified Trainer) i prowadząc zajęcia z kursantami z systemów Microsoft Windows - głównie serwerowych – często spotykam się z niezrozumieniem pojęć związanych za zarządzaniem pamięcią w systemach Windows. Mam nadzieję, iż ten artykuł pomoże wielu osobom zrozumieć sposób pracy systemów (w tym i samego procesora) oraz mechanizmy zarządzania pamięcią w systemach Windows zarówno klienckich, jak i serwerowych. Pierwsze części będą omawiać zagadnienia trochę oderwane od samego systemu Windows. Ale w późniejszych częściach będziemy wracali do omawianych mechanizmów i prezentowali ich wykorzystanie oraz konfigurację w różnych systemach Windows.

 Do początku strony Do początku strony

Wstęp

Aby zrozumieć sposób zarządzania pamięcią, należy zrozumieć sposób pracy procesorów o architekturze zgodnej z procesorem 80386 (©Intel’a) pracujących w trybie chronionym (ang. Protected Mode).

Dodatkowe mechanizmy i ograniczenia obsługi określonej ilości pamięci fizycznej RAM wynikające z typu danej platformy sprzętowej (wersji procesora i płyty głównej) oraz wersji systemu Windows będą stopniowo wyjaśniane.

Uwaga

Na wielu forach można często spotkać 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śnić!

 

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).

Tabela 1. Wielkość obsługiwanej pamięci w systemach Windows
Wersja systemu operacyjnego Edycja systemu Maksymalna obsługiwana wielkość pamięci dla pojedynczej aplikacji; w tym i systemu operacyjnego Maksymalna obsługiwana przez system ilość pamięci fizycznej - RAM
Microsoft Windows Server 2003 SP 1 Standard 4 GB 4 GB
  Web 4 GB 2 GB
  Enterprise 4 GB 64 GB – jeżeli sprzęt obsługuje tryb PAE
  Enterprise (64-bit) 16 TB 1 TB
  Datacenter 4 GB 128 GB – jeżeli sprzęt obsługuje tryb PAE
  Datacenter (64-bit) 16 TB 1 TB
Windows Server 2003 Standard 4 GB 4 GB
  Web 4 GB 2 GB
  Enterprise 4 GB 32 GB – jeżeli sprzęt obsługuje tryb PAE
  Enterprise (64-bit) 16 TB 64 GB
  Datacenter 4 GB 128 GB – jeżeli sprzęt obsługuje tryb PAE
  Datacenter (64-bit) 16 TB 512 GB
Windows XP Home 4 GB 4 GB
  Professional 4 GB 4 GB
  64-bit Edycja 2003 16 TB 128 GB
Windows 2000 Professional 4 GB 4 GB
  Server 4 GB 4 GB
  Advanced Server 4 GB 8 GB
  Datacenter Server 4 GB 32 GB – jeżeli sprzęt obsługuje tryb PAE

 

Aby zrozumieć mechanizmy adresowania pamięci, należy zrozumieć podstawowe mechanizmy pracy procesora zgodnego z i386 pracującego w tzw. trybie chronionym procesora. Wewnętrznie procesor do przetwarzania danych korzysta z rejestrów (poniżej przedstawimy podstawowe rejestry procesorów zgodnych z architekturą Intel 80386/i486, zwanych w skrócie dalej i386). Jeżeli dany tryb pracy lub właściwość dostępna jest od jakiegoś modelu procesora lub systemu operacyjnego – zostanie to dodatkowo podane. I486 różni się od 80386 wbudowaną jednostką z operacji zmiennoprzecinkowych FPU (ang. Floating Point Unit) oraz wbudowaną pamięcią Cache L1.

Rys. 1.1. Rejestry główne procesora zgodnego z procesorem i386/i486 – dla trybu 32-bitowego.

Rys. 1.1. Rejestry główne procesora zgodnego z procesorem i386/i486 – dla trybu 32-bitowego.

 

Do wykonania podstawowych operacji arytmetycznych i logicznych wykorzystuje się rejestry oznaczone jako E(AX), E(BX), E(CX), E(DX) oraz rejestr (E)FLAGS (są to 32-bitowe rejestry, mogące pracować również, jako 16-bitowe – oznaczane są wtedy, jako AX, BX, CX, DX, FLAGS lub 8–bitowe: AH, AL, BH, BL, CH, CL, DH, DL). Dokładnego przeznaczenia rejestrów nie będę omawiał, gdyż to nie ma w naszym przypadku znaczenia.

W skrócie. I386 posiada następujące, najważniejsze rejestry:

- osiem 32-bitowych rejestrów ogólnego przeznaczenia (ang. General-Purpose Register): E(AX), E(BX), E(CX), E(DX), E(SI), E(DI), E(BP) i E(SP)

- sześć 16-bitowych rejestrów segmentowych (ang. Segment register): CS, DS, SS, ES, FS i GS

- cztery rejestry systemowe zarządzania dostępem do pamięci (ang. System Register): GDTR, IDTR, LDTR, TR

- wskaźnik instrukcji (zwany również licznikiem rozkazów) (ang. Instruction Pointer): E(IP)

- rejestr znaczników/flag: E(FLAGS)

- rejestry sterujące (ang. Control Register): CRO (MSW), CR2, CR3, (od procesora Pentium dodano CR4)

- rejestry uruchomieniowe (ang. Debug Register): DR0, DR1, DR2, DR3, DR6, DR7

- rejestry testowe (ang. Test Register): TR6 i TR7, (od i486 dodano TR3,TR4,TR5)

 Do początku strony Do początku strony

Przeznaczenie rejestrów procesora

Rejestry ogólnego przeznaczenia są wykorzystywane przez programy systemowe i użytkowe. Niektóre pełnią również funkcje specjalne: AX – akumulator – zapisywany jest w nim wynik operacji arytmetyczno-logicznych, SP – wskaźnik stosu, CX – licznik, SI i DI – wskaźnik pozycji w łańcuchu. Nie będziemy omawiać przeznaczenia wszystkich rejestrów, gdyż dla celów tego artykułu są one nieistotne.

System Windows (2k, 2k3, 2k8, XP, Vista) w momencie startu pracuje w trybie 16-bitowym (tzw. trybie rzeczywistym), po czym następuje za pomocą odpowiednich wpisów do dodatkowych rejestrów systemowych przełączenie w 32-bitowy tryb chroniony procesora (chyba że jest to procesor z rozszerzeniem EM-64T i mamy zainstalowany system 64-bitowy, wtedy następuje przełączenie w tryb 64-bitowy). Mechanizm ten opisany zostanie dalej.

Większość operacji arytmetycznych i logicznych wykonuje się na (w) pamięci. Zatem procesor o architekturze 32-bitowej widzi aplikację jako kolejny ciąg komórek pamięci zaczynających się od zera a kończących na wartości (4GB – tryb 32-bitowy). Dla procesora taką aplikacją jest również de facto 32-bitowy system operacyjny. Nazwijmy ten adres adresem logicznym aplikacji.

 Do początku strony Do początku strony

Rejestr znaczników/flag

W wielu operacjach wykorzystywany jest rejestr znaczników (flag) zwany FLAGS (EFLAGS). Poniżej przedstawiamy jego budowę. Występowanie poszczególnych bitów jest zależne od danego modelu (wersji procesora):

Rys. 1.2. Budowa rejestru (E)FLAGS dla procesora i386.

Rys. 1.2. Budowa rejestru (E)FLAGS dla procesora i386.

 

Uwaga

W procesorach późniejszych, jak i486 dodano dodatkowe flagi do rejestru EFLAGS, ale to dla naszego artykułu nie ma teraz znaczenia.

 

Gdzie:

VM - (ang. Virtual 8086 Mode Flag) - znacznik trybu wirtualnego 8086,

RF – (ang. Resume Flag) - znacznik wznowienia,

NT – (ang. Nested Task Flag) - znacznik zadania zagnieżdżonego,

IOPL – (ang. I/O Privilege Level) - znacznik poziomu ochrony I/O,

OP – (ang. Overflow Flag) - znacznik nadmiaru,

DF – (ang. Direction Flag) - znacznik kierunku,

IF – (ang. Interrupt Enabled Flag) - znacznik odblokowania przerwań,

TF – (ang. Trap Flag) - znacznik pracy krokowej,

SF – (ang. Sign Flag) - znacznik znaku,

ZF – (ang. Zero Flag) - znacznik zera,

AF – (ang. Auxiliary Carry Flag) - znacznik przeniesienia pomocniczego,

PF – (ang. Parity Flag) - znacznik parzystości,

CF – (ang. Carry Flag) - znacznik przeniesienia,

Nie będziemy przedstawiali przeznaczenia poszczególnych znaczników, gdyż dla celów zarządzania pamięcią i trybów pracy procesora (systemu operacyjnego) nie mają znaczenia – poza znacznikiem VM – ale tryb Virtual 8086 Mode w systemach Windows nie jest stosowany.

Rejestry sterujące CR0-CR3 służą do sterowania trybem pracy procesora i trybem pracy bloku stronicowania pamięci (mechanizm stronicowania opisany zostanie dalej).

 Do początku strony Do początku strony

Rejestr CR0

Rejestr CR0 – odpowiada za sterowanie pracą procesora.

Rys. 1.3. Budowa rejestru CR0 dla procesora zgodnego z i386.

Rys. 1.3. Budowa rejestru CR0 dla procesora zgodnego z i386.

 

Rys. 1.4. Budowa rejestru CR0 dla procesorów późniejszych niż i386.

Rys. 1.4. Budowa rejestru CR0 dla procesorów późniejszych niż i386.

 

Uwaga

W procesorach późniejszych, po i486 dodano dodatkowe flagi do rejestru CR0, ale to dla naszego artykułu nie ma teraz znaczenia. Bity 0…15 rejestru CR0 oznaczane są również jako MSW - Machine Status Word.

 

Gdzie:

PG – (ang. Paging Enable) - bit stronicowania (będzie później dokładnie omawiany)

ET – (ang. Procesor Extension Type) - bit typu koprocesora,

TS – (ang. Task Switched) - bit przełączania zadania,

EM – (ang. Emulate Coprocessor) - bit trybu emulacji koprocesora,

MP – (ang. Monitor Coprocessor) - bit monitorowania koprocesora,

PE – (ang. Protected Mode Enable) - bit trybu wirtualnego, (będzie później dokładnie omawiany)

Od i486 dodano i zmodyfikowano następujące flagi:

ET – ma ustaloną na stałe wartość 1 – oznacza koprocesor obecny,

NE – (ang. Numerics Exception lub Numeric Error Enable) – tryb zgłaszania błędów przez koprocesor,

WP – (ang. Write Protect) - bit ochrony przed zapisem,

AM – (ang. Alignment Mask) - bit maski wyrównania,

NW – (ang. Not Write-Through) - bit wyłączenia jednoczesnego zapisu do pamięci podręcznej (cache) i głównej,

CD – (ang. Cache Disable) - bit wyłączenia pamięci podręcznej (cache),

Uwaga

Rejestr CR1 nigdy nie został zaimplementowany w procesorach zgodnych z i386.

 

 Do początku strony Do początku strony

Rejestr CR4

Od procesorów z serii Pentium dodano kolejny rejestr kontrolny - CR4.

Rys. 1.5. Format rejestru CR4 (dostępny od procesorów Pentium).

Rys. 1.5. Format rejestru CR4 (dostępny od procesorów Pentium).

 

Rejestr ten odpowiada głównie za rozszerzone tryby adresowania procesora, w szczególności: Virtual-8086, PAE i PSE (PSE-36).

Rejestry systemowe służą do ustalania adresów w globalnej i lokalnych tablicach deskryptorów segmentów (rejestry GDTR i LDTR), adresu segmentu aktualnie wykonywanego zadania (rejestr TR) i adresu tablicy deskryptorów przerwań (rejestr IDTR).

Rejestry uruchomieniowe (rejestry DR0-DR7) służą do sterowania pułapkami sprzętowymi.

Rejestry testowe (rejestry TR6 i TR7) służą do testowania poprawności działania pamięci asocjacyjnej elementów tablic stron (TLB). Są również wykorzystywane podczas autotestowania procesora.

 Do początku strony Do początku strony

Tryby pracy procesora

Podobnie jak jego poprzednik (czyli 80286) 80386, i486, Pentium i późniejsze mogą pracować w dwóch trybach pracy: rzeczywistym i wirtualnym. W trybie wirtualnym potrafią adresować 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 być umieszczony w dowolnym miejscu przestrzeni adresowej i mieć wielkość 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.

Na rysunku poniżej widać również specjalny tryb IA-32e. Tryb ten wykorzystywany jest do przełączenia procesorów wyposażonych w rozszerzenie 64-bitowe (EM-64T) w tryb 64-bitowy i będzie omawiany oddzielnie.

Rys. 1.6. Tryby pracy procesorów od i386 w górę.

Rys. 1.6. Tryby pracy procesorów od i386 w górę.

 

Od modelu i486SL wprowadzono dodatkowy tryb zwany SMM (ang. System Management Mode). Odpowiada on za zarządzanie energią i monitorowanie czujników termicznych.

Tryb rzeczywisty (ang. Real Mode) wykorzystywany był przez systemy operacyjne poprzedniej generacji, np. MS-DOS.

 Do początku strony Do początku strony

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 zaadresować 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.

Rys. 1.7. Tworzenie adresu liniowego dla trybu rzeczywistego.

Rys. 1.7. Tworzenie adresu liniowego dla trybu rzeczywistego.

 

W tym trybie można zaadresować 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 zwolnić część 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ą przestrzeń 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ą być 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ęć 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.

Rys. 1.8. Ogólny proces translacji adresu.

Rys. 1.8. Ogólny proces translacji adresu.

 

Rys. 1.9. Ogólny proces translacji adresu logicznego na liniowy – zarówno dla trybu 32 jak i 64-bitowego.

Rys. 1.9. Ogólny proces translacji adresu logicznego na liniowy – zarówno dla trybu 32 jak i 64-bitowego.

 

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 wykorzystać do zarządzania pamięcią operacyjną, segmentację do realizacji wielozadaniowości i ochrony zadań. Systemy z serii Windows NT (4/5/6) wykorzystują do swej pracy tryb wirtualny procesora, do jego cech należy możliwość 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ą pogodzić:

Założenie pierwsze. KOMPATYBILNOŚĆ wsteczna - utrzymywana, aż do dziś, z procesorami INTEL 8088/8086, 80286.

Założenie drugie. Wiele komputerów nie dysponowało w ówczesnym czasie (rok 1985 – prezentacja procesora i386) dużą ilością pamięci RAM, aby przydzielić jej wystarczająco dla całości systemu i aplikacji.

Założenie trzecie. Systemy serwerowe (32-bitowe) posiadające po kilkadziesiąt GB pamięci RAM, nie były w stanie adresować powyżej 4 GB pamięci RAM.

Założenie czwarte. Zgodność 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 wykorzystać pamięć RAM z zakresu ponad 4 GB. Te specjalne tryby adresowania to PSE i PAE. Na koniec, rozszerzając wielkość 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ść 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.

Uwaga

Proszę nie mylić architektury x64 z architekturą 64-bitową dostępną w procesorach ITANIUM – ta nosi skróconą nazwa IA-64

 

W następnej części artykułu przybliżymy dokładniej pracę w trybie z ochroną oraz mechanizm zwany segmentacją.

 Do początku strony Do początku strony

Przeczytaj pozostałe części tego artykułu


Jacek Światowiak Jacek Światowiak (MCT, MCSE, MCSE+M, MCSE+S, MCTS, MCP)
Absolwent Wydział Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej. Obecnie zatrudniony w Altkom Akademia S.A. jako Trener Technologii Microsoft. Posiada bogate doświadczenie w zakresie wdrażania różnych technologii informatycznych. Od 2002 roku wykładowca Technologii i Protokołów Sieciowych na Podyplomowym Studium Politechniki Gdańskiej. Jest współautorem skryptu dla studentów informatyki: „Protokoły IPv6 – Opis protokołów. Materiały do laboratorium”. Posiada certyfikaty MCT, MCSE, MCSE+M, MCSE+S, MCTS Microsoft Exchange Server 2007, MCP ID 3621156.
 Do początku strony Do początku strony

Windows Server 2008     Zarządzanie pamięcią w 32 i 64-bitowych systemach Windows, cz. II