<<<<<<<<<<           >>>>>>>>>>

Bliźniaki w Linuksie

 
 
 
 
 
 
 
 
 

W linuksie są trzy różne rodzaje pamięci. Pamięć poniżej 16 MB jest dostępna dla DMA dla szyny ISA (DMA dla innych szyn może korzystać z większego obszaru pamięci fizycznej). Pamięć powyżej 896 MB nie jest odwzorowana w tablicy stron jądra i nie jest dla jądra bezpośrednio dostępna (warto zauważyć, w architekturze x86 można adresować 64 GB pamięci fizycznej, a obszar pamięci wirtualnej - również dla jądra - to jedynie 4GB). Pozostała pamięć - do 16 do 896 MB może być dowolnie używana.

Aby umożliwić alokacje różnych rodzajów pamięci, w linuksie pamięć podzielono na strefy. Każda strefa ma niezależne listy wolnych bloków. Przy alokacji trzeba podać z których stref pamięć może być zaalokowana.

Przy zwalnianiu bloku trzeba szybko sprawdzać, czy bliźniak danego bloku jest wolny. W tym celu do każdej listy wolnych bloków dołączona jest mapa bitowa. Ponieważ wielkość pamięci fizycznej jest stała (nie zmienia się w czasie działania systemu), można przy starcie jądra przydzielić odpowiednią ilość pamięci na mapy bitowe. Jeśli system ma 64 MB pamięci, a rozmiar ramki to 4 KB, to jest 16384 bloków rozmiaru 1 ramki, 8192 bloków rozmiaru 2 ramek, 4096 bloków rozmiaru 4 ramek, itd.

W mapie bitowej wystarczy jeden bit na dwóch bliźniaków. Konkretnie, bit odpowiadający bliźniakom jest zapalony, gdy dokładnie jeden z bliźniaków jest w liście wolnych bloków, a zgaszony, gdy w liście nie ma żadnego bliźniaka, lub gdy są w niej obaj (to jest możliwe tylko dla bloków największego rozmiaru). Sprawdzanie, czy bliźniak danego bloku jest wolny występuje jedynie przy zwalnianiu bloku. Wtedy wiadomo, że jeśli bit odpowiadający) bliźniakom jest zapalony, to bliźniak zwalnianego bloku jest wolny, a jeśli bit jest zgaszony, to bliźniak jest zajęty (choć być może nie w całości).

Pozostaje jeszcze kwestia który bit odpowiada danemu blokowi. To łatwo wyznaczyć mając adres (fizyczny!) bloku. Wystarczy adres bloku podzielić przez jego rozmiar (wtedy dostaniemy numer bloku) i jeszcze przez 2 (bo jest jeden bit na dwóch bliźniaków).