This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
linux-kernel-dev:capitole:capitol-03 [2015/09/09 11:22] razvan [Depanarea unui oops] |
linux-kernel-dev:capitole:capitol-03 [2016/08/31 07:50] (current) razvan [Resurse utile] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 3. Drivere de dispozitiv ====== | + | ====== 3. Kernel API ====== |
===== Subiecte abordate ===== | ===== Subiecte abordate ===== | ||
Line 5: | Line 5: | ||
* API-ul expus de kernel pentru module de kernel: printing, lucrul cu memoria, liste | * API-ul expus de kernel pentru module de kernel: printing, lucrul cu memoria, liste | ||
* Erori în kernel, depanarea erorilor | * Erori în kernel, depanarea erorilor | ||
- | * Dispozitive văzute în user space | + | |
- | * Dispozitive virtuale | + | |
- | * Operații pe dispozitive | + | |
===== Resurse utile ===== | ===== Resurse utile ===== | ||
- | * http://ocw.cs.pub.ro/courses/so2/laboratoare/lab03 | + | * [[https://www.kernel.org/doc/htmldocs/kernel-api/|The Linux Kernel API]] |
- | * http://ocw.cs.pub.ro/courses/so2/laboratoare/lab04 | + | * [[http://ocw.cs.pub.ro/courses/so2/laboratoare/lab03|SO2: Kernel API]] |
===== Exerciții ===== | ===== Exerciții ===== | ||
Line 108: | Line 107: | ||
</note> | </note> | ||
- | ==== ioctl în dispozitiv de tip caracter ==== | ||
- | |||
- | Comunicarea și interacțiunea dintre user space și kernel space se poate face prind dispozitive (//devices//). Acestea sunt vizibile utilizatorului ca intrări în sistemul de fișier (de obicei în ''/dev'') pe care acesta le poate opera. | ||
- | |||
- | În directorul ''ioctl-print/'' avem un modul de kernel care expunde dispozitivul ''/dev/print'' și care, la operații de tip ioctl (''Input/Output Control'') afișează un mesaj. Este un modul didactic, vrem să urmărim comportamentul ioctl. | ||
- | |||
- | Pentru a putea observa apelul ''ioctl()'' folosim și un modul de test rulabil din user space, care este compilat static în executabilul ''print_test''. | ||
- | |||
- | <note> | ||
- | Modulul de kernel se găsește în subdirectorul ''kernel/'' în vreme ce testul de user space se găsește în subdirectorul ''user/''. | ||
- | </note> | ||
- | |||
- | Atât fișierul de test cât și fișierul modul se copiază pe mașina virtuală pentru a putea testa funcționalitatea respectivă: afișarea unui mesaj la apelul ''ioctl()''. | ||
- | |||
- | După ce modulul este inserat, trebuie creat dispozitivul ''/dev/print'' cu ajutorul comenzii<code> | ||
- | mknod /dev/print c 42 0 | ||
- | </code> | ||
- | |||
- | Apoi se poate rula executabilul de test cu opțiunea aferentă pentru a invoca funcționalitatea de tip ioctl:<code> | ||
- | ./print_test p | ||
- | </code> | ||
- | |||
- | ==== Alocare și dezalocare la ioctl ==== | ||
- | |||
- | Adăugați două noi operații la ''ioctl'', astfel încât la una dintre ele să aloce o zonă de memorie de 10KB și să rețină pointer-ul rezultat într-o variabilă globală, iar la cealaltă să-l elibereze. | ||
- | |||
- | Nu va aloca dacă a fost deja alocată zona de memorie, nu o va elibera dacă a fost deja eliberată. | ||
- | |||
- | ==== Citire din dispozitiv ==== | ||
- | |||
- | Operațiile de tipul ''ioctl'' sunt operații de comandă/control. Pentru transfer de informație cel mai adesea follosim operații de tipul ''read'' și ''write''. Pentru început să folosim operația ''read''. | ||
- | |||
- | În directorul ''read-string/'' din arhiva de suport a capitolului se găsește o implementare de modul care întoarce un șir predefinit (//anaaremere//) la orice operație de citire. Practic, oricând folosim comanda ''cat'' pe dispozitivul afernet (''/dev/string'') ne va afișa șirul predefinit. | ||
- | |||
- | Compilați modululul și apoi copiați-l pe mașina virtuală QEMU și testați această funcționalitate. | ||
- | |||
- | <note tip> | ||
- | După ce modulul este inserat în kernel, va trebui să creați dispozitivul aferent. Pentru aceasta rulați, în mașina virtuală QEMU, comanda<code> | ||
- | mknod /dev/string c 43 0 | ||
- | </code> | ||
- | |||
- | Apoi, pentru a testa, folosiți comanda ''cat'' pe dispozitiv, pentru a citi șirul:<code> | ||
- | cat /dev/string | ||
- | </code> | ||
- | </note> | ||
- | |||
- | În modul vor fi, pentru fiecare apel al funcției ''string_read()'', afișate niște mesaje legat de numărul de octeți care s-au dorit citiți și numărul de octeți care s-a citit. De câte ori a fost apelată funcția ''string_read()''? Cum explicați mesajele afișate (în fapt ne interesează valorile de retur ale funcției)? | ||
- | |||
- | ==== Generator de caractere de 1 ==== | ||
- | |||
- | Creați un modul de kernel care expune un dispozitiv ''/dev/one'' care la citire generează o infinnitate de caractere de ''1''. Se oprește doar când cere spațiul utilizator să se oprească. Este similar cu ''/dev/zero''. | ||
- | |||
- | ==== Reply device ==== | ||
- | |||
- | Adăugați funcționalitatea de ''write'' modulului din directorul ''read-string/'' astfel încât sa și permită scrierea de mesaje în dispozitiv. După ce un mesaj este scris, același mesaj este citit de operațiile de citire. | ||
- | |||
- | <note tip> | ||
- | Pentru a scrie un mesaj într-un fișier, folosiți comanda:<code> | ||
- | echo "mesaj" > <fisier> | ||
- | </code> | ||
- | unde ''<fisier>'' este numele intrării în care vreți să scrieți, de exemplu ''/dev/string''. | ||
- | </note> | ||
- | |||
- | ==== Length device ==== | ||
- | |||
- | Actualizați modulul de mai sus astfel încât la citire să nu mai întoarcă șirul scris, ci un șir de cifre care să însemne lungimea șirului scris anterior. | ||