Hlavné menuUser loginSearch |
Vývoj ovladačů 1 - obecný úvod
Thursday, 12.06.2008 16:07
V tomto článku se dozvíte některé základní věci o ovladačích: Co to je ovladač (moje definice), nejdůležitější charakteristiky či způsob načítání ovladače do jádra. Nebudu zde mluvit o ovladačích hardwaru.
Co je to ovladačNěkteří tvrdí, že ovladač je speciální druh programu. S tímto tvrzením bych nesouhlasil, protože ovladače se od obyčejných programů (procesů) hodně odlišují, například v tomto: Každý program má svůj vlastní adresový prostor. To pro ovladače neplatí. Všechny drivery se nachází v tomtéž adresovém prostoru, který je většinou namapován na adresy 0x80000000 - 0xFFFFFFFF. Paměť na těchto adresách je stejná pro každý proces. Procesy k této paměti nemohou standardně přistupovat. Kód procesu je vykonáván prostřednictvím vláken, která mu patří. Kód ovladačů vykonávají rovněž vlákna (kdo jiný také, že?), avšak nejsou to jejich vlastní vlákna. Ovladače si "půjčují" vlákna od procesů. Z toho vyplývá, že ovladač může běžet v kontextech různých procesů. To může být nebezpečné ,rptože se proces, v jehož kontextu kód ovladače vykonáván, mohl pokusit narušit činnost driveru. Jelikož ovladače mají daleko větší moc nad systémem než obyčejné procesy, vzniká tu bezpečnostní riziko. Proto existuje proces s názvem "System" a PID 4, v jehož kontextu mohou ovladače bezpečně vykonávat svůj kód. Tento proces nevykonává nic v uživatelském režimu (ačkoliv jej k tomu pravděpodobně lze donutit). Procesy běží v tzv. uživatelském režimu (user mode, Ring 3), kdežto ovladače v tzv. režimu jádra (kernel mode, Ring 0). Platí, že čím menší číslo Ring módu, tím více privilegií. Omezení privilegií procesů spočívá v tom, že např. nemoou vykonávat některé (privilegované) instrukce či číst nebo měnit paměť jádra. Na druhé straně, pro ovladače neplatí žádná omezení. Ukončení nežádoucích procesů je mnohem snažší než odstranění nežádoucích ovladačů (ovladačů, které nechtějí být odstraněny). To je způsobeno tím, že moc ovladačů nad operačním systémem je neomezená. Soubory EXE a DLL nemůžete smazat, pokud jsou používány v nějakém procesu (přejmenovat je lze). Soubor ovladače (SYS) lze smazat, i když je ovladač zaveden v jádře. Neošetřená výjimka v normálních procesech končí chybovým hlášením, nebo ukončením daného procesu. Neošetřená výjimka v kódu ovladače vede k modré smrti (Blue Screen of Deatch - BSOD). Při psaní ovladače si proto člověk musí dávat mnohem větší pozor než při psaní normálního programu. Při programování ovladačů se musíte často rozmýšlet, zda použijete stránkovanou, nebo nestránkovanou paměť. U normálních procesů vám téměř vždy stačí paměť stránkovaná. To by z výčtu odlišností stačilo. Nyní se podívejme, jak takový ovladač napsat. Psaní a kompilování ovladačePokud chcete vytvořit ovladač, musíte napsat nejen jeho zdrojové kódy, ale přidat ještě dva soubory s některými údaji pro překladač. Prvním z ncih je soubor s názvem MAKEFILE, jehož obsah je následující:
TARGETNAME= <název ovladače> TARGETPATH= obj TARGETTYPE= DRIVER SOURCES= <soubory zdrojáků> INCLUDES= <cesta ke knihovnám> Kompilace ovladače je vcelku jednoduchá, i když složitější než kompilace klasického programu. Musíte si nejprve z webu Microsoftu stáhnout "Microsoft Windows Driver Development Kit." Po instalaci se vám ve Start -> Programy vytvoří položka "Development Kits". v nabídce "Build Environments" vyberte operační systém, pro který má být ovladač zkompilován a zvolte, jestli chcete "Free", nebo "Checked" Build (při kompilování "Free" se do ovladače nevkládají debugovací symboly). Otevře se příkazová řádka. Nyní se stačí jen dostat do adresáře se zdrojáky vašeho ovladače a zadat příkaz Načtení ovladače do jádraJe několik možností. Na tomto místě uvedu jen jednu - tu nejspárvnější a nejpoctivější.
Var hSCM : THandle;
hService : THandle;
Begin
hSCM:=OpenSCManager(
Nil,
Nil,
SC_MANAGER_ALL_ACCESS);
If hSCM = 0 Then
Exit;
// Vytvoření záznamu o ovladači v Registrech
hService:=CreateService(
hSCM,
< název ovladače >,
< popis >,
SERVICE_ALL_ACCESS,
// Typ služby - zde ovladač jádra
SERVICE_KERNEL_DRIVER,
// Jak spouštět ovladač.
// Zde je to "na příkaz"
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
< soubor ovladače >,
Nil, Nil, Nil, Nil, Nil);
If (hService = 0) And
(GetLastError <> ERROR_SERVICE_EXISTS) Then
begin
CloseServiceHandle(hSCM);
Exit;
end;
CloseServiceHandle(hSCM);
If hService > 0 Then
begin
// Loadujem ovladač! Teď se provede DriverEntry
If Not StartService(hService,0,Dummy) Then
begin
CloseServiceHandle(hService);
Exit;
end;
CloseServiceHandle(hService);
end;
end;
ZávěrTak to by bylo obecné povídání. V příštích dílech se podíváme na specifické problémy při tvorbě ovladačů a na jejich řešení. Nemyslím, že by tento článek změnil váš názor na obtížnost psaní ovladačů. Psaní ovladačů není tak těžké - jen to může být trochu nezvyk pro ty¨, co programují ve Windows API. Tady jsou totiž většinou úplně jiné funkce - které ještě neznáte. To se ale po pár set řádcích rychle napraví. Psaní ovladačů také nutí k větší přesnosti uvažování. Najednou není jedno, zda k určité paměti přistupuje více procesů najednou, náhle záleží na počtu procesorů, na verzi OS... a na mnoha dalších věcech, které si člověk neuvědomí, dokud nezačne ovladač psát. |
LinksOdkazy |
xp64 sp2
RE: XP x64