Differences

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

Link to this comparison view

so2:laboratoare:lab12 [2014/05/14 10:18]
razvan.deaconescu [Sysfs]
so2:laboratoare:lab12 [2018/05/17 09:18] (current)
elena.sandulescu [Structuri de bază în dispozitivele Linux]
Line 1: Line 1:
-====== Laborator 12 - Linux Device Model. Plug and Play======+ ====== Laborator 12 - Linux Device Model. Plug and Play ======
  
 ===== Obiectivele laboratorului ===== ===== Obiectivele laboratorului =====
  
-  * Dobândirea de cunoștințe legate de ''​Linux Device Model'' ​şi principalele componente ale acestuia: dispozitive,​ drivere, clase şi magistrale.+  * Dobândirea de cunoștințe legate de ''​Linux Device Model'' ​și principalele componente ale acestuia: dispozitive,​ drivere, clase și magistrale.
   * Cunoștințe legate de modul de funcționare al mecanismelor ''​Hotplug''​ / ''​Plug and Play''​.   * Cunoștințe legate de modul de funcționare al mecanismelor ''​Hotplug''​ / ''​Plug and Play''​.
  
Line 22: Line 22:
 ===== Noțiuni teoretice ===== ===== Noțiuni teoretice =====
  
-**Plug and Play** este o tehnologie care oferă suport pentru adăugarea ​şi eliminarea automată a dispozitivelor în sistem. În acest mod se reduc conflictele legate de resursele folosite de acestea prin configurare automată la pornirea sistemului. Pentru a îndeplini aceste scopuri, sunt necesare următoarele caracteristici:​+**Plug and Play** este o tehnologie care oferă suport pentru adăugarea ​și eliminarea automată a dispozitivelor în sistem. În acest mod se reduc conflictele legate de resursele folosite de acestea prin configurare automată la pornirea sistemului. Pentru a îndeplini aceste scopuri, sunt necesare următoarele caracteristici:​
  
-  * Detectarea automată a adaugării ​şi eliminării dispozitivelor din sistem (dispozitivul ​şi magistrala acestuia trebuie sa anunțe driver-ul corespunzător că a apărut o modificare în configurație). +  * Detectarea automată a adaugării ​și eliminării dispozitivelor din sistem (dispozitivul ​și magistrala acestuia trebuie sa anunțe driver-ul corespunzător că a apărut o modificare în configurație). 
-  * Managementul resurselor (adrese, linii irq, canale DMA, zone de memorie), ce include alocarea resurselor către dispozitive ​şi rezolvarea conflictelor ce pot apărea.+  * Managementul resurselor (adrese, linii irq, canale DMA, zone de memorie), ce include alocarea resurselor către dispozitive ​și rezolvarea conflictelor ce pot apărea.
   * Dispozitivele trebuie să permită configurarea software (resursele dispozitivului – porturi, întreruperi,​ resurse DMA – trebuie să permită atribuirea din partea driver-ului).   * Dispozitivele trebuie să permită configurarea software (resursele dispozitivului – porturi, întreruperi,​ resurse DMA – trebuie să permită atribuirea din partea driver-ului).
   * Driver-ele necesare pentru dispozitive noi trebuie să fie încarcate automat de sistemul de operare atunci când este nevoie.   * Driver-ele necesare pentru dispozitive noi trebuie să fie încarcate automat de sistemul de operare atunci când este nevoie.
-  * Atunci când dispozitivul ​şi magistrala acestuia permit, sistemul ar trebui să poată adăuga sau elimina dispozitivul din sistem în timp ce acesta rulează, fără a fi necesară repornirea sistemului (''​hotplug''​).+  * Atunci când dispozitivul ​și magistrala acestuia permit, sistemul ar trebui să poată adăuga sau elimina dispozitivul din sistem în timp ce acesta rulează, fără a fi necesară repornirea sistemului (''​hotplug''​).
  
-Pentru ca un sistem să suporte plug and play trebuie ca ''​BIOS''​-ul,​ sistemul de operare ​şi dispozitivul să suporte această tehnologie. Dispozitivul trebuie să dețină un ''​ID''​ pe care să îl ofere driver-ului pentru identificare,​ iar sistemul de operare trebuie să poată să identifice aceste modificări în configurație pe măsură ce ele apar.+Pentru ca un sistem să suporte plug and play trebuie ca ''​BIOS''​-ul,​ sistemul de operare ​și dispozitivul să suporte această tehnologie. Dispozitivul trebuie să dețină un ''​ID''​ pe care să îl ofere driver-ului pentru identificare,​ iar sistemul de operare trebuie să poată să identifice aceste modificări în configurație pe măsură ce ele apar.
  
-Dispozitive care le suportă plug and play sunt: dispozitivele ''​PCI''​ (plăci de rețea), ''​USB''​ (tastatură,​ mouse, imprimantă),​ etc.+Dispozitive care suportă plug and play sunt: dispozitivele ''​PCI''​ (plăci de rețea), ''​USB''​ (tastatură,​ mouse, imprimantă),​ etc.
  
 =====  Linux Device Model  ===== =====  Linux Device Model  =====
Line 38: Line 38:
 Înainte de versiunea 2.6, kernel-ul nu dispunea de un model unificat prin care să se obțină informații despre acesta. Din acest motiv s-a realizat un model pentru dispozitivele din Linux, ''​Linux Device Model''​. Înainte de versiunea 2.6, kernel-ul nu dispunea de un model unificat prin care să se obțină informații despre acesta. Din acest motiv s-a realizat un model pentru dispozitivele din Linux, ''​Linux Device Model''​.
  
-Scopul principal al acestui model este de a menține structuri de date interne care să reflecte starea ​şi structura sistemului. Astfel de infomații includ ce dispozitive există în sistem, în ce stare se află din punct de vedere al managementului consumului (power management),​ la ce magistrală sunt ataşate, ce drivere au asociate, alături de structura magistralelor,​ dispozitivelor,​ driverelor din sistem.+Scopul principal al acestui model este de a menține structuri de date interne care să reflecte starea ​și structura sistemului. Astfel de infomații includ ce dispozitive există în sistem, în ce stare se află din punct de vedere al managementului consumului (power management),​ la ce magistrală sunt atașate, ce drivere au asociate, alături de structura magistralelor,​ dispozitivelor,​ driverelor din sistem.
  
-Pentru a menține aceste informații,​ kernel-ul foloseşte următoarele entități:+Pentru a menține aceste informații,​ kernel-ul folosește următoarele entități:
  
-  * **dispozitiv** - un dispozitiv fizic care este ataşat unei magistrale+  * **dispozitiv** - un dispozitiv fizic care este atașat unei magistrale
   * **driver** – o entitate software care poate fi asociată unui dispozitiv și execută operații cu acesta   * **driver** – o entitate software care poate fi asociată unui dispozitiv și execută operații cu acesta
-  * **magistrală (bus)** – un dispozitiv la care se pot ataşa alte dispozitive+  * **magistrală (bus)** – un dispozitiv la care se pot atașa alte dispozitive
   * **clasă** – un tip de dispozitive care au o comportare similară; există o clasă pentru discuri, partiții, porturi seriale, etc.   * **clasă** – un tip de dispozitive care au o comportare similară; există o clasă pentru discuri, partiții, porturi seriale, etc.
-  * **subsistem** – o vedere asupra structurii sistemului; subsistemele din kernel includ dispozitive (devices - o vedere ierarhică asupra tuturor dispozitivelor din sistem), magistrale (bus - o vedere a dispozitivelor în funcție de cum sunt ataşate la magistrale),​ clase, etc.+  * **subsistem** – o vedere asupra structurii sistemului; subsistemele din kernel includ dispozitive (devices - o vedere ierarhică asupra tuturor dispozitivelor din sistem), magistrale (bus - o vedere a dispozitivelor în funcție de cum sunt atașate la magistrale),​ clase, etc.
  
 ==== sysfs ==== ==== sysfs ====
  
-Kernel-ul oferă o reprezentare a modelului său în userspace prin intermediul sistemului virtual de fişiere sysfs. Acesta este de obicei montat în directorul ''/​sys'' ​şi conține următoarele subdirectoare:​+Kernel-ul oferă o reprezentare a modelului său în userspace prin intermediul sistemului virtual de fișiere sysfs. Acesta este de obicei montat în directorul ''/​sys'' ​și conține următoarele subdirectoare:​
  
   * **block** - toate dispozitivele de tip bloc disponibile în sistem (discuri, partiții)   * **block** - toate dispozitivele de tip bloc disponibile în sistem (discuri, partiții)
