User Tools

Site Tools


linux-kernel-dev:capitole:capitol-02

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
linux-kernel-dev:capitole:capitol-02 [2015/09/08 12:57]
razvan [Actualizare modul de hook]
linux-kernel-dev:capitole:capitol-02 [2016/08/30 12:18] (current)
razvan [Informații cscope]
Line 15: Line 15:
 ===== Resurse utile ===== ===== Resurse utile =====
  
-  * http://​www.tldp.org/​LDP/​lkmpg/​2.6/​html/​x323.html+  * [[http://​www.tldp.org/​LDP/​lkmpg/​2.6/​html/​x323.html|The Linux Kernel Module Programming Guide: Passing Command Line Arguments to a Module]] 
 +  * [[https://​lwn.net/​Kernel/​LDD3/​|Linux Device Drivers, 3rd Edition]] (free) 
 +  * [[https://​lwn.net/​images/​pdf/​LDD3/​ch02.pdf|Linux Device Drivers, 3rd Edition, Chapter 2: Building and Running Modules]] (free, PDF) 
 +  * [[http://​lxr.free-electrons.com/​|Linux Cross Reference (LXR) (Free Electrons)]]
  
 ===== Exerciții ===== ===== Exerciții =====
Line 110: Line 113:
 Actualizați modulul ''​hello.c''​ pentru a afișa un mesaj și la descărcarea din kernel, la operația ''​rmmod''​. Actualizați modulul ''​hello.c''​ pentru a afișa un mesaj și la descărcarea din kernel, la operația ''​rmmod''​.
  
-Folosiți funcția ''​printk''​ astfel încât mesajele să fie afișate în bufferul kernel-ului (adică să fie afișate cu ''​dmesg''​) ​dar să nu fie afișate la consolă.+Folosiți funcția ''​printk''​ astfel încât mesajele să fie afișate ​atât în bufferul kernel-ului (adică să fie afișate cu ''​dmesg''​) ​cât șla consolă.
  
 <note tip> <note tip>
Line 124: Line 127:
 </​note>​ </​note>​
  
 +<note tip>
 +Pentru a include conținutul fișierului header ''​include/​linux/​sched.h''​ folosiți construcția
 +<​code>​
 +#include <​linux/​sched.h>​
 +</​code>​
 +La fel veți proceda și în cazul altor fișiere de tip header în care sunt definite structuri, tipuri de date sau macro-uri pe care le folosiți în modulul vostru.
 +</​note>​
 ==== Afișare comandă ==== ==== Afișare comandă ====
  
Line 171: Line 181:
 ==== Modul nou din surse multiple ==== ==== Modul nou din surse multiple ====
  
-Creați un modul care să aibă două fișiere cod sursă. Într-un fișier cod sursă sunt implementate funcțiile de inițializare și ieșire ale modulului. În celălalt fișier implementați o funcție care face dump în hexacimal la cel mult 4096 de octeți de la o adresă dată. Adresa dată trebuie să fie adresă de kernel space (>= ''​0xc0000000''​). Funcția este apelată din primul modul.+Creați un modul care să aibă două fișiere cod sursă. Într-un fișier cod sursă sunt implementate funcțiile de inițializare și ieșire ale modulului. În celălalt fișier implementați o funcție care face dump în hexacimal la cel mult 4096 de octeți de la o adresă dată. Adresa dată trebuie să fie adresă de kernel space (>= ''​0xc0000000''​). Funcția este apelată din primul modul în cadrul funcției de inițializare a acestuia.
  
 Compilați modulul, copiați-l în mașina virtuală QEMU și testați-l. Compilați modulul, copiați-l în mașina virtuală QEMU și testați-l.
Line 180: Line 190:
  
 <note tip> <note tip>
-Pentru pachetele care pleacă folosiți ca ''​hooknum''​ valoarea ''​NF_INET_LOCAL_OUT''​.+Pentru pachetele care pleacă folosiți ca ''​hooknum''​ valoarea ''​NF_INET_LOCAL_OUT''​. Este vorba de câmpul ''​hooknum''​ din cadrul structura ''​icmp_nf_ops''​.
  
 Pachetele de tipul ''​echo reply''​ au câmpul ''​icmp_type''​ al structurii ''​icmp_hdr''​ egal cu valoarea ''​ICMP_ECHOREPLY''​. Pachetele de tipul ''​echo reply''​ au câmpul ''​icmp_type''​ al structurii ''​icmp_hdr''​ egal cu valoarea ''​ICMP_ECHOREPLY''​.
Line 187: Line 197:
 vi -t ICMP_ECHO vi -t ICMP_ECHO
 </​code>​ </​code>​
 +</​note>​
 +
 +==== Informații cscope ====
 +
 +[[http://​cscope.sourceforge.net/​|Cscope]] este un program pentru parcurgerea eficientă a surselor C.  Pentru a-l folosi, trebuie generată o bază de date cscope din sursele existente. ​ Într-un tree Linux, este suficientă folosirea ''​make ARCH=x86 cscope''​. ​ Precizarea arhitecturii prin variabila ARCH este opțională,​ dar recomandată;​ altfel, unele funcții dependente de arhitectură vor apărea de mai multe ori în baza de date.
 +
 +Cscope poate fi folosit și stand-alone,​ dar este mult mai util în combinație cu un editor. ​ Pentru a folosi cscope cu Vim, este necesar să instalați ambele pachete și să adăugați următoarele linii în fișierul ''​.vimrc''​ (mașina din laborator are deja configurările făcute):
 +
 +<code vim>
 +if has("​cscope"​)
 +        " Look for a '​cscope.out'​ file starting from the current directory,
 +        " going up to the root directory.
 +        let s:dirs = split(getcwd(),​ "/"​)
 +        while s:dirs != []
 +                let s:path = "/"​ . join(s:​dirs,​ "/"​)
 +                if (filereadable(s:​path . "/​cscope.out"​))
 +                        execute "cs add " . s:path . "/​cscope.out " . s:path . " -v"
 +                        break
 +                endif
 +                let s:dirs = s:dirs[:-2]
 +        endwhile
 +
 +        set csto=0 "​ Use cscope first, then ctags
 +        set cst " Only search cscope
 +        set csverb "​ Make cs verbose
 +
 +        nmap <​C-\>​s :cs find s <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +        nmap <​C-\>​g :cs find g <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +        nmap <​C-\>​c :cs find c <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +        nmap <​C-\>​t :cs find t <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +        nmap <​C-\>​e :cs find e <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +        nmap <​C-\>​f :cs find f <​C-R>​=expand("<​cfile>"​)<​CR><​CR>​
 +        nmap <​C-\>​i :cs find i ^<​C-R>​=expand("<​cfile>"​)<​CR>​$<​CR>​
 +        nmap <​C-\>​d :cs find d <​C-R>​=expand("<​cword>"​)<​CR><​CR>​
 +
 +        " Open a quickfix window for the following queries.
 +        set cscopequickfix=s-,​c-,​d-,​i-,​t-,​e-,​g-
 +endif
 +</​code>​
 +
 +Script-ul caută un fișier numit ''​cscope.out''​ în directorul curent, sau în directoarele părinte ale acestuia. ​ Dacă Vim găsește acest fișier, puteți folosi combinația ''​Ctrl+]''​ sau ''​Ctrl+\ g''​ (combinația control-\, urmată de tasta g) pentru a sări direct la definiția cuvântului de sub cursor (funcție, variabilă, structură etc.). ​ Similar, puteți folosi ''​Ctrl+\ s''​ pentru a merge la locurile unde este folosit cuvântul de sub cursor.
 +
 +Puteți lua un fișier ''​.vimrc''​ cscope-enabled (and other goodies) de la [[https://​github.com/​ddvlad/​cfg/​blob/​master/​_vimrc]]. ​ Următoarele indicații se bazează pe acest fișier, dar au listate și comenzile de bază vim care obțin același efect.
 +
 +Dacă există mai multe rezultate (de obicei există) vă puteți deplasa între ele folosind ''​F6''​ și ''​F5''​ ('':​cnext''​ și '':​cprev''​) sau deschizând o subfereastră nouă cu rezultatele,​ folosind '':​copen''​. Ca să închideți subfereastra folosiți comanda '':​cclose''​.
 +
 +Pentru a vă întoarce la locația precedentă,​ folosiți ''​Ctrl+o''​ (litera o, nu cifra zero). ​ Comanda poate fi invocată de mai multe ori și funcționează chiar dacă cscope a schimbat fișierul pe care îl editați.
 +
 +Pentru a merge la definiția unui simbol direct când porniți vim, folosiți ''​vim -t task_struct''​. Sau, dacă ați deschis Vim și vreți ulterior să căutați un simbol după nume, puteți folosi comanda '':​cs find g <​symbol_name>''​ (unde ''<​symbol_name>''​ este numele simbolului.
 +
 +Dacă ați găsit mai multe match-uri și dacă ați deschis o subfereastră cu toate match-urile (folosind '':​copen''​) și dacă sunteți în căutarea unui simbol de tip structură, este indicat să căutați în subfereastră (folosind ''/''​ -- //slash//) caracterul ''​{''​ (acoladă deschisă).
 +
 +<note important>​
 +Un sumar al comenzilor ''​cscope''​ îl puteți obține folosind '':​cs help''​.
 +
 +Pentru mai multe informații,​ folosiți help-ul integrat al Vim: '':​h cscope''​ sau '':​h copen''​.
 +</​note>​
 +
 +Dacă sunteți utilizatori emacs, [[http://​www.emacswiki.org/​emacs/​CScopeAndEmacs|wiki-ul emacs]] conține informații relevante pentru configurarea cscope.
 +
 +Pentru o interfață mai simplă, [[http://​sourceforge.net/​projects/​kscope/​|Kscope]] este un frontend pentru cscope care foloseşte QT. Este lightweight,​ foarte rapid și foarte ușor de folosit. Permite căutare folosind expresii regulate, grafuri de apel etc. Kscope nu mai este, în momentul de fața, menținut. Există şi un [[https://​opendesktop.org/​content/​show.php/​Kscope4?​content=156987|port]] al versiunii 1.6 pentru Qt4 şi KDE 4 care păstrează integrarea editorului Kate şi este mai uşor de folosit decât ultima versiune prezentă pe SourceForge.
 +
 +<note important>​
 +Dacă nu există deja un fișier ''​cscope.out''​ generat sau dacă s-a stricat, îl puteți genera folosind
 +<​code>​
 +make ARCH=x86 cscope
 +</​code>​
 +</​note>​
 +==== cscope spelunking ====
 +
 +Folosiți direct Vim și comenzile cscope pentru parcurgerea codului sursă cu indicațiile de mai jos.
 +
 +Determinați fișierul în care sunt definite următoarele tipuri de date:
 +  * ''​struct task_struct''​
 +  * ''​struct semaphore''​
 +  * ''​struct list_head''​
 +  * ''​spinlock_t''​
 +  * ''​struct file_system_type''​
 +
 +<note tip>
 +Pentru o structură se caută doar numele ei. Spre exemplu, în cazul ''​struct task_struct''​ se caută șirul ''​task_struct''​.
 +
 +De obicei veți obține mai multe match-uri caz în care:
 +  - Listați toate match-urile folosind, în Vim, comanda '':​copen''​. Vă apare o fereastră secundară cu toate match-urile.
 +  - Căutați match-ul potrivit (în care este definită structura) căutând după acoladă deschisă (''​{''​),​ un caracter sigur pe linia de definire a structurii. Pentru căutarea acoladei deschise folosiți, în Vim, construcția ''/​{''​.
 +  - Pe linia aferentă apăsați ''​Enter''​ ca să vă ajungă editorul în codul sursă unde e definită variabila.
 +  - Închideți fereastra secundară folosind coamanda '':​cclose''​.
 +</​note>​
 +
 +Determinați fișierul în care sunt declarate următoarele variabile globale la nivelul nucleului:
 +  * ''​sys_call_table''​
 +  * ''​file_systems''​
 +  * ''​current''​
 +  * ''​chrdevs''​
 +
 +<note tip>
 +Pentru aceasta folosiți în Vim o comandă de forma '':​cs f g <​symbol>''​ (unde construcția ''<​symbol>''​ reprezintă numele simbolului căutat).
 +</​note>​
 +
 +Determinați fișierul în care sunt declarate următoarele funcții:
 +  * ''​copy_from_user''​
 +  * ''​vmalloc''​
 +  * ''​schedule_timeout''​
 +  * ''​add_timer''​
 +
 +<note tip>
 +Pentru aceasta folosiți în Vim o comandă de forma '':​cs f g <​symbol>''​ (unde construcția ''<​symbol>''​ reprezintă numele simbolului căutat).
 +</​note>​
 +
 +Parcurgeți secvența de structuri:
 +  - ''​struct task_struct''​
 +  - ''​struct mm_struct''​
 +  - ''​struct vm_area_struct''​
 +  - ''​struct vm_operations_struct''​
 +Adică parcurgeți din aproape în aproape structurile:​ accesați o structură și apoi găsiți câmpuri cu tipul de date al următoarei structuri, accesați-o pe aceasta etc. Rețineți în ce fișiere sunt definite; o să vă fie utile la alte laboratoare.
 +
 +<note tip>
 +Pentru a căuta un simbol în Vim (cu suport ''​cscope''​) atunci când sunteți plasați cu cursorul pe acesta, folosiți construcția ''​Ctrl+]''​.
 +
 +Pentru a reveni în match-ul anterior (înante de căutare/​salt) folosiți construcția ''​Ctrl+o''​. Pentru a avansa în căutare (pentru a reveni la match-urile de dinainte de ''​Ctrl+o''​) folosiți construcția ''​Ctrl+i''​.
 +</​note>​
 +
 +La fel ca mai sus, parcurgeți secvența de apeluri de funcții:
 +  - ''​bio_alloc''​
 +  - ''​bio_alloc_bioset''​
 +  - ''​bvec_alloc''​
 +  - ''​kmem_cache_alloc''​
 +  - ''​slab_alloc''​
 +
 +<note tip>
 +Aveți în vedere indicațiile din secțiunea [[#​informatii-cscope|Informații cscope]] de mai sus.
 </​note>​ </​note>​
 ==== [BONUS] Afișarea unui șir primit ca parametru pentru modul ==== ==== [BONUS] Afișarea unui șir primit ca parametru pentru modul ====
Line 193: Line 334:
  
 <note tip> <note tip>
-Indicații sunt în directorul ''​cap-02-doc/''​ din arhiva capitolului.+Indicații sunt în directorul ''​cap-02-doc/''​ din arhiva capitolului ​și la link-urile din [[#​resurse-utile|secțiunea de resurse]]:​ 
 +  * [[http://​www.tldp.org/​LDP/​lkmpg/​2.6/​html/​x323.html|The Linux Kernel Module Programming Guide: Passing Command Line Arguments to a Module]] 
 +  * [[https://​lwn.net/​images/​pdf/​LDD3/​ch02.pdf|Linux Device Drivers, 3rd Edition, Chapter 2: Building and Running Modules]], secțiunea ''​Module Parameters''​ 
 </​note>​ </​note>​
  
linux-kernel-dev/capitole/capitol-02.1441706226.txt.gz · Last modified: 2015/09/08 12:57 by razvan