LINUXZONE






 >> Hlavní stránka

(1713/30.07.2010)


 >> Administrace

(160/29.07.2010)


 >> Literatura

(305/28.07.2010)


 >> Bezpečnost

(340/30.07.2010)


 >> Programování

(307/19.04.2010)


 >> Distribuce

(97/09.06.2010)


 >> Síťování

(86/03.06.2010)


 >> Lokalizace

(10/15.09.2004)


 >> Aplikace

(175/12.04.2010)


 >> Multimedia

(32/31.03.2006)


 >> Hardware

(45/02.03.2007)


 >> Začínáme

(228/24.06.2010)


 >> Aktuálně

(556/27.07.2010)


 >> RELAX

(201/26.07.2010)


 >> Jinde vyšlo

přehled ostatních serverů




 Přihlášení




Login:
Heslo:
 uložit v prohlížeči


Nejste-li ješte zaregistrováni, můžete tak učinit zde.





 Vyhledávání




Hledaný výraz:
v klíčových slovech
v titulku
v anotaci
v textu








 Reklama









 Servis




*   Vaše náměty a připomínky
Máte k Linuxzone.cz nějaké připomínky nebo náměty? Našli jste na stránkách chybu? Dejte nám o tom vědět pomocí formuláře nebo v diskuzi.
Komentářů: 30
*   Podpořte Linuxzone.cz
Chcete podpořit náš server umístěním odkazu nebo zveřejněním backendu? Zde najdete vše potřebné.
*   Pište pro Linuxzone.cz
Máte zájem podílet se na obsahu Linuxzone.cz ať už jako redaktoři nebo i jinak? Dejte nám o sobě vědět!





 Aktuálně z bezpečnosti




-- 
6.12.2005, 19:01
Na serveru informit.com vyšla ukázková kapitola týkající se práce s řetězci z knihy Secure Coding in C and C++. (lz)

-- 
3.12.2005, 12:34
Bugtraq: Format String Vulnerabilities in Perl Programs. (lz)

-- 
3.12.2005, 12:32
Linux Advisory Watch December 2nd 2005. (lz)

-- 
23.10.2005, 13:28
Rozhovor na téma klasické zálohování versus CDP. (lz)

-- 
23.10.2005, 13:24
Linux Advisory Watch October 21st 2005. (lz)

další >>





 Aktuálně o software




-- 
6.12.2005, 19:07
Potřebujete-li pod linuxem rozchodit bezdrát založený na čipsetech Broadcom 43xx, konečně existuje linuxový ovladač. (lz)

-- 
6.12.2005, 19:04
Byla uvolněna verze Xen 3.0.0 virtualizační technologie XEN. (lz)

-- 
6.12.2005, 18:59
Byla uvolněna verze X11R6.9/X11R7 RC 3 grafickérho rozhraní X Window System. (lz)

-- 
3.12.2005, 12:45
Co je nového okolo projektu Amanda (open source zálohovací software)? Více na osnews.com. (lz)

-- 
3.12.2005, 12:40
Jak to akuálně v linuxu vypadá s podporou SATA.. (lz)

další >>





 Aktuálně z IT




-- 
3.12.2005, 12:51
Novellu se daří prodej linuxových produktů, oproti loňskému roku se Novell dočkal výrazného nárůstu. (lz)

-- 
3.12.2005, 12:48
Třetí verzi licence GPL by měla být publikována během jara 2007. (lz)

-- 
23.10.2005, 13:20
V Peru nyní mají zákon, který umožňuje nasazení open source software ve vládní správě. (lz)

-- 
23.10.2005, 13:14
Proč se Microsoft bojí Google? (lz)

-- 
27.9.2005, 22:01
Peru má zákon podporující free software. (lz)

další >>





 Nejčtenější články




-- 
Hurd včera dnes a zítra

-- 
XEN aneb virtualizujeme (3/6)

-- 
Security Digest (15/2010)

-- 
Fotografický ateliér

-- 
XEN aneb virtualizujeme (4/6)

-- 
Novinky ze světa svobodného software (16/2010)

-- 
Gamesárium [138]

-- 
Proč používat svobodný software?

-- 
Velká kniha sportovní fotografie

-- 
Security Digest (16/2010)






 Nejlepší články




-- 
Gamesárium [138]

-- 
XEN aneb virtualizujeme (4/6)

-- 
Datové struktury bez předchozích znalostí

-- 
XEN aneb virtualizujeme (3/6)

-- 
Security Digest (16/2010)

-- 
Novinky ze světa svobodného software (17/2010)

-- 
Velká kniha sportovní fotografie

-- 
XEN aneb virtualizujeme (5/6)

-- 
Security Digest (15/2010)

-- 
Proč používat svobodný software?






 Anketa




Používáte nějaké rozšíření bezpečnostního modelu linuxového jádra?

Openwall (18%)

LIDS (12%)

Pax/Grsecurity (3%)

SELinux (6%)

RSBAC (1%)

jiné (1%)

používám standardní jádro (59%)







Linuxzone.cz - server o Linuxu pro programátory, administrátory a fanoušky.
Provozuje společnost Impossible.
ISSN: 1213-8738





Jak to chodí v jádře aneb napište si vlastní ovladač (5)

Dnešní díl bude trochu delší a podíváme se na to jakým způsobem jádro pozná jaký ovladač použít. Co to jsou major, minor čísla a jak se s nimi pracuje a také se podíváme na modul znakového zařízení a v krátkosti si představíme nějaké souborové operace nad tímto zařízením. Samozřejmostí jsou ukázky připojené k článku.

Malá změna

Rozhodl jsem se opustit téma verzí u exportovaných symbolů a přesunout je na pozdější dobu. Budeme se věnovat zajímavějším věcem a k nim se vrátíme hned jak bude potřeba.

Napsal jsem tento díl a snažil jsem se do něj umístit co nejvíce potřebných informací. Bohužel se mi to nepovedlo a tak jsem je musel (z důvodu úspory místa) přesunout do dalšího dílu. Potom mi to nedalo a říkal jsem si, že přece nemohu popisovat strukturu file, kterou používám v tomto díle až v díle dalším a tak jsem ty články zase spojil. Tím vznikl o malinko delší a informativně obsažnější díl.

Rozlišování zařízení

V některém z prvních dílů jsem vám psal, že takřka vše je v Linuxu soubor. Není tomu jinak v rámci přístupu na zařízení, který je řešen pomocí speciálních souborů umístěných v adresáři /dev. Chceme-li například přehrát audio data na našem DSP procesoru (zvukové kartě), použijeme k tomu zařízení /dev/dsp. Tady se ale naskýtá otázka jakým způsobem jádro pozná, že tento speciální soubor obsluhuje zrovna náš ovladač? K tomu slouží tzv. hlavní a vedlejší čísla. Mě se tento překlad nelíbí a tak v dalším textu zůstanu u originálu a budeme tomu říkat major a minor čísla.

Major, minor čísla

Zvuková karta má několik zařízení (a speciálních souborů) kde jedním z nich je již zmiňovaný /dev/dsp. Podívejme se na něj blíže (ls -l /dev/dsp*).

crw-------    1 vojta    root   14,   3 čec 23 20:50 /dev/dsp
crw-------    1 vojta    root   14,  19 čec 23 20:50 /dev/dsp1
crw-------    1 vojta    root   55,   0 čec 23 20:50 /dev/dsp56k

Z nabitých znalostí poznáme, že se jedná o znakově orientované zařízení. Jeho vlastníkem jsem já a dále tu vidíme časovou informaci udávající datum vytvoření. Ona dvě čárkou oddělená čísla jsou major a minor čísla.

Pomocí prvního z nich, neboli major čísla, jádro pozná, který modul (ovladač) dané zařízení obsluhuje. V případě, že máme více zařízení stejného druhu (zvukové karty), tak je rozlišujeme pomocí minor čísla. Toto minor číslo je předáváno přímo ovladači (jádru samotnému na nic neslouží).

Obě čísla jsou osmibitová a jejich rozsah je "pouze" 0 až 255. Z toho jsou rozsahy major čísla 60-63, 120-127 a 240-254 rezervovány pro experimentování. Je to docela málo a tak vznikla možnost dynamického přidělování major čísel.

Již alokovaná major čísla získáme ze souboru /usr/src/linux/Documentation/devices.txt.

Ještě malá poznámka: dvě typově různá zařízení (blokové, znakové, ...) mohou mít stejné major číslo.

Dynamická major čísla

