de gestionare a memoriei în Linux

Mai degrabă decât să descrie teoria managementului memoriei în sistemele de operare, această secțiune va încerca să identifice principalele caracteristici ale punerii sale în aplicare în Linux. Cu toate că nu trebuie să fie un guru în memoria virtuală Linux pentru mmap. prezentare generală de bază a modului în care funcționează este util. Ceea ce urmează este o descriere destul de lungă a structurilor de date utilizate de către nucleu pentru a gestiona memoria. După obținerea cunoștințelor prealabile necesare putem începe să lucreze cu aceste structuri.

de gestionare a memoriei în Linux

Memoria fizică este împărțit în module separate, numite pagini. O parte semnificativă a prelucrării memoriei sistemului intern se realizează pe bază de pagină. Dimensiunea paginii variază de la o arhitectura la alta, cu toate că cele mai multe sisteme folosesc în prezent 4096 pagina octet. PAGE_SIZE permanentă (definită în ) Definește dimensiunea paginii pentru orice arhitectură.

Memoria superioară și inferioară

Termenul de „memorie de mare“ poate fi o oarecare confuzie, mai ales că acesta are un sens diferit în lumea calculatoarelor personale. Deci, să fie clar, definim acești termeni aici:

Noi subliniem restricțiile privind utilizarea memoriei de mare ca am ajuns la ei în acest capitol.

Harta structura paginii de memorie

Astfel, funcțiile de kernel care se ocupă cu memorie, în loc din ce în ce folosind indicii pentru a struct pagina (definite in ). Această structură de date este utilizat pentru a stoca informații despre aproape tot ceea ce kernel-ul trebuie să știe despre memoria fizică; pentru fiecare pagină fizică în sistem, există o pagină a struct. Unele dintre domeniile acestei structuri includ următoarele:

Numărul de link-uri existente pe aceasta pagina. În cazul în care numărul scade la 0, pagina este returnat la lista liberă.

steaguri lungi fără semn;

Un set de steaguri de biți care descriu starea paginii. Acestea includ PG_locked. ceea ce indică faptul că pagina a fost blocat în memorie, și PG_reserved. care împiedică sistemul de management al memoriei este, în general de lucru cu această pagină.

Nucleul menține unul sau mai multe șiruri de pagini de înregistrări struct. care vă permit să urmăriți toată memoria fizică a sistemului. Pe unele sisteme, există o singură matrice numită mem_map. Pe alte sisteme, cu toate acestea, situația este mai complicată. Sistem cu un acces de memorie neuniforma (acces neuniforma de memorie, NUMA) și altele, cu o memorie fizică extrem de divizată poate avea mai mult de o serie de card de memorie, astfel încât codul, care este proiectat pentru portabilitate, ar trebui să evite accesul direct la matrice ori de câte ori este posibil. Din fericire, de regulă, este destul de ușor de a lucra doar cu indicii pagina struct fara a avea grija de unde vin.

Pagina struct * virt_to_page (void * kaddr);

Pagina struct * pfn_to_page (int PFN);

Returnează pagina struct indicatorul pentru renumerotate frame de pagină. Dacă este necesar, se verifică pagina numărul cadrului de valabilitate folosind pfn_valid înainte de a trece-l la pfn_to_page.

void * page_address (struct pagina *);

void * kmap (struct pagina *);

void kunmap (struct pagina * pagina);

void * kmap_atomic (pagina struct * pagina, enum km_type tip);

void kunmap_atomic (void * adr, enum km_type tip);

kmap_atomic este o formă ridicată de kmap. Fiecare arhitectura menține o listă mică de sloturi (intrări în tabelul de pagini speciale) pentru atomic kmap-uri; kmap_atomic apelant trebuie să spună sistemul în tipul argument. unele dintre aceste sloturi de a utiliza. Singurele sloturi care sunt semnificative pentru șofer, și sunt KM_USER0 KM_USER1 (pentru cod care rulează direct de apel din spațiul utilizator) și KM_IRQ0 și KM_IRQ1 (pentru cârlige). Rețineți că atomic kmap-s trebuie prelucrate atomically; codul nu poate dormi în timp ce-l deține. De asemenea, observăm că nimic în miezul nu împiedică cele două funcții ale încercărilor de a utiliza același slot și împiedică reciproc (deși pentru fiecare procesor are un set unic de sloturi). În practică, competiția pentru spațiile kmap atomice, nu pare a fi o problemă.

Vom vedea opțiunile pentru utilizarea acestor funcții atunci când apelează la codul de exemplu, mai târziu în acest capitol și în capitolele următoare.

tabela de pagini

Zona de memorie virtuală

• Zona pentru codul de program executabil (adesea numit text).

• Un domeniu pentru fiecare mapare de memorie activă.

# Cat / proc / 1 / maps se uite la inițializare

08048000-0804e000 r-XP 3:01 00000000 64652 / sbin / init textului

0804e000-0804f000 rw-p date 00006000 03:01 64652 / sbin / init

0804f000-08053000 rwxp 00000000 00:00 0 zero mapat BSS

40000000-40015000 r-xp 00000000 96278 03:01 text /lib/ld-2.3.2.so

40015000-40016000 rw-p 00014000 03:01 96278 /lib/ld-2.3.2.so date

40016000-40017000 rw-p 00000000 00:00 0 BSS pentru ld.so

4212e000-42131000 rw-p 0012e000 03:01 80290 /lib/tls/libc-2.3.2.so date

42131000-42133000 rw-p 00000000 00:00 0 BSS libc

bffff000-c0000000 rwxp segment 00000000 00:00 0 stivă

ffffe000-fffff000 --- p 00000000 0 00:00 pagina vsyscall

