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

Dnes dodržíme slib z minulého článku a rozebereme si podrobněji některé již naťuknuté pasáže z minulých dílů. Co se výkladu týká, nepůjdeme o moc dále, ale o to hlouběji.

Kompilace

Makro __KERNEL__

Určitě jste si všimli trochu opomíjeného makra __KERNEL__ z minulého dílu. O co jde? Jádro nabízí několik API pro přístup ke svým funkcím a zpřístupňuje je uživatelským aplikacím a utilitám pomocí hlavičkových souborů. V těchto souborech jsou deklarovány jak věci jádra samotného, tak věci určené pro uživatelské aplikace. Právě k tomuto rozlišení slouží naše makro __KERNEL__.

Podívejme se například na hlavičkový soubor linux/errno.h.

#ifndef _LINUX_ERRNO_H
#define _LINUX_ERRNO_H

#include <asm/errno.h>

#ifdef __KERNEL__

/* Should never be seen by user programs */
#define ERESTARTSYS     512
#define ERESTARTNOINTR  513
...

V případě, že překládáme věci pro jádro (definujeme makro __KERNEL__) můžeme pracovat s makry ERESTARTSYS, atp. V případě, že tento hlavičkový soubor vkládáme do uživatelské aplikace, toto makro neni definováno a náš program "vidí" definice pouze ze souboru asm/errno.h.

V případě vývoje jakékoli části jádra je nezbytně nutné definovat makro __KERNEL__ a nejlépe na úrovni argumentu překladače (-D__KERNEL__). V opačném případě nebude zpřístupněna celá řada funkcí, které je možne v jádru využít.

Makro __MODULE__

Ještě malá poznámka k nám již známému makru. Definice musí být provedena dříve než budeme vkládát hlavičkový soubor linux/module.h do našeho ovladače.

Následující ukázka je samozřejmě špatně!

#include <linux/module.h>
#define MODULE

Nejlelegantnější řešení je definovat makro na úrovni překladače a to pomocí -DMODULE. V našem ovladači již pouze kontrolujeme existenci makra a podle toho se zařizujeme. Viz ukázky v minulém díle.

Konfigurační soubor linux/config.h

Tento soubor slouží ke zjištění přesné konfigurace jádra při kompilaci. Využívá k tomu automaticky generovaný hlavičkový soubor linux/autoconf.h, který obsahuje námi vytvořenou konfiguraci (pomocí make config, make menuconfig či make xconfig).

Podíváme-li se blíže do souboru linux/autoconf.h uvidíme nám notoricky známé konfigurační volby ...

/*
 * Automatically generated C config: don't edit
 */
#define AUTOCONF_INCLUDED
#define CONFIG_X86 1
#define CONFIG_ISA 1
#undef  CONFIG_SBUS
#define CONFIG_UID16 1

/*
 * Code maturity level options
 */
#define CONFIG_EXPERIMENTAL 1
...

Informace z tohoto hlavičkového souboru (tedy přesnou konfiguraci jádra) využijeme v případě, že se náš ovladač chová rozdílně při několika nastaveních jádra. V tom případě musíme vložit hlavičkový soubor linux/config.h do našeho ovladače a odkazovat se na CONFIG_* makra. Chcete-li předejít problémům, raději nikdy přímo nevkládejte hlavičkový soubor linux/autoconf.h.

Makro __SMP__

Většina lidí vlastní počítač s jedním procesorem a říká si, že tímto makrem se nebude zabývat, protože ho stejně nikdy nevyužije. To je ale samozřejmě špatně, protože ostatní mohou vlastnit více procesorový stroj a Váš ovladač jim tam nebude správně pracovat. Proto je nutné se tímto makrem zabývat i na jedno procesorových systémech. Samozřejmě pouze v případě, že se Váš ovladač chová rozdílně na jedno a na více procesorových strojích.

V případě, že ovladač překládáme pro více procesorový stroj musíme definovat makro __SMP__ před vkládáním jakýchkoli hlavičkových souborů jádra. To nám zajistí krátký kód na začátku našeho modulu ...

#include <linux/config.h>
#ifdef CONFIG_SMP
#define __SMP__
#endif /* CONFIG_SMP */

Optimalizace, inline funkce

Co je inline funkce? Je to v podstatě "obdoba" maker kdy funkce není volána, ale na místo volání je vloženo její tělo. Rozdíl mezi makrem a inline funkcí je ten, že makra zpracovává preprocesor a inline funkce již samotný překladač.

Velké množství funkcí je deklarováno jako tzv. inline funkce. Vše se odehrává v námi používaných hlavičkových souborech a pro správnou funkci je nutné zapnout optimalizaci -Ox překladače (mluvím o překladači, který je v drtivé většině používán a tím je gcc).

Verze a moduly

Každý modul si v sobě nese informaci o verzi jádra, pro které byl přeložen. Tento údaj je uložen jako řetězec a je deklarován v hlavičkovém souboru linux/module.h takto ...

static const char __module_kernel_version[]
  __attribute__((section(".modinfo"))) = "kernel_version=" \
  UTS_RELEASE;

Problém ale nastává v případě, že je náš ovladač rozdělen do více zdrojových souborů a v každém z nich je nutné použít zmiňovaný hlavičkový soubor. Proč? V tom případě, by pole __module_kernel_version bylo definována několikrát, což je nežádoucí.