Tato možnost je o něco složitější než výše uvedená a to z toho důvodu, že je nutné vytvořit speciální soubory pro přístup k zařízením až po zavedení modulu do jádra. Máme podporu dynamických major čísel v modulu, zavedeme ho a jakým způsobem zjistíme, které major číslo nám bylo přiděleno? Tyto informace dostaneme necháme-li si vypsat obsah souboru /proc/devices. Ukázkový výstup následuje:

Character devices:
  1 mem
  2 pty
  3 ttyp
  4 ttyS
  5 cua
  6 lp
  7 vcs
 10 misc
 13 input

Vzniká nám zde potřeba vlastního skriptu na zavádění modulu, který provede samotné zavedení, vyparsuje major číslo z výstupu cat /proc/devices a vytvoří příslušné speciální soubory v adresáři /dev. Ukázkový skript je připojen k tomuto článku, ale teď nepředbíhejme.

Souborový systém zařízení

Další možností je tzv. "Device filesystem". Ve zkratce jde o to, že při inicializaci modulu bude vytvořen speciální soubor a po odstranění modulu bude tento soubor také odstraněn. My se teď touto možností nebudeme zabývat (kvůli rozsahu článku) a necháme si ji na začátek článku dalšího.

Major, minor čísla a jádro

V rámci jádra jsou tato dvě čísla zkombinována do jednoho a jsou uloženy v jedné proměnné. Můžeme se setkat se dvěma typy:

  1. kdev_t (linux/kdev_t.h)

    Typ kdev_t se používá v rámci Linuxu a kombinuje major, minor číslo do jednoho. Žádná část jádra nezná jeho přesnou strukturu a přistupuje s k němu pomocí několika maker a funkcí. Proč tomu tak je se dozvíme u dalšího typu.


  2. dev_t (sys/types.h)

    Typ dev_t byl definován pro UNIXy jako 16 bitové číslo, to znamená osm bitů pro major a osm bitů pro minor číslo. S postupem času vznikla potřeba rozšířit alespoň rozsah minor čísel, ale nešlo to. Spousta ovladačů přistupuje k tomuto typu přímo (zná jeho strukturu) a tak by se změnou tohoto typu musela přijít i změna všech ovladačů, který tento typ takto využívají. Což je nemyslitelné a tak se to stalo tomuto typu osudným. Proto se u kdev_t používá sada maker a funkcí pro případ, že by někdo chtěl kdev_t nadále modifikovat bez nutnosti zasahovat do věcí, které ho používají.


Teď se podíváme na sadu maker a funkcí, které je nutné znát pro práci s kdev_t.

  1. MAJOR(kdev_t dev)

    Toto makro vrátí major číslo.


  2. MINOR(kdev_t dev)

    Toto makro vrátí minor číslo.


  3. MKDEV(int ma, int mi)

    Toto makro vytvoří kdev_t typ z major a minor čísel.


  4. kdev_t_to_nr(kdev_t dev)

    Převede typ kdev_t na typ dev_t.


  5. to_kdev_t(int dev)

    Převede číslo dev_t na typ kdev_t.


Vytváření speciálních souborů aneb mknod

Zde si dovolím vložit část manuálové stránky příkazu mknod.


JMÉNO
       mknod - vytváří speciální soubory

POUŽITÍ
       mknod [volby] soubor {bcu} major minor
       mknod [volby] soubor p
       Volby:
       [-m práva] [--mode=práva] [--help] [--version]

Písmena {bcu} či p znamenají typ vytvářeného souboru.

  1. b - blokově orientované zařízení
  2. c - znakově orientované zařízení
  3. u - znakově orientované zařízení (nebufferované)
  4. p - pojmenovaná roura (FIFO) bez major a minor čísla

V následující ukázce si vytvoříme znakové zařízení lzdev s major číslem 62 a minor číslem 0.

[root@echelon root]# mknod /dev/lzdev c 62 0
[root@echelon root]# ls -l /dev/lzdev
crw-r--r--    1 root     root      62,   0 lis 16 19:54 /dev/lzdev
[root@echelon root]# 

Takto vytvořený soubor bude na disku do té doby než ho smažeme a stačí nám na to "obyčejný" příkaz rm.

Ukázka zavedení modulu s dynamicky přiděleným major číslem

Nyní známe všechny informace, které potřebujeme pro vytvoření ukázkového skriptu na zavedení modulu s dynamicky přidělovaným major číslem. Tady je:

#!/bin/sh

#
# Pri hrani si dejte pozor na prikaz ve skriptu rm -rf a 
# promennou DESCRIPTION. Mozna dopadnete jako ja, kdyz 
# jsem si pri psani toho smazal /dev/* adresar :)
#