Line 57: Line 57:
   * **devices** - structura ierarhica a dispozitivelor conectate în sistem   * **devices** - structura ierarhica a dispozitivelor conectate în sistem
   * **firmware** - informații obținute de la firmware-ul sistemului (ACPI)   * **firmware** - informații obținute de la firmware-ul sistemului (ACPI)
-  * **fs** - informații legate de sistemele de fişiere montate+  * **fs** - informații legate de sistemele de fișiere montate
   * **kernel** - informații legate de starea kernel-ului (utilizatorii logați, hotplug)   * **kernel** - informații legate de starea kernel-ului (utilizatorii logați, hotplug)
   * **module** - lista modulelor încarcate la momentul curent   * **module** - lista modulelor încarcate la momentul curent
   * **power** - informații legate de subsistemul de power management   * **power** - informații legate de subsistemul de power management
  
-După cum se poate observa, există o corespondență între structurile de date din kernel în cadrul modelului descris ​şi subdirectoarele din sistemul virtual de fişiere ''​sysfs''​. Deşi această asemănare poate duce la confundarea celor două concepte, ele sunt diferite. Modelul pentru dispozitive în kernel poate funcționa ​şi fără sistemul de fişiere ''​sysfs'',​ dar reciproca nu este adevărată.+După cum se poate observa, există o corespondență între structurile de date din kernel în cadrul modelului descris ​și subdirectoarele din sistemul virtual de fișiere ''​sysfs''​. Deși această asemănare poate duce la confundarea celor două concepte, ele sunt diferite. Modelul pentru dispozitive în kernel poate funcționa ​și fără sistemul de fișiere ''​sysfs'',​ dar reciproca nu este adevărată.
  
-Informația din ''​sysfs''​ se găseşte în fişiere ce conțin câte un atribut. Câteva atribute standard (reprezentate de fişiere sau directoare cu acelaşi nume) sunt următoarele:​+Informația din ''​sysfs''​ se găsește în fișiere ce conțin câte un atribut. Câteva atribute standard (reprezentate de fișiere sau directoare cu același nume) sunt următoarele:​
  
-  * **dev** - identificatorul major şi minor al dispozitivului;​ acesta poate fi folosit pentru a crea automat intrările în directorul ''/​dev''​+  * **dev** - identificatorul major și minor al dispozitivului;​ acesta poate fi folosit pentru a crea automat intrările în directorul ''/​dev''​
   * **device** - o legătură simbolică spre directorul ce conține dispozitive;​ acesta poate fi folosit pentru a descoperi dispozitivele hardware care oferă un anumit serviciu (spre exemplu dispozitivul PCI al plăcii de rețea eth0)   * **device** - o legătură simbolică spre directorul ce conține dispozitive;​ acesta poate fi folosit pentru a descoperi dispozitivele hardware care oferă un anumit serviciu (spre exemplu dispozitivul PCI al plăcii de rețea eth0)
   * **driver** - o legătură simbolică spre directorul ce conține drivere (care se află în ''/​sys/​bus/​*/​drivers''​)   * **driver** - o legătură simbolică spre directorul ce conține drivere (care se află în ''/​sys/​bus/​*/​drivers''​)
  
-Sunt disponibile ​şi alte atribute, în funcție de magistrala ​şi driverul folosit.+Sunt disponibile ​și alte atribute, în funcție de magistrala ​și driverul folosit.
  
 {{ :​so2:​laboratoare:​laboratoare-plug_and_play-sysfs.png |}} {{ :​so2:​laboratoare:​laboratoare-plug_and_play-sysfs.png |}}
Line 76: Line 76:
 ==== Structuri de bază în dispozitivele Linux ==== ==== Structuri de bază în dispozitivele Linux ====
  
-''​Linux Device Model''​ oferă o serie de structuri care să asigure interacțiunea între un dispozitiv hardware ​şi un device driver. Întreg modelul are la bază structuri [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | struct kobject]]. Cu ajutorul acestei structuri sunt construite ierarhii ​şi sunt implementate următoarele structuri: [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | struct bus_type]], [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | struct device]] ​şi [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L225 | struct device_driver]].+''​Linux Device Model''​ oferă o serie de structuri care să asigure interacțiunea între un dispozitiv hardware ​și un device driver. Întreg modelul are la bază structuri [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | struct kobject]]. Cu ajutorul acestei structuri sunt construite ierarhii ​și sunt implementate următoarele structuri: [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | struct device_driver]].
  
 {{ :​so2:​laboratoare:​laboratoare-plug_and_play-linux_device_model_structures.png |}} {{ :​so2:​laboratoare:​laboratoare-plug_and_play-linux_device_model_structures.png |}}
Line 82: Line 82:
 === Structura kobject === === Structura kobject ===
  
-O structură [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] nu îndeplineşte o funcție de una singură. O astfel de structură este de obicei integrată într-o structură mai mare. O structură [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] incorporează de fapt un set de facilități care vor fi oferite unui obiect de nivel de abstracție mai înalt în ierarhia ''​Linux Device Model''​.+O structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] nu îndeplinește o funcție de una singură. O astfel de structură este de obicei integrată într-o structură mai mare. O structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] incorporează de fapt un set de facilități care vor fi oferite unui obiect de nivel de abstracție mai înalt în ierarhia ''​Linux Device Model''​.
  
-Spre exemplu, structura [[http://lxr.free-electrons.com/​source/​include/​linux/​cdev.h?v=3.11#L12 | cdev]] are următoarea definiție:+Spre exemplu, structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​cdev.h#​L12 | cdev]] are următoarea definiție:
  
 <code c> <code c>
Line 97: Line 97:
 </​code>​ </​code>​
  
-Se observă că această structură include un câmp de tipul [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | struct kobject]].+Se observă că această structură include un câmp de tipul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | struct kobject]].
  
-O structură [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | struct kobject]] este definită astfel:+O structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | struct kobject]] este definită astfel:
  
 <code c> <code c>
Line 120: Line 120:
 </​code>​ </​code>​
  
-După cum se observă, structurile [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] sunt într-o ierarhie: un obiect are un părinte ​şi deține un membru kset, care cuprinde obiecte de pe acelaşi nivel.+După cum se observă, structurile [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] sunt într-o ierarhie: un obiect are un părinte ​și deține un membru kset, care cuprinde obiecte de pe același nivel.
  
-Lucrul cu structura presupune inițializarea ei, cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​lib/​kobject.c?v=3.11#L268 | kobject_init]]. Tot în procesul de inițializare este necesară stabilirea numelui structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]], care va apărea în sysfs, cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​lib/​kobject.c?v=3.11#L243 | kobject_set_name]].+Lucrul cu structura presupune inițializarea ei, cu ajutorul funcției [[http://elixir.free-electrons.com/linux/v4.9/​source/​lib/​kobject.c#​L313 | kobject_init]]. Tot în procesul de inițializare este necesară stabilirea numelui structurii [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]], care va apărea în sysfs, cu ajutorul funcției [[http://elixir.free-electrons.com/linux/v4.9/​source/​lib/​kobject.c#​L291 | kobject_set_name]].
  
-Orice operație asupra unui [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] se realizează prin incrementarea contorului intern al acestuia cu [[http://lxr.free-electrons.com/​source/​lib/​kobject.c?v=3.11#L525 | kobject_get]],​ sau decrementarea în cazul în care nu se mai foloseşte cu [[http://lxr.free-electrons.com/​source/​lib/​kobject.c?v=3.11#L594 | kobject_put]]. Astfel, un obiect de tip [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] nu va fi eliberat decât în momentul în care contorul intern al acestuia ajunge la valoarea 0. Este nevoie de o metodă de notificare a acestui lucru, pentru ca, apoi, să fie eliberate resursele asociate structurii de dispozitiv care includea [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | struct kobject]] (spre exemplu [[http://lxr.free-electrons.com/​source/​include/​linux/​cdev.h?v=3.11#L12 | cdev]]). Metoda se numeşte release ​şi este asociată obiectului prin intermediul câmpului ktype (de tip [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L108 | struct kobj_type]]).+Orice operație asupra unui [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] se realizează prin incrementarea contorului intern al acestuia cu [[http://elixir.free-electrons.com/linux/v4.9/​source/​lib/​kobject.c#​L587 | kobject_get]],​ sau decrementarea în cazul în care nu se mai folosește cu [[http://elixir.free-electrons.com/linux/v4.9/​source/​lib/​kobject.c#​L678 | kobject_put]]. Astfel, un obiect de tip [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] nu va fi eliberat decât în momentul în care contorul intern al acestuia ajunge la valoarea 0. Este nevoie de o metodă de notificare a acestui lucru, pentru ca, apoi, să fie eliberate resursele asociate structurii de dispozitiv care includea [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | struct kobject]] (spre exemplu [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​cdev.h#​L12 | cdev]]). Metoda se numește release ​și este asociată obiectului prin intermediul câmpului ktype (de tip [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L116 | struct kobj_type]]).
  
-Structura [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | struct kobject]] este structura de bază din Linux Device Model. Structurile din nivelurile mai înalte ale modelului sunt [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | struct bus_type]], [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | struct device]] ​şi [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L225 | struct device_driver]].+Structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | struct kobject]] este structura de bază din Linux Device Model. Structurile din nivelurile mai înalte ale modelului sunt [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | struct device_driver]].
  
 === Magistrale === === Magistrale ===
  
