This shows you the differences between two versions of the page.
so2:laboratoare:lab03 [2018/03/04 20:21] ionel.ghita [Accesarea memoriei] |
so2:laboratoare:lab03 [2018/03/04 20:32] (current) ionel.ghita [Resurse utile] |
||
---|---|---|---|
Line 73: | Line 73: | ||
</code> | </code> | ||
- | Lista exhaustivă a erorilor și o sumară explicație găsiți în [[http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno-base.h?v=4.9| include/asm-generic/errno-base.h]] și [[http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno.h?v=4.9 | include/asm-generic/ernno.h]]. | + | Lista exhaustivă a erorilor și o sumară explicație găsiți în [[http://elixir.bootlin.com/linux/v4.9/source/include/uapi/asm-generic/errno-base.h?| include/asm-generic/errno-base.h]] și [[http://elixir.bootlin.com/linux/v4.9/source/include/uapi/asm-generic/errno.h? | include/asm-generic/ernno.h]]. |
==== Șiruri de caractere ==== | ==== Șiruri de caractere ==== | ||
- | În Linux, programatorului de kernel i se pun la dispoziție funcțiile uzuale de lucru pe șiruri: ''strcpy'', ''strncpy'', ''strlcpy'', ''strcat'', ''strncat'', ''strlcat'', ''strcmp'', ''strncmp'', ''strnicmp'', ''strchr'', ''strnchr'', ''strrchr'', ''strstr'', ''strlen'', ''memset'', ''memcpy'', ''memmove'', ''memscan'', ''memcmp'', ''memchr''. Aceste funcții sunt declarate în headerul [[http://lxr.free-electrons.com/source/include/linux/string.h?v=4.9|include/linux/string.h]] și sunt implementate în kernel în fișierul [[http://lxr.free-electrons.com/source/lib/string.c?v=4.9|lib/string.c]]. | + | În Linux, programatorului de kernel i se pun la dispoziție funcțiile uzuale de lucru pe șiruri: ''strcpy'', ''strncpy'', ''strlcpy'', ''strcat'', ''strncat'', ''strlcat'', ''strcmp'', ''strncmp'', ''strnicmp'', ''strchr'', ''strnchr'', ''strrchr'', ''strstr'', ''strlen'', ''memset'', ''memcpy'', ''memmove'', ''memscan'', ''memcmp'', ''memchr''. Aceste funcții sunt declarate în headerul [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/string.h?|include/linux/string.h]] și sunt implementate în kernel în fișierul [[http://elixir.bootlin.com/linux/v4.9/source/lib/string.c?|lib/string.c]]. |
==== printk ==== | ==== printk ==== | ||
- | Echivalentul ''printf'' în kernel este ''printk'', definit în [[http://lxr.free-electrons.com/source/include/linux/printk.h?v=4.9|include/linux/printk.h]]. Sintaxa printk seamănă foarte mult cu cea a printf. Primul parametru al printk decide categoria de mesaje în care se încadrează mesajul curent: | + | Echivalentul ''printf'' în kernel este ''printk'', definit în [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/printk.h?|include/linux/printk.h]]. Sintaxa printk seamănă foarte mult cu cea a printf. Primul parametru al printk decide categoria de mesaje în care se încadrează mesajul curent: |
<code C> | <code C> | ||
Line 117: | Line 117: | ||
==== Alocare memorie ==== | ==== Alocare memorie ==== | ||
- | În Linux se poate aloca doar memorie **rezidentă**, cu ajutorul apelului [[http://lxr.free-electrons.com/source/include/linux/slab.h?v=4.9#L425 | kmalloc]]. Un apel tipic kmalloc este prezentat în continuare: | + | În Linux se poate aloca doar memorie **rezidentă**, cu ajutorul apelului [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/slab.h?#L425 | kmalloc]]. Un apel tipic kmalloc este prezentat în continuare: |
<code C> | <code C> | ||
Line 133: | Line 133: | ||
*''GFP_ATOMIC'' - atunci când se folosește această valoare se garantează ca funcția kmalloc nu suspendă procesul curent; poate fi folosită oricând. | *''GFP_ATOMIC'' - atunci când se folosește această valoare se garantează ca funcția kmalloc nu suspendă procesul curent; poate fi folosită oricând. | ||
- | Complementara funcției ''kmalloc'' este [[http://lxr.free-electrons.com/source/mm/slab.c?v=4.9#L3804 | kfree]], funcție ce primește ca argument o zonă alocată de ''kmalloc''. Această funcție nu suspendă procesul curent și, în consecință, poate fi apelată din orice context. | + | Complementara funcției ''kmalloc'' este [[http://elixir.bootlin.com/linux/v4.9/source/mm/slab.c?#L3804 | kfree]], funcție ce primește ca argument o zonă alocată de ''kmalloc''. Această funcție nu suspendă procesul curent și, în consecință, poate fi apelată din orice context. |
==== Liste ==== | ==== Liste ==== | ||
- | Pentru că listele înlănțuite sunt deseori folosite, Linux kernel API pune la dispoziție o modalitate unitară de definire și folosire a listelor. Aceasta implică folosirea unui element de tipul ''struct list_head'' în cadrul structurii pe care vrem să o considerăm nod al unei liste. Structura ''list_head'' este definită în [[ http://lxr.free-electrons.com/source/include/linux/list.h?v=4.9 | include/linux/list.h]] alături de toate celelalte funcții ce lucrează pe liste. Codul următor arată definiția structurii ''list_head'' și folosirea unui element din acest tip într-o altă structură bine cunoscută din kernelul Linux: | + | Pentru că listele înlănțuite sunt deseori folosite, Linux kernel API pune la dispoziție o modalitate unitară de definire și folosire a listelor. Aceasta implică folosirea unui element de tipul ''struct list_head'' în cadrul structurii pe care vrem să o considerăm nod al unei liste. Structura ''list_head'' este definită în [[ http://elixir.bootlin.com/linux/v4.9/source/include/linux/list.h? | include/linux/list.h]] alături de toate celelalte funcții ce lucrează pe liste. Codul următor arată definiția structurii ''list_head'' și folosirea unui element din acest tip într-o altă structură bine cunoscută din kernelul Linux: |
<code C> | <code C> | ||
Line 223: | Line 223: | ||
Din exemplul de mai sus se observă că modalitatea de definire și folosire a unei liste (dublu înlănțuite) este generică și, în același timp, nu introduce un overhead suplimentar. Structura ''list_head'' este folosită pentru a menține legăturile între elementele listei. Se observă, de asemenea, că iterarea prin listă se face tot cu ajutorul acestei structuri, iar obținerea elementelor din listă se face cu ajutorul ''list_entry''. Această idee de implementare și folosire a unei liste nu este nouă, ea fiind descrisă în ''The Art of Computer Programming'' de Donald Knuth în anii '80. | Din exemplul de mai sus se observă că modalitatea de definire și folosire a unei liste (dublu înlănțuite) este generică și, în același timp, nu introduce un overhead suplimentar. Structura ''list_head'' este folosită pentru a menține legăturile între elementele listei. Se observă, de asemenea, că iterarea prin listă se face tot cu ajutorul acestei structuri, iar obținerea elementelor din listă se face cu ajutorul ''list_entry''. Această idee de implementare și folosire a unei liste nu este nouă, ea fiind descrisă în ''The Art of Computer Programming'' de Donald Knuth în anii '80. | ||
- | Mai multe funcții și macrodefiniții de lucru cu liste kernel sunt prezentate și explicate în headerul [[http://lxr.free-electrons.com/source/include/linux/list.h?v=4.9 | include/linux/list.h]]. | + | Mai multe funcții și macrodefiniții de lucru cu liste kernel sunt prezentate și explicate în headerul [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/list.h? | include/linux/list.h]]. |
==== Locking ==== | ==== Locking ==== | ||
==== Spinlock-uri ==== | ==== Spinlock-uri ==== | ||
- | ''spinlock_t'' (definit in [[http://lxr.free-electrons.com/source/include/linux/spinlock.h?v=4.9 | linux/spinlock.h]]) este tipul de bază ce implementează conceptul de spinlock în Linux. El descrie un spinlock, iar operațiile asociate cu un spinlock sunt ''spin_lock_init'', ''spin_lock'', ''spin_unlock''. Un exemplu de utilizare este prezentat mai jos: | + | ''spinlock_t'' (definit in [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/spinlock.h? | linux/spinlock.h]]) este tipul de bază ce implementează conceptul de spinlock în Linux. El descrie un spinlock, iar operațiile asociate cu un spinlock sunt ''spin_lock_init'', ''spin_lock'', ''spin_unlock''. Un exemplu de utilizare este prezentat mai jos: |
<code C> | <code C> | ||
Line 287: | Line 287: | ||
==== Mutex ==== | ==== Mutex ==== | ||
- | Un mutex este reprezentat de o variabilă de tipul ''struct mutex'' (definit în [[http://lxr.free-electrons.com/source/include/linux/mutex.h?v=4.9#L22 | linux/mutex.h]]). Funcțiile și macro-urile pentru lucrul cu mutex sunt prezentate în continuare: | + | Un mutex este reprezentat de o variabilă de tipul ''struct mutex'' (definit în [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/mutex.h?#L22 | linux/mutex.h]]). Funcțiile și macro-urile pentru lucrul cu mutex sunt prezentate în continuare: |
<code C> | <code C> | ||
Line 308: | Line 308: | ||
==== Variabile atomice ==== | ==== Variabile atomice ==== | ||
- | De multe ori, este nevoie doar de sincronizarea accesului la o variabilă simplă, de exemplu un contor. Pentru aceasta se poate folosi o variabilă de tip ''atomic_t'' (definit în [[http://lxr.free-electrons.com/source/include/linux/atomic.h?v=4.9 | include/linux/atomic.h]]) care ține o valoare întreagă. Mai jos sunt prezentate unele operații care pot fi efectuate asupra unei variabile ''atomic_t'': | + | De multe ori, este nevoie doar de sincronizarea accesului la o variabilă simplă, de exemplu un contor. Pentru aceasta se poate folosi o variabilă de tip ''atomic_t'' (definit în [[http://elixir.bootlin.com/linux/v4.9/source/include/linux/atomic.h? | include/linux/atomic.h]]) care ține o valoare întreagă. Mai jos sunt prezentate unele operații care pot fi efectuate asupra unei variabile ''atomic_t'': |
<code C> | <code C> | ||
Line 417: | Line 417: | ||
==== Operatii atomice pe biți ==== | ==== Operatii atomice pe biți ==== | ||
- | Kernelul pune la dispoziție un set de funcții (în [[http://lxr.free-electrons.com/source/include/asm-generic/bitops/atomic.h?v=4.9#L50 | asm/bitops.h]]) care modifică sau testează biți în mod atomic. | + | Kernelul pune la dispoziție un set de funcții (în [[http://elixir.bootlin.com/linux/v4.9/source/include/asm-generic/bitops/atomic.h?#L50 | asm/bitops.h]]) care modifică sau testează biți în mod atomic. |
<code C> | <code C> | ||
Line 438: | Line 438: | ||
* [[http://lwn.net/images/pdf/LDD3/ch08.pdf | Chapter 8. Allocating Memory]] | * [[http://lwn.net/images/pdf/LDD3/ch08.pdf | Chapter 8. Allocating Memory]] | ||
* [[http://lwn.net/images/pdf/LDD3/ch11.pdf | Chapter 11. Data Types in the Kernel]] | * [[http://lwn.net/images/pdf/LDD3/ch11.pdf | Chapter 11. Data Types in the Kernel]] | ||
- | - [[http://www.gnugeneration.com/books/linux/2.6.20/kernel-api/ | The Linux Kernel API]] | + | - [[https://www.kernel.org/doc/htmldocs/kernel-api/ | The Linux Kernel API]] |
- [[http://isis.poly.edu/kulesh/stuff/src/klist/ | Linux Kernel Linked-List Explained]] | - [[http://isis.poly.edu/kulesh/stuff/src/klist/ | Linux Kernel Linked-List Explained]] | ||
- [[http://kernelbook.sourceforge.net/kernel-locking.html/ | Unreliable Guide To Locking]] | - [[http://kernelbook.sourceforge.net/kernel-locking.html/ | Unreliable Guide To Locking]] | ||
- [[http://excess.org/article/2008/07/oclug-june-kernel-walkthrough/ | Linux Kernel Walkthrough Screencast]] | - [[http://excess.org/article/2008/07/oclug-june-kernel-walkthrough/ | Linux Kernel Walkthrough Screencast]] | ||
- | - [[http://linuxwell.com/2012/11/10/magical-container_of-macro/| Magical container_of() Macro]] | + | - [[http://radek.io/2012/11/10/magical-container_of-macro/| Magical container_of() Macro]] |