MODULE=lzdev
DEVICE=lzdev
DESCRIPTION=LZ_oc_example
MODE=644

#
# 0 - dynamicky pridelene, > 0 staticky urcene Vami
#
MAJOR=0

# Nahrajeme nas modul
insmod $MODULE.o major=${MAJOR} || exit 1

# Smazeme vsechny nase zarizeni v /dev/
rm -rf /dev/${DEVICE}*

# Zjistime major cislo naseho modulu
MAJOR=`awk "\\$2==\"${DESCRIPTION}\" {print \\$1}" /proc/devices`

for MINOR in `seq 0 255`; do
    mknod -m ${MODE} /dev/${DEVICE}${MINOR} c ${MAJOR} ${MINOR}
done

echo "Module ${MODULE} loaded with major device number ${MAJOR}"

Jak jednoduché, že? Nyní se podíváme na to, jak naše zařízení implementovat.

Implementace ovladače - znakové zařízení

Myslím, že již máme dost teoretických informací a tak je na čase podívat se na implementaci nějakého ovladače zařízení. Nejjednodušší zařízení je znakové a tak stejně jako Alessandro začneme u něj.

Registrace zařízení

Řekli jsme si, že při nahrávání modulu, resp. jeho inicializaci se musí zaregistrovat všechny nabízené možnosti našeho ovladače. Zabýváme-li se ovladačem znakového zařízení musíme toto zařízení (ať už třeba fiktivní) zaregistrovat. K tomu nám slouží následující funkce:

extern int register_chrdev(unsigned int, const char *, \
   struct file_operations *);

Prvním argumentem je námi požadované major číslo pro zařízení. Číslo musí být v rozsahu 0 až 255. Pokud chceme dynamicky přidělené major číslo tak použijeme hodnotu 0.

Druhým argumentem je popis našeho zařízení, který se objevuje například ve výstupu /proc/devices.

A na konec zde máme ukazatel na strukturu file_operations. Co to je? Jelikož se jedná o znakové zařízení, přistupuje se k němu jako k souboru, je nutné implementovan souborové operace jakými jsou například open, read, write, close, ... K tomu slouží uvedená struktura, kterou si popíšeme o pár řádků níže.

U návratových hodnot této funkce mohou nastat tři možnosti:

  1. < 0

    V případě, že návratová hodnota je menší jako nula - nastala chyba.


  2. == 0

    V tomto případě funkce proběhla bez problémů a naše zařízení je zaregistrováno.


  3. > 0

    V tomto případě funkce také proběhla bez problémů, naše zařízení je zaregistrováno a dynamicky přidělené major číslo je právě tato návratová hodnota. Již víme, že o dynamické major číslo žádáme použitím 0 jako prvního argumentu registrační funkce.


Souborové operace

Dnes se zaměříme pouze na základní souborové operace jakými jsou open a close. Je to z toho důvodu, že článek by neměl přesahovat určité množství řádků a tak se na zbývající operace podíváme v rámci pokračování série.

Struktura file_operations je deklarována v hlavičkovém souboru linux/fs.h. (Doporučuji se předběžně podívat na další typy funkcí z této struktury)

  1. int (*open) (struct inode *, struct file *)

    Otevře-li někdo naše zařízení (speciální soubor) zavolá se tato funkce. Prvním parametrem je struktura inode ke které se dostaneme v dalších dílech a dnes si jenom povíme, že jedna její část i_rdev je typu kdev_t a obsahuje major a minor číslo našeho otevřeného zařízení (inode->i_rdev).

    Druhým důležitým parametrem je struktura file deklarována taktéž v hlavičkovém souboru linux/fs.h. Tuto strukturu si popíšeme níže a zatím ji přeskočíme.

    Návratová hodnota funkce by měla být 0 v případě úspěchu. V opačném případě je hodnota záporná a obsahuje jeden z předem definovaných chybových kódů.

    Funkce nemusí být ve struktuře definovaná a stejně se nám podaří zařízení úspěšně otevřít. Jediný problém je, že o tom nebude náš ovladač nijak informován.


  2. int (*release) (struct inode *, struct file *)

    Tato funkce má parametry stejné jako funkce open. V případě úspěchu vrací 0, jinak vrací záporný již předem definovaný chybový kód.


