Lxf78 driver de dispozitiv de rețea - cu propriile mâini

În ciuda faptului că, în cursul prezentării, voi încerca să fac explicațiile și referințele necesare, pentru o înțelegere reușită și corectă a articolului, cititorul va avea nevoie de cunoștințe inițiale. În primul rând, familiaritatea cu limba de programare C, în plus, cred că cititorul reprezintă modul în care funcționează rețelele de calculatoare, deja lucrat în sistemul de operare Linux și știe ce este "modulul kernel".







Toate exemplele prezentate în articol sunt lucrători și reprezintă etapele inițiale necesare ale aceleiași căi pe care trebuie să le treceți pentru a afla cum să creați drivere pentru diferite dispozitive de rețea. Am folosit distribuția Mandrake 10.1 cu kernelul 2.6.8.1-12mdk. Pentru alte versiuni de kernel, este posibil să fie nevoie să faceți niște modificări minore ale codului sursă.

Pentru a putea compila modulele de kernel după o instalare tipică de distribuție, trebuie să instalați, de asemenea, codul sursă al kernel-ului dvs. în directorul usr / src. În distribuția mea a trebuit să fie făcut manual, deoarece, chiar dacă ați selectat opțiuni avansate de instalare, și subliniind necesitatea de a include în codul sursă în locația corectă am fost doar surse de kernel 2.4 dense. Distribuția sursă dorită localizată pe al treilea disc în / media / main3 / a-pachetul rpm dosar: kernel-source-2.6-2.6.8.1-12mdk.i586.rpm. Puteți să le instalați utilizând comanda:

Instalarea trebuie făcută în modul consola din directorul care conține pachetul, în modul superuser.

Înainte de a începe să lucrați, vă sugerăm să creați directorul de lucru / home / user /<что-нибудь>. în care veți găsi codul sursă și puneți Makefile-ul, pe care l-am luat de la un exemplu oferit de mediul de dezvoltare KDevelop, ușor modificat, pentru a vă asigura funcționalitatea acestuia (oh, aceste caracteristici ale software-ului gratuit!):

Pentru a adapta acest fișier la nevoile dvs., înlocuiți numele meu cu numele modulului. Construcția se face cu comanda "make".

Bine ați venit în lumea hackerilor Linux!

Salvați acest modul într-un fișier (de exemplu, helloworld.c), modificați corespunzător fișierul Makefile (vedeți mai sus) și apoi emiteți marca. Textul trebuie să apară pe ecran:

După compilarea cu succes, în directorul dvs. sunt create o mulțime de fișiere, din care modulul obiect helloworld.ko este foarte interesant. Pentru a încărca modulul rezultat în kernel, utilizați comanda:

În acest caz, modulul nostru va fi listat în lista modulelor încărcate în fișierul / proc / modules (puteți verifica acest lucru folosind comanda cat / proc / modules | grep helloworld). În plus, funcția de inițializare ssl_init_module (void) va fi pornită. care apelează sistemul funcția printk (). care este proiectat pentru a înregistra evenimente și avertismente din modul kernel. Nu vom lua în considerare funcționarea acestei funcții în detaliu, dar rețineți că mesajul "Hello World!" După încărcarea modulului trebuie căutat în fișierul / var / log / messages. unde (cu configurația corespunzătoare a daemonului syslog), majoritatea mesajelor trimise din kernel sunt trimise. Pentru comoditatea monitorizării mesajelor noi apărute în acest fișier, puteți folosi comanda

Dacă ignorați sfaturile utilizatorilor experimentați și dezvoltați în continuare module de kernel într-un mediu grafic, este convenabil să-l rulați într-o fereastră separată de terminal, creând un fel de "consolă de mesaje".

Puteți descărca un modul din kernel folosind comanda:

În același timp, puteți vedea în consola mesajelor de funcționare modul în care modulul va spune la revedere lumii cu aceleași "mijloace disponibile".

Matrice: Conexiune

Următorul pas pe calea noastră este de a crea cel mai simplu modul de driver de rețea. Pentru a face acest lucru, în modulul nostru, trebuie să definiți structura de date a driverului de rețea struct net_device. definiția căruia se află în fișierul header /usr/include/linux/netdevice.h. Structura conține multe funcții și domenii, dintre care cele mai importante pentru noi sunt următoarele:






• numele caracterelor [IFNAMSIZ] - conține numele interfeței care va fi afișată la configurarea subsistemului de rețea.
• int (* open) (struct net_device * dev) este o funcție care se execută de fiecare dată când utilitarul ifconfig activează interfața.
• int (* stop) (struct net_device * dev) - o funcție care începe când interfața este oprită.
• int (* hard_start_xmit) (struct sk_buff * skb, struct net_device * dev) este o funcție activată de subsistemul de rețea ori de câte ori aveți nevoie pentru a transfera un pachet de date.
• struct net_device_stats * (* get_stats) (struct net_device * dev) este o funcție care se numește ori de câte ori o aplicație încearcă să obțină statistici despre funcționarea interfeței.
• void * priv este un indicator opțional care poate fi folosit în mod arbitrar.

