DOC

Vjeba 9 Linux Device Drivers

By Connie Armstrong,2014-08-11 02:09
11 views 0
Vjeba 9 Linux Device Drivers

    Fakultet elektrotehnike i računarstva Sveučilišta u Zagrebu

    Zavod za elektroničke sustave i obradbu informacija

    Laboratorij za sustave i signale

    Programska podrška mjernih i procesnih sustava

    vjeţba br. 9: I/O SYSTEM

UVOD

    Pisanje device drivera je u uskoj vezi sa samom jezgrom operacijskog sustava. Zato je potrebno dobro poznavanje jezgre za uspješno implementiranje device drivera. Ovdje ćemo se zadrţati samo na najosnovnijim konceptima kako bi se dobio osjećaj što je device driver i koja

    je njegova funkcija.

    Ukratko driver je dio jezgre koji je zaduţen za komuniciranje sa ureĎajem koji je spojen na računalo. Većina ureĎaja je korisniku predstavljena preko datoteke i čitanjem odnosno pisanjem u datoteku pristupa ureĎaju.

Postoji nekoliko vrsti ureĎaja:

    ; Chracter devices

     Primjer su serijski i paralelni port. Nad njima se najčešće obavljaju funkcije poput read(), write(), open(), close(). Obiljeţja su da se komunikacija sa njima vodi

    na obično slanje nekoliko byte-ova. Moţe se usporediti sa stream-om.

    ; Block devices

     Tipičan predstavnik je hard disk. Za njih je specifično da mogu na sebi sadrţavati cijeli datotečni sustav. To omogućava izvršenje naredbe mount nad njima. TakoĎer moguće se je

    micati po block device-u te zapisivati podatke gdje hoćemo.

    ; Network interface

     Svi prijenosi preko mreţe se obavljaju preko mreţnog sučelja. Tu se vodi računa o primanju i slanju paketa i sl. Primjer toga je mreţna kartica. Takav device se ne vidi kao datoteka.

    Kada korisnik u svom programu počne čitati i pisati po datoteci koja zapravo predstavlja ureĎaj tada jezgra OS-a taj zahtijev proslijedi driver-u koji zna kako razgovarati sa ureĎajem.

U ovoj vjeţbi mi ćemo se primarno baviti char. ureĎajima jer su oni jednostavniji za koristiti.

Ovu vjeţbu je moguće napraviti u potpunosti samo na računalima tipa siemens/nixdorf.

    Na njima je na samom početku potrebno bootati noviju inačicu kernela 2.4.x a ne defaultnu 2.2.x. Prekid defaultnog boota se postiţe pritiskom tipke shift kad se na ekranu ukaţe LILO. Tipkom tab se vidi koje se mogućnosti mogu odabrati. Treba odabrati Linux jer je LinuxOLD defaultni odabir.

    Naziv datoteke: 70147336.doc Zagreb, 11.8.2010. List 1 od 5

    Ovaj dokument predstavlja intelektualno vlasništvo FER, ZESOI, LSS.

ZADACI ZA VJEŢBU

1. KORISNO JE ZNATI (10%)

KONFIGURIRANJE KERNELA

Konfiguriranje se moţe postići tako da pokrenemo naredbu:

    cd /usr/src/linux/

    make menuconfig

    Time smo editirali /usr/src/Linux/.config datoteku gdje je definirano koje sve ureĎaje, procesore, datotečne sustave jezgra podrţava. Neki driver-i se mogu direktno uključiti u kod

    samog kernela dok se drugi mogu uključiti kao moduli tj. njihovo uključivanje i isključivanje se

    moţe dinamički obaviti nakon sto je jezgra već formirana. Nakon što se pokrene make

    menuconfig, odreĎenu podršku moţemo tipkom y uključiti u jezgru odnosno tipkom m

    uključiti kao modul, ako je ta opcija omogućena.

    Probajte mijenjati neke postavke da vidite što sve jezgra moţe podrţati ali postavke nemojte sačuvati.

    Kada smo podesili postavke moţemo samu jezgru i prevesti u izvršni kod. MeĎutim to se ne preporuča da se radi na ovoj vjeţbi jer prevoĎenje traje preko 1 sat na starim računalima.

2. HELLO WORLD PRIMJER ZA DRIVER (10%)

Kao prvi primjer drivera ćemo napisati sljedeći kod

     #define MODULE

     #include <linux/module.h>

     int init_module(void) {

    printk("<1>Pozdrav svima, koliko vas ima\n");

    return 0;

    }

     void cleanup_module(void) {

    printk("<1>Dovidenja") // <1> daje visoki prioritet

    }

    MODULE_LICENSE("GPL");

