Segmentacja w Linuxie

Każdy proces w Linuxie, jak wszyscy wiedzą, może zaadresować 4GB6pamięci. Jednak może użyć tylko 3GB, bo ostatni gigabajt jest przeznaczony dla jądra systemu. Dostępne 3GB pamięci są podzielone na następujące logiczne segmenty:
-- segment kodu
-- segment danych zainicjalizowanych
-- segment danych niezainicjalizowanych (jest to pamięć na np. mapowane pliki, pamięć dzieloną) nazywany też segmentem BSS7
-- segment pamięci nieużywanej
-- segment stosu
-- segment zawierający parametry wywołania
-- segment zawierający zmienne środowiskowe
Powyższy podział dobrze widać w strukturze struct mm_struct opisywanej parę punktów dalej.

Rysunek: Przykładowa segmentacja pamięci procesu.

Segment kodu, danych zainicjalizowanych oraz segment z parametrami wywołania i segment ze zmiennymi środowiskowymi są ustawiane podczas startu procesu, a ściślej to dopiero podczas wczytywania procesu z pliku wykonywalnego. W trakcie działania procesu, zasadniczo nie zmienia się, ani rozmiar, ani zawartość tych segmentów. O wiele ciekawsze są pozostałe segmenty których wielkość może być zmieniana dynamicznie.

Segment danych niezainicjalizowanych, inaczej sterta (ang. heap) programu może dynamicznie zmieniać swój rozmiar. Jego początek jest ustawiany na sztywno przy starcie procesu, a koniec wskazywany jest przez zmienną brk8, którą proces może pośrednio zmieniać w wyniku wywołania takich funkcji jak np. malloc() lub free(), zmieniając tym samym rozmiar segmentu BSS. Warto może jeszcze wiedzieć, że architektura i386 nie pozwala na to, aby brk pokazywał dalej jak na 2GB.


Tomasz Szymko 27 listopada 2001