Câmpurile și funcțiile rămase oferă șoferului capabilități suplimentare, pe care nu le vom lua în considerare acum. Numirea lor poate fi găsită în literatura de specialitate. Trebuie remarcat imediat că recepția datelor de la dispozitivul de rețea are loc, de obicei, prin întrerupere, de către manipulatorul său și nu există nici o indicație explicită a acestui handler în structura interfeței.

Trebuie să umplem câmpurile de șofer necesare pentru muncă. Dacă câmpul conține un indicator pentru o funcție, trebuie să implementați această funcție. În driverul nostru, definim funcțiile de inițializare (deschise). stop și transfer de date (hard_start_xmit). În plus, definim structura net_device_stats. conținutul căruia vom primi prin intermediul unui indicator suplimentar (priv).

Pentru ca sistemul să știe că modulul încărcat este driverul dispozitivului de rețea, atunci când modulul este încărcat, modulul trebuie să-i spună despre acest lucru cu funcția specială register_netdev (). Modulul raportează despre descărcarea lui prin funcția unregister_netdev (). Ca argument pentru aceste funcții, este trecut un indicator pentru structura de date a driverului.

Pentru a inițializa interfața din subsistemul de rețea, driverul trebuie să utilizeze funcția specială netif_start_queue (). când este oprit - prin funcția netif_stop_queue (). argumentul căruia este, de asemenea, un indicator al structurii șoferului.

Dacă trebuie să transferați date prin interfața de rețea, sistemul de operare solicită funcția hard_start_xmit () care transmite un pointer la tampon (sk_buff) ca argument. conținând datagrama IP terminată. Funcția apelată ar trebui să facă tot ce este necesar pentru a trimite datagrama la dispozitivul de rețea pentru a fi transmisă la nivel fizic și apoi să informeze sistemul că pachetul a fost transferat apelând funcția dev_kfree_skb (). argumentul căruia este un indicator al tamponului primit de la OS. Aceasta completează ciclul de transfer pentru șofer, sistemul poate umple tamponul eliberat cu date noi, iar șoferul așteaptă următorul transfer și un indicator la tamponul terminat.

Deoarece driverul nostru nu este încă conectat la niciun dispozitiv, funcția de transfer va transfera datele transmise în tamponul propriu (my_buf). și apoi înregistrați aceste date ca mesaje utilizând funcția printk (). Pentru a reprezenta datele înregistrate în format text, vom introduce funcțiile auxiliare tpdumpk () și printAddr () în program.

Iată textul driverului nostru, chiar și cel mai simplu, dar deja al rețelei:

Pentru a încărca și inițializa driverul compilat, este convenabil să folosiți un script mic, textul căruia este prezentat mai jos:

O întârziere (somn 1) este necesară pentru ca sistemul să înregistreze modulul și este pregătit să-și inișeze interfața până la emiterea comenzii ifconfig. După încărcarea și inițializarea driverului nostru, pe ecran trebuie să apară un text (informațiile despre alte interfețe de rețea sunt omise pentru a economisi spațiu):

Dacă computerul este conectat la Internet, înainte de a trimite date către interfața noastră, asigurați-vă că nu interferează cu setările computerului. Configurați paravanul de protecție, ținând seama de aspectul unei noi subrețele sau chiar dezactivați-o în momentul depanării (în special, cu precauție, puteți să vă deconectați de la Internet în același timp).

Pentru a testa funcționalitatea interfeței noastre, trebuie să executați comanda tail -f / var / log / messages într-o consolă separată pentru a afișa mesajele curente de la kernel, iar în consola de lucru folosiți comanda:

Astfel, încercăm să trimitem pachete ICMP la o interfață inexistentă accesibilă prin driverul nostru. Deoarece această interfață, precum și funcțiile de recepție a datelor nu sunt încă disponibile pentru driverul nostru, toate pachetele trimise pentru sistemul de operare vor fi pierdute. Dar nu pentru noi! Toate pachetele transmise vor fi documentate în fișierul / var / log / messages. iar acest lucru poate fi văzut în consola de mesaje în acest fel:

Dacă computerul este configurat să funcționeze în rețea, atunci veți vedea că interfața noastră recepționează și difuzează periodic pachete, care sunt ușor de învățat pe fundalul managerilor monotoni.

Următoarea noastră sarcină este să învețe conducătorul auto să primească date și să le trimită subsistemului de rețea al sistemului de operare Linux. Pentru a face acest lucru, vom introduce funcțiile necesare în el și apoi îl vom conecta la dispozitivul hardware care controlează transferul de date prin intermediul cablului. Ca un astfel de dispozitiv, folosim portul COM al computerului. Deci, avem un program similar cu șoferul cunoscut SLIP. Desigur, șoferul nostru nu va susține toate funcțiile prototipului său bine cunoscut, dar va fi mult mai ușor și nu va necesita programe suplimentare de demon pentru muncă. Cu toate acestea, toate acestea vor fi deja în următoarea parte. Nu ratați!

. Link-uri utile







Articole similare

Trimiteți-le prietenilor: