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

I v tomto díle budeme stále věrni minulému tématu a tím jsou "problémy" se zaváděním a odstraňováním modulů.

Jmenný prostor

Jmenný prostor je v celém jádru pouze jeden a proto je nutné dbát na rozumné pojmenování funkcí, proměnných a maker (pro všechny tři věci budu dále používat pojem symbol) použitých ve Vašem ovladači. Veškeré veřejně přístupné symboly jsou uloženy v tzv. Kernel symbol table. Rozumná doporučení pro pojmenování můžeme shrnout takto:

  1. všechny symboly které chcete skrýt (a nechcete pro ně vymýšlet unikátní názvy) deklarujte jako static
  2. u symbolů, které je nutné deklarovat jako veřejné použijte rozumné jméno, které jednoznačně říká co daný symbol znamená
  3. pro celý ovladač, resp. modul si vyberte unikátní prefix pro všechny symboly

Není mnoho doporučení jak správně nazvat Vaše symboly, ale pokud se jich budete držet předejdete mnoha konfliktům a ušetříte si čas.

Symboly

Níže uvedená makra jsou definována v hlavičkoveém souboru linux/module.h.

Makro EXPORT_NO_SYMBOLS

V případě, že Váš modul nemá žádný symbol, který má být veřejný je dobré zapsat makro EXPORT_NO_SYMBOLS kdekoli ve zdrojovém souboru. Z důvodu portability doporučejeme toto makro uvádět ve funkci init_module() (což je jediné místo kde toto makro pracuje správně ve starších verzích jádra).

static int __init
init_module(void)
{
...
  EXPORT_NO_SYMBOLS;
...
}

Makra EXPORT_SYMBOL(symbol), EXPORT_SYMBOL_NOVERS(symbol)

Pokud máme několik symbolů v modulu, které chceme zpřístupnit celému jádru (i ostatním modulům) je nutné tento symbol tzv. exportovat. K tomuto účelu nám slouží dvě výše uvedená makra, která se liší pouze v tom, že první exportuje symbol s verzí a druhé bez verze. My zatím budeme používat exportování symbolů bez verzí a k problematice symbolů s verzemi se dostaneme v některém z dalších dílů.

Aby tato makra mohla fungovat, je nutné definovat makro EXPORT_SYMTAB ještě před použitím hlavičkového souboru linux/module.h a nejlépe na úrovni argumentu překladače -DEXPORT_SYMTAB.

Příklad exportovaného symbolu a jeho použití

První část našeho příkladu bude kratičký modul, který bude exportovat jeden symbol bez verze. Tím symbolem bude funkce int lz_get_value(), která vrací obsah proměnné value. Pro větší rozmanitost je tato proměnná také parametrem modulu a tudíž můžeme její hodnotu ovlivnit při zavádění. Následující ukázku je taktéž přiložena k článku jako soubor lzsym.c.

#ifdef MODULE

#include <linux/module.h>

MODULE_DESCRIPTION("Exported symbol example");
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

MODULE_PARM(value, "i");
MODULE_PARM_DESC(value, "Exported symbol value");

#endif /* MODULE */

#include <linux/init.h>

static int value = 0;

static int __init
init_module(void)
{
	printk("<1>symbol module started\n");
	return 0;
}

static void __exit
cleanup_module(void)
{
	printk("<1>Symbol module unloaded\n");
}

int
lz_get_value(void)
{
	return value;
}

#ifdef EXPORT_SYMTAB
EXPORT_SYMBOL_NOVERS (lz_get_value);
#endif /* EXPORT_SYMBOL */

Jak sami vidíte není to vůbec nic složitého. Teď potřebujeme hlavičkový soubor (lzsym.h), který bude deklarovat námi exportovaný symbol lz_get_value pro použití v jiných modulech. Tento symbol bude definován v případě existence makra __KERNEL__, protože může obsahovat i jiné deklarace použitelné v uživatelských aplikacích.

#ifndef LZ_SYMBOL_H
#define LZ_SYMBOL_H

#ifdef __KERNEL__
extern int lz_get_value(void); 
#endif /* __KERNEL__ */

#endif /* LZ_SYMBOL_H */

A teď se dostáváme k poslední části našeho příkladu a tím je modul, který náš exportovaný symbol použije. Není to nic složitého, pouze při zavádění vypíše vrácenou hodnotu onoho symbolu (lzsymuse.c).

#ifdef MODULE

#include <linux/module.h>

MODULE_DESCRIPTION("LZ Symbol usage");
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

#endif /* MODULE */

#include <linux/init.h>
#include "lzsym.h"

static int __init
init_module(void)
{
	printk("<1>LZ symbol value is %d\n", lz_get_value());
	return 0;
}

static void __exit
cleanup_module(void)
{
	printk("<1>LZ symbol usage modul unloading\n");
}

Jak sami vidíte, jedinou nutností bylo použití hlavičkového souboru lzsym.h v kterém je deklarace našeho symbolu lz_get_value.

Ještě nám zbývá uvést ukázkový Makefile pro tento příklad.

MODULES = lzsym.o lzsymuse.o
CC = gcc
CFLAGS = -O2 -DMODULE -D__KERNEL__

all: $(MODULES)

clean:
	rm -f $(MODULES)

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

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

Za domácí úlohu si zkuste zrušit definici makra EXPORT_SYMTAB z argumentu překladače a uvidíte co to udělá.

Nyní si moduly zkompilujeme.

[echelon:~/linuxzone/ldd/4/v0jta-ldd-4]make
gcc -O2 -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -o lzsym.o \
    -c lzsym.c
gcc -O2 -DMODULE -D__KERNEL__ -o lzsymuse.o -c lzsymuse.c 
[echelon:~/linuxzone/ldd/4/v0jta-ldd-4]

