Differences

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

Link to this comparison view

so2:laboratoare:lab12:exercitii [2018/05/15 20:21]
ionel.ghita
so2:laboratoare:lab12:exercitii [2019/05/20 14:32] (current)
razvan.deaconescu [1. [2p] Implementare bus]
Line 101: Line 101:
   * funcțiile ''​pnp_device_probe'',​ ''​pnp_bus_match'',​ ''​pnp_register_driver''​ și variabila ''​pnp_bus_type''​.   * funcțiile ''​pnp_device_probe'',​ ''​pnp_bus_match'',​ ''​pnp_register_driver''​ și variabila ''​pnp_bus_type''​.
  
-===== [1p] BONUS: ​Completare formular de feedback =====+===== Completare formular de feedback =====
  
-Apreciem opinia voastră legată de activitățile cursului de SO2. Ne ajută să îmbunătățim cursul și să facem materia cât mai accesibilă și interesantă. Pentru această vă rugăm să completați [[http://cs.curs.pub.ro/​2016/blocks/​feedbackacs/view.php?courseid=150&​blockid=3269|formularul de feedback de pe cs.curs.pub.ro]] (trebuie să fiți autentificați și înrolați în cadrul cursului). Vă mulțumim! +Apreciem opinia voastră legată de activitățile cursului de SO2. Ne ajută să îmbunătățim cursul și să facem materia cât mai accesibilă și interesantă. Pentru această vă rugăm să completați [[https://acs.curs.pub.ro/​2018/course/view.php?id=295|formularul de feedback de pe cs.curs.pub.ro]] (trebuie să fiți autentificați și înrolați în cadrul cursului). Vă mulțumim!
-===== [6.5p] Linux Device Model =====+
  
-În prima parte ne propunem să ne familiarizăm cu modelul ''​Linux Device Model''​ șreflectarea acestuia în userspace prin intermediul sistemului virtual de fișiere ''​sysfs''​. Vom analiza ​implementarea ​magistralelor și modul în care device driverele se conectează la o magistrală. ​Pentru început, vom lucra cu magistrală ​virtuală, definită în modulul ​''​mybus.ko'' ​din subdirectorul ​''​virtual_bus/​mybus/​'' ​la care vom atașa driverul ''​mydriver.ko''​ din subdirectorul ​''​virtual_bus/​mydriver''​.+==== 1. [2p] Implementare bus ==== 
 + 
 +Analizațconținutul ​fișierului ​''​bex.c''​, care conține ​implementarea ​unui driver de magistrală. ​Urmăriți comentariile marcate ​cu ''​TODO 1''​ pentru a implementa părțile ce lipsesc: înregistrați driverul de magistrală ​și adăugați un nou devicenumit ''​root''​, cu tipul ''​none''​ și versiunea ​''​1''​.
  
 <note tip> <note tip>
-În rezolvarea acestui exerciţiu vă veţîntâlni cu:  +Aruncațo privire pe implementarea funcției ​''​bex_add_dev()''​.
-  * ''​my_bus_type''​(mybus.c): variabilă globală pentru tipul de magistrală +
-  * ''​my_bus_device''​(mybus.c): variabilă globală pentru dispozitivul magistralei +
-  * ''​my_device''​(virtual_bus.h):​ structură folosită pentru dispozitivele ce se conectează la magistrală +
-  * ''​my_driver''​(virtual_bus.h):​ structură folosită pentru driverul care lucrează cu dispozitivele ce se conectează la magistrală +
-  * ''​dev_data''​(mydriver.c):​ variabilă globală ce menţine datele necesare driverului+
 </​note>​ </​note>​
-==== 1. [1p] Implementare magistrală ==== 
- 
-Intrați în directorul ''​virtual_bus/​mybus'',​ unde găsiți implementarea unei magistrale ''​mybus'',​ așa cum este descrisă în laborator. Analizați conținutul fișierelor ''​mybus/​mybus.c''​ și ''​include/​virtual_bus.h''​. 
-Observaţi că la încărcarea modulului se înregistrează atât o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L109|bus_type]],​ reprezentând tipul de magistrală,​ cât și o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|device]],​ reprezentând dispozitivul efectiv al magistralei. ​ 
- 
-Compilați și inserați modulul. 
-Verificaţi că tipul de magistrală apare în /sys/bus, iar dispozitivul în /​sys/​devices. 
-Scoateți modulul şi observaţi că intrările din sysfs sunt înlăturate. 
- 
-Modificați sursa astfel încât intrările pentru magistrală și dispozitivul asociat să fie ''​virtualbus'',​ respectiv ''​virtualbus0''​. 
  
 <note tip> <note tip>
