Jak jądro Linuksa zarządza mniej niż 1GB pamięci fizycznej?

Uczę się jądra Linuksa i podczas czytania "Understanding Linux Kernel", uderzyło mnie kilka pytań związanych z pamięcią. Jednym z nich jest, jak jądro Linuksa radzi sobie z mapowaniem pamięci, jeśli fizyczna pamięć powiedzmy tylko 512 MB jest zainstalowana w moim systemie.

Jak czytam, Kernel mapuje 0(lub 16) MB-896MB fizycznej pamięci RAM na adres liniowy 0xC0000000 i może go bezpośrednio adresować. Tak więc w wyżej opisanym przypadku, gdzie mam tylko 512 MB:

  • Jak czy jądro może mapować 896 MB z zaledwie 512 MB ? W opisywanym schemacie jądro ustawiło tak, że tabele stron każdego procesu mapowały adresy wirtualne od 0xC0000000 do 0xFFFFFFFF (1GB) bezpośrednio na adresy fizyczne od 0x00000000 do 0x3fffffff (1GB). Ale kiedy mam tylko 512 MB fizycznej pamięci RAM, Jak mogę mapować wirtualne adresy od 0xC0000000-0xFFFFFFFF do fizycznego 0x00000000-0x3FFFFFFF ? Chodzi o to, że mam fizyczny Zakres tylko 0x00000000-0x20000000.

  • A co z tryb użytkownika procesy w tej sytuacji?

  • Każdy artykuł wyjaśnia tylko sytuację, gdy zainstalowano 4 GB pamięci i jądro mapuje 1 GB w przestrzeni jądra, a procesy użytkownika zużywają pozostałą ilość pamięci RAM.

Byłbym wdzięczny za każdą pomoc w poprawie mojego zrozumienia.

Dzięki..!
Author: TheLoneJoker, 2010-12-25

5 answers

Nie wszystkie wirtualne (liniowe) adresy muszą być mapowane do czegokolwiek. Jeśli kod uzyska dostęp do nieumapowanej strony, Błąd strony zostanie podniesiony.

Strona fizyczna może być mapowana na kilka adresów wirtualnych jednocześnie.

W 4 GB pamięci wirtualnej znajdują się 2 sekcje: 0x0... 0xbfffffff - jest procesową pamięcią wirtualną oraz 0xc0000000 .. 0xffffffff jest wirtualną pamięcią jądra.

  • jak jądro może mapować 896 MB z zaledwie 512 MB ?

Mapuje do 896 MB. Tak więc, jeśli masz tylko 512, będzie tylko 512 MB zmapowane.

Jeśli twoja pamięć fizyczna ma wartość 0x00000000 do 0x20000000, zostanie ona zmapowana dla bezpośredniego dostępu jądra do wirtualnych adresów 0xc0000000 do 0xe0000000 (mapowanie liniowe).

  • co z procesami trybu użytkownika w tej sytuacji?

Pamięć Phys dla procesów użytkownika będzie mapowana (nie sekwencyjnie, ale raczej losowo) do adresów wirtualnych 0x0 .... 0xc0000000. Mapowanie to będzie drugim mapowanie stron od 0..896MB. Strony zostaną pobrane z darmowych list stron.

  • gdzie są procesy trybu użytkownika w phys RAM?
Gdziekolwiek.
  • każdy artykuł wyjaśnia tylko sytuację, gdy masz Zainstalowane 4 GB pamięci i
Nie. Każdy artykuł wyjaśnia, w jaki sposób mapowane jest 4 Gb wirtualnej przestrzeni adresowej. Rozmiar pamięci wirtualnej wynosi zawsze 4 GB (dla 32-bitowej maszyny bez rozszerzeń pamięci, takich jak PAE / PSE / etc dla x86)

Jak stwierdzono w 8.1.3. Memory Zones książki Linux Kernel Development autorstwa Roberta Love( używam trzeciego wydania), istnieje kilka stref pamięci fizycznej:

  • ZONE_DMA-zawiera ramki strony pamięci poniżej 16 MB
  • zone_normal-zawiera ramki strony pamięci powyżej 16 MB i poniżej 896 MB
  • ZONE_HIGHMEM-zawiera ramki strony o wielkości 896 MB

Więc jeśli masz 512 MB, Twój ZONE_HIGHMEM będzie pusty, a ZONE_NORMAL będzie miał 496 MB pamięć fizyczna zmapowana.

Zajrzyj też do 2.5.5.2. Final kernel Page Table when RAM size is less than 896 MB sekcji książki. Chodzi o przypadek, gdy masz mniej pamięci niż 896 MB.

Również dla ARM jest jakiś opis układu pamięci wirtualnej: http://www.mjmwired.net/kernel/Documentation/arm/memory.txt

Linia 63 PAGE_OFFSET high_memory-1 jest bezpośrednią mapowaną częścią pamięci

 43
Author: osgx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-21 06:20:32