A postupně zavedeme v pořadí lzsym.o a lzsymuse.o.

[root@echelon v0jta-ldd-4]# insmod ./lzsym.o value=111
symbol module started
[root@echelon v0jta-ldd-4]# insmod ./lzsymuse.o 
LZ symbol value is 111
[root@echelon v0jta-ldd-4]#

Teď si oba moduly zkuste odstranit v opačném pořadí než jste je zaváděli, tedy lzsymuse a poté lzsym. Pokud máte, zkuste si zavést modul lzsymuse.o a uvidíte notoricky známou hlášku ...

[root@echelon v0jta-ldd-4]# insmod ./lzsymuse.o 
./lzsymuse.o: unresolved symbol lz_get_value
[root@echelon v0jta-ldd-4]#

... o neexistujícím symbolu, protože modul, který tento symbol exportuje (lzsym) není zaveden. Existuje zde možnost jak automaticky zavádět potřebné moduly do jádra, ale tu si probereme v některém z dalších dílů. Teď si zaveďte oba moduly ve správném pořadí a zkuste z jádra odstranit modul lzsym.

[root@echelon v0jta-ldd-4]# rmmod lzsym
lzsym: Device or resource busy
[root@echelon v0jta-ldd-4]#

100% se Vám to nepodaří z jednoho důvodu - v jádru jsou stále aktivní moduly, které potřebují ke svému běhu symboly exportované z našeho moduly a proto ho jádro nemůže odstranit. Tuto informace můžete získat i jinou cestou a tím je příkaz lsmod, který Vám ukáže závislost modulů.

[root@echelon v0jta-ldd-4]# lsmod | grep lzsym
lzsymuse                 896   0  (unused)
lzsym                    984   0  [lzsymuse]
[root@echelon v0jta-ldd-4]# 

Zde vidíte, že modul lzsym je používán modulem lzsymuse a proto ho jádro nemůže odstranit.

Počítadlo počtu použití modulu

Zmiňujeme-li problémy s odstraňováním modulu z jádra, musíme se také zastavit u dalších tří maker, které jsou definována v hlavičkovém souboru linux/module.h a jsou jimi:

  1. MOD_INC_USE_COUNT

    Při použití tohoto makra se počítadlo použití modulu zvýší o jedničku.


  2. MOD_DEC_USE_COUNT

    Při použití tohoto makra se počítadlo použití modulu sníží o jedničku.


  3. MOD_IN_USE

    Toto počítadlo vrátí hodnotu true v případě, že modul je používán, resp. pokud je počítadlo použití větší jak nula.


Dnešní jádra si sami zjišťují jestli je modul používán či nikoli a proto není nutné využívat těchto maker. Kdo chce ale psát portabilní kód (pro starší jádra) musí tyto makra použít, protože starší jádra touto funkcí nedisponují.

Kdy se to používá?

Představme si modul pro zvukovou kartu, který po zavedení není používán a proto ho můžeme bez problémů odstranit. Tento modul se začne používat v případě, že si například pustíme XMMS a začneme si přehrávat MP3. Poté nám XMMS zavolá funkci open na zařízení /dev/dsp (či jiné). Dále se nám zavolá funkce open implementovaná v našem ovladači, která zavolá makro MOD_INC_USE_COUNT a modul je již používán. Během ukončování XMMS se zavolá funkce close, kterou také náš modul implementuje a v ní je zavoláno makro MOD_DEC_USE_COUNT. V tomto případě už není náš modul používán a můžeme ho bez problémů odstranit.

Mohu zjistit kolikrát je náš modul používán? Ano, můžete a to pomocí příkazu lsmod, který ve třetím sloupečku (Used) ukazuje počítadlo použití u daného modulu. Právě teď poslouchám MP3 a když se podívám na zvukovou kartu, vidím že je opravdu použita a modul neodstraním dokud neukončím přehrávání MP3, neboli dokud nepřestanu používat dané zařízení.

i810_audio             24712   1 (autoclean)
ac97_codec             13320   0 (autoclean) [i810_audio]
soundcore               6500   2 (autoclean) [i810_audio]

(autoclean)

Tento sloupeček souvisí s automatickým zaváděním modulů, které jsem zmiňoval výše a bude podrobněji rozebrán v některém z dalších dílů.

Možné problémy

V případě, že budete používat tyto makra je nutná obezřetnost z jednoho prostého důvodu - jestliže kvůli nějaké akci zvýšíte počítadlo použití modulu je nutné po ukončení dané akce počítadlo zase snížit. Jinak se Vám počítadlo nevrátí zpět na nulu a modul z jádra neodstraníte. Podobné případy mohou vzniknout při ladění modulu kdy Vaše funkce nejsou bezproblémové a nastane-li havárie Vašeho modulu, počítadlo zůstane větší jako nula a modul zase neodstraníte. Ladíte-li, doporučuji předefinovat makra MOD_INC_USE_COUNT a MOD_DEC_USE_COUNT například na {}.

Závěr

Teď už umíte exportovat symboly, používat je v jiných modulech a také jste zase o něco chytřejší co se problematiky zavádění a odstraňování modulů týče. K exportování symbolů, jejich smyslu a použití se vrátíme ještě v příštím díle a posuneme se o malinko dále.

Deklarace vs Definice

Zjistil jsem, že při psaní článků docela často zaměňuji pojmy deklarace a definice. Vynasnažím se, aby od příštího dílu byla vždy použita správná terminologie. Omlouvám se.

Soubory

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

Další části seriálu:

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

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:21
RE: Reseni domaciho ukolu? (EXPORT_SYMTAB)












--

m, 09. 12. 2002 00:24
Reseni domaciho ukolu? (EXPORT_SYMTAB)















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










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