-O magistrală este un canal de comunicație între procesor ​şi un dispozitiv de intrare/ieşire. Pentru asigurarea genericității modelului, toate dispozitivele de intrare/ieşire sunt conectate la procesor prin intermediul unei astfel de magistrale (chiar dacă aceasta poate fi una virtuală fără un corespondent fizic hardware).+O magistrală este un canal de comunicație între procesor ​și un dispozitiv de intrare/ieșire. Pentru asigurarea genericității modelului, toate dispozitivele de intrare/ieșire sunt conectate la procesor prin intermediul unei astfel de magistrale (chiar dacă aceasta poate fi una virtuală fără un corespondent fizic hardware).
  
-La adăugarea unei magistrale în sistem, aceasta va apărea în sistemul de fişiere ''​sysfs'',​ în ''/​sys/​bus''​. Ca şi la structurile [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobjects]], magistralele pot fi organizate în ierarhii ​şi vor fi reprezentate astfel ​şi în ''​sysfs''​.+La adăugarea unei magistrale în sistem, aceasta va apărea în sistemul de fișiere ''​sysfs'',​ în ''/​sys/​bus''​. Ca și la structurile [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobjects]], magistralele pot fi organizate în ierarhii ​și vor fi reprezentate astfel ​și în ''​sysfs''​.
  
  
-În Linux Device Model, o magistrală este reprezentată de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | struct bus_type]]:+În Linux Device Model, o magistrală este reprezentată de structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]]:
  
 <code c> <code c>
Line 155: Line 155:
 </​code>​ </​code>​
  
-Se observă că unei magistrale îi este asociat un nume, liste de atribute default, o serie de funcții specifice ​şi datele private ale driverului. Funcția ''​uevent''​ (fostă ''​hotplug''​),​ este folosită în cazul dispozitivelor ''​hotplug''​.+Se observă că unei magistrale îi este asociat un nume, liste de atribute default, o serie de funcții specifice ​și datele private ale driverului. Funcția ''​uevent''​ (fostă ''​hotplug''​),​ este folosită în cazul dispozitivelor ''​hotplug''​.
  
-Operațiile cu magistrala sunt operații de înregistrare,​ implementarea operațiilor descrise în structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | struct bus_type]] ​şi operații de parcurgere ​şi inspecție a dispozitivelor conectate la magistrală.+Operațiile cu magistrala sunt operații de înregistrare,​ implementarea operațiilor descrise în structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]] ​și operații de parcurgere ​și inspecție a dispozitivelor conectate la magistrală.
  
-Înregistrarea unei magistrale se realizează folosind [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L908 | bus_register]],​ iar deînregistrarea folosind [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L987 | bus_unregister]]:​+Înregistrarea unei magistrale se realizează folosind [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L879 | bus_register]],​ iar deînregistrarea folosind [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L965 | bus_unregister]]:​
  
 <spoiler onHidden="​Afișați exemplu implementare"​ onVisible="​Ascundeți exemplu implementare"​ > <spoiler onHidden="​Afișați exemplu implementare"​ onVisible="​Ascundeți exemplu implementare"​ >
Line 198: Line 198:
 \\ \\
  
-Funcțiile care vor fi inițializate uzual în cadrul unei structuri [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | struct bus_type]] sunt ''​match'' ​şi ''​uevent'':​+Funcțiile care vor fi inițializate uzual în cadrul unei structuri [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]] sunt ''​match'' ​și ''​uevent'':​
  
 <code c> <code c>
Line 209: Line 209:
 static int my_match (struct device *dev, struct device_driver *driver) static int my_match (struct device *dev, struct device_driver *driver)
 { {
- return ​!strncmp (dev_name(dev),​ driver->​name,​ strlen (driver->​name));​+ return strncmp (dev_name(dev),​ driver->​name,​ strlen (driver->​name));​
 } }
    
Line 221: Line 221:
 </​code>​ </​code>​
  
-Funcția ''​match''​ este utilizată în momentul în care se adaugă la magistrală un nou dispozitiv sau un nou driver. Rolul ei este de a realiza comparația între identificatorul dispozitivului ​şi cel al driverului. Funcția ''​uevent''​ este apelată înainte de generarea unui eveniment de tip ''​hotplug''​ în user-space ​şi are drept rol adăugarea de variabile de mediu.+Funcția ''​match''​ este utilizată în momentul în care se adaugă la magistrală un nou dispozitiv sau un nou driver. Rolul ei este de a realiza comparația între identificatorul dispozitivului ​și cel al driverului. Funcția ''​uevent''​ este apelată înainte de generarea unui eveniment de tip ''​hotplug''​ în user-space ​și are drept rol adăugarea de variabile de mediu.
  
-Alte operații posibile în cazul unei magistrale sunt parcurgerea driverelor sau dispozitivelor ataşate acesteia. Deşi nu le putem accesa în mod direct (listele cu driverele ​şi dispozitive fiind stocate în datele private ale driverului, câmpul [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L126 | struct subsys_private *p]]), acestea pot fi parcurse cu ajutorul macrodefinițiilor [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L286 | bus_for_each_dev]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L418 | bus_for_each_drv]].+Alte operații posibile în cazul unei magistrale sunt parcurgerea driverelor sau dispozitivelor atașate acesteia. Deși nu le putem accesa în mod direct (listele cu driverele ​și dispozitive fiind stocate în datele private ale driverului, câmpul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L134 | struct subsys_private *p]]), acestea pot fi parcurse cu ajutorul macrodefinițiilor [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L281 | bus_for_each_dev]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L431 | bus_for_each_drv]].
  
-Interfața ''​Linux Device Model''​ permite crearea de atribute pentru obiectele asociate. Aceste atribute vor avea drept corespondent un fişier în subdirectorul magistralei din ''​sysfs''​. Atributele asociate unei magistrale sunt descrise de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L43 | bus_attribute]]:​+Interfața ''​Linux Device Model''​ permite crearea de atribute pentru obiectele asociate. Aceste atribute vor avea drept corespondent un fișier în subdirectorul magistralei din ''​sysfs''​. Atributele asociate unei magistrale sunt descrise de structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L46 | bus_attribute]]:​
  
 <code c> <code c>
Line 237: Line 237:
 </​code>​ </​code>​
  
-De obicei, un atribut se defineşte cu ajutorul macrodefiniției [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L49 | BUS_ATTR]]. Pentru adăugarea/ştergerea unui atribut din cadrul structurii de magistrală se folosesc funcțiile [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L127 | bus_create_file]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​bus.c?v=3.11#L139 | bus_remove_file]].+De obicei, un atribut se definește cu ajutorul macrodefiniției [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L52 | BUS_ATTR]]. Pentru adăugarea/ștergerea unui atribut din cadrul structurii de magistrală se folosesc funcțiile [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L129 | bus_create_file]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​bus.c#​L141 | bus_remove_file]].
  
 Un exemplu de definire a unui atribut pentru magistrala ''​my_bus''​ este prezentat în continuare: Un exemplu de definire a unui atribut pentru magistrala ''​my_bus''​ este prezentat în continuare:
Line 287: Line 287:
 \\ \\
  
-Magistrala este reprezentată atât de un obiect [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | bus_type]], cât şi de un obiect [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | device]], aşa cum vom vedea în continuare (magistrala este şi ea un dispozitiv).+Magistrala este reprezentată atât de un obiect [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | bus_type]], cât și de un obiect [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | device]], așa cum vom vedea în continuare (magistrala este și ea un dispozitiv).
  
 === Dispozitive === === Dispozitive ===
  