Teď víme jak vypadají typy našich základních funkcí a my se v krátkosti podíváme na to co by zhruba měli dělat.

  1. open
    1. zvýšit počítadlo použití modulu
    2. zkontrolovat HW zařízení
    3. inicializovat HW zařízení v případě, že jej otevíráme poprvé
    4. pomocí minor čísla se rozhodnout o jaké zařízení jde, případně modifikovat ukazatel na souborové operace (viz. dále file->f_op)
    5. alokovat datové struktury a uložit je do file->private_data

  2. close
    1. uvolnit všechny použité prostředky uložené v private_data
    2. ukončit činnost zařízení pokud jde o poslední zavření
    3. snížit počítadlo použití modulu

Jedna z dalších věcí, která se týká struktury file_operations je nastavení vlastníka. Slouží k automatickému určování toho, zda je modul využíván či nikoli. K tomuto účelu je určeno makro SET_MODULE_OWNER() definováno v hlavičkovém souboru linux/module.h.

  SET_MODULE_OWNER(&fop);

Struktura file

Každý otevřený soubor je v Linuxu reprezentován touto strukturou. Pokud otevřeme jakýkoli soubor, jádro alokuje tuto strukturu, naplní ji a pracuje s ní. Struktura je uvolněna jakmile je soubor všemi procesy, které ho používají uzavřen.

Upozorňuji, že to nemá nic společného se známým typem FILE a také to nemá nic společného se souborem na disku, který je reprezentován strukturou inode.

My se teď podíváme na důležité části struktury:

  1. mode_t f_mode

    Tato část reprezentuje informaci, která nám říka jestli je soubor otevřen pouze pro čtení, pro zápis či pro oba dva režimy. Zjistíte to podle nastavených bitů FMODE_READ a FMODE_WRITE. Zda je soubor otevřen pro čtení, zápis kontrolujeme pouze v naší ioctl funkci. Jádro totiž naši metodu pro zápis nepovolí zavolat v případě, že je soubor otevřen pouze pro čtení, ale to malinko předbíháme.


  2. loff_t f_pos

    V této proměnné je uložena aktuální pozice pro čtení či zápis. Ovladač tuto proměnnou může používat chce-li zjistit aktuální pozici, ale neměl by tuto hodnotu nikdy měnit (kromě funkcí read, write, ale o tom až se k tomu dostaneme).


  3. unsigned int f_flags

    Zde jsou nastaveny známé flagy O_RDONLY, O_NONBLOCK či O_SYNC. Všechny jsou definovány v hlavičkovém souboru linux/fcntl.h. Tato proměnná je nejpoužívanější pro kontrolu zda-li naše operace jsou blokující či nikoli. Zbytek se moc často nepoužívá, protože například mód čtení/zápisu je kontrolován vůči f_mode.


  4. struct file_operations f_op

    Tato část ukazuje na námi implementované souborové operace pro dané zařízení. Hodnotu ukazatele může dle libosti měnit a ihned po změně se promítne a budou používány naše nové funkce. Slouží to například k tomu, že pro jedno major číslo můžeme implementovan několik různých zařízení, které rozlišujeme podle minor čísla. Tuto možnost jsem zmiňoval výše, když jsem psal o tom co by měl ovladač udělat při otevření souboru. Ukázka použití této vlastnosti je v příkladu na konci článku.


  5. void *private_data

    Také jsem zmiňoval, že si ovladač při otevření může alokovat svá vlastní data a ukazatel na ně uložit do této proměnné. Tak tady ji máte, je obsažena ve struktuře file.


Struktura file obsahuje několik dalších informací, ale ty pro nás nejsou důležité. Náš modul bude tyto informace pouze číst a nebude je modifikovat, proto nás zbylé tolik nezajímají.

Odregistrování zařízení

K tomu nám slouží podobná funkce jako k zaregistrování:

extern int unregister_chrdev(unsigned int, const char *);

Kde prvním argumentem je major číslo (ať už námi pevně zvolené či dynamicky přidělené). Druhým argumentem musí být stejný popis zařízení, který jsem použil v případě registrace zařízení.

Ukázky

lzdev modul

Tento modul implementuje jak statické tak dynamické přidělování major čísla (ovlivnitelné pomocí parametru major). Dále nám při otevření zařízení vypíše v jakém módu jsme ho otevřeli a podle minor čísla přiřadí správné souborové operace. Po uzavření zařízení nám bude vypsáno, která funkce tento soubor zavřela. Ukázka je velmi jednoduchá a proto nepotřebuje dalšího komentáře.

