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]

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

-- 
XEN aneb virtualizujeme (4/6)

-- 
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č (2)

V dnešním díle si ukážeme možnosti které nám jádro nabízí při sestavování výsledného ovladače a nedočkavý člověk si taktéž přijde na své při klasické ukázce "Hello world!" se stručným popisem.

Ovladač jako modul či nikoli?

Dnes máme na výběr dvě možnosti jak daný ovaladač sestavit. První možnost je přímá kompilace do jádra. Druhá možnost je sestavení ovladače jako modulu. Obě mají své výhody a nevýhody, které ve stručnosti shrneme níže.

Ovladač jako modul

Jako nesporná výhoda tohoto řešení se jeví snadná výměna chybného či staršího ovladače za novější. V případě, že je daný ovladač nevyužit nám jádro nabízí snadnou cestu jak právě "běžící" ovladač vyjmout a to pomocí příkazu rmmod (více viz. man rmmod). Vyměnit stávající modul za nový a následně ho opětovně zavést do jádra pomocí příkazu insmod či modprobe (více viz. man insmod, resp. man modprobe).

Tento systém modulárních ovladačů se nehodí například pro embedded systémy. Proč? Embedded systémy většinou disponují velmi malou kapacitou a utility na zavádění a vyjímání ovladače z jádra zbytečně zabírají místo včetně přílušného kódu v samotném jádru. Pro představu tento kód zabírá v současné stabilní řadě zhruba 1200 řádků jazyka C a uznejte, že v embedded systémech je uspořených 1200 řádků celkem dost.

Další z výhod je možnost zadávání různých parametrů při opětovném zavádění modulu a to pomocí souboru /etc/modules.conf či přímo na příkazové řádce insmod, resp. modprobe.

V případě, že se rozhodnete zkompilovat ovladač jako modul, je nutné definovat makro MODULE ať už na úrovni argumentu překladače (-DMODULE) či přímo ve zdrojovém souboru #define MODULE. Další nutností je zahrnutí hlavičkového souboru linux/module.h. Více informací získate v níže uvedeném příkladu.

Ovladač přímo v jádře

Nevýhoda tohoto řešení je "krkolomný" update ovladače s nutností sestavit celé jádro znovu a poté restartovat počítač využívající tohoto jádra. Na druhou stranu se tato možnost perfektně hodí pro embedded systému.

Pamatuji se, jak zde panoval mýtus o tom, že ovladač přímo zakompilovaný v jádru je rychlejší než ovladač zavedený jako modul. Nikdy jsem to nezkoušel, nikdy jsem to neměřil, ale mohu zde prohlásit, že tomu tak není.

Modul či přímo do jádra?

Jak se rozhodnout? Záleží na spoustě okolností a rozhodnutí na tom, jak daný ovladač sestavit nechám na čtenáři. Pokud Vás netrápí místo (jako jsou v embedded systémech) doporučuji zůstat u ovladačů v modulech.

Ať už se rozhodnete jakkoli, měl by Váš ovladač nabízet obě možnosti a v případě rozdílného chování ošetřit patřičné části kódu pomocí #ifdef, atd.

Dodatečné informace ohledně modulu

Modul má ještě jednu "výhodu", lze v něm nadefinovat několik doplňujících informací jakými jsou například popis, autor modulu, licence modulu či seznam parametrů modulu.

  1. MODULE_DESCRIPTION(string)

    Pomocí tohoto makra můžeme nadefinovat jednoduchý popis modulu. Text by měl být stručný, maximálně jednořádkový a měl by informovat o čem daný modul pojednává.


  2. MODULE_AUTHOR(string)

    Pomocí tohoto makra můžeme nadefinovat autora či případné autory modulu. Platí zde "omezení" stejně jako v popisu, co nejkratší a co nejvýstižnější.


  3. MODULE_LICENSE(string)

    Toto makro definuje pod jakou licencí je daný modul napsán. Pokud zavádíte modul a licence není uvedena nebo se "neshoduje" s licencí jádra, bude vypsáno varování, že Váš modul nakazil jádro a bude zaveden.

    Seznam akceptovaných licencí (pro free software) je tento - "GPL", "GPL and additional rights", Dual BSD/GPL" and "Dual MPL/GPL". Pokud vytváříte komerční produkt Vaše licence by měla být nastavena na "Proprietary".


  4. MODULE_PARM(var,type-string)

    Tímto makrem definujeme parametr jádra a jeho typ. První argument je var což značí název parametru a druhý argument je typ, který značí typ námi definovaného parametru.

    Jako typ můžete uvést b (pro byte), h (pro short), i (pro int), l (pro long) a s (pro string). Dále můžete uvést minimální a maximální počet prvků pole, které zastupuje daný parametr a to ve formátu [MIN[-MAX]]{b,h,i,l,s}. V případě, že neuvedete ani MIN ani MAX, považuje se MIN za 1. V případě, že uvedete pouze MIN, tak MAX se nastaví na MIN a tudíž udáváte pevný počet prvků pole. Pokud uvedete i MIN i MAX, definujete minimální a maximální počet zadávaných prvků.

    Například MODULE_PARM(irq, "1-2i") uvádí, že parametr irq je typu int a může obsahovat jedno až dvě čísla, například irq=7,11.

    Ukázku použití parametrů modulu najdete na konci tohoto článku a v přiloženém souboru, který obsahuje všechny dnes použité ukázky.


  5. MODULE_PARM_DESC(var,desc-string)

    Tímto makrem definujeme popis parametru jádra. Například MODULE_PARM_DESC(irq, "IRQ lines") definuje popis parametru irq.


  6. A další ...

    ... které zatím nebudeme zmiňovat.


