Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:laboratoare:lab11 [2016/05/09 19:42]
victor.ciurel fix links
so2:laboratoare:lab11 [2017/05/07 19:19] (current)
octavian.purdila update lxr links to use 4.9
Line 25: Line 25:
 În kernel-ul Linux există posibilitatea mapării unui spaţiu de adresă kernel într-un spaţiu de adresă utilizator. În acest fel se elimină overhead-ul datorat copierii informaţiei din user-space în kernel-space (şi invers). Acest lucru poate fi realizat prin intermediul unui device driver şi a interfeţei dispozitiv (''/​dev''​) a acestuia în user-space. În kernel-ul Linux există posibilitatea mapării unui spaţiu de adresă kernel într-un spaţiu de adresă utilizator. În acest fel se elimină overhead-ul datorat copierii informaţiei din user-space în kernel-space (şi invers). Acest lucru poate fi realizat prin intermediul unui device driver şi a interfeţei dispozitiv (''/​dev''​) a acestuia în user-space.
  
-Această facilitate poate fi folosită prin completarea operaţiei [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=3.13#L1532|mmap]] din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=3.13#L1521|struct file_operations]] asociată dispozitivului şi utilizând apelul ''​mmap''​ din user-space.+Această facilitate poate fi folosită prin completarea operaţiei [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​fs.h#​L1708|mmap]] din structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​fs.h#​L1696|struct file_operations]] asociată dispozitivului şi utilizând apelul ''​mmap''​ din user-space.
  
 ==== Structuri de lucru cu memoria ==== ==== Structuri de lucru cu memoria ====
Line 31: Line 31:
 Înainte de a discuta despre mecanismul de memory-mapping peste un dispozitiv, vom prezenta câteva din structurile de bază legate de subsistemul de management al memoriei în kernel-ul Linux. Înainte de a discuta despre mecanismul de memory-mapping peste un dispozitiv, vom prezenta câteva din structurile de bază legate de subsistemul de management al memoriei în kernel-ul Linux.
  
-Cateva din structurile importante sunt: [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L31|struct page]], [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L241|struct vm_area_struct]] şi [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L344|struct mm_struct]].+Cateva din structurile importante sunt: [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L45|struct page]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L300|struct vm_area_struct]] şi [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L396|struct mm_struct]].
  
 ==== Structura ''​page''​ ==== ==== Structura ''​page''​ ====
  
-Structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L31|struct page]] este utilizată pentru a încorpora informaţii despre toate paginile fizice din sistem. Kernel-ul deţine o structură ''​struct page''​ pentru toate paginile din sistem+Structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L45|struct page]] este utilizată pentru a încorpora informaţii despre toate paginile fizice din sistem. Kernel-ul deţine o structură ''​struct page''​ pentru toate paginile din sistem.
- +
-Printre câmpurile importante ale acestei structuri amintim: +
-  *[[http://​lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?​v=3.13#​L117|_count]],​ contorul de utilizare al paginii; când acesta devine 0 pagina este adăugată la lista de pagini libere; +
-  *[[http://​lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?​v=3.13#​L180|virtual]],​ adresa virtuală în spaţiul kernel asociată acestei pagini fizice; paginile din ''​ZONE_DMA''​ sau ''​ZONE_NORMAL''​ sunt tot timpul mapate; paginile din ''​ZONE_HIHGMEM''​ nu sunt tot timpul mapate; Aceste constante se găsesc în [[http://​lxr.free-electrons.com/​source/​include/​linux/​mmzone.h?​v=3.13#​L261|enum zone_type]] +
-  *[[http://​lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?​v=3.13#​L46|flags]],​ un set de flag-uri care descriu atributele paginii.+
  
 Există numeroase funcţii care interacţionează cu această structură: Există numeroase funcţii care interacţionează cu această structură:
-  *[[http://lxr.free-electrons.com/​source/​arch/​x86/​include/​asm/​page.h?v=3.13#L63|virt_to_page]] întoarce pagina asociată unei adrese virtuale; +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​arch/​x86/​include/​asm/​page.h#​L68|virt_to_page]] întoarce pagina asociată unei adrese virtuale; 
-  *[[http://lxr.free-electrons.com/​source/​include/​asm-generic/​memory_model.h?v=3.13#L73|pfn_to_page]] întoarce pagina asociată pentru un număr de pagină (''​page frame number''​);​ +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​asm-generic/​memory_model.h#​L81|pfn_to_page]] întoarce pagina asociată pentru un număr de pagină (''​page frame number''​);​ 
-  *[[http://lxr.free-electrons.com/​source/​mm/highmem.c?v=3.13#L348|page_address]] întoarce adresa virtuală a paginii transmise ca parametru.+  *[[http://elixir.free-electrons.com/linux/v4.9/source/include/linux/mm.h#L1013|page_address]] întoarce adresa virtuală a paginii transmise ca parametru.
  
 ==== Structura ''​vm_area_struct''​ ==== ==== Structura ''​vm_area_struct''​ ====
  
-Structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L246|struct vm_area_struct]] deţine informaţii despre o zonă de memorie virtuală contiguă. Zonele de memorie ale unui proces pot fi vizualizate inspectând ''​procfs'':​+Structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L300|struct vm_area_struct]] deţine informaţii despre o zonă de memorie virtuală contiguă. Zonele de memorie ale unui proces pot fi vizualizate inspectând ''​procfs'':​
  
 <code bash> <code bash>
Line 69: Line 64:
  
 O structură ''​vm_area_struct''​ este creată la fiecare apel ''​mmap''​ din user-space. Un driver care are suport pentru operaţia de ''​mmap''​ trebuie să completeze şi să iniţializeze structura ''​vm_area_struct''​ asociată. Cele mai importante câmpuri ale acestei structuri sunt: O structură ''​vm_area_struct''​ este creată la fiecare apel ''​mmap''​ din user-space. Un driver care are suport pentru operaţia de ''​mmap''​ trebuie să completeze şi să iniţializeze structura ''​vm_area_struct''​ asociată. Cele mai importante câmpuri ale acestei structuri sunt:
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L249|vm_start]],​ [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L250|vm_end]], reprezintă începutul, respectiv, sfârşitul zonei de memorie (aceste câmpuri apar şi in ''/​proc/​*/​maps''​);​ +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L303|vm_start]],​ [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L304|vm_end]], reprezintă începutul, respectiv, sfârşitul zonei de memorie (aceste câmpuri apar şi in ''/​proc/​*/​maps''​);​ 
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L301|vm_file]], pointer-ul la structura de fişier asociată (dacă există); +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L351|vm_file]], pointer-ul la structura de fişier asociată (dacă există); 
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L299|vm_pgoff]],​ offset-ul zonei în cadrul fişierului;​ +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L349|vm_pgoff]],​ offset-ul zonei în cadrul fişierului;​ 
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L270|vm_flags]],​ un set de indicatori;​ +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L324|vm_flags]],​ un set de indicatori;​ 
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L296|vm_ops]], un set de funcţii de lucru asupra acestei zone. +  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L346|vm_ops]], un set de funcţii de lucru asupra acestei zone. 
-  *[[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L254|vm_next]], [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L254|vm_prev]], ''​vm_area''​-urile aferente unui proces sunt înlănțuite printr-o listă+  *[[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L308|vm_next]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L308|vm_prev]], ''​vm_area''​-urile aferente unui proces sunt înlănțuite printr-o listă
  
 ==== Structura ''​mm_struct''​ ==== ==== Structura ''​mm_struct''​ ====
  
-Structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L344|struct mm_struct]] înglobează toate zonele de memorie asociate unui proces; folosind câmpul ''​mm''​ al structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​sched.h?v=3.13#L1042|task_struct]] se poate obţine structura ''​mm_struct''​ asociată procesului curent.+Structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mm_types.h#​L396|struct mm_struct]] înglobează toate zonele de memorie asociate unui proces; folosind câmpul ''​mm''​ al structurii [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​sched.h#​L1475|task_struct]] se poate obţine structura ''​mm_struct''​ asociată procesului curent.
  
 ==== Maparea memoriei ==== ==== Maparea memoriei ====
Line 84: Line 79:
 Maparea memoriei (''​memory mapping''​) este una dintre cele mai interesante caracteristici ale unui sistem Unix. Din punct de vedere al unui driver, facilitatea de ''​memory-mapping''​ permite accesul direct al memoriei unui dispozitiv din user-space. Maparea memoriei (''​memory mapping''​) este una dintre cele mai interesante caracteristici ale unui sistem Unix. Din punct de vedere al unui driver, facilitatea de ''​memory-mapping''​ permite accesul direct al memoriei unui dispozitiv din user-space.
  