Sprzęt zapewnia jednostkę zarządzania pamięcią . Jest to Element obwodu, który jest w stanie przechwycić i zmienić każdy dostęp do pamięci. Gdy procesor uzyskuje dostęp do pamięci RAM, np. w celu odczytania następnej instrukcji do wykonania, lub jako dostęp do danych wywołany przez instrukcję, robi to pod pewnym adresem , który jest, z grubsza mówiąc, wartością 32-bitową. Słowo 32-bitowe może mieć nieco więcej niż 4 miliardy różnych wartości, więc istnieje przestrzeń adresowa wynosząca 4 GB: to liczba bajtów, które mogą mieć unikalny adres.

Tak więc procesor wysyła żądanie do swojego podsystemu pamięci, jako "fetch the byte at address x and give it back to Me". Wniosek przechodzi przez MMU, który decyduje, co z nim zrobić. MMU praktycznie dzieli 4 GB miejsca na strony ; rozmiar strony zależy od używanego sprzętu, ale typowe rozmiary to 4 i 8 kB. MMU używa tabel, które mówią mu, co zrobić z dostępami dla każdej strony: albo dostęp jest przyznawany z przepisanym adresem (wpis strony mówi: "Tak, strona zawierająca adres x istnieje, znajduje się w fizycznej pamięci RAM pod adresem y") lub odrzucany, w którym to momencie jądro jest wywoływane do dalszej obsługi. Jądro może podjąć decyzję o zabiciu procesu, lub wykonać jakąś pracę i zmienić tabele MMU, tak aby dostęp mógł być ponownie wypróbowany, tym razem z powodzeniem.

Jest to podstawa pamięci wirtualnej : z punktu widzenia, proces ma pewne RAM, ale jądro przeniosło go na dysk twardy, w "przestrzeni wymiany". Odpowiednia tabela jest oznaczona jako" nieobecna " w tabelach MMU. Gdy proces uzyskuje dostęp do jego danych, MMU wywołuje jądro, które pobiera dane ze swapu, umieszcza je z powrotem w wolnej przestrzeni w fizycznej pamięci RAM i zmienia tabele MMU, aby wskazywały na tę przestrzeń. Jądro następnie przeskakuje z powrotem do kodu procesu, bezpośrednio na instrukcję, która uruchomiła całość. Kod procesu nie widzi nic z całego biznesu, tylko, że dostęp do pamięci zajął sporo czasu.

MMU obsługuje również prawa dostępu, co uniemożliwia procesowi odczyt lub zapis danych, które należą do innych procesów lub do jądra. Każdy proces ma swój własny zestaw tabel MMU, a jądro zarządza tymi tabelami. Tak więc, każdy proces ma swoją własną przestrzeń adresową, tak jakby był sam na komputerze z 4 GB PAMIĘCI RAM-z tym, że proces lepiej nie miał dostępu do pamięci, której nie przydzielił prawidłowo z jądra, ponieważ odpowiednie strony są oznaczone jako nieobecne lub zabronione.

Gdy jądro jest wywoływane przez wywołanie systemowe z jakiegoś procesu, kod jądra musi działać w przestrzeni adresowej procesu; więc kod jądra musi znajdować się gdzieś w przestrzeni adresowej każdego procesu (ale chroniony: tabele MMU uniemożliwiają dostęp do pamięci jądra z nieuprzywilejowanego kodu użytkownika). Ponieważ kod może zawierać adresy zakodowane na twardo, jądro powinno być pod tym samym adresem dla wszystkich procesów; konwencjonalnie, w Linuksie, adres ten to 0xC0000000. Tabele MMU dla każdego procesu mapują tę część przestrzeni adresowej do dowolnych fizycznych bloków pamięci RAM , które jądro zostało załadowane podczas rozruchu. Zauważ, że pamięć jądra nigdy nie jest wymieniana (jeśli kod, który może odczytywać dane z przestrzeni wymiany, został sam zamieniony, sprawy potoczyłyby się dość szybko).

Na PC sprawy mogą być nieco bardziej skomplikowane, ponieważ istnieją tryby 32-bitowe i 64-bitowe, rejestry segmentów i PAE (który działa jako rodzaj MMU drugiego poziomu z ogromnymi stronami). Podstawowa koncepcja pozostaje taka sama: każdy proces ma swój własny widok wirtualnej przestrzeni adresowej 4 GB, a jądro używa MMU do mapowania każdej wirtualnej strony do odpowiedniej fizycznej pozycji w pamięci RAM, lub w ogóle nigdzie.

 17
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 17:46:35

Osgx ma doskonałą odpowiedź, ale widzę komentarz, w którym ktoś nadal nie rozumie.

Każdy artykuł wyjaśnia tylko sytuację, gdy zainstalujesz 4 GB pamięci, a jądro mapuje 1 GB do przestrzeni jądra i użytkownika procesy zużywają pozostałą ilość pamięci RAM.

Tutaj jest wiele zamieszania. Istnieje Pamięć wirtualna oraz pamięć fizyczna. Każdy 32-bitowy procesor ma 4 GB pamięci wirtualnej . Jądro Linuksa tradycyjny podział był 3G/1G dla pamięci użytkownika i pamięci jądra, ale nowsze opcje pozwalają na różne partycjonowanie.