-Orice dispozitiv din sistem are asociată o structură [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | struct device]]. Dispozitivele sunt descoperite prin diferite metode de kernel (hotplug, de către device drivere, la inițializarea sistemului) ​şi sunt înregistrate în sistem. Toate dispozitivele prezente în kernel au câte o intrare în ''/​sys/​devices''​.+Orice dispozitiv din sistem are asociată o structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]]. Dispozitivele sunt descoperite prin diferite metode de kernel (hotplug, de către device drivere, la inițializarea sistemului) ​și sunt înregistrate în sistem. Toate dispozitivele prezente în kernel au câte o intrare în ''/​sys/​devices''​.
  
-La cel mai jos nivel, un dispozitiv în ''​Linux Device Model''​ este reprezentat de o structură [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | struct device]]:+La cel mai jos nivel, un dispozitiv în ''​Linux Device Model''​ este reprezentat de o structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]]:
  
 <code c> <code c>
Line 314: Line 314:
 </​code>​ </​code>​
  
-Printre câmpurile structurii se numără dispozitivul părinte care este de obicei un controller, obiectul [[http://lxr.free-electrons.com/​source/​include/​linux/​kobject.h?v=3.11#L60 | kobject]] asociat, magistrala pe care se găseşte, driverul care se ocupă de dispozitiv ​şi o funcție apelată în momentul în care contorul dispozitivului ajunge la 0.+Printre câmpurile structurii se numără dispozitivul părinte care este de obicei un controller, obiectul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​kobject.h#​L63 | kobject]] asociat, magistrala pe care se găsește, driverul care se ocupă de dispozitiv ​și o funcție apelată în momentul în care contorul dispozitivului ajunge la 0.
  
-Ca de obicei, avem funcții de înregistrare/​deînregistrare [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c?v=3.11#L1209 | device_register]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c?v=3.11#L1302 | device_unregister]].+Ca de obicei, avem funcții de înregistrare/​deînregistrare [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1185 | device_register]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1305 | device_unregister]].
  
-Pentru lucrul cu atributele avem structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L499 | struct device_attribute]],​ macrodefiniția [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L525 | DEVICE_ATTR]] pentru definire ​şi funcțiile [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c?v=3.11#L612 | device_create_file]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c?v=3.11#L635 | device_remove_file]] pentru adăugarea atributului la dispozitiv.+Pentru lucrul cu atributele avem structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L549 | struct device_attribute]],​ macrodefiniția [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L575 | DEVICE_ATTR]] pentru definire ​și funcțiile [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L582 | device_create_file]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L606 | device_remove_file]] pentru adăugarea atributului la dispozitiv.
  
-Un lucru important de notat este faptul că, de obicei, nu se lucrează direct cu o structură de tip [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L689 | struct device]], ci cu o structură care o conține pe aceasta, de forma:+Un lucru important de notat este faptul că, de obicei, nu se lucrează direct cu o structură de tip [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]], ci cu o structură care o conține pe aceasta, de forma:
  
 <code c> <code c>
Line 389: Line 389:
 \\ \\
  
-După cum se poate observa, funcțiile ''​my_register_device'' ​şi ''​my_unregister_device''​ de adăugare, respectiv scoatere a unui device de pe o magistrală sunt definite în fişierul în care este definită magistrala. Nu se inițializează obiecte de tip dispozitiv; acestea se vor ințializa în momentul în care vor fi descoperite în sistem (prin hotplug sau înregistrare directă din driver) ​şi se va apela funcția ''​my_register_device''​ pentru adăugarea la magistrală.+După cum se poate observa, funcțiile ''​my_register_device'' ​și ''​my_unregister_device''​ de adăugare, respectiv scoatere a unui device de pe o magistrală sunt definite în fișierul în care este definită magistrala. Nu se inițializează obiecte de tip dispozitiv; acestea se vor ințializa în momentul în care vor fi descoperite în sistem (prin hotplug sau înregistrare directă din driver) ​și se va apela funcția ''​my_register_device''​ pentru adăugarea la magistrală.
  
-Pentru utilizare (în implementarea driver-ului),​ trebuie declarată o structură de tipul celei exportate, inițializată ​şi înregistrată cu metoda exportata de magistrală:​+Pentru utilizare (în implementarea driver-ului),​ trebuie declarată o structură de tipul celei exportate, inițializată ​și înregistrată cu metoda exportata de magistrală:​
  
 <spoiler onHidden="​Afișați exemplu înregistrare device"​ onVisible="​Ascundeți exemplu înregistrare device"​ > <spoiler onHidden="​Afișați exemplu înregistrare device"​ onVisible="​Ascundeți exemplu înregistrare device"​ >
Line 427: Line 427:
 === Drivere == === Drivere ==
  
-''​Linux Device Model''​ este folosit pentru a permite asocierea foarte uşoară între dispozitivele sistemului ​şi drivere. Driverele pot exporta informații independente de dispozitivul fizic din spate.+''​Linux Device Model''​ este folosit pentru a permite asocierea foarte ușoară între dispozitivele sistemului ​și drivere. Driverele pot exporta informații independente de dispozitivul fizic din spate.
  
-În ''​sysfs''​ informațiile despre drivere nu au asociate un singur subdirector;​ ele se pot găsi în structura de directoare, în diferite locuri: în ''/​sys/​module''​ se găseşte modulul încărcat, în ''​devices''​ se poate găsi driverul asociat fiecărui device, în ''​classes''​ driverele care aparțin unei clase, în ''/​sys/​bus''​ driverele asociate fiecărei magistrale.+În ''​sysfs''​ informațiile despre drivere nu au asociate un singur subdirector;​ ele se pot găsi în structura de directoare, în diferite locuri: în ''/​sys/​module''​ se găsește modulul încărcat, în ''​devices''​ se poate găsi driverul asociat fiecărui device, în ''​classes''​ driverele care aparțin unei clase, în ''/​sys/​bus''​ driverele asociate fiecărei magistrale.
  
-Un device driver este identificat prin structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L194 | struct device_driver]]:​+Un device driver este identificat prin structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | struct device_driver]]:​
  
 <code c> <code c>
Line 453: Line 453:
 </​code>​ </​code>​
  
-Printre câmpurile structurii regăsim numele driver-ului (apare în ''​sysfs''​),​ magistrala cu care driverul lucrează ​şi funcții apelate în diverse momente din funcționarea unui dispozitiv.+Printre câmpurile structurii regăsim numele driver-ului (apare în ''​sysfs''​),​ magistrala cu care driverul lucrează ​și funcții apelate în diverse momente din funcționarea unui dispozitiv.
  
-Ca şi până acum, avem funcțiile de înregistrare/​deînregistrare [[http://lxr.free-electrons.com/​source/​drivers/​base/​driver.c?v=3.11#L157 | driver_register]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​driver.c?v=3.11#L199 | driver_unregister]].+Ca și până acum, avem funcțiile de înregistrare/​deînregistrare [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​driver.c#​L140 | driver_register]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​driver.c#​L182 | driver_unregister]].
  
-Pentru lucrul cu atributele avem structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L264 | struct driver_attribute]],​ macrodefiniția [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L271 | DRIVER_ATTR]] pentru definire ​şi funcțiile [[http://lxr.free-electrons.com/​source/​drivers/​base/​driver.c?v=3.11#L101 | driver_create_file]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​driver.c?v=3.11#L118 | driver_remove_file]] pentru adăugarea atributului la dispozitiv.+Pentru lucrul cu atributele avem structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L301 | struct driver_attribute]],​ macrodefiniția [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L308 | DRIVER_ATTR]] pentru definire ​și funcțiile [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​driver.c#​L97 | driver_create_file]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​driver.c#​L115 | driver_remove_file]] pentru adăugarea atributului la dispozitiv.
  
-Ca şi în cazul dispozitivelor,​ structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L194 | struct device_driver]] este, de obicei, incorporată în cadrul unei alte structuri specifice unei anumite magistrale (''​PCI'',​ ''​USB'',​ etc.):+Ca și în cazul dispozitivelor,​ structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | struct device_driver]] este, de obicei, incorporată în cadrul unei alte structuri specifice unei anumite magistrale (''​PCI'',​ ''​USB'',​ etc.):
  
 <spoiler onHidden="​Afișați cod" onVisible="​Ascundeți cod" > <spoiler onHidden="​Afișați cod" onVisible="​Ascundeți cod" >