# Rsh pisica lup / proc / auto / harti #### x86-64 (Redus)

00400000-00405000 r-XP 3:01 00000000 1596291 / bin / pisica de text

00504000-00505000 rw-p 3:01 00004000 1596291 / bin / date pisica

00505000-00526000 rwxp 00505000 00:00 0 bss

3252300000-3252301000 r - p 03:01 1237890 00100000 /lib64/ld-2.3.3.so

7fbfffe000-7fc0000000 rw-p 7fbfffe000 00:00 0 stivă

ffffffffff600000-ffffffffffe00000 --- p 00000000 0 00:00 vsyscall

Câmpurile din fiecare linie:

start-end permanent de compensare majore: imagine minoră inod

Fiecare câmp din / proc / * / hărți (cu excepția maparea nume) corespunde unui câmp din vm_area_struct structura:

O mască de biți cu permisiuni de citire memorie, scriere și execuție. Acest câmp descrie ceea ce procesul este permis de a face cu pagini care aparțin acestei zone. Ultimul caracter într-un domeniu - este fie p pentru „privat“ ( „privat“), sau pentru „partajat“ ( „comun“).

În cazul în care zona de memorie începe în dosar, cu care este asociat. Decalajul de la 0 înseamnă că, la începutul zonei de memorie corespunde la începutul fișierului.

Numerele majore și minore dispozitiv țineți fișierul a fost afișat. În mod ironic, atunci când dispozitivul de afișare, numerele majore și minore se referă la partiția de disc care conține fișierul dispozitiv special, care a fost deschis de către utilizator, nu aparatul în sine.

Numărul inode al fișierului mapat.

Numele de fișier (de obicei, un fișier executabil), care a fost cartografiat.

structura vm_area_struct

Să ne uităm la cele mai importante domenii din vm_area_struct struct (determinată în ). Aceste câmpuri pot fi utilizate de drivere de dispozitiv în mmap punerea lor în aplicare. Rețineți că nucleul menține liste și arbori VMA pentru a optimiza căutarea și unele domenii vm_area_struct folosite pentru a sprijini o astfel de organizație. Prin urmare, VMA nu poate fi creat la cererea conducătorului auto, sau structura încălcat. Principalele domenii VMA sunt după cum urmează (nota similitudinea dintre aceste domenii și terminalul / proc pe care tocmai l-am văzut.):

vm_start unsigned long;

vm_end unsigned long;

struct fișier * vm_file;

Pointer la struct structura de fișiere. asociate cu acest domeniu (dacă este cazul).

vm_pgoff unsigned long;

câmp Offset în fișier, în pagini. Când fișierul sau dispozitivul afișat, această poziție în prima pagină a fișierului afișat în această zonă.

vm_flags lungi fără semn;

struct vm_operations_struct * vm_ops;

Un set de funcții care kernel-ul poate apela pentru a lucra în acea zonă de memorie. Prezența sa indică faptul că zona de depozitare este „obiect“ al nucleului, precum și fișierul struct. folosim în toată această carte.

Zonele care pot fi utilizate de către conducătorul auto pentru a menține propriile informații.

Ca vm_area_struct struct. vm_operations_struct definite în ; aceasta include operațiunile enumerate mai jos. Aceste operațiuni sunt necesare numai pentru cerințele de procesare și memorie sunt enumerate în ordinea în care acestea sunt declarate. În continuare, în acest capitol vom pune în aplicare unele dintre aceste funcții.

void (* deschis) (struct vm_area_struct * VMA);

void (* close) (struct vm_area_struct * VMA);

Când ștergeți un nucleu câmp solicită această operațiune de aproape. Vă rugăm să rețineți că nu există nici un număr de utilizare asociată cu VMA; zona este deschisă și închisă exact o dată de către fiecare proces pe care-l folosește.

Pagina struct * (* nopage) (struct vm_area_struct * VMA, nesemnate adresa lung, int * tip);

Atunci când un proces încearcă să acceseze o pagină care se referă la VMA valabil, dar care nu sunt în prezent în memorie, pentru zona respectivă se numește metoda nopage (în cazul în care este definit). Metoda returneaza pagina struct indicatorul pentru pagina fizică după ce poate a citit din memoria secundara. În cazul în care acest domeniu nopage metodă nu este definită, miezul iese în evidență o pagină goală.

int (* populați) (struct vm_area_struct * vm, nesemnate adresa lung, Len lung nesemnat,

pgprot_t prot, unsigned pgoff lung, int nonblock);

Această metodă permite kernel-ul pentru a „daune“, pagina în memorie înainte de acestea sunt disponibile în spațiul utilizator. De fapt, conducătorul auto nu este necesară pentru a pune în aplicare metoda populați.

memorie proces Harta

Ultima parte a puzzle-ului este un proces de management al memoriei, structura card de memorie, care deține toate celelalte structuri de date împreună. Fiecare proces din sistem (cu excepția câtorva fluxuri auxiliare in spatiul nucleu) are mm_struct struct (în anumite ) Care conține o listă a procesului de regiuni de memorie tabele virtuale de pagină și alte informații de control diverse biți agricole de memorie acasă, împreună cu un semafor (mmap_sem) și spinlock (page_table_lock). Un pointer la această structură poate fi găsită în structura problemei; în cazuri rare, în cazul în care conducătorul auto este necesar pentru a accesa, modul obișnuit este de a utiliza a curentului> mm. Rețineți că structura de gestionare a memoriei poate fi partajată între procese; de exemplu, acționează astfel punerea în aplicare a fluxurilor în Linux.

La care se încheie analiza noastră a structurilor de memorie în datele de management Linux. Acest lucru face, putem continua acum cu punerea în aplicare a apelului sistem mmap.