K čemu mi ale takové dodatečné informace jsou? Takové informace jsou důležité pro uživatele, který chce Váš modul použít a nezná seznam dostupných parametrů. K získání těchto informací slouží utilita modinfo se kterou se seznámíme níže v rámci ukázkového příkladu.

Hello world!

Pro nedočkavé jedince zde máme ukázkový modul ...

Zdrojový kód

#ifdef MODULE

#include <linux/module.h>

MODULE_DESCRIPTION("Hello wolrd example");
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

#endif /* MODULE */

#include <linux/init.h>

int __init
init_module(void)
{
        printk("<1>Hello world!\n");
        return 0;
}

void __exit
cleanup_module(void)
{
        printk("<1>Hello world is going home ...\n");
}

MODULE

Jak sami vidíte, v našem jednoduchém ovladači kontrolujeme definici makra MODULE a podle toho se v našem zdrojovém souboru zařizujeme. V případě, že náš ovladač kompilujeme jako modul tak musíme zahrnout hlavičkový soubor linux/module.h a také definujeme dodatečné informace ohledně našeho modulu.

modinfo

Nyní se dostáváme k ukázce použití utility modinfo aplikovanou na náš ukázkový modul.

[root@echelon 2]# modinfo ./hello.o 
filename:    ./hello.o
description: "Hello wolrd example"
author:      "Robert V0jta "
license:     "GPL"
[root@echelon 2]# 

Inicializace a deinicializace ovladače

Inicializace našeho modulu provádí jedna z hlavních funkcí a tou je int init_module(void), která je volána jádrem při zavádění modulu. V této funkci se provádí inicializace modulu, HW a registrují se veškeré funkce, které modul nabízí. Rozdíl proti klasické aplikaci a modulem je ten, že aplikace se spustí a její hlavní funkce běží dál a obstarává komunikaci s uživatelem, atd. Kdežto modul se spustí, init_module() zaregistruje veškeré nabízené funkce a ukončí se. Návratová hodnota, která značí úspěšnou inicializaci je 0 a jakákoli jiná hodnota signalizuje chybu při zavádění modulu.

Druhou funkcí tohoto modulu je void cleanup_module(void) která se volá před odstraněním modulu z jádra a obstarává odregistrování veškerých funkcí, které modul nabízí. Jedná se o tzv. úklid kdy je potřeba uvolnit všechny alokované a používané prostředky.

Pozorný čtenář si jistě všiml maker __init či __exit, která jsou definována v hlavičkovém souboru linux/init.h. Co znamenají? Takto označujeme funkce, které jsou inicializační a deinicializační. Vysvětlím blíže, při zavádění modulu se zavolá funkce init_module která po úspěšném provedení nebude již nikdy použita a tudíž ji označíme pomocí __init a jádro je schopno tuto funkci po použití odstranit z paměti a nově vzniklé místo využít jinak. Analogicky funguje makro __exit.

Poslední použitou funkcí je printk(). Jedná se o obdobu notoricky známé printf() přizpůsobenou potřebám jádra. Již na první pohled Vás zaujme ona "ozávorkovaná" jednička. Jedná se úroveň logování použitou pro danou zprávu. Úrovní máme osm a může je vyžívat pomocí "ozávorkovaných" čísel (0-7) či pomocí definovaných maker:

#define KERN_EMERG     "<0>"  /* system is unusable                */
#define KERN_ALERT     "<1>"  /* action must be taken immediately  */
#define KERN_CRIT      "<2>"  /* critical conditions               */
#define KERN_ERR       "<3>"  /* error conditions                  */
#define KERN_WARNING   "<4>"  /* warning conditions                */
#define KERN_NOTICE    "<5>"  /* normal but significant condition  */
#define KERN_INFO      "<6>"  /* informational                     */
#define KERN_DEBUG     "<7>"  /* debug-level messages              */

Zápis printk(KERN_ALERT "Hello world!\n"); je ekvivalentní volání printk() z funkce init_module(). Pro použití těchto maker je nutné vložit hlavičkový soubor linux/kernel.h.

Prvně definovanou úroveň (KERN_EMERG) doporučuji používat pouze v naléhavých případech, kdy hrozí, že se systém zhroutí, protože tato zpráva je vypsána na všechny aktivní terminály počítače.

Kompilace modulu, zavádění modulů

Stále tu mluvíme o kompilaci modulu, zavedení a odstranění modulu. Kde nic tu nic o praktické ukázce kompilace. Zde je ukázkový Makefile ...

MODULES = hello.o hello-fail.o
CC = gcc

all: $(MODULES)

clean:
        rm -f $(MODULES)