#ifdef MODULE

#include <linux/module.h>

MODULE_DESCRIPTION("LZ open/close example"); 
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

#endif /* MODULE */

#include <linux/init.h>
#include <linux/fs.h>

// Popis major cisla pro /proc/devices
static char *major_description = "LZ_oc_example";

// Nas modul bude automaticky zadat o dynamicke major cislo
static int major = 0;

// Pokud mame nejake pridele major cislo, muzeme ho zmenit 
// pomoci major parametru tohoto modulu
MODULE_PARM(major, "i");
MODULE_PARM_DESC(major, "0 = dynamic, < 0 = static");

// Nasledujici dve funkce lz_release_* jsou zde na ukazku toho, 
// jakym zpusobem muzeme zmenit ukazatel na souborove operace
// a tak ovlivnit chovani modulu pro ruzna minor cisla, resp. 
// ruzna zarizeni

// Tato funkce je volana po close() na zarizeni s minor
//  cislem 0-127
static int
lz_release_minor_0_127(struct inode *i, struct file *f)
{
	printk("<1>lz_release_minor_0_127: Closing device \
                with minor number %d\n",
		   MINOR(i->i_rdev));
	MOD_DEC_USE_COUNT;
	return 0;
}

// Tato funkce je volana po close() na zarizeni s major
// cislem 128-255
static int
lz_release_minor_128_255(struct inode *i, struct file *f)
{
	printk("<1>lz_release_minor_128_255: Closing device \
                with minor number %d\n",
		   MINOR(i->i_rdev));
	MOD_DEC_USE_COUNT;
	return 0;
}

// Nyni si nadefinujeme dve struktury souborovych operaci pro 
// ruzna zarizeni, ktera se lisi podle vyse uvedenych minor cisel

static struct file_operations minor_0_127_fop =
{
	release: lz_release_minor_0_127
};

static struct file_operations minor_128_255_fop =
{
	release: lz_release_minor_128_255
};

// Tato funkce bude pouzivat pro vsechny zarizeni s major cislem.
// V ni se rozhoduje jake operace priradime ruznym zarizenim 
// (ruznym minor cislum)
static int
lz_open(struct inode *i, struct file *f)
{
    MOD_INC_USE_COUNT;

    printk("<1>lz_open: Opening device with minor number \
           %d\n", MINOR(i->i_rdev));

    // Tady se podivame v jakem modu je nase zarizeni otevreno
    if ((f->f_mode & FMODE_READ) == FMODE_READ)
	printk("<1>lz_open: Opening device for reading%s\n",
	   (f->f_mode & FMODE_WRITE) != FMODE_WRITE ? " only" : "");

    if ((f->f_mode & FMODE_WRITE) == FMODE_WRITE)
       	printk("<1>lz_open: Opening device for writing%s\n",
	   (f->f_mode & FMODE_READ) != FMODE_READ ? " only" : "");

    if ((f->f_flags & O_NONBLOCK) == O_NONBLOCK)
      	printk("<1>lz_open: Opening device in \
               non-blocking mode\n");

    // A podle minor cisla priradime spravne souborove operace
    if (MINOR(i->i_rdev) < 128)
       f->f_op = &minor_0_127_fop;
    else
       f->f_op = &minor_128_255_fop;

    return 0;
}

// Definice zakladni operace open na nase zarizeni
static struct file_operations basic_fop =
{
    open: lz_open
};

// Funkce zaregistruje nase zarizeni, eventuelne zaroven pozada 
// o dynamicke prideleni major cisla a sdeli nam to pomoci 
// printk()
static int __init
init_module(void)
{
    int res;

    SET_MODULE_OWNER(&basic_fop);
    SET_MODULE_OWNER(&minor_0_127_fop);
    SET_MODULE_OWNER(&minor_128_255_fop);

    res = register_chrdev(major, major_description, &basic_fop);
    if (res < 0)
	    return res;

    if (res > 0)
	    major = res;

    printk("<1>lz_sym device registered with major\
           number %d\n", major);

    return 0;
}

// Funkce odregistruje nase znakove zarizeni a da nam 
// o tom zpravu
static void __exit
cleanup_module(void)
{
    unregister_chrdev(major, major_description);
    printk("<1>lz_sym device unregistered with major number\
           %d\n", major);
}