Line 502: Line 502:
 Se observă că se exportă operațiile de înregistrare/​deînregistrare de driver pentru folosire în cadrul altor module. Se observă că se exportă operațiile de înregistrare/​deînregistrare de driver pentru folosire în cadrul altor module.
  
-Ca şi în cazul dispozitivelor, ​şi operațiile cu drivere sunt definite la inițializarea magistralei, ​şi sunt exportate pentru a putea fi folosite de drivere. În momentul în care se implementează un driver ce lucrează cu dispozitive ataşate la această magistrală,​ acesta va apela funcțiile ''​my_register_driver'' ​şi ''​my_unregister_driver''​ pentru a se asocia cu aceasta.+Ca și în cazul dispozitivelor, ​și operațiile cu drivere sunt definite la inițializarea magistralei, ​și sunt exportate pentru a putea fi folosite de drivere. În momentul în care se implementează un driver ce lucrează cu dispozitive atașate la această magistrală,​ acesta va apela funcțiile ''​my_register_driver'' ​și ''​my_unregister_driver''​ pentru a se asocia cu aceasta.
  
-Pentru utilizare (în implementarea driver-ului),​ trebuie declarată o structură de tipul celei exportate, inițializată ​şi înregistrată cu metoda exportata de magistrală:​+Pentru utilizare (în implementarea driver-ului),​ trebuie declarată o structură de tipul celei exportate, inițializată ​și înregistrată cu metoda exportata de magistrală:​
  
 <code c> <code c>
Line 533: Line 533:
 === Clase === === Clase ===
  
-O clasă este o vedere de nivel înalt asupra ''​Linux Device Model'',​ care abstractizează detaliile de implementare. Spre exemplu, există drivere pentru discurile ''​SCSI'' ​şi drivere pentru discurile ''​ATA'',​ dar toate aparțin clasei discuri. Clasele asigură o grupare a dispozitivelor bazată pe funcționalitate,​ nu pe modul în care sunt conectate sau cum funcționează. Clasele au corespondent în ''/​sys/​classes''​.+O clasă este o vedere de nivel înalt asupra ''​Linux Device Model'',​ care abstractizează detaliile de implementare. Spre exemplu, există drivere pentru discurile ''​SCSI'' ​și drivere pentru discurile ''​ATA'',​ dar toate aparțin clasei discuri. Clasele asigură o grupare a dispozitivelor bazată pe funcționalitate,​ nu pe modul în care sunt conectate sau cum funcționează. Clasele au corespondent în ''/​sys/​classes''​.
  
-Există doua structuri principale care descriu clasele: [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L319 | struct class]] ​şi [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L722 | struct device]]. Structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L319 | class]] descrie o clasa generică, în timp ce structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L722 | struct device]] descrie o clasă asociată unui dispozitiv. Există funcții pentru inițializare/​deinițializare ​şi adăugare de atribute pentru fiecare dintre acestea, descrise în ''​include/​linux/​device.h''​.+Există doua structuri principale care descriu clasele: [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L388 | struct class]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]]. Structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L388 | class]] descrie o clasa generică, în timp ce structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]] descrie o clasă asociată unui dispozitiv. Există funcții pentru inițializare/​deinițializare ​și adăugare de atribute pentru fiecare dintre acestea, descrise în ''​include/​linux/​device.h''​.
  
 Avantajul folosirii claselor este că programul udev din userspace, despre care vom discuta în continuare, permite crearea automată a dispozitivelor în directorul ''/​dev''​ pe baza informațiilor clasei. Avantajul folosirii claselor este că programul udev din userspace, despre care vom discuta în continuare, permite crearea automată a dispozitivelor în directorul ''/​dev''​ pe baza informațiilor clasei.
Line 541: Line 541:
 Din acest motiv, vom prezenta în continuare un set restrâns de funcții care lucrează cu clasele pentru a simplifica folosirea mecanismului de plug and play. Din acest motiv, vom prezenta în continuare un set restrâns de funcții care lucrează cu clasele pentru a simplifica folosirea mecanismului de plug and play.
  
-O clasă generică este descrisă de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L319 | struct class]]:+O clasă generică este descrisă de structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L388 | struct class]]:
  
 <code c> <code c>
Line 564: Line 564:
 </​code>​ </​code>​
  
