Do spisu tresci tematu 4

4.2.3 Stronicowanie plikow




Spis tresci


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);
/* swapout, 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

  1. Pliki zrodlowe Linuxa:


Pytania i odpowiedzi

brak...


Autor: Grzegorz Rowinski