-Pentru a asocia unui driver o operaţie ''​mmap'',​ trebuie utilizat câmpul [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=3.13#L1532|mmap]] din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=3.13#L1521|struct file_operations]] asociată dispozitivului. Metoda astfel asociată este utilizată în cazul unui apel ''​mmap''​ din user-space.+Pentru a asocia unui driver o operaţie ''​mmap'',​ trebuie utilizat câmpul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​fs.h#​L1708|mmap]] din structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​fs.h#​L1696|struct file_operations]] asociată dispozitivului. Metoda astfel asociată este utilizată în cazul unui apel ''​mmap''​ din user-space.
  
 ==== User-space ==== ==== User-space ====
Line 107: Line 102:
 ===== ''​remap_pfn_range''​ ===== ===== ''​remap_pfn_range''​ =====
  
-Pentru maparea unui spaţiu de memorie fizică în spaţiul virtual utilizator, reprezentat de structura ''​struct vm_area_struct'',​ se folosește apelul [[http://lxr.free-electrons.com/​source/​mm/memory.c?​v=3.13#L2319| remap_pfn_range]]. Acesta va mapa un spaţiu de adresă fizic contiguu în spaţiul virtual reprezentat de ''​struct vm_area_struct'':​+Pentru maparea unui spaţiu de memorie fizică în spaţiul virtual utilizator, reprezentat de structura ''​struct vm_area_struct'',​ se folosește apelul [[http://elixir.free-electrons.com/linux/v4.9/source/include/linux/mm.h#L2193|remap_pfn_range]]. Acesta va mapa un spaţiu de adresă fizic contiguu în spaţiul virtual reprezentat de ''​struct vm_area_struct'':​
 <code C> <code C>
 int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
Line 116: Line 111:
   *''​vma'',​ spaţiul de memorie virtuală în cadrul căruia se face maparea;   *''​vma'',​ spaţiul de memorie virtuală în cadrul căruia se face maparea;
   *''​addr'',​ spaţiul virtual de adresă de unde se începe remaparea; se vor construi tabele de pagini pentru spaţiul virtual de adresă cuprins intre ''​addr''​ şi ''​addr + size'';​   *''​addr'',​ spaţiul virtual de adresă de unde se începe remaparea; se vor construi tabele de pagini pentru spaţiul virtual de adresă cuprins intre ''​addr''​ şi ''​addr + size'';​
-  *''​pfn'',​ numărul paginii fizice (''​page frame number''​) în care se mapează adresa virtuală; de obicei acesta se obţine prin shifting-ul adresei fizice [[http://lxr.free-electrons.com/​source/​include/​asm-generic/page.h?v=3.13#L15| PAGE_SHIFT]] biţi la dreapta+  *''​pfn'',​ numărul paginii fizice (''​page frame number''​) în care se mapează adresa virtuală; de obicei acesta se obţine prin shifting-ul adresei fizice [[http://elixir.free-electrons.com/linux/v4.9/source/arch/x86/​include/​asm/​page_types.h#L8|PAGE_SHIFT]] biţi la dreapta
   *''​size'',​ dimensiunea (în octeţi) a spaţiului de memorie care va fi remapat;   *''​size'',​ dimensiunea (în octeţi) a spaţiului de memorie care va fi remapat;
   *''​prot'',​ caracteristicile de protecţie pentru noul spaţiu de adresă.   *''​prot'',​ caracteristicile de protecţie pentru noul spaţiu de adresă.
Line 136: Line 131:
 În exemplul de mai sus se realizează o mapare a zonei fizice începând de la numărul de pagină ''​phys_pgoff''​ în întreg spaţiul virtual de adresă reprezentat de ''​vma''​. În exemplul de mai sus se realizează o mapare a zonei fizice începând de la numărul de pagină ''​phys_pgoff''​ în întreg spaţiul virtual de adresă reprezentat de ''​vma''​.
  
-Două funcţii care sunt utile sunt cele de translatare a unei adrese virtuale din spaţiul kernel în adrese fizice. Acestea sunt [[http://lxr.free-electrons.com/​source/​arch/​x86/​include/​asm/​io.h?v=3.13#L111| virt_to_phys]] pentru adrese alocate folosind ''​kmalloc''​ şi [[http://lxr.free-electrons.com/​source/​mm/vmalloc.c?v=3.13#L259| vmalloc_to_pfn]] pentru adrese alocate folosind ''​vmalloc''​.+Două funcţii care sunt utile sunt cele de translatare a unei adrese virtuale din spaţiul kernel în adrese fizice. Acestea sunt [[http://elixir.free-electrons.com/linux/v4.9/​source/​arch/​x86/​include/​asm/​io.h#​L118| virt_to_phys]] pentru adrese alocate folosind ''​kmalloc''​ şi [[http://elixir.free-electrons.com/linux/v4.9/source/include/linux/mm.h#L473|vmalloc_to_pfn]] pentru adrese alocate folosind ''​vmalloc''​.
  
 Astfel, numărul de pagină ''​phys_pgoff''​ din exemplul de mai sus se va obţine în cazul unei adrese ''​kmalloc_area''​ alocate folosind ''​kmalloc''​ astfel: Astfel, numărul de pagină ''​phys_pgoff''​ din exemplul de mai sus se va obţine în cazul unei adrese ''​kmalloc_area''​ alocate folosind ''​kmalloc''​ astfel:
Line 155: Line 150:
 ===== ''​SetPageReserved''/''​ClearPageReserved''​ ===== ===== ''​SetPageReserved''/''​ClearPageReserved''​ =====
  
-Înainte de a fi utilizată, unei pagini îi va trebui activat bitul [[http://lxr.free-electrons.com/​source/​include/​linux/​page-flags.h?v=3.13#​L85|PG_reserved]]. Acest bit înseamnă că pagina nu poate fi evacuată pe disk (''​swap''​). Activarea se realizează cu ajutorul macroului [[http://lxr.free-electrons.com/​source/​include/​linux/​page-flags.h?v=3.13#L182|SetPageReserved]]. Macrodefiniţia primeşte ca parametru un pointer către structura de pagină, ''​struct page'',​ care se obţine din adresa virtuală din kernel cu ajutorul funcţiei ''​virt_to_page'',​ pentru adrese alocate folosind ''​kmalloc'':​+Înainte de a fi utilizată, unei pagini îi va trebui activat bitul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​page-flags.h#​L85|PG_reserved]]. Acest bit înseamnă că pagina nu poate fi evacuată pe disk (''​swap''​). Activarea se realizează cu ajutorul macroului [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​page-flags.h#​L194|SetPageReserved]]. Macrodefiniţia primeşte ca parametru un pointer către structura de pagină, ''​struct page'',​ care se obţine din adresa virtuală din kernel cu ajutorul funcţiei ''​virt_to_page'',​ pentru adrese alocate folosind ''​kmalloc'':​
 <code C> <code C>
 #define NPAGES 16 #define NPAGES 16
Line 166: Line 161:
 } }
 </​code>​ </​code>​
-şi cu ajutorul funcţiei [[http://lxr.free-electrons.com/​source/​mm/​vmalloc.c?v=3.13#L225|vmalloc_to_page]] pentru adrese alocate folosind ''​vmalloc'':​+şi cu ajutorul funcţiei [[http://elixir.free-electrons.com/linux/v4.9/​source/​mm/​vmalloc.c#​L235|vmalloc_to_page]] pentru adrese alocate folosind ''​vmalloc'':​
 <code C> <code C>
 #define NPAGES 16 #define NPAGES 16
Line 178: Line 173:
 </​code>​ </​code>​
  
-Înainte de eliberarea paginii (''​kfree''/''​vfree''​),​ bitul de pagină rezervată trebuie dezactivat cu ajutorul macroului [[http://​lxr.free-electrons.com/​source/​include/​linux/​page-flags.h?​v=3.13#​L185|ClearPageReserved]]. Acesta primeşte ca parametru acelaşi pointer către o structura de pagină care a fost dat la ''​SetPageReserved''​.+Înainte de eliberarea paginii (''​kfree''/''​vfree''​),​ bitul de pagină rezervată trebuie dezactivat cu ajutorul macroului [[http://​lxr.free-electrons.com/​source/​include/​linux/​page-flags.h?​v=4.9#​L185|ClearPageReserved]]. Acesta primeşte ca parametru acelaşi pointer către o structura de pagină care a fost dat la ''​SetPageReserved''​.
  
  
so2/laboratoare/lab11.txt · Last modified: 2017/05/07 19:19 by octavian.purdila
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0