This is an old revision of the document!
TODO
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
.
kernel/
în vreme ce testul de user space se găsește în subdirectorul user/
.
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
mknod /dev/print c 42 0
Apoi se poate rula executabilul de test cu opțiunea aferentă pentru a invoca funcționalitatea de tip ioctl:
./print_test p
Actualizați modulul anterior și 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ă.
include/util.h
.
Implementarea noilor operații o veți face în cadrul blocului switch
din funcția print_ioctl()
.
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.
mknod /dev/string c 43 0
Apoi, pentru a testa, folosiți comanda cat
pe dispozitiv, pentru a citi șirul:
cat /dev/string
Î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)?
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
.
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.
echo "mesaj" > <fisier>
unde <fisier>
este numele intrării în care vreți să scrieți, de exemplu /dev/string
.
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.