User Tools

Site Tools


linux-kernel-dev:capitole:capitol-03

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
linux-kernel-dev:capitole:capitol-03 [2015/09/08 22:30]
razvan
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 35: Line 34:
 </​note>​ </​note>​
  
-==== Eliberarea ​memorie ​alocate dinamic ==+==== Eliberarea ​memoriei ​alocate dinamic ==
  
 Pentru anularea încărcării memoriei, trebuie să eliberăm memoria alocată dinamică. Pentru anularea încărcării memoriei, trebuie să eliberăm memoria alocată dinamică.
  
 Pentru aceasta definiți un vector în care rețineți pointerii către zonele de memorie alocate. Apoi, în funcția de ''​exit''​ a modulului, folosiți funcția ''​kfree()''​ pentru a elibera memoria astfel alocată. Pentru aceasta definiți un vector în care rețineți pointerii către zonele de memorie alocate. Apoi, în funcția de ''​exit''​ a modulului, folosiți funcția ''​kfree()''​ pentru a elibera memoria astfel alocată.
 +
 +<note tip>
 +Vectorul trebuie definit ca variabilă globală ca să fie accesibil atât în funcția de inițializare cât și în funcția de ''​exit''​.
 +</​note>​
  
 ==== Afișarea listei de procese a sistemului ==== ==== Afișarea listei de procese a sistemului ====
Line 58: Line 61:
 Santinela listei dublu înlănțuite este dată de câmpul ''​children''​ al structurii ''​task_struct''​. Santinela listei dublu înlănțuite este dată de câmpul ''​children''​ al structurii ''​task_struct''​.
  
-Folosiți macro-ul ''​list_for_each''​ pentru a parcurge procesele copil și apoi macro-ul ''​list_entry''​ pentru a obține structura ''​task_struct''​ pentru fiecare proces din listă.+Folosiți macro-ul ''​list_for_each''​ pentru a parcurge procesele copil și apoi macro-ul ''​list_entry''​ pentru a obține structura ''​task_struct''​ pentru fiecare proces din listă. Câmpul din cadrul structurii ''​task_struct''​ care definește structura de tip listă care leagă toate procesele copil este ''​sibling''​.
 </​note>​ </​note>​
  
Line 73: Line 76:
 ==== Depanarea unui oops ==== ==== Depanarea unui oops ====
  
-Atunci când nucleul întâlnește o eroare afișează un mesaj de eroare similar //​Segmentation fault// numit //oops//. Este o indicație că ceva nepotrivit a avut loc; sistemul de operare continuă execuția, dar este posibil ca eroare ​să se propage.+Atunci când nucleul întâlnește o eroare afișează un mesaj de eroare similar //​Segmentation fault// numit //oops//. Este o indicație că ceva nepotrivit a avut loc; sistemul de operare continuă execuția, dar este posibil ca eroarea ​să se propage.
  
 Erorile grave se prezintă în formă de //kernel panic// și conduc la înghețarea sistemului. Erorile grave se prezintă în formă de //kernel panic// și conduc la înghețarea sistemului.
Line 104: 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. 
  
linux-kernel-dev/capitole/capitol-03.1441740645.txt.gz · Last modified: 2015/09/08 22:30 by razvan