-Pentru inițializare/​deinițializare există funcțiile [[http://​lxr.free-electrons.com/​source/​include/​linux/​device.h#​L389 | class_register]] ​şi [[http://​lxr.free-electrons.com/​source/​drivers/​base/​class.c#​L211 | class_unregister]]:​+Pentru inițializare/​deinițializare există funcțiile [[http://​lxr.free-electrons.com/​source/​include/​linux/​device.h#​L389 | class_register]] ​și [[http://​lxr.free-electrons.com/​source/​drivers/​base/​class.c#​L211 | class_unregister]]:​
  
 <spoiler onHidden="​Afișați cod" onVisible="​Ascundeți cod" > <spoiler onHidden="​Afișați cod" onVisible="​Ascundeți cod" >
Line 597: Line 597:
 \\ \\
  
-O clasă asociată unui dispozitiv este descrisă de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L722 | device]]. Pentru inițializare/​deinițializare există funcțiile [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c#​L1689 | device_create]] ​şi [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c#​L1754 device destroy]]. Funcția [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c#​L1689 | device_create]] inițializează stuctura [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L722 | device]], îi asociază structura generică [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L319 | class]] ​şi dispozitivul ​primite ​ca parametru; în plus, va crea un atribut al clasei, ''​dev'',​ care conține minorul ​şi majorul dispozitivului (''​minor:​major''​). Astfel, utilitarul ''​udev''​ din usermode poate citi datele necesare din acest fişier atribut pentru a crea un nod în directorul ''/​dev''​ apelând ''​makenod''​.+O clasă asociată unui dispozitiv este descrisă de structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | device]]. Pentru inițializare/​deinițializare există funcțiile [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1774 | device_create]] ​și [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1862 device_destroy]]. Funcția [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1774 | device_create]] inițializează stuctura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | device]], îi asociază structura generică [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L388 | class]] ​și dispozitivul ​primit ​ca parametru; în plus, va crea un atribut al clasei, ''​dev'',​ care conține minorul ​și majorul dispozitivului (''​minor:​major''​). Astfel, utilitarul ''​udev''​ din usermode poate citi datele necesare din acest fișier atribut pentru a crea un nod în directorul ''/​dev''​ apelând ''​makenod''​.
  
 Un exemplu de inițializare:​ Un exemplu de inițializare:​
Line 615: Line 615:
 </​code>​ </​code>​
  
-În momentul în care un nou dispozitiv va fi descoperit, i se va asocia o clasă ​şi un nod în directorul ''/​dev''​. Pentru exemplul de mai sus, se va genera un nod ''/​dev/​myclass0''​.+În momentul în care un nou dispozitiv va fi descoperit, i se va asocia o clasă ​și un nod în directorul ''/​dev''​. Pentru exemplul de mai sus, se va genera un nod ''/​dev/​myclass0''​.
  
 ===== Hotplug ===== ===== Hotplug =====
Line 621: Line 621:
 ''​Hotplug''​ descrie mecanismul de adăugare sau eliminare a unui dispozitiv din sistem în timp ce acesta rulează, fără a fi necesară repornirea sistemului. ''​Hotplug''​ descrie mecanismul de adăugare sau eliminare a unui dispozitiv din sistem în timp ce acesta rulează, fără a fi necesară repornirea sistemului.
  
-Un eveniment ''​hotplug''​ este o notificare din partea kernel-ului către user-space atunci când se modifică ceva în configurația sistemului. Aceste evenimente sunt generate la crearea sau eliminarea unui obiect kobject din kernel. Întrucât aceste obiecte stau la baza ''​Linux Device Model'',​ fiind incluse în toate structurile ([[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L61 | struct bus_type]], [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h#​L722 | struct device]], [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L194 | struct device_driver]],​ [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L319 | struct class]], etc.), se va genera un eveniment ''​hotplug''​ la crearea sau eliminarea oricăreia dintre aceste structuri (''​uevent''​). +Un eveniment ''​hotplug''​ este o notificare din partea kernel-ului către user-space atunci când se modifică ceva în configurația sistemului. Aceste evenimente sunt generate la crearea sau eliminarea unui obiect kobject din kernel. Întrucât aceste obiecte stau la baza ''​Linux Device Model'',​ fiind incluse în toate structurile ([[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | struct bus_type]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L782 | struct device]], [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | struct device_driver]],​ [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L388 | struct class]], etc.), se va genera un eveniment ''​hotplug''​ la crearea sau eliminarea oricăreia dintre aceste structuri (''​uevent''​). 
-În momentul în care un dispozitiv este descoperit în sistem, se generează un eveniment. În funcție de punctul în care se află în ''​Linux Device Model'',​ se vor apela funcțiile corespunzătoare apariției unui eveniment (de obicei, este cazul funcției ''​uevent''​ a magistralei sau clasei). Driverul are posibilitatea,​ prin intermediul acestor funcții, să seteze variabile de sistem pentru user-space. Evenimentul generat ajunge în user-space apoi. Aici există utilitarul ''​udev'',​ care capturează aceste evenimente. În directorul ''/​etc/​udev/''​ există fişierele de configurare pentru acest utilitar. Se pot specifica diferite reguli pentru a captura numai anumite evenimente ​şi a executa anumite acțiuni, în funcție de variabilele de sistem setate din kernel sau în funcțiile ''​uevent''​.+În momentul în care un dispozitiv este descoperit în sistem, se generează un eveniment. În funcție de punctul în care se află în ''​Linux Device Model'',​ se vor apela funcțiile corespunzătoare apariției unui eveniment (de obicei, este cazul funcției ''​uevent''​ a magistralei sau clasei). Driverul are posibilitatea,​ prin intermediul acestor funcții, să seteze variabile de sistem pentru user-space. Evenimentul generat ajunge în user-space apoi. Aici există utilitarul ''​udev'',​ care capturează aceste evenimente. În directorul ''/​etc/​udev/''​ există fișierele de configurare pentru acest utilitar. Se pot specifica diferite reguli pentru a captura numai anumite evenimente ​și a executa anumite acțiuni, în funcție de variabilele de sistem setate din kernel sau în funcțiile ''​uevent''​.
  
 O consecință importantă este că în acest mod se poate realiza mecanismul ''​plug and play'';​ cu ajutorul lui ''​udev''​ si a claselor, descrise anterior, se pot crea automat intrările în directorul ''/​dev''​ pentru dispozitive,​ iar cu ajutorul ''​udev''​ se pot încărca automat driverele necesare pentru un dispozitiv. În acest fel, întreg procesul este automatizat. O consecință importantă este că în acest mod se poate realiza mecanismul ''​plug and play'';​ cu ajutorul lui ''​udev''​ si a claselor, descrise anterior, se pot crea automat intrările în directorul ''/​dev''​ pentru dispozitive,​ iar cu ajutorul ''​udev''​ se pot încărca automat driverele necesare pentru un dispozitiv. În acest fel, întreg procesul este automatizat.
  
-Regulile pentru ''​udev''​ sunt localizate în ''/​etc/​udev/​rules.d''​. Orice fişier de aici care se termină cu .conf va fi parsat la apariția unui eveniment. Pentru mai multe detalii despre cum se scriu regulile în aceste fişiere consultați [[http://​www.reactivated.net/​writing_udev_rules.html | Writing udev rules]]. Pentru testare, există utilitarele ''​udevmonitor'',​ ''​udevinfo'' ​şi ''​udevtest''​.+Regulile pentru ''​udev''​ sunt localizate în ''/​etc/​udev/​rules.d''​. Orice fișier de aici care se termină cu .conf va fi parsat la apariția unui eveniment. Pentru mai multe detalii despre cum se scriu regulile în aceste fișiere consultați [[http://​www.reactivated.net/​writing_udev_rules.html | Writing udev rules]]. Pentru testare, există utilitarele ''​udevmonitor'',​ ''​udevinfo'' ​și ''​udevtest''​.
  
-Pentru un scurt exemplu, sa consideram situația în care dorim sa încarcăm automat un driver pentru un dispozitiv în momentul apariției unui eveniment. Putem crea un nou fişier ''/​etc/​udev/​rules.d/​myrules.rules'',​ în care vom avea următoarea linie:+Pentru un scurt exemplu, sa consideram situația în care dorim sa încarcăm automat un driver pentru un dispozitiv în momentul apariției unui eveniment. Putem crea un nou fișier ''/​etc/​udev/​rules.d/​myrules.rules'',​ în care vom avea următoarea linie:
  
 <code bash> <code bash>
Line 634: Line 634:
 </​code>​ </​code>​
  
-Astfel, se vor alege dintre evenimentele generate doar cele care aparțin subsistemului ''​pnp''​ (sunt conectate la magistrala PNP) şi au un atribut id cu valoarea ''​PNP0400''​. În momentul în care se va găsi această regulă, se va executa comanda ce inserează driverul corespunzător în kernel.+Astfel, se vor alege dintre evenimentele generate doar cele care aparțin subsistemului ''​pnp''​ (sunt conectate la magistrala PNP) și au un atribut id cu valoarea ''​PNP0400''​. În momentul în care se va găsi această regulă, se va executa comanda ce inserează driverul corespunzător în kernel.
  
 ===== Plug and Play ===== ===== Plug and Play =====
Line 640: Line 640:
 După cum s-a specificat mai sus, în ''​Linux Device Model''​ toate dispozitivele sunt conectate printr-o magistrală,​ chiar dacă are corespondent fizic hardware sau este virtuală. După cum s-a specificat mai sus, în ''​Linux Device Model''​ toate dispozitivele sunt conectate printr-o magistrală,​ chiar dacă are corespondent fizic hardware sau este virtuală.
  
-În kernel, există deja implementate majoritatea magistralelor prin definirea unei structuri [[http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L102 | bus_type]] ​şi a funcțiilor de înregistrare/​deînregistrare a driverelor ​şi dispozitivelor asociate. Pentru implementarea unui driver trebuie determinată magistrala la care se ataşează dispozitivele suportate ​şi trebuie folosite funcțiile ​şi structurile acesteia. Principalele magistrale sunt [[http://​lxr.free-electrons.com/​source/​drivers/​pci/​pci-driver.c?​v=3.11 | PCI]], [[http://​lxr.free-electrons.com/​source/​drivers/​usb/​core/​driver.c?​v=3.11 | USB]], [[http://​lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?​v=3.11 | PNP]], [[http://​lxr.free-electrons.com/​source/​drivers/​ide/​ide.c?​v=3.11 | IDE]], [[http://​lxr.free-electrons.com/​source/​drivers/​scsi/​scsi_sysfs.c?​v=3.11 | SCSI]], [[http://​lxr.free-electrons.com/​source/​drivers/​base/​platform.c?​v=3.11 | platform]], [[http://​lxr.free-electrons.com/​source/​drivers/​acpi/​scan.c?​v=3.11 | ACPI]], etc.+În kernel, există deja implementate majoritatea magistralelor prin definirea unei structuri [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L109 | bus_type]] ​și a funcțiilor de înregistrare/​deînregistrare a driverelor ​și dispozitivelor asociate. Pentru implementarea unui driver trebuie determinată magistrala la care se atașează dispozitivele suportate ​și trebuie folosite funcțiile ​și structurile acesteia. Principalele magistrale sunt [[http://​lxr.free-electrons.com/​source/​drivers/​pci/​pci-driver.c?​v=4.| PCI]], [[http://​lxr.free-electrons.com/​source/​drivers/​usb/​core/​driver.c?​v=4.| USB]], [[http://​lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?​v=4.| PNP]], [[http://​lxr.free-electrons.com/​source/​drivers/​ide/​ide.c?​v=4.| IDE]], [[http://​lxr.free-electrons.com/​source/​drivers/​scsi/​scsi_sysfs.c?​v=4.| SCSI]], [[http://​lxr.free-electrons.com/​source/​drivers/​base/​platform.c?​v=4.| platform]], [[http://​lxr.free-electrons.com/​source/​drivers/​acpi/​scan.c?​v=4.| ACPI]], etc.
  
 ==== Magistrala PNP ==== ==== Magistrala PNP ====
  
-Mecanismul plug and play oferă un mijloc de detectarea ​şi setare a resurselor pentru drivere legacy sau care nu pot fi configurate în alt mod. Toate driverele plug and play, protocoalele,​ serviciile au la bază nivelul ''​Plug and Play''​. Acesta este responsabil cu schimbul de informație între drivere ​şi protocoale. Următoarele protocoale sunt disponibile:​+Mecanismul plug and play oferă un mijloc de detectarea ​și setare a resurselor pentru drivere legacy sau care nu pot fi configurate în alt mod. Toate driverele plug and play, protocoalele,​ serviciile au la bază nivelul ''​Plug and Play''​. Acesta este responsabil cu schimbul de informație între drivere ​și protocoale. Următoarele protocoale sunt disponibile:​
  
-  * **PNPBIOS** - folosite pentru sisteme cum ar fi porturile seriale ​şi paralele+  * **PNPBIOS** - folosite pentru sisteme cum ar fi porturile seriale ​și paralele
   * **ISAPNP** - oferă suport pentru magistrala ISA   * **ISAPNP** - oferă suport pentru magistrala ISA
   * **ACPI** - care oferă, printre altele, informații despre dispozitivele la nivel de sistem   * **ACPI** - care oferă, printre altele, informații despre dispozitivele la nivel de sistem
  
-În kernel există o magistrala ''​pnp_bus'',​ care este folosită pentru conectare de multe drivere. Implementarea ​şi modul de lucru cu această magistrală respectă modelul ''​Linux Device Model'' ​şi este foarte asemănatoare cu ce s-a prezentat până acum.+În kernel există o magistrala ''​pnp_bus'',​ care este folosită pentru conectare de multe drivere. Implementarea ​și modul de lucru cu această magistrală respectă modelul ''​Linux Device Model'' ​și este foarte asemănatoare cu ce s-a prezentat până acum.
  
-Principalele funcții ​şi structuri exportate de această magistrală, ​şi care pot fi folosite de către drivere sunt:+Principalele funcții ​și structuri exportate de această magistrală, ​și care pot fi folosite de către drivere sunt:
  
-  * [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]],​ tipul de driver asociat magistralei +  * [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]],​ tipul de driver asociat magistralei 
-  * [[http://lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?v=3.11#L224 | pnp_register_driver]],​ pentru a înregistra un driver pnp în sistem +  * [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​pnp/​driver.c#​L266 | pnp_register_driver]],​ pentru a înregistra un driver pnp în sistem 
-  * [[http://lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?v=3.11#L232 | pnp_unregister_driver]],​ pentru a deînregistra un driver pnp din sistem+  * [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​pnp/​driver.c#​L274 | pnp_unregister_driver]],​ pentru a deînregistra un driver pnp din sistem
  
-După cum am observat în secțiunile anterioare, magistrala are o funcție ''​match''​ cu ajutorul căreia asociaza dispozitive cu driverele corespunzătoare. Spre exemplu, în cazul descoperirii unui dispozitiv, se va căuta driver-ul care îndeplineşte condiția dată de această funcție relativă la dispozitiv. De obicei, această condiție reprezintă o comparație de id-uri ale driverului ​şi dispozitivului. Un mecanism răspândit este folosirea unei tabele statice în fiecare driver, ce conține informații despre dispozitivele suportate de driver ​şi vor fi folosite de magistrală la comparație. Spre exemplu, pentru un driver de port paralel vom avea tabela ''​parport_pc_pnp_tbl'':​+După cum am observat în secțiunile anterioare, magistrala are o funcție ''​match''​ cu ajutorul căreia asociaza dispozitive cu driverele corespunzătoare. Spre exemplu, în cazul descoperirii unui dispozitiv, se va căuta driver-ul care îndeplinește condiția dată de această funcție relativă la dispozitiv. De obicei, această condiție reprezintă o comparație de id-uri ale driverului ​și dispozitivului. Un mecanism răspândit este folosirea unei tabele statice în fiecare driver, ce conține informații despre dispozitivele suportate de driver ​și vor fi folosite de magistrală la comparație. Spre exemplu, pentru un driver de port paralel vom avea tabela ''​parport_pc_pnp_tbl'':​
  
 <code c> <code c>
Line 673: Line 673:
 </​code>​ </​code>​
  
-Se declară ​şi inițializează o structură [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]],​ cum ar fi ''​parport_pc_pnp_driver'':​+Se declară ​și inițializează o structură [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]],​ cum ar fi ''​parport_pc_pnp_driver'':​
  
 <code c> <code c>
Line 710: Line 710:
 ==== Operații PNP ==== ==== Operații PNP ====
  
-Până acum am discutat despre modelul ''​Linux Device Model'' ​şi API-ul folosit. Pentru a implementa un driver plug and play, trebuie respectat modelul ''​Linux Device Model''​.+Până acum am discutat despre modelul ''​Linux Device Model'' ​și API-ul folosit. Pentru a implementa un driver plug and play, trebuie respectat modelul ''​Linux Device Model''​.
  
-De cele mai multe ori, adăugarea unei magistrale în kernel nu este necesară (bus), întrucât deja sunt implementate majoritatea magistralelor (''​PCI'',​ ''​USB'',​ etc.). Astfel, mai întâi trebuie identificată magistrala la care se ataşează dispozitivul. În exemplele de mai jos, vom considera că această magistrală este magistrala ''​PNP''​. Astfel, se vor folosi structurile ​şi funcțiile prezentate mai sus.+De cele mai multe ori, adăugarea unei magistrale în kernel nu este necesară (bus), întrucât deja sunt implementate majoritatea magistralelor (''​PCI'',​ ''​USB'',​ etc.). Astfel, mai întâi trebuie identificată magistrala la care se atașează dispozitivul. În exemplele de mai jos, vom considera că această magistrală este magistrala ''​PNP''​. Astfel, se vor folosi structurile ​și funcțiile prezentate mai sus.
  
 {{ :​so2:​laboratoare:​laboratoare-plug_and_play-linux_device_model_operations.png |}} {{ :​so2:​laboratoare:​laboratoare-plug_and_play-linux_device_model_operations.png |}}
Line 718: Line 718:
 === Adăugare driver === === Adăugare driver ===
  
-Pe lângă operațiile uzuale, un driver trebuie să respecte modelul ''​Linux Device Model''​. Astfel, se va înregistra în sistem folosind funcțiile puse la dispoziție de magistrală în acest scop. De obicei, magistrala pune la dispoziție o structură particulară de driver, ce conține o structură [[ http://lxr.free-electrons.com/​source/​include/​linux/​device.h?v=3.11#L225 | device_driver]],​ pe care driverul trebuie să o inițializeze ​şi să o înregistreze cu o funcție ''​*_register_driver''​. Spre exemplu, pentru magistrala ''​PNP'',​ driverul trebuie să declare ​şi să inițializeze o structură de tipul [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]],​ pe care să o înregistreze cu [[http://lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?v=3.11#L224 | pnp_register_driver]]:​+Pe lângă operațiile uzuale, un driver trebuie să respecte modelul ''​Linux Device Model''​. Astfel, se va înregistra în sistem folosind funcțiile puse la dispoziție de magistrală în acest scop. De obicei, magistrala pune la dispoziție o structură particulară de driver, ce conține o structură [[ http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​device.h#​L264 | device_driver]],​ pe care driverul trebuie să o inițializeze ​și să o înregistreze cu o funcție ''​*_register_driver''​. Spre exemplu, pentru magistrala ''​PNP'',​ driverul trebuie să declare ​și să inițializeze o structură de tipul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]],​ pe care să o înregistreze cu [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​pnp/​driver.c#​L266 | pnp_register_driver]]:​
  
 <code c> <code c>
Line 737: Line 737:
  
 Spre deosebire de driverele legacy, driverele plug and play nu înregistrează dispozitivele la inițializare,​ în funcția ''​my_init''​ (''​register_device''​). Spre deosebire de driverele legacy, driverele plug and play nu înregistrează dispozitivele la inițializare,​ în funcția ''​my_init''​ (''​register_device''​).
-După cum s-a descris mai sus, fiecare magistrală are o funcție ''​match''​ care se apelează la detectarea unui dispozitv pentru a determina driverul asociat acestuia. Prin urmare, trebuie să existe o modalitate ca fiecare driver să exporte informații despre ce dispozitive suportă, pentru a putea trece de această comparație ​şi pentru a fi apelate funcțiile sale. În exemplele prezentate în laborator, se face o simplă comparație între numele dispozitivului ​şi numele driver-ului. Cele mai multe drivere folosesc o tabelă cu informații despre dispozitiv, pentru care au un pointer în structura driver-ului. Spre exemplu, un driver asociat cu o magistrală ''​PNP'',​ declară o tabelă de tipul [[http://lxr.free-electrons.com/​source/​include/​linux/​mod_devicetable.h?v=3.11#L197 | pnp_device_id]], ​şi inițializează câmpul ''​id_table''​ din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]] cu un pointer către aceasta:+După cum s-a descris mai sus, fiecare magistrală are o funcție ''​match''​ care se apelează la detectarea unui dispozitv pentru a determina driverul asociat acestuia. Prin urmare, trebuie să existe o modalitate ca fiecare driver să exporte informații despre ce dispozitive suportă, pentru a putea trece de această comparație ​și pentru a fi apelate funcțiile sale. În exemplele prezentate în laborator, se face o simplă comparație între numele dispozitivului ​și numele driver-ului. Cele mai multe drivere folosesc o tabelă cu informații despre dispozitiv, pentru care au un pointer în structura driver-ului. Spre exemplu, un driver asociat cu o magistrală ''​PNP'',​ declară o tabelă de tipul [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​mod_devicetable.h#​L199 | pnp_device_id]], ​și inițializează câmpul ''​id_table''​ din structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]] cu un pointer către aceasta:
  
 <code c> <code c>
Line 759: Line 759:
 </​code>​ </​code>​
  
-În exemplul de mai sus driver-ul suportă operații pentru portul paralel. Aceaste informații sunt folosite de magistrală,​ în funcția ''​match_device''​. La adăugarea unui driver, se va asocia driverul magistralei ​şi se vor crea intrări în ''​sysfs''​ bazate pe numele driver-ului. Apoi se va apela funcția ''​match''​ a magistralei pentru toate dispozitivele asociate, pentru a asocia driver-ul cu orice dispozitiv conectat pe care îl suportă.+În exemplul de mai sus driver-ul suportă operații pentru portul paralel. Aceaste informații sunt folosite de magistrală,​ în funcția ''​match_device''​. La adăugarea unui driver, se va asocia driverul magistralei ​și se vor crea intrări în ''​sysfs''​ bazate pe numele driver-ului. Apoi se va apela funcția ''​match''​ a magistralei pentru toate dispozitivele asociate, pentru a asocia driver-ul cu orice dispozitiv conectat pe care îl suportă.
  
 === Eliminare driver === === Eliminare driver ===
  
-Pentru a elimina un driver din kernel, pe lângă operațiile necesare unui driver legacy, trebuie deînregistrată structura device_driver. În cazul unui driver pentru un dispozitiv asociat magistralei ''​PNP'',​ trebuie deînregistrată structura [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]] cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​drivers/​pnp/​driver.c?v=3.11#L232 | pnp_unregister_driver]]:​+Pentru a elimina un driver din kernel, pe lângă operațiile necesare unui driver legacy, trebuie deînregistrată structura device_driver. În cazul unui driver pentru un dispozitiv asociat magistralei ''​PNP'',​ trebuie deînregistrată structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]] cu ajutorul funcției [[http://elixir.free-electrons.com/linux/v4.9/​source/​drivers/​pnp/​driver.c#​L274 | pnp_unregister_driver]]:​
  
 <code c> <code c>
Line 776: Line 776:
 </​code>​ </​code>​
  
-Spre deosebire de driverele legacy, driverele plug and play nu deînregistrează dispozitivele la deînregistrarea driver-ului,​ în funcția ''​my_exit''​ (unregister_device). La eliminarea unui driver, se vor elimina toate referințele către el pentru toate dispozitivele pe care le suportă ​şi se vor şterge intrările din ''​sysfs''​.+Spre deosebire de driverele legacy, driverele plug and play nu deînregistrează dispozitivele la deînregistrarea driver-ului,​ în funcția ''​my_exit''​ (unregister_device). La eliminarea unui driver, se vor elimina toate referințele către el pentru toate dispozitivele pe care le suportă ​și se vor șterge intrările din ''​sysfs''​.
  
 === Adăugare dispozitiv === === Adăugare dispozitiv ===
  
-Dupa cum am văzut mai sus, driverele plug and play nu înregistrează dispozitivele la inițializare. Această operație se va realiza în funcția ''​probe'',​ care se va apela la detectarea unui dispozitiv. În cazul unui driver pentru un dispozitiv ataşat la magistrala ''​PNP'',​ adăugarea se va realiza în funcția ''​probe''​ din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]]:​+Dupa cum am văzut mai sus, driverele plug and play nu înregistrează dispozitivele la inițializare. Această operație se va realiza în funcția ''​probe'',​ care se va apela la detectarea unui dispozitiv. În cazul unui driver pentru un dispozitiv atașat la magistrala ''​PNP'',​ adăugarea se va realiza în funcția ''​probe''​ din structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]]:​
  
 <code c> <code c>
Line 808: Line 808:
 </​code>​ </​code>​
  
-La detectarea unui dispozitiv în kernel (în procesul de boot sau la adăugarea dispozitivului prin ''​hotplug''​),​ se transmite o întrerupere în sistem care ajunge la magistrală. Dispozitivul este înregistrat cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​drivers/​base/​core.c?v=3.11#L1209 | device_register]] ​şi este ataşat magistralei (şi se va genera un apel în userspace, care poate fi detectat de ''​udev''​). Apoi se va parcurge lista de drivere a magistralei ​şi se va apela funcția ''​match''​ pentru fiecare dintre ele. Funcția ''​match''​ încearcă să asocieze un driver cu un dispozitiv. După ce a fost determinat driverul asociat dispozitivului,​ se va apela funcția ''​probe''​ a driver-ului. Dacă funcția se termină cu succes, dispozitivul este adăugat în lista de dispozitive a driver-ului ​şi se creează intrările corespunzătoare în ''​sysfs''​ bazate pe numele dispozitivului.+La detectarea unui dispozitiv în kernel (în procesul de boot sau la adăugarea dispozitivului prin ''​hotplug''​),​ se transmite o întrerupere în sistem care ajunge la magistrală. Dispozitivul este înregistrat cu ajutorul funcției [[https://elixir.bootlin.com/linux/v4.9/​source/​drivers/​base/​core.c#​L1185 | device_register]] ​și este atașat magistralei (și se va genera un apel în userspace, care poate fi detectat de ''​udev''​). Apoi se va parcurge lista de drivere a magistralei ​și se va apela funcția ''​match''​ pentru fiecare dintre ele. Funcția ''​match''​ încearcă să asocieze un driver cu un dispozitiv. După ce a fost determinat driverul asociat dispozitivului,​ se va apela funcția ''​probe''​ a driver-ului. Dacă funcția se termină cu succes, dispozitivul este adăugat în lista de dispozitive a driver-ului ​și se creează intrările corespunzătoare în ''​sysfs''​ bazate pe numele dispozitivului.
  
 === Eliminare dispozitiv === === Eliminare dispozitiv ===
  
-Dupa cum am văzut mai sus, driverele plug and play nu deînregistrează dispozitivele la deînregistrarea driver-ului. Această operație se va realiza în funcția ''​remove'',​ care se va apela la detectarea eliminării unui dispozitiv din kernel. În cazul unui driver pentru un dispozitiv ataşat la magistrala ''​PNP'',​ adăugarea se va realiza în funcția ''​remove''​ din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​pnp.h?v=3.11#L370 | pnp_driver]]:​+Dupa cum am văzut mai sus, driverele plug and play nu deînregistrează dispozitivele la deînregistrarea driver-ului. Această operație se va realiza în funcția ''​remove'',​ care se va apela la detectarea eliminării unui dispozitiv din kernel. În cazul unui driver pentru un dispozitiv atașat la magistrala ''​PNP'',​ adăugarea se va realiza în funcția ''​remove''​ din structura [[http://elixir.free-electrons.com/linux/v4.9/​source/​include/​linux/​pnp.h#​L380 | pnp_driver]]:​
  
 <code c> <code c>
Line 827: Line 827:
 </​code>​ </​code>​
  
-După cum se poate observa, la detectarea eliminării unui dispozitiv din sistem, se va apela funcția remove a driver-ului,​ se va genera un apel în user-space, ce poate fi detectat de ''​udev'' ​şi se vor elimina intrările din ''​sysfs''​.+După cum se poate observa, la detectarea eliminării unui dispozitiv din sistem, se va apela funcția remove a driver-ului,​ se va genera un apel în user-space, ce poate fi detectat de ''​udev'' ​și se vor elimina intrările din ''​sysfs''​.
  
 ===== Resurse utile ===== ===== Resurse utile =====
so2/laboratoare/lab12.1400051907.txt.gz · Last modified: 2014/05/14 10:18 by razvan.deaconescu
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