hello.o: hello.c
        gcc -o hello.o -c hello.c -DMODULE -D__KERNEL__

hello-fail.o: hello.c
        gcc -o hello-fail.o -c hello.c -D__KERNEL__

... který zkompiluje z našeho zdrojového souboru dva moduly. Jeden z nich je hello.o a druhý z nich je hello-fail.o. V prvním definujeme makro MODULE které je nutné pro modul a v druhém tuto definici vypustíme. Nyní si tedy moduly zkompilujeme ...

[root@echelon 2]# make
gcc -o hello.o -c hello.c -DMODULE
gcc -o hello-fail.o -c hello.c
[root@echelon 2]#

... zavedeme první z nich ...

[root@echelon 2]# insmod hello.o

... podíváme se, zda je modul zaveden ...

[root@echelon 2]# lsmod | grep hello
hello                    796   0  (unused)
[root@echelon 2]#

... a náš modul odstraníme z jádra.

[root@echelon 2]# rmmod hello

Pokud jste na konzoli neviděli kýžené výpisy zpráv pomocí printk() nezoufejte a prohlédněte si je pomocí dmesg.

[root@echelon 2]# dmesg | tail -2
Hello world!
Hello world is going home ...
[root@echelon 2]# 

Nyní si ukážeme co se stane pokud zadáme příkaz na zavedení našeho druhého modulu v kterém nebylo při kompilaci definováno makro MODULE.

[root@echelon 2]# insmod hello-fail.o  
hello-fail.o: couldn't find the kernel version the module was \
   compiled for
[root@echelon 2]# 

Na závěr si ukážeme co nám poví jádro v případě, že není uvedena licence u modulu.

[root@echelon 2]# insmod hello.o 
Warning: loading hello.o will taint the kernel: no license
  See http://www.tux.org/lkml/#export-tainted for information about\
   tainted modules
Module hello loaded, with warnings
[root@echelon 2]# 

Ukázka ovladače s parametry

Zde je malá ukázka ovladače, který využívá možnosti paremtrů.

#ifdef MODULE


#include <linux/module.h>

#define MAX_IRQ 9

static int irq [ MAX_IRQ + 1 ] = { [ 0 ... MAX_IRQ ] = -1 };
static int verbose = 0;

MODULE_DESCRIPTION("Hello wolrd example");
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

MODULE_PARM(irq, "1-10i");
MODULE_PARM_DESC(irq, "IRQ lines");

MODULE_PARM(verbose, "i");
MODULE_PARM_DESC(verbose, "Be verbose about IRQs?");

#endif

#include <linux/init.h>

int __init
init_module(void)
{
	printk("<1>Loading modargs module ...\n");

	if (verbose)
	{
		int i;
		
		printk("<1>modargs verbose on ...\n");
	
		for (i = 0 ; i <= MAX_IRQ ; i++)
			if (irq[i] != -1)
		    	printk("<1>modargs IRQ: %i\n", irq[i]);
			else
			    break;
	}
	
	return 0;
}

void __exit
cleanup_module(void)
{
	printk("<1>Unloading modargs module ...\n");
}

Použití parametrů při zavádění modulu ...

[root@echelon v0jta-ldd-2]# insmod ./modargs.o irq=10,5,6
Loading modargs module ...
[root@echelon v0jta-ldd-2]# rmmod modargs
Unloading modargs module ...
[root@echelon v0jta-ldd-2]# insmod ./modargs.o irq=10,5,6 verbose=1
Loading modargs module ...
modargs verbose on ...
modargs IRQ: 10
modargs IRQ: 5
modargs IRQ: 6
[root@echelon v0jta-ldd-2]# rmmod modargs
Unloading modargs module ...
[root@echelon v0jta-ldd-2]#

Závěr

Nyní jsme schopni napsat jednoduchý modul a zkompilovat ho. Dále umíme zjistit informace o modulu pomocí modinfo a také umíme modul zavést a odstranit z jádra.

V příštím díle se podíváme na problematiku kompilace, instalace a zavádění modulu více podrobněji.

Soubory

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

Další části seriálu:

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

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, 09. 12. 2002 10:11
Re: KERN_ALERT












--

m, 08. 12. 2002 19:18
KERN_ALERT?












--

Primitif, 12. 11. 2002 17:34
RE: MODUL NA RS232












--

Robert V0jta, 12. 11. 2002 17:09
RE: MODUL NA RS232












--

Primitif, 12. 11. 2002 16:54
RE: MODUL NA RS232












--

Robert V0jta, 12. 11. 2002 16:45
RE: REALTIME MODUL












--

Frn, 12. 11. 2002 15:15
RealTime modul












--

Robert V0jta, 12. 11. 2002 10:46
RE: MODUL RS232












--

Primitif, 11. 11. 2002 19:32
Re: Modul RS 232












--

Maa01, 11. 11. 2002 17:17
Vyborny clanek












--

Robert V0jta, 11. 11. 2002 14:47
RE: MODUL NA RS232












--

Primitif, 11. 11. 2002 11:01
Modul na RS232












--

Petr Buzrla, 11. 11. 2002 09:07
Fajn serial















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










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