Po co odróżniać jądro od przestrzeni użytkownika? - moje własne pytanie

Gdy zadanie zostanie zamienione, MMU musi zostać zaktualizowane. Przestrzeń MMU jądra powinna pozostać taka sama dla wszystkich procesów. Jądro musi obsługiwać przerwania i żądania błędów w dowolnym momencie.

Jak działa mapowanie wirtualne na fizyczne? - moje własne pytanie.

Są wiele permutacji pamięci wirtualnej.

  • pojedyncze prywatne mapowanie do fizycznej strony PAMIĘCI RAM.
  • duplikat Wirtualnego mapowania na pojedynczą stronę fizyczną.
  • mapowanie, które wyrzuca SIGBUS lub inny błąd.
  • mapowanie wspierane przez Disk / swap.

Z powyższej listy łatwo zrozumieć, dlaczego możesz mieć więcej wirtualnej przestrzeni adresowej niż fizycznej pamięci. W rzeczywistości obsługa błędów zazwyczaj sprawdza pamięć procesu informacje, aby sprawdzić, czy strona jest zmapowana (mam na myśli alokowana dla procesu), ale nie w pamięci. W takim przypadku obsługa błędów wywoła podsystem We / Wy do odczytu na stronie. Po przeczytaniu strony i zaktualizowaniu tabel MMU w celu skierowania adresu wirtualnego na nowy adres fizyczny proces, który spowodował usterkę, wznawia się.

Jeśli rozumiesz powyższe, staje się jasne, dlaczego chcesz mieć większe wirtualne mapowanie niż pamięć fizyczna. Informatyka jak jest obsługiwana wymiana pamięci.

Są inne zastosowania. Na przykład dwa procesy mogą używać tej samej biblioteki kodu. Jest możliwe, że znajdują się one pod różnymi adresami wirtualnymi w przestrzeni procesowej ze względu na łączenie. Możesz mapować różne wirtualne adresy do tej samej fizycznej strony w tym przypadku w celu zapisania fizycznej pamięci. Jest to dość powszechne w przypadku nowych alokacji; wszystkie one wskazują na fizyczną "stronę zerową". Kiedy dotykasz / zapisujesz pamięć strona zerowa jest kopiowana i przydzielana jest nowa strona fizyczna (COW lub copy przy zapisie).

Czasami przydatne jest również aliasowanie stron wirtualnych z jedną jako buforowane, a drugą jako niebuforowane. Dwie strony mogą być zbadane, aby zobaczyć, jakie dane są buforowane, a co nie.

Głównie wirtualne i fizyczne to nie to samo! Łatwo stwierdzone, ale często mylące, gdy patrzymy na kod VMM Linuksa.

 4
Author: artless noise,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-11 16:44:41

-

Witam, właściwie nie pracuję na platformie sprzętowej x86, więc w moim poście mogą pojawić się jakieś błędy techniczne.

Według mojej wiedzy, zakres między 0 (lub 16)MB-896MB jest wymieniony specjalnie, gdy masz więcej pamięci RAM niż ta liczba, powiedzmy, masz 1GB fizycznej pamięci RAM na płycie, która nazywa się"low-memory". Jeśli masz więcej fizycznej pamięci RAM niż 896MB na swojej płycie, reszta fizycznej pamięci RAM nazywa się highmem.

Mówiąc o twoim pytaniu, jest 512mibajtów fizyczna PAMIĘĆ RAM na Twojej płycie, więc właściwie nie ma 896, nie ma highmem.

Całkowite jądro RAM widzi i może mapować to 512MB.

Ponieważ istnieje mapowanie 1 do 1 pomiędzy pamięcią fizyczną a wirtualnym adresem jądra, więc istnieje 512mibajtów wirtualnej przestrzeni adresowej dla jądra. Naprawdę nie jestem pewien, czy poprzednie zdanie jest dobre, ale to jest to, co w mojej głowie.

Chodzi mi o to, że jeśli jest 512 MB, to ilość fizycznej pamięci RAM, którą może zarządzać jądro, jest również 512mibytes, co więcej, jądro nie może stworzyć tak dużej przestrzeni adresowej, jak powyżej 512MBytes.

Odnosi się do przestrzeni użytkownika, jest jeden inny punkt, strony aplikacji użytkownika mogą być zamieniane na dysk twardy, ale strony jądra nie mogą.

Tak więc, dla przestrzeni użytkownika, z pomocą tabel stron i innych powiązanych modułów, wydaje się, że nadal jest 4gbajtowa przestrzeń adresowa. Oczywiście jest to wirtualna przestrzeń adresowa, a nie fizyczna przestrzeń RAM.

This is what I Rozumiem.

Dzięki.
 3
Author: shawn xy bai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-30 08:33:14

JeĹ " li pamiÄ ™ Ä ‡ fizyczna jest mniejsza niĹź 896 MB, to kernel Linuksa mapuje liniÄ ™ tego adresu fizycznego.

Po szczegóły zobacz to.. http://learnlinuxconcepts.blogspot.in/2014/02/linux-addressing.html

 0
Author: JIN007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-09 12:54:09