Blog literacki, portal erotyczny - seks i humor nie z tej ziemi
Do spisu tresci tematu 4
4.2.3 Stronicowanie plikow
Spis tresci
Wprowadzenie
Implementacja: wprowadzenie,
struktury: vm_area_struct,
vm_operations_struct,
funkcje: do_mmap, do_munmap,
generic_file_mmap
Bibliografia
Pytania i odpowiedzi
Wprowadzenie
Stronicowanie plikow (zwane tez mapowaniem plikow) jest mechanizmem
pozwalajacym an odzwierciedlenie binarnej postaci pliku dyskowego (a dokladniej
pliku pochodzacego z dowolnego systemu plikow wspierajacego mechanizm stronicowania
plikow) w obszar wirtualnej przestrzeni adresowej procesu. Strony objete
takim obszarem sa stonicowane bezposrednio z/do danego pliku, a nie z/do
standardowych urzadzen wymiany stron.
Najszerszym chyba zastosowaniem tego mechanizmu jest ladoanie przez
jadro plikow wykonywalnych (funkcja exec), ktore zamiast wczytywac,
po prostu mapujemy do pamieci wirtualnej - potrzebne strony beda wczytywane
w wyniku bledow braku strony. Programista Linuxowy moze uzywac mapowania
plikow dla wlasnych zastosowan za pomoca funkcji bibliotecznych:
caddr_t mmap(caddr_t addr, size_t len, int prot, int fd, off_t off);
int munmap(caddr_t addr, size_t len);
Implementacja
Wprowadzenie
Stronicowanie plikow w Linuxie zostalo zrealizowanie na bazie ogolnego
mechanizmu pamieci wirtualnej procesu i jest z nim bardzo silnie powiazane.
Pamiec wirtualna procesu reprezentowana jest przez zbor (dokladnie: liste
i drzewo AVL - polea mm->mmap i mm->mmap_avl w
task_struct) struktur vm_area_struct opisujacych przyznane
procesowi spojne obszary wirtualnej przestrzeni adresowej. Z karzdym takim
obszaem sa zwiazane jego wlasciwosci i potencjalnie rozne funkcje obslugi
stronicowania. Tak ogolnie rozumiana wirtualnosc obszarow pozwala na stosunkowo
proste implementowanie roznorakich rozszerzen, w tym mapowania plikow!!!
Struktura vm_area_struct
Oto dokladna definicja struktury vm_area_struct z pliku include/linux/mm.h:
struct vm_area_struct {
struct mm_struct * vm_mm; /* parametry obszaru: */
unsigned long vm_start; /* adres poczatku, */
unsigned long vm_end; /* konca */
pgprot_t vm_page_prot; /* znaczniki ochrony */
unsigned short vm_flags; /* dodatkowe znaczniki (obszar dzielony, etc.) */
/* pola organizujace drzewo AVL (sortowane po vm_start) struktur vm_area_struct danego procesu */
short vm_avl_height;
struct vm_area_struct * vm_avl_left;
struct vm_area_struct * vm_avl_right;
/* pole organizujace liste (sortowana po vm_start) struktur vm_area_struct danego procesu*/
struct vm_area_struct * vm_next;
/* pola organizujace cykliczna liste struktur vm_area_struct (nie koniecznie jednego procesu) */
/* uzywane tylko dla pamieci dzielonej lub obszarow z i-wezlem (n.p. stronicowania plikow) */
struct vm_area_struct * vm_next_share;
struct vm_area_struct * vm_prev_share;
struct vm_operations_struct * vm_ops; /* funkcje obslugi stronicowania */
unsigned long vm_offset; /* offset w pliku */
struct inode * vm_inode; /* i-wezel pliku */
unsigned long vm_pte; /* katalog stron */
};
Struktura vm_operations_struct
Oto dokladna definicja struktury vm_operations_struct z pliku include/linux/mm.h:
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
/* unmap - wywolywana przed odlaczeniem obszaru - typowo wywoluje sync*/
void (*unmap)(struct vm_area_struct *area, unsigned long, size_t);
void (*protect)(struct vm_area_struct *area, unsigned long, size_t, unsigned int newprot);
/* sync - wywolywana na rzadanie procesu - ma za zadanie zsynchronizowac pamiec z plikiem */
int (*sync)(struct vm_area_struct *area, unsigned long, size_t, unsigned int flags);
void (*advise)(struct vm_area_struct *area, unsigned long, size_t, unsigned int advise);
/* nopage - wywolywana przy bledzie braku strony */
unsigned long (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access);
/* wppage - wywolywana przy zapisie do strony chronionej przed zapisem */
unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address,
unsigned long page);
/* sapout, swapin - wywolywane przy wymianie stron */
int (*swapout)(struct vm_area_struct *, unsigned long, pte_t *);
pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
};
Funkcja do_mmap
unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long off);
argumenty:
file - okreslenie pliku, ktory mapujemy; mozliwe jest podanie
NULL wtedy przylaczany segment nie bedzie zwiazany z plikiem (czyli
bedzie zupelnie normalnym segmentem - warto zauwazyc, ze funkcja sys_brk
sprowadza sie do wywolania do_mmap(NULL,...) lub do_munmap(...)
po uprzednim sprawdzeniu argumentow)
addr - adres pod jaki chcemy zmapowac (do flags trzeba
wtedy dodac MAP_FIXED) lub NULL aby system sam przydzielil adres
prot, flags - opcje ochrony i dzielenia (patrz include/asm/mman.h)
off - offset w pliku (uwaga: przy trybie dzielenia offset musi
byc wielokrotnoscia rozmiaru strony)
zwraca:
przydzielony adres lub ujemny kod bledu
dzialanie:
- sprawdza poprawnasc argumentow (wlacznie z trybem otwarcia pliku)
- alokuje pamiec jadra na nowa strukture vm_area_struct i inicjuje
ja (pola vm_ops, vm_inode, vm_pte sa zerowane)
- wywoluje do_munmap(addr,len)
aby zwolnic poprzednie obszary o zachodzacych adresach
- wywoluje funkcje (*mmap) charakterystyczna dla systemu plikow
pliku file (dla zwyklych systemow plikow n.p. ext2 jest to funkcja
generic_file_mmap,
a dla NFS jakas inna), ktora to funkcja konczy inicjalizacje struktury
vm_area_struct (pola vm_ops, vm_inode, ...)
- wstawia nowa strukture do zbioru (funkcje insert_vm_struct,
merge_segments)
Funkcja do_munmap
int do_munmap(unsigned long addr, size_t len)
argumenty:
addr, len - specyfikacja obszaru do odlaczenia
zwraca:
0 gdy OK lub ujemny kod bledu
dzialanie:
- sprawdza poprawnosc argumentow
- wyjmuje odpowiednia strukture vm_area_struct ze zbioru (funkcja
remove_shared_vm_struct)
- wywoluje funkcje (*unmap) specuficzna dla danej struktury
- zwalnia strony
- zwalnia pamiec jadra uzywana przez vm_area_struct
Funkcja generic_file_mmap
int generic_file_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
argumenty:
inode - i-wezel mapowanego pliku
file - "okreslenie" pliku
vma - obszar wirtualnej przestrzeni adresowej
zwraca:
0 gdy OK lub ujemny kod bledu
dzialanie:
- sprawdza prawa dostepu, etc.
- wpisuje inode do vma->vm_inode i zwieksza licznik
dowiazan i-wezla
- inicjuje strukture funkcji obslugi stronicowania (vma->vm_ops)
na file_shared_mmap
dla obszarow dzielonych lub na file_private_mmap
dla prywatnych
Bibliografia
Pliki zrodlowe Linuxa:
include/asm/mman.h
include/linux/mm.h
include/linux/fs.h
mm/filemap.c
mm/mmap.c
Pytania i odpowiedzi
brak...
Autor: Grzegorz Rowinski