sys_brk
include/linux/sched.h zdefiniowana
jest struktura task_struct, stanowiaca opis kontekstu
procesu. W sklad opisu kontekstu wchodzi rowniez informacja o
polozeniu i dostepnej pamieci procesu. Jest ona przechowywana
w polu ww. struktury o nazwie mm typu mm_struct
(definicja rowniez w include/linux/sched.h).
W strukturze task_struct znajduje sie ponadto pole
rlim typu rlimit[] (definicja w
include/linux/resouce.h) opisujace ograniczenia
procesu, m.in. ograniczenie na ilosc przylaczonej pamieci operacyjnej.
exec, a takze
podczas inicjacji systemu, do pamieci operacyjnej ladowany jest kod
programu oraz rezerwowane jest miejsce na zmienne i stos procesu.
W systemie Linux mapa wirtualnej przestrzeni adresowej dzialajacego
procesu wyglada nastepujaco:

Podzial pamieci jest wyznaczny przez opis kontekstu procesu, a scislej
przez jego pole mm (zob. Struktury).
Na samym dole
przestrzeni adresowej umieszczony jest kod wykonywalny
(zazwyczaj od adresu 0, mozna jednak skompilowac jadro tak,
zeby pierwsza strona (=4kB) przestrzeni adresowej byla wolna;
dzieki takiemu rozwiazaniu przypisania na wskaznik o wartosci
NULL powoduja zgloszenie bledu ochrony pamieci. Algorytmy
ladowania kodu programu znajduja sie w plikach
/fs/binfmt_aout.c oraz /fs/binfmt_elf.c).
Za segmentem kodu rozpoczyna sie segment danych.
Jego poczatkowa czesc stanowi blok danych inicjowanych
(tj. takich, dla ktorych wartosci sa wczytywane z pliku
wykonywalnego). Druga czesc to tzw. dane nieinicjowane (bss),
zerowane przed uruchomieniem procesu przez system operacyjny.
Podzial powyzszy jest wyznaczany przez pola struktury mm:
start_code - adres pierwszego bajtu kodu wykonywalnego
end_code - adres pierwszego bajtu za kodem wykonywalnym
start_data - adres pierwszego bajtu danych inicjowanych
end_data - adres pierwszego bajtu po danych inicjowanych
brk - adres pierwszego bajtu podanych nieinicjowanych
(wartosc break)
start_brk - wartosc brk w momencie
uruchomienia procesu
(na poczatku brk=start_brk).
brk lub sbrk o nastepujacej semantyce:
int brk(void *new_brk) - ustawia nowa wartosc break,
zwraca -1 w przypadku bledu,
void *sbrk(ptrdiff_t increment) - zmienia wartosc
break o increment, zwracajac nowa otrzymana
wartosc.
Zadna z tych funkcji nie jest jednak prostym wywolaniem systemowej funkcji
sys_brk (definicja w pliku mm/mmap.c) o semantyce:
unsigned long sys_brk(unsigned long brk) - sprobuj
zmienic wartosc break i zwroc obowiazujaca wartosc.
Jak widac, nie istnieje w systemie cos takiego, jak
algorytm sbrk. Algorytmy realizujace funkcje brk
i sbrk mozna zrealizowac w latwy sposob np. poprzez
wywolanie sys_brk(0) w celu sprawdzenia biezacej
wartosci break, a nastepnie ponowne wywolanie
sys_brk z odpowiednim parametrem i przygotowanie wyniku
na podstawie porownania ze stara wartoscia break
end_code
(czyli: program chce oddac wiecej niz posiada).
rlim
w strukturze task_struct; w systemie Linux
limit przylaczonej pamieci operacyjnej dla jednego procesu wynosi
standardowo 2GB).
brk
arch/i386/entry.S,
fs/exec.c,
fs/binfmt_aout.c,
fs/binfmt_elf.c,
include/linux/resource.h,
kernel/fork.c,
kernel/sched.c,
mm/mmap.c
struct task_struct,
struct mm_struct
exit, ktorej wartosc (w zapisie
szestnastkowym) wynosi
deadbeef.
MAX_TASKS_PER_USER = 256 (liczba procesow jednego uzytkownika)
MIN_TASKS_LEFT_FOR_ROOT = 4 (liczba procesow zarezerwowanych
dla administratora),
NR_TASKS = 512 (liczba procesow w systemie),
TASK_SIZE = 3GB (maksymalny adres w wirtualnej przestrzeni
adresowej procesu). Oprocz tego nie nazwany parametr przechowywany
w current -> rlim okresla maksymalna ilosc pamieci
przylaczonej do procesu na 2GB.