K tomuto účelu slouží další makro __NO_VERSION__. V případě, že toto makro existuje před vložením hlavičkového souboru linux/module.h bude upuštěno od definice symbolu __module_kernel_version. Pro nás to znamená jediné. V hlavním zdrojovém souboru ovladače vložíme hlavičkový soubor klasickou cestou a v ostatních zdrojových souborech budeme definovat makro __NO_VERSION__ a náš problém bude vyřešen.

Další makra spojená s verzemi

  1. UTS_RELEASE

    Jedná se o textovou reprezentaci verze jádra. Například "2.4.18".


  2. KERNEL_VERSION(major, minor, release)

    Toto makro vytváří číselnou reprezentaci jádra a je definováno následovně.

    #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
    

    Například číselná reprezentace verze jádra "2.4.18" je 132114.


  3. LINUX_VERSION_CODE

    Toto makro nese číselnou reprezentaci jádra, kterou jsme si ukázali v předchozím případě. Neboli pro jádro "2.4.18" to bude 132114.


Tyto makra se používají při porovnávání verzí jádra v kterých došlo ke změnám, které je nutné ošetřit v ovladači. Praktickou ukázku nalezneme například v hlavičkovém souboru inteligentního více portového ovladače stallion.

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
        struct wait_queue       *open_wait;
        struct wait_queue       *close_wait;
        struct wait_queue       *raw_wait;
#else
        wait_queue_head_t       open_wait;
        wait_queue_head_t       close_wait;
        wait_queue_head_t       raw_wait;
#endif

K ukázce není nutný další komentář. Téma verzí jsme prozkoumali zase o něco blíže a jelikož se jedná o rozsáhlejší kapitolu, necháme si některé další pasáže do dalších dílů.

Inicializace, ...

Vlastní názvy funkcí

V minulém článku jsem si ukázali jakým způsobem je modul inicializován a jakým způsobem se ukončuje. V případě, že se nám nelíbí funkce init_module() a cleanup_module() můžeme použít vlastní a pomocí maker module_init() a module_exit() označit naší inicializační a ukončovací funkci. Na ukázku si zmodifikujeme příklad (hello.c) z minulého dílu.

#ifdef MODULE

#include <linux/module.h>

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

#endif

#include <linux/init.h>

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

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

module_init(module_start);
module_exit(module_end);

Obě uvedená makra jsou definována v hlavičkovém souboru linux/init.h.

Kontrola chyb v rámci inicializace modulu

Důležitou součástí inicializační funkce je i správná kontrola všech potencionálních chyb. Znamená to zjednodušeně to, že v případě neúspěšné inicializace NENÍ volána funkce cleanup_module() a proto je nutné uvolnit veškeré, již alokované, prostředky v rámci funkce init_module(), případně zavolat vlastní silou funkci cleanup_module().

Nyní si ukážeme kratičkou ukázku, které se zabývá kontrolou chyb při inicializaci.

#ifdef MODULE

#include <linux/module.h>

MODULE_DESCRIPTION("Error check example");
MODULE_AUTHOR("Robert V0jta ");
MODULE_LICENSE("GPL");

#endif

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

static void *mem1 = NULL;
static void *mem2 = NULL;

static void __exit
cleanup_module(void)
{
	if (mem1 != NULL)
	{
		kfree(mem1);
		mem1 = NULL;
	}

	if (mem2 != NULL)
	{
		kfree(mem2);
		mem2 = NULL;
	}
}

static int __init
init_module(void)
{
	mem1 = (void *)kmalloc(4096, GFP_KERNEL);
	mem2 = (void *)kmalloc(4096, GFP_KERNEL);

	if (mem1 == NULL || mem2 == NULL)
	{
		printk("<1>Out of free memory");
		cleanup_module();
		return -ENOMEM;
	}
	
	return 0;
}

Existuje zde několik možností jak vzniklé chyby ošetřit a další ukázku můžete nalézt v přiloženém souboru (errcheck2.c).

User space, Kernel space

V krátkosti se zmíníme o významu oněch magických pojmů. Většina dnešních procesorů nabízí několik úrovní ochrany, resp. přístupů k systémovým prostředkům (například paměť, ...). Většinou je tento počet roven dvoum, ale některé produkty nabízejí i víceúrovňové rozdělení.

Jádro samotné pracuje v té nejvyšší úrovni, tzv. supervisor módu, kdy má neomezený přístup ke všem funkcím, které procesor nabízí. Tomuto módu se v Linuxovém světě říká tzv. Kernel space.

Uživatelské aplikace běží na opačné straně, v té nejnižší úrovni a přístup k prostředkům je kontrolován jádrem, resp. procesorem které dostává pokyny od jádra. Tomuto módu se v Linuxovém světě zase říká tzv. User space.

Zájemce o problematiku odkazuji na stranu 19 LDD či do zdrojových kódů jádra.

Závěr

Když jsem minule avizoval, které téma budeme probírat v dnešním díle tak jsem si neuvědomil jaký rozsah jsem si určil (nad rámec tohoto článku) a proto se i v následujícím díle budeme věnovat dnešnímu tématu.

Soubory

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

Další části seriálu:

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

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:13
RE: wolrd x world












--

m, 08. 12. 2002 20:48
wolrd x world















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










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