-Recitiți secțiunile [[:​so2:​laboratoare:​lab12#​magistrale|Magistrale]] ​și [[:​so2:​laboratoare:​lab12#​dispozitive|Dispozitive]] din laborator.+Înregistrarea și deînregistrarea o faceți folosind respectiv funcțiile ''​bus_register()'' ​și ''​bus_unregister()''​.
 </​note>​ </​note>​
  
-Pentru verificare trebuie să se fi creat pe mașina virtuală în ''/​sys'' ​intrările aferente magistralei (''​virtualbus''​) șdispozitivului părinte (''virtualbus0''​):<​code>​ +Compilați, copiați modulul ​pe mașina virtuală, încărcați-l în kernel și verificați faptul că dispozitivul de tip magistrală este vizibil ​în ''/​sys/bus''​. De asemenea, verificațcă dispozitivul este vizibil în ''/​sys/​bus/​bex/devices.''​.
-# ls /sys/bus/virtualbus/​ +
-# ls /sys/devices/​virtualbus0/​ +
-</​code>​+
  
-==== 2. [2p] Conectare driver la magistrală ====+Eliminați modulul și observați că intrările din ''​sysfs''​ sunt eliminate.
  
-Intrați în directorul ''​virtual_bus/​mydriver'',​ unde găsițimplementarea unui device driver de tip caracter.+==== 2. [2p] Adăugare atribute pentru tip șversiune ====
  
-Modificați sursa astfel încât să respecte modelul ​''​Linux Device Model''​. Dispozitivul ​''​echo''​ se va conecta la magistrala virtualbus de la exercițiul anterior, având un driver asociat ''​echo''​. ​Numele driverului și al dispozitivului trebuie să fie identice. +Adăugați două atribute read-only: ​''​type'' ​și ''​version''​. Urmăriți comentariile ​marcate cu ''​TODO 2''​.
- +
-Urmăriți comentariile ''​TODO 2''​ din cod și exemplele de înregistrare dispozitiv/​driver din laborator: [[:​so2:​laboratoare:​lab12#​dispozitive|înregistrare dispozitiv]],​ [[:​so2:​laboratoare:​lab12#​drivere|înregistrare driver]]. +
- +
-Pentru a vă conecta la magistrala ''​virtualbus'',​ va trebui să folosiți funcțiile și tipurile de driver/​device exportate de aceasta. +
- +
-În structura ''​struct my_device_data''​ adăugați un câmp de tipul ''​struct my_device''​ (tip de date definit în ''​include/​virtual_bus.h''​). Câmpurile structurii ''​my_device''​ vor fi inițializate în funcția ''​my_init''​. +
- +
-Definiți o variabilă de tipul ''​struct my_driver''​ şi inițializați pentru aceasta modulul şi numele driver-ului. Înregistraţi driverul în funcţia ''​my_init''​.+
  
 <note tip> <note tip>
-Parcurgeți secțiunea [[:​so2:​laboratoare:​lab12#​drivere|Drivere]] din laborator. Urmărițexemplele de cod.+Va trebui să adăugați cele două atribute ''​type''​ ș''​version''​ în structura ''​bex_dev_attrs''​ pe modelul: 
 +<​code>​ 
 +&​dev_attr_<​insert-attribute-type-here>​.attr, 
 +</​code>​
 </​note>​ </​note>​
  
-<note tip> +Observați că cele două atribute noi sunt vizibile în ''​/​sys/​bus/​bex/​devices/​root''​. ​Verificați conținutul acestor atribute.
-Trebuie să înregistrați / deînregistrați variabilele de tipul ''​struct my_device'' ​și ''​struct my_driver''​ în funcția de init / exit a modululuiPentru aceasta folosiți funcțiile ''​my_register_driver''​ / ''​my_unregister_driver'',​ respectiv ''​my_register_device''​ / ''​my_unregister_device'',​ definite în fișierul ''​mybus.c''​. +
-</​note>​+
  
-<note tip> +O implementare pentru ​funcția de afișare ​de type este
-Pentru a transmite primul argument (magistrala) ​funcției ''​bus_find_device''​ folosiți o expresie ​de forma ''​mydriver.driver.bus''​. +
-</​note>​+
  
-În cadrul funcţiei ''​my_init''​iniţializaţi dispozitivul şi înregistraţi-lVor trebui completate cel puțin câmpurile ''​name'' ​și ''​driver''​.+<code c> 
 +static ssize_t 
 +type_show(struct device *devstruct device_attribute *attr, char *buf) 
 +
 + struct bex_device *bex_dev = to_bex_device(dev);​ 
 + 
 + return sprintf(buf,​ "​%s\n",​ bex_dev->​type);​ 
 +
 +DEVICE_ATTR_RO(type);​ 
 +</​code>​ 
 +==== 3[2p] Adăugare atribute del și add ====
  
-De asemenea, puteți stoca un back pointer către ''​struct my_device_data'' ​în câmpul ​''​%%dev->​p->​driver_data%%''​. ​Acest câmp e util pentru a putea accesa datele private (''​my_device_data''​) ale dispozitivului ​și din locurile în care aveți acces doar la structura generică [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|struct device]]. Fiind un câmp din [[http://​elixir.free-electrons.com/​linux/​v3.13/​source/​drivers/​base/​base.h#​L73|datele private]] ale dispozitivului, ​pentru a accesa ​''​%%dev->​p->​driver_data%%'' ​e recomandat să folosițfuncțiile (interfața) [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L920|dev_set_drvdata]],​ [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L915|dev_get_drvdata]].+Adăugați două atribute write-only, numite ​''​del'' ​și ''​add''​. ''​del'' ​așteaptă un nume de device pentru a îl elimina, iar ''​add'' ​așteaptă numele, tipul șversiunea pentru ​crea un device ​nouUrmăriți comentariile marcate cu ''​TODO 3''​.
  
 <note tip> <note tip>
-Parcurgeți secțiunea [[:​so2:​laboratoare:​lab12#​dispozitive|Dispozitive]] din laborator. Urmăriți exemplele de cod. +Va trebui ​să adăugați atributele ​''​del''​ și ''​add''​ în structura ​''​bex_bus_attr''​ pe modelul:
-</​note>​ +
- +
-Compilaţi modulul şi copiaţi-l pe maşina virtuală, împreună cu modulul de la exerciţiul anterior. +
- +
-<note warning>​ +
-Pentru a elimina warning-urile legate de nedefinirea funcțiilor de înregistrare/​deînregistrare de dispozitiv, compilați ambele module din directorul părinte. Aveți în vedere ​să inserați modulul de la pasul anterior (''​mybus.ko''​) înaintea inserării modulului curent. +
-</​note>​ +
- +
-Pentru testare urmăriți intrările de dispozitiv (''​echo''​și de driver (''​echo''​în ''​/sys''​ pe mașina virtuală:+
 <​code>​ <​code>​
-# ls /​sys/​bus/​virtualbus/​devices/​ +&​bus_attr_<​insert-attribute-name-here>​.attr,​
-# ls /​sys/​bus/​virtualbus/​drivers/​ +
-# ls /​sys/​devices/​virtualbus0/​+
 </​code>​ </​code>​
  
-==== 2.1. [1.5p] Informații device-uri de pe magistrală ==== +</​note>​
- +
-La sfârșitul inițilizării modulului ''​mydriver''​ (TODO 2.1), verificați dacă device-ul a fost atașat la magistrală. Pornind de la magistrala asociată, parcurgeți device-urile atașate și căutați-l pe cel cu numele ''​echo''​. Afișați numele device-ului,​ dacă acesta a fost găsit.+
  
 <note tip> <note tip>
-Pentru căutarea unui dispozitiv folosiți funcția [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​bus.c#​L371|bus_find_device_by_name]]. Transmiteți ''​NULL'' ​ca al doilea argument al funcției.+Folosiți ''​sscanf''​ pentru a parsa inputul de la ''​sysfs''​ și ''​bex_del_dev()'' ​and ''​bex_add_dev()''​ pentru a șterge și crea un device nou. 
 +</​note>​
  
-Obțineți structura ​de tip magistrală (''​struct bus_type''​) printr-o construcție de forma ''​my_driver.driver.bus''​.+Un exemplu ​de funcție de tipul ''​store'' ​este:
  
-Numele device-ului întors de funcția [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​bus.c#​L371|bus_find_device_by_name]se poate obține cu funcția ​[[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L868|dev_name]]. +<​code ​c
-</​note>​+static ssize_t 
 +add_store(struct bus_type *bt, const char *buf, size_t count) 
 +
 + char type[32], name[32]; 
 + int version; 
 + int ret;
  
-Pentru verificare la inserarea modulului se va afișa mesaj cu numele dispozitivului.+ ret = sscanf(buf, "%31s %31s %d", name, type, &​version);​ 
 + if (ret != 3) 
 + return -EINVAL;
  
-==== 3. [2p] Atribute device drivere ====+ return bex_add_dev(name,​ type, version) ? : count; 
 +
 +BUS_ATTR(add,​ S_IWUSR, NULL, add_store);​ 
 +</​code>​
  
-Extindeți driverul echo de la exercițiul anterior prin adăugarea unui atribut ​''​myattr'' ​pentru dispozitivul creat, ce va conține majorul ​și minorul dispozitivului (''​major:​minor''​). Acest atribut va fi expus prin interfaţa ''​sysfs'' ​din directorul device-ului ''​echo''​. +Creați un device nou și verificați dacă este vizibil în ''​/​sys/​bus/​bex/​devices''​. Eliminați-l și verificați că dispărut din ''​sysfs''​.
- +
-Urmăriți comentariile ''​TODO 3''​ din cod.+
  
 <note tip> <note tip>
-Va trebui să declarați și să înregistrați o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L549| device_attribute]]. Puteți folosi macro-ul [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L575|DEVICE_ATTR]] ce va crea o structură cu numele ​''​dev_attr_##​_name''​, unde ''##​_name''​ este numele atributului. +Folosiți ''​echo'' ​pentru a scrie în atributele magistralei:
-Pentru folosirea macro-ului va trebui să specificaţi, ​în această ordine: +
-  * numele atributului +
-  * permisiunile la acces la intrarea din sysfs aferentă atributului;​ folosiţi valoarea ''​0444''​. +
-  * o funcție [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L551|show]] ce afișează valoarea atributului pornind de la informațiile din [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|struct device]]. +
-  * o funcţie [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L553|store]],​ care în cazul vostru poate fi ''​NULL''​.+
  
-În funcţia [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L303|show]],​ puteți folosi macrodefinițiile [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​kdev_t.h#​L9|MAJOR]] și [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​kdev_t.h#​L9|MINOR]] pentru aflarea majorului și minorului. Aceste funcții primesc ca argument câmpul ''​dev''​ al structurii ''​struct cdev''​. Câmpul de tipul ''​struct cdev''​ îl găsiți în structura de tipul ''​struct my_device_data''​. Pentru a obține structura de tipul ''​struct my_device_data'',​ atunci când știți adresa unei variabile de tipul ''​struct device'',​ puteți folosi funcția [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L915|dev_get_drvdata]]. 
- 
-Țineți cont să adăugați/​eliminați atributul la inițializarea/​dezactivarea modulului cu ajutorul funcțiilor [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​core.c#​L587|device_create_file]],​ [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​core.c#​L611|device_remove_file]]. 
- 
-Parcurgeți secțiunile [[:​so2:​laboratoare:​lab12#​magistrale|Magistrale]] și [[:​so2:​laboratoare:​lab12#​dispozitive|Dispozitive]] din laborator. 
-</​note>​ 
- 
-Pentru testare rulați comanda: 
 <​code>​ <​code>​
-# cat /sys/devices/virtualbus0/echo/myattr+$ echo "name type 1" > /sys/bus/bex/add 
 +echo "​name"​ > /​sys/​bus/​bex/del
 </​code>​ </​code>​
-Această comanda va conduce la rularea funcției ''​my_show''​.+</​note>​
  
-====[4pPlug and Play =====+==== 4. [2pÎnregistrarea driver-ului bex misc ====
  
-==== 4[2p] Conectarea ​la magistrala ​PNP ====+Modificați fișierul ''​bex-misc.c''​ pentru a înregistra driver-ul ​la magistrala ​''​bex''​.  
 +Inserați modulul bex_misc.ko și creați un nou device de tip ''​bex''​ din ''​sysfs'',​ cu numele //Test//, tipul //misc// și versiunea //2//. Urmăriți comentariile marcate cu ''​TODO 4''​.
  
-Intrați în directorul ​''​parallel''​, unde găsiți implementarea unui driver simplu pentru portul paralel+Verificați dacă noul driver este vizibil ​în ''​/​sys/​bus/​bex/​drivers''​. 
-Analizați conținutul fișierului ​''​parallel.c''​. Modificați sursa astfel încât să respecte modelul ''​Linux Device Model''​ și ''​plug and play''​. Dispozitivul se va conecta la magistrala ''​PNP''​.+De ce nu este apelată funcția ''​probe''​?
  
 <note tip> <note tip>
-Înregistrați/​deînregistrați structura [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​pnp.h#​L380|pnp_driver]] la încărcarea/descărcarea modulului cu ajutorul funcțiilor [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​pnp/​driver.c#​L266|pnp_register_driver]],​ respectiv [[http://​elixir.free-electrons.com/linux/​v4.9/​source/​drivers/​pnp/​driver.c#​L274|pnp_unregister_driver]].+Observați faptul că funcția de ''​match''​ pentru magistrală nu este implementată în ''​bex.c''​. 
 +</note>
  
-Pentru a fi un driver ​''​plug and play''​, inițializarea dispozitivelor trebuie făcută în momentul în care acestea apar în sistem (la execuția funcției ​''​parallel_pnp_probe''​), iar deînregistrarea în momentul în care dispar ​din sistem (la execuția funcției ''​parallel_pnp_remove''​).+Implementați funcția pentru match în fișierul ​''​bex.c''​. Urmăriți comentariile marcate cu ''​TODO 5''​
 +Încercați ​din nou adăugarea unui dispozitiv de tip ''​bex''​ și observați că de data aceasta ​funcția de ''​probe'' ​este apelată.
  
-Recitiți secțiunile [[:​so2:​laboratoare:​lab12#​magistrala_pnp|Magistrala PNP]] și [[:​so2:​laboratoare:​lab12#​operatii_pnp|Operații plug and play]] din laborator. +==== 5. [1.5p] Înregistrarea unui device bex misc în funcția probe ==== 
-</​note>​+ 
 +Modificați ''​bex_misc.c''​ astfel încât operația ''​probe''​ să eșueze dacă ''​version > 1''​. Înregistrațdevice-ul misc în funcția ''​bex_misc_probe()''​ și deînregistrați-l în ''​bex_misc_remove''​. Urmăriți comentariile marcate cu ''​TODO 6''​.
  
 <note tip> <note tip>
-Pentru înregistrarea și deînregistrarea unui dispozitiv folosiți funcțiile ​''​register_parallel_dev'' ​respectiv ​''​unregister_parallel_dev'' ​definite în cadrul scheletului de cod de laborator.+Folosiți ''​misc_register()'' ​and ''​misc_deregister()''​.
 </​note>​ </​note>​
  
-Pentru verificareurmăriți conținutul din directorul aferent din sysfs: +Creați un device nou cu numele //test//tipul //misc// și versiunea //2// și verificați că operația ''​probe''​ eșuează. 
-<​code>​ +Creați un nou device cu numele ​//test//, tipul //misc// și versiunea //1// și verificați că operația se termină cu succes.
-# ls /sys/bus/pnp/drivers/parallel +
-</code>+
  
-==== 5. [2p] Clase ==== +Verificați conținutul fișierului ''/​sys/​bus/​bex/​devices/​test''​ și observați că există ​o nouă intrare. Identificați majorul și minorul pentru device-ul ​''​misc'', ​creați un device node de tip caracter pentru acest dispozitiv (''​Hint''​: mknod) și încercați operații de citire și scriere pe fișierul creat, pentru a accesa buffer-ul dispozitivului.
- +
-Pornind de la modulul anterior, adăugați informațiile pentru ​o nouă clasă ​''​parclass'', ​de care aparține modulul ​''​paralel''​.+
  
 <note tip> <note tip>
-Definiți o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L388|class]] și o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|device]]. +Indicatorii ​''​major''​ și ''​minor'' ​sunt vizibili în atributul ​''​dev''​ al dispozitivului ​de tip ''​misc''​.
- +
-Structura [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L388|class]] trebuie inițializată odată cu resursele driver-ului (la execuția funcției ​''​parallel_init''​și eliminată la ieșirea driverului (''​parallel_exit''​). Va trebui să folosiţi funcţiile [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L424|class_register]] şi [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​class.c#​L212|class_unregister]]. +
- +
-În plus, pentru fiecare dispozitiv trebuie inițializată o structură [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|device]] și înregistrată cu [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​core.c#​L1798|device_create]] (la execuția funcției ​''​parallel_pnp_probe''​). La apelul funcţiei [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​core.c#​L1798|device_create]],​ folosiți pentru al patrulea parametru construcția ''​%%&​dev->​dev%%''​. Este câmpul de tipul [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​device.h#​L782|struct device]] ​al structurii [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​include/​linux/​pnp.h#​L244|struct pnp_dev]]. +
- +
-La înlăturarea ​dispozitivului ​(în funcţia ​''​parallel_pnp_remove''​) folosiți funcția [[http://​elixir.free-electrons.com/​linux/​v4.9/​source/​drivers/​base/​core.c#​L1870|device_destroy]]. +
- +
-Recitiți secțiunea [[:​so2:​laboratoare:​lab12#​clase|Clase]] din laborator. +
- +
 </​note>​ </​note>​
  
-Pentru verificare, urmăriți conținutul directorului aferent din sysfs:<​code>​ +==== 6. [1p] Monitorizarea notificărilor uevent ​==== 
-# ls /​sys/​class/​parclass/​ +Folosiți comanda ​''​udevadm''​ și observați ​ce se întâmplă când: 
-</​code>​ +  * modulele ​''​bex.ko'' ​and ''​bex_misc.ko'' ​sunt inserate 
-===== Extra ===== +  * un nou device ​cu tipul //test// este creat 
-== (+3 karma) USB Hotplug == +  ​* ​un nou device ​cu tipul //​misc// ​și versiunea //2// este creat 
- +  ​* ​un nou device cu tipul //​misc// ​și versiunea //1// este creat 
-În subdirectorul ''​usb_extra''​ găsiți o implementare minimală a unui driver USB. Analizați sursa ''​usb.c''​ și observați ​implementarea mecanismului de ''​Hotplug''​ si conectarea la magistrala ''​USB''​. Observați asemănările cu interfața dintre magistralei ''​PNP''​ studiată în laborator și driverele asociate: ''​struct usb_driver'' ​''​struct pnp_driver'',​ implementarea funcției ''​probe''​ (''​skel_probe''​),​ tabela ''​skel_table''​ cu care se inițializează câmpul ''​id_table''​ pentru a identifica device-urile compatibile,​ etc. +  * toate de mai sus sunt eliminate
- +
-Conectați ​un device ​USB pe mașina fizică. Apelaț''​dmesg''​ sau ''​lsusb''​ pentru a identifica vendorId-ul și productId-ul device-ul atașat.  +
- +
-<code bash> +
-usb 3-2: New USB device found, idVendor=1e3d,​ idProduct=6025 +
-</code> +
- +
-Modificați codul din ''​usb.c''​ pentru a crea un driver compatibil cu device-ul vostru. Compilați modulul și inserați-l pe mașina fizică (sau pe o mașină virtuală ​cu udev și acces la USB-ul gazdei). Reconectați device-ul USB. Ce observați la rularea comenzii dmesg? +
- +
-Cel mai probabil device-ul va fi preluat de alt driver usb din sistem (e.x. usb_storage). În acest caz, puteți descărca temporar modulul concurent (rmmod usb_storage). Dacă device-ul se conectează la driverului ''​usb.ko'',​ puteți observa mesajul "USB Skeleton device now attached to USBSkel-0",​ mesaj afișat de funcția ''​skel_probe''​. ​   +
- +
-Descărcați modulul. Creați o regulă ''​udev'',​ care la identificarea dispozitivului (după ''​ATTRS{idVendor}''​ și ''​ATTRS{idProduct}''​),​ să încarce driverul ''​usb.ko''​. Recitiți secțiunea [[:​so2:​laboratoare:​lab12#​hotplug | Hotplug]] din laborator. Cu modulul descărcat, reconectați device-ul USB. Ce observați la rularea comenzilor ''​dmesg''​ și ''​lsmod''?​+
  
-===== Soluții ===== 
  
-  * [[http://​elf.cs.pub.ro/​so2/​res/​laboratoare/​lab12-sol.zip|Soluții exerciții laborator 12]] 
so2/laboratoare/lab12/exercitii.1526404884.txt.gz · Last modified: 2018/05/15 20:21 by ionel.ghita
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