lzdevuse program

Tento ukázkový program otevře naše fiktivní zařízení v několika různých módech. Výstup z modulu, které nám říká v jakých módech bylo zařízení otevřeno si můžeme přečíst pomocí dmesg.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

void
use_dev(char *dev, int flags)
{
     int fd = open(dev, flags);
     if (fd == -1)
     {
        fprintf(stderr, "Failed to open '%s' device\n", dev);
	   return;
     }
     close(fd);
}

int
main(int argc, char *argv[])
{
     int i;

     if (argc == 1)
     {
         printf("Usage: lzdevuse dev1 [dev2 [dev3] [...]]]\n");
	    return -1;
     }

     for (i = 1 ; i < argc ; i++)
     {
         use_dev(argv[i], O_RDONLY);
         use_dev(argv[i], O_WRONLY);
         use_dev(argv[i], O_RDWR);
         use_dev(argv[i], O_RDWR | O_NONBLOCK);
     }
}

Makefile

MODULES = lzdev.o 
CC = gcc
CFLAGS = -O2 -DMODULE -D__KERNEL__

USERPROG = lzdevuse

all: $(MODULES) $(USERPROG)

clean:
	rm -f $(MODULES) $(USERPROG)

lzdev.o: lzdev.c
	$(CC) $(CFLAGS) -o $@ -c $<

lzdevuse: lzdevuse.c
	$(CC) -o $@ $<

Použití

Pomocí Makefile si sestavte modul včetně ukázkové aplikace. Modul zaveďte pomocí lzload.sh a dále spusťe ukázkovou aplikaci lzdevuse. V případě, že neuvidíte žádný výstup, podívejte se na něj pomocí dmesg. Ukázkové příklady jsou jednoduché a nepotřebují dalšího komentáře.

Ukázky není nutné kopírovat neb na konci článku najdete odkaz na archiv obsahující všechny výše uvedené zdrojové kódy.

Závěr

Jsme zase o kus dále a umíme vytvořit modul pro znakově orientované zařízení, umíme mu nadefinovat základní souborové operace a také zvládáme zavádět a používat modul s dynamicky přidělovaným major číslem.

Příště se podíváme na zmiňovaný Device filesystem a další souborové operace.

Soubory

Použité ukázky v dnešním díle naleznete zde.

Další části seriálu:

Autor: Robert V0jta, 18. 11. 2002, 00:00
Sekce Programování, Komentářů: 14
Průměrné hodnocení: 2,94

o Poslat e-mailem
o Tisk článku
o Uložit do profilu


 Přispějte nám




Líbil se Vám tento článek? Můžete ho ocenit zavoláním na tel. číslo 906 460 134.
Cena hovoru za 1 minutu je 46 Kč.





 Hodnocení článku




Článek hodnotím jako:  [1] výborný   [2] dobrý   [3] průměr   [4] špatný   [5] hrůza  





 Komentáře




--

Robert V0jta, 26. 11. 2002 10:50
Makefile












--

pavep, 26. 11. 2002 06:07
NEJDE MI TO PRELOZIT












--

pavep, 24. 11. 2002 17:01
NEJDE MI TO PRELOZIT












--

Robert V0jta, 21. 11. 2002 11:11
Re: NEJDE MI TO PRELOZIT












--

Robert V0jta, 21. 11. 2002 11:08
Re: NEJDE MI TO PRELOZIT












--

pavep, 21. 11. 2002 06:55
Re: NEJDE MI TO PRELOZIT












--

pavep, 21. 11. 2002 06:43
Re: NEJDE MI TO PRELOZIT












--

pavep, 21. 11. 2002 06:38
Re: NEJDE MI TO PRELOZIT












--

Robert V0jta, 20. 11. 2002 10:54
Re: NEJDE MI TO PRELOZIT












--

pavep, 20. 11. 2002 07:21
Nejde mi to prelozit












--

Robert V0jta, 18. 11. 2002 13:57
Re: KNIGA












--

Mr. Zdeeck  - , 18. 11. 2002 13:54
Kniga ...












--

Robert V0jta, 18. 11. 2002 13:20
Re: HMMM...












--

Mr. Zdeeck  - , 18. 11. 2002 13:02
Hmmm...















PŘIDAT KOMENTÁŘ ZOBRAZ VŠE >>










2002 © Impossible, s.r.o.   >> Kontaktujte redakci >> Právní upozornění >> Reklama