printk() funkcija je ekvivalentna printf() funkciji samo je printk() definirana unutar

    kernela. Postoji bitna razlika izmeĎu programa koji izvršavaju funkciju driver-a i programa

    (aplikacije) koji je napisao korisnik i izvršava se u normalnom načinu rada (user space). Dva

    su prostora u kojima se izvršava proces. Moţe biti user space ili kernel space. Aplikacija se

    izvršava u user space-u i ona koristi biblioteke koje su joj tamo namijenjene (npr. libc). U kernel space-u se izvršavaju funkcije driver-a i koristi se biblioteka od kernela. TakoĎer jedina zaglavlja koja se koriste su definirana u /usr/include/linux i /usr/include/asm.

    Naziv datoteke: 70147336.doc Zagreb, 11.8.2010. List 2 od 5

    Ovaj dokument predstavlja intelektualno vlasništvo FER, ZESOI, LSS.

Zato je glavni posao drivera da podatke prebacuje iz kernel space-a u user space i obratno

    odakle je startana aplikacija koja je traţila podatke sa ureĎaja.

Gornji primjer drivera je zamišljen da bude implementiran kao modul. On se uključuje u jezgru

    naredbom insmod. Dakle potrebno je učiniti sljedeće:

# gcc -c hello.c

Ovdje opcija -c znači da se samo kompajlira bez linkanja tako da je rezultat hello.o

# insmod hello.o

Da vidimo da je modul doista učitan mozemo se posluţiti lsmod naredbom.

    Kad ga hocemo maknuti potrebno je otipkati:

# rmmod hello

U trenutku učitavanja driver-a starta se funkcija init_module() koja obično sluţi za

    inicijalizaciju drivera. TakoĎer kod rmmod izvrši se funkcija cleanup_module().

    Zanimljivo je primjetiti da driver nema main() funkciju. Aplikacija obično izvrši zadatak i onda umre. Za razliku od nje driver se sastoji od skupa funkcija za rukovanje ureĎajima i te funkcije

    se zovu onda kada se trebaju. Ovaj gornji primjer driver-a ne implementira niti jednu upotrebljivu funkciju nego je samo dan primjer onog što svaki driver mora imati.

4. KORIŠTENJE IOCTL() FUNKCIJE (30%)

Za podešavanje nekih kontrolnih parametara ureĎaja posebno je pogodna ioctl() funkcija.

    Neke kontrolne operacije se ne mogu dobiti slanjem i čitanjem podataka sa ureĎaja. Za takve

    stvari koristi se ioctl() funkcija. Npr. ne moţemo čitanjem i pisanjem serijskog porta promijeniti baud rate nego to moramo učiniti sa ioctl() funkcijom.

    Njenu primjenu ćemo isprobati na primjeru ledica na tastaturi. Zadatak se sastoji u tome da

    treba na tastaturi naizmjenično paliti i gasiti ledicu za num_lock, scroll_lock i caps_lock.

    Datoteka u /dev direktoriju koja predstavlja tastaturu je /dev/tty0.

Otvaranje tog device-a postiţemo sa npr.

    fd=open("/dev/tty0",O_RDONLY)

Ovdje smo otvorili sa zastavicom O_RDONLY ali to nije bitno jer mi nećemo ni čitati ni pisati.

Opći oblik ioctl naredbe koja se koristi u aplikaciji (user space) je slijedeći:

    int ioctl(int fd, int cmd, ...);

fd je file descriptor i on se dobije funkcijom open.

    cmd odreĎuje naredbu koju ţelimo izvesti.

    Povratna vrijednost je 0 za uspješnu operaciju.

Naziv datoteke: 70147336.doc Zagreb, 11.8.2010. List 3 od 5

    Ovaj dokument predstavlja intelektualno vlasništvo FER, ZESOI, LSS.

Pozivanjem te funkcije se poziva ioctl() funkcija koju implementira driver. Ona ima malo

    drugačije argumente. Mi ćemo se ovdje baviti isključivo korištenjem iz aplikacije i koristit ćemo već napisane driver-e kao npr. driver za tastaturu /dev/tty0

Tako za upravljanje LED-om se koriste dve naredbe.

    ioctl(fd,KDGETLED,&led);

    led je char varijabla gdje su zadnja 3 bita, stanja 3 led-ova (num, caps, scroll lock). Gornjom naredbom se u varijablu led