MASARYKOVA UNIVERZITA V BRNĚ FAKULTA
INFORMATIKY
#ris mp
Ovladač klávesnice přes event interface v XFree86 a Linuxu BAKALÁŘSKÁ PRÁCE
Josef Kubín
Brno, podzim 2005
Prohlášení Prohlašuji, že tato bakalářská práce je mým původním autorským dílem, které jsem vy pracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Vedoucí práce: Mgr. Jan Kasprzak 11
Shrnutí Tato bakalářská práce popisuje současné lokální sdílení jediného počítače typu PC dvěma uživateli, přičemž oba uživatelé mají k dispozici samostatnou klávesnici, myš a monitor. Je zde vysvětleno v čem spočíval problém, který bránil současnému použití několika instancí X serveru. Je zde také stručný popis vnitřní architektury ovladačů klávesnic pro event inter face. Na závěr je uveden návod, jakým způsobem lze zkoumat X server.
m
Klíčová slova multi seat, multi user, local multi user, multiple local XFree/X.Org Xll users, dual head, udev rules
Obsah 1
Úvod 1.1 Jak funguje lokální sdílení 1.2 Dvouhlavá konfigurace X serveru 2 Klávesnice a myš 2.1 Úvod do zpracování ScanCode->KeyCode 2.2 Nové rozhraní - event interface 2.3 Exkluzívni přístup na zařízení 2.4 Jednoznačné pojmenování periferií 3 X server 3.1 Nároky na zdroje počítače 3.2 PCI konfigurační hlavička 3.3 PCI-to-PCI bridge 3.4 Štart X serveru 3.5 Virtuální terminály - přepínání 3.6 Původní řešení 4 Grafická karta 4.1 Režim VGA 4.2 Modul INT10 4.3 Kompatibilita grafických karet 5 Ovladače pro X server 5.1 Hlavní části ovladačů 5.2 Ovladače pro event interface 5.2.1 vtkbd 5.2.2 evdev 5.3 Kompilace ovladače 5.4 Použití ovladače 6 Užitečné tipy 6.1 Pronikání do hlubin X serveru 6.2 Trasování X serveru 7 Závěr Bibliografie A Optimalizace grafické karty B Použitý hardware/software C Soubory na přiloženém CD
2 2 3 4 4 4 5 6 9 9 10 12 14 14 17 18 18 18 19 20 20 22 23 26 28 28 30 30 30 32 33 34 35 36
1
Kapitola 1
Úvod V blízké budoucnosti lze očekávat, že s narůstajícím výkonem osobních počítačů bude zcela normální lokálně sdílet počítač s dalšími uživateli. Je jasné, že uživatel píšící textový do kument nepotřebuje ke své práci počítač s 3 GHz procesorem. Zatímco jeden uživatel píše, další uživatel může nerušené na tomtéž počítači dělat úplně jinou činnost. Stačí pořídit další kompatibilní grafickou kartu, monitor a dostatečně dlouhé VGA a USB kabely. Proč mít dva průměrně vybavené počítače, když za stejnou nebo nižší cenu je možné mít jeden špičkově vybavený? Důvodů bylo několik proč za tímto účelem už dávno [ ] nedošlo k úpravě oficiální dis tribuce X serveru. Především na straně jádra nebylo vyhovující rozhraní pro periferie. Poté co bylo takové rozhraní vytvořeno, bylo třeba naprogramovat nový ovladač pro X server. Dalším problémem je vnitřní architektura X serveru, která je v současnosti 1 nepřipravena pro lokální sdílení jediného počítače. Takové úpravy vyžadují netriviální znalosti a úsilí ze strany vývojářů, kteří často pracují bez nároku na odměnu ve svém volném čase. 1.1
Jak funguje lokální sdílení
Jednoduše řečeno, spustí se nad jediným jádrem více instancí X serveru přičemž každá in stance má svoje periferie a posílá svůj grafický výstup na svojí grafickou kartu. Linux je ve svojí podstatě multiuživatelský operační systém, takže sdílení hardwarových a softwa rových prostředků počítače bylo už od začátku vyřešeno. Všichni uživatelé sdílí stejný strom se soubory. Ve Windows je grafické rozhraní součástí jádra, takže jediný počítač s obyčejnou základní deskou jednoduše nelze sdílet mezi několika uživateli. X server je v podstatě obyčejná grafická aplikace běžící v prostoru paměťi pro uživatelské aplikace, která může v jediném počítači běžet i ve více instancích. Tuto grafickou aplikaci lze ovládat prostřednictvím nového rozhraní jádra - event interface. Vstupy z periferií od jednotlivých uživatelů jsou posílány přes toto rozhraní do jednotlivých instancí X serveru. Před verzí jádra 2.4. nešlo jednoduše zařídit, aby jednotliví uživatelé prostřednictvím nezávislých periferií mohli ovládat jednotlivé instance X serveru. Bez event interface taktéž nebylo možné mít zároveň na jednom monitoru virtuální terminály (VT) v režimu VGA a na druhém monitoru jedinou běžící instanci X serveru. Tehdejším jediným řešením byla úprava zdrojového kódu jádra a X serveru. Pro distribuce X serveru X.Org X11R6.8.2 a nižší existo1. Všechny ukázky zdrojového kódu uvedené v této práci se vztahují k distribuci X.Org X11R6.8.2.
2
1.2. DVOUHLAVÁ KONFIGURACE X SERVERU válo několik záplat, které se skládaly v podstatě ze dvou hlavních částí. První část obvykle zrušila implicitní zamknutí všech grafických karet při startu X serveru, druhá přizpůsobila vstupní část X serveru pro event interface. Avšak žádná úprava neumožňovala zároveň bez chybné přepínání na virtuální terminály alespoň u jedné instance. V této práci je popsáno úplně jiné plně funkční řešení pro dva uživatele v podobě jediného ovladače klávesnice. Není třeba aplikovat jakoukoliv dodatečnou záplatu na zdrojový kód X serveru nebo jádra. V kapitole týkající se klávesnice a myši bude čtenář seznámen se základními principy přenosu dat mezi klávesnicí a X serverem. Bude zde uveden také poměrně podrobný návod, jak jednoznačně svázat jednotlivé periferie s jednotlivými instancemi X serveru. Na začátku kapitoly věnované samotnému X serveru je ukázka, jak velké paměťové nároky budou kladeny na zdroje počítače při současném běhu dvou instancí. V té samé kapitole bude odhalena samotná příčina, proč nešlo naráz použít dvě instance X serveru. Čtenář bude seznámen s nejnižší úrovní konfigurace grafických karet, která se provádí manipulací s re gistry PCI sběrnice. Odvážnější mohou na základě předvedených ukázek provádět pokusy na svém počítači. Další část bude pojednávat o způsobu, jak si instance během spuštění vytvoří vazbu na přepínání virtuálních terminálů prostřednictvím signálu SIGUSR1. V po slední části kapitoly věnované X serveru je ukázána podstata starého špatného řešení, které dříve umožňovalo současné použití několika instancí X serveru. Cílem další kapitoly je dát představu o tom, jak se startují grafické karty ve třicetidvoubitovém prostředí (soft-boot), krátce je zmíněn problém vzájemné kompatibility grafických karet. V kapitole věnované ovladačům jsou popsány ukázky zdrojového kódu z ovladače nezbytné pro lokální sdílení počítače. Na závěr kapitoly jsou uvedeny ukázky příkazů pro X server, které jistě budou použity pro spuštění několika instancí. Předposlední kapitola poskytuje několik užitečných tipů pro bližší seznámení se s X serverem. 1.2
Dvouhlavá konfigurace X serveru
Jedinou instanci X serveru je možné konfigurovat pro dvě současně běžící grafické karty. Tento režim pro jediného uživatele v duálním grafickém módu se jmenuje Xinerama. Pro zobrazení na dvou monitorech Xinerama používá takové řešení, že se rozdělí právě ak tivní velká virtuální plocha mezi dva monitory. Pokud na druhém monitoru jsou například manuály, přepnutím na jinou virtuální plochu manuály zmizí. Může to být dost nevýhodné, protože se tak částečně vytrácí výhoda virtuálních ploch. Lze to vyřešit spuštěním další in stance X serveru běžící na jiné grafické kartě čímž se získá další nezávislé pracoviště na kterém mohou být další nezávisle ovladatelné virtuální plochy. Takto získané nezávislé pra coviště je proto výhodné i pro jediného vývojáře-programátora, protože omezuje neustálé přepínání ploch za účelem čtení potřebných informací z manuálu během práce. V konečném důsledku taková konfigurace zvyšuje produktivitu. Dvouhlavou konfiguraci X serveru bez Xineramy lze spustit na jedné grafické kartě se dvěma grafickými výstupy, zmíněný problém s virtuálními plochami je menší. Žádná z obou konfigurací ale neumožňuje mít současně dostupné virtuální terminály a grafické rozhraní X serveru. 3
Kapitola 2
Klávesnice a myš 2.1
Úvod do zpracování ScanCode->KeyCode
Stisknutím nebo uvolněním klávesy se řadičem klávesnice generuje ScanCode. Tento Scan Code je až čtyřbajtové číslo jednoznačně identifikující každou stisknutou nebo uvolněnou klávesu. Například ScanCode klávesy PrintScreen je dlouhý čtyři bajty, při KeyDown a KeyUp se celkem vygeneruje osm bajtů. Jak vypadá ScanCode, který je generován klávesnicí, lze jednoduše ověřit příkazem showkey: $ showkey - s
Uvnitř jádra se ScanCode převede na KeyCode, což je jednobajtová reprezentace stisk nuté klávesy. Několik stisknutých kláves zaráz se posílá jako sekvence stisknutých kláves. Co která sekvence znamená se vyhodnocuje až za ovladačem klávesnice uvnitř X serveru. Jaký KeyCode se skrývá pod právě stisknutou klávesou lze zjistit spuštěním příkazu show key bez parametru. X server vnitřně ale nepracuje se stejným KeyCode jaké mu posílá jádro, ale s podobnou formou kódu, který vznikne transpozicí a přemapováním 1 původního Key Code. 2.2
N o v é rozhraní - event interface
Rozhraní se nalézá v adresáři / d e v / i n p u t / jako zařízení s názvem eventN 2 . Při stisku nebo uvolnění klávesy na klávesnici je KeyCode posílán jako součást paketu na event inter face. Nezáleží na tom, jestli se jedná o USB nebo PS/2 klávesnici. Schéma paketu struct
input_event { struct timeval ul6 type; ul6 code; s32 v a l u e ;
time; /* k l á v e s n i c e / m y š / o s t a t n í / * KeyCode */ / * KeyDown/KeyUp */
*/
};
1. Děje se tak ve funkci ovladače klávesnice PostKbdEventO, která je v sekci 5.2.1. 2. Pokud v tomto adresáři není takové zařízení, pak se může jednat o starší jádro než 2.4. a nebo novější jádro nebylo zkompilováno s podporou pro event interface.
4
2.3. EXKLUZÍVNÍ PŘÍSTUP NA ZAŘÍZENÍ X server se nemusí starat o hardwarové zvláštnosti použité periferie, protože tyto detaily jsou přesunuty na úroveň jádra. Z toho samozřejmě plyne jednodušší implementace vstupní části v jakékoliv jiné uživatelské aplikaci, která je propojena s periferií prostřednictvím to hoto rozhraní. Stačí porovnat zdrojový kód ovladačů ze stromu zdrojového kódu X serveru e v d e v . c, mouse . c nebo kbd. c. Jaké periferii je přiřazeno odpovídající zařízení se zjistí následujícím příkazem: $ cat /proc/bus/input/devices
O tom, že z event interface lze číst data přicházející z periferie je možné se přesvědčit jednoduchým pokusem: $ cat /dev/input/eventN
Pokud se vypisuje shluk znaků při stisku nebo uvolnění klávesy a nebo při pohybu myši, pak zařízení odpovídá právě použité periferii. Připojí-li se další klávesnice nebo jiná perife rie, pak se v tomto adresáři objeví další soubor s názvem eventN přičemž číslo N je dalším v pořadí vedle existujících souborů. Každé zařízení / d e v / i n p u t / e v e n t N samozřejmě lze z uživatelského programu otevřít, číst anebo do něj zapisovat. fd = open("/dev/input/eventN", 0_RDWR, 0 ) ;
2.3
Exkluzivní přístup na zařízení
Normálně se data z více připojených klávesnic zpracovávají v jádru tak, jako kdyby byla připojena k počítači jediná klávesnice. Exkluzivní přístup na periferii je nová vlastnost im plementovaná v jádru, kterou lze ovládat prostřednictvím event interface, proto se v apli kaci z toho důvodu při otevření nastaví také příznak pro zápis. Tato vlastnost je důležitá pro lokální sdílení jednoho počítače, protože je třeba mít zcela nezávislé periferie. Data z perife rie pak nejsou jádrem poslána na virtuální terminál, jádro pouze zprostředkovává komuni kaci mezi event interface a periferií. Ovládání exkluzivního přístupu na periferii 3 #include
ioctl(fd, ioctl(fd,
EVIOCGRAB, EVIOCGRAB,
/ * # d e f i n e EVIOCGRAB _ I O W ( ' E ' ,
(void * ) 1 ) ; / * z a p n u t i (void * ) 0 ) ; / * v y p n u t i
0x90,
int);*/
*/ */
Avšak pokud jsou virtuální terminály prostřednictvím služby jádra i o c t l () přepnuty do grafického režimu, je možné se do jisté míry zbavit nutnosti exkluzivního přístupu, protože data z periferie taktéž nejsou posílána a prováděna na virtuálním terminálu. 3. co se přesně děje v jádře lze zjistit ve zdrojovém souboru kernel_root / d r i ver s / i n p u t /evdev. c
5
2.4. JEDNOZNAČNÉ POJMENOVÁNÍ PERIFERIÍ /* přepnutí VT do grafického režimu */ ioctl(ConsoleFd, KDSETMODE, KD_GRAPHICS); /* přepnutí VT do textového režimu */ ioctl(ConsoleFd, KDSETMODE, KD_TEXT) ;
Problémem je ale nezávislé ovládání LED na klávesnicích, protože se bez exkluzivního přístupu nepředpokládá lokální sdílení jednoho počítače a tak dochází ke zmatku v nasta vení NumLock/CapsLock/ScrollLock a skutečným stavem klávesnice uvnitř jednotlivých instancí X serveru. Dalším problémem je instance X serveru, která se přepne na virtuální terminál ve VGA a tím způsobí přepnutí virtuálních terminálů z grafického režimu do tex tového režimu. Po přepnutí režimu všechny klávesnice píší na jeden virtuální terminál, což je nepřijatelné. 2.4
Jednoznačné pojmenování periferií
Informace byly čerpány z [2] a [3]. Pro každou periferii se při startu jádra vytvoří odpovídající zařízení / d e v / i n p u t / e v e n t N , v případě myši také zařízení mouseN. Připojení periferie za běhu jádra nebo spuštění jádra s už připojenou periferií má vliv na pojmenování zařízení. Taktéž vždy připojené periferie se při každém startu jádra nemusí detekovat ve stejném pořadí a tak je dobré provést trvalé pojmenování zařízení v konfiguračním souboru / e t c / u d e v / r u l e s . d/2 0 - i n p u t . r u l e s . Bez takového pojmenování by občas docházelo k nekonzistenci mezi názvem zařízení v x o r g . conf a mezi skutečným zařízením v adresáři /dev/input/. Na základě jednoznačných atributů periferie vytváří démon udevd jednoznačný symlink, který odkazuje na dynamicky vytvořený název zařízení eventN nebo mouseN. Po odpojení periferie tento symlink zase zmizí. V souboru / e t c / u d e v / r u l e s . d / 5 0 - u d e v . r u l e s jsou definována pravidla pro pojmenování zařízení, je v něm také zahrnuto několik ukázek jak vytvářet vlastní pravidla. Pokud není nalezeno pravidlo pro pojmenování periferie, pak zůstane pouze implicitní název eventN nebo mouseN. Do tohoto souboru by uživatel neměl zapisovat, pokud se chce vyhnout problémům v případě update udev. Soubory v adresáři / e t c / u d e v / r u l e s . d/ jsou parsovány v lexikálním pořadí. Taktéž platí, že první nale zené pravidlo v definici se uplatní, další duplicitní pravidla se neuplatní. Proto je důležité, aby soubor s uživatelskými pravidly byl zpracován dříve než soubor s implicitními pra vidly jinak mohou být uživatelsky definovaná pravidla ignorována. Řádky začínající zna kem # jsou považovány za komentáře, každé pravidlo musí být na jednom řádku. Soubor s názvem 2 0 - i n p u t . r u l e s se musí vytvořit, 20 je lexikograficky menší než 50 a proto je zajištěno, že se bude parsovat dříve než soubor 5 0 - u d e v . r u l e s . Také je důležité zachovat příponu . r u l e s , jinak soubor nebude parsován. Problémem se mohou stát periferie bez výrobního čísla od jednoho výrobce připojené pouze na USB sběrnici, v takovém případě je možné rozlišit periferii pouze podle USB zásuvky, kterou lze jednoznačně identifikovat. 6
2.4. JEDNOZNAČNÉ POJMENOVÁNÍ PERIFERIÍ Stejné periferie bez výrobního čísla připojené na USB a přes redukci na PS/2 nepředstavují problém. Výpis hodnot pro pravidla se získá příkazem: $ udevinfo -a -p $(udevinfo -q path -n $ udevinfo -a -p $(udevinfo -q path -n
/dev/input/eventN) /dev/input/mouseN)
Ukázka výpisu předchozího příkazu:
looking at class device SYSFS{dev}="13:32"
'/sys/class/input/mouseO':
follow the c l a s s d e v i c e ' s "device" looking at the device chain at '/sys/devices/pciOOOO:00/0000:00:07.2/usbl/l-2/l-2.4/1-2.4:1.0': BUS="usb" ID="l-2.4:1.0" S Y S F S { b A l t e r n a t e S e t t i n g } = " 0" SYSFS{bInterfaceClass}="03" SYSFS{bInterfaceNumber}="00" SYSFS{bInterfaceProtocol}="02" SYSFS{bInterfaceSubClass}="01" SYSFS{bNumEndpoints}="01" S Y S F S { m o d a l i a s } = " u s b : v 0 4 6DpC03Ed2 0 0 0dc0 0dsc0 0 d p 0 0 i c 0 3 i s c 0 1 i p 0 2 " Ukázka pravidel (řádky jsou zlámány): # definice pro libovolnou PS/2 klávesnici a mys SYSFS{description}="i8042 Kbd Port", KERNEL="event*", SYMLINK="input/ps2_keyboard" SYSFS{description}="i8042 Aux Port", KERNEL="mouse*", SYMLINK="input/ps2_mouse" # definice pro lib. USB klavesnici/mys v lib. USB zásuvce BUS="usb", SYSFS{bInterfaceProtocol}="01", KERNEL="event*", SYMLINK="input/usb_keyboard" BUS="usb", SYSFS{bInterfaceProtocol}="02", KERNEL="mouse*", SYMLINK="input/usb_mouse" # definice pro dve stejné USB klávesnice a myši #ID="l-2.4:1.0", SYSFS{bInterfaceProtocol}="01", KERNEL="event*", SYMLINK="input/usb_keyboardl" #ID="1-2.3:1.0", SYSFS{bInterfaceProtocol}="01", KERNEL="event*", SYMLINK="input/usb_keyboard2" #ID="1-2.2:1.0", SYSFS{bInterfaceProtocol}="02",
7
2.4. JEDNOZNAČNÉ POJMENOVÁNÍ PERIFERIÍ KERNEL="mouse*", SYMLINK="input/usb_mousel" #ID="1-2.1:1.0", SYSFS{bInterfaceProtocol}="02", KERNEL="mouse*", SYMLINK="input/usb_mouse2" # d e f i n i c e p r o dve r u z n e USB myši (podobne p r o k l á v e s n i c i ) # S Y S F S { m o d a l i a s } = " u s b : v 0 4 58p0 035d0110dc0 0dsc0 0dp0 0 i c 0 3 i s c 0 1 i p 0 2 " , KERNEL="mouse*", SYMLINK="input/usb_mousel" # S Y S F S { m o d a l i a s } = " u s b : v 0 4 6DpC03Ed2 0 0 0dc0 0dsc0 0dp0 0 i c 0 3 i s c 0 1 i p 0 2 " , KERNEL="mouse*", SYMLINK="input/usb_mouse2"
Poté co byla pravidla definována nebo modifikována v konfiguračním souboru, uplatní se následujícím příkazem 4 : # /sbin/udevstart V konfiguračním soubouru / e t c / u d e v / u d e v . conf lze nastavit volbu u d e v _ l o g = " y e s " způsobující výpis do souboru / v a r / l o g / m e s s a g e s ; je to užitečné pro případ ladění konfiguračních souborů. Do konfiguračního souboru x o r g . conf se nakonec zapíše název symlinku reprezentující vstupní zařízení.
4. Po provedení redefinice pravidel je dobré před spuštěním příkazu smazat symlinky, protože po restartu udev mohou v adresáři zůstat staré neplatné symlinky, které ale ukazují na skutečná zařízení.
8
Kapitola 3
X server 3.1
Nároky na zdroje počítače
Počítač pro dva nenáročné uživatele by neměl mít méně jak 128MB paměti, nižší hodnota by už mohla negativně ovlivňovat odezvu počítače. Naopak počítač na kterém se budou spouštět náročnější aplikace, by měl být podstatně lépe vybavený. Následující výpis představuje zátěž počítače se dvěma běžícími instancemi X serveru, přičemž aplikace v každé instanci sdílí jeden uživatelský účet. První instance má spuštěny tři okna Firefox-u (verze 1.0.2), a dva terminály, druhá instance má spuštěno jedno okno Firef ox-u, a jeden terminál. Jako správce oken je v obou případech použit twm s minimální konfigurací.
Setříděný výpis příkazu top PID 4558 4820 4349 4429 1944 4758 4382 4462 2104 4526 4460 4380
USER kubin kubin root root root kubin kubin kubin xf s kubin kubin kubin
PR NI VI RT RES SHR S %CPU %MEM 15 0 72000 21m 12m S 0 0 3 4 15 0 61960 19m 12m S 0 0 3 1 15 0 58872 7628 2544 S 0 3 1 2 15 0 58880 7256 2232 S 0 0 1 1 16 0 14704 6000 1168 S 0 0 0 9 16 0 8304 4108 1988 S 0 0 0 6 15 0 8312 4076 1956 S 0 3 0 6 16 0 8028 3012 1940 S 0 0 0 5 16 0 3920 2224 820 S 0 0 0 3 16 0 5520 2048 1608 S 0 0 0 3 16 0 5556 1964 1448 S 0 0 0 3 15 0 5560 1940 1424 S 0 0 0 3
TIME+
0 0 0 0 0 0 0 0 0 0 0 0
07 01 21 03 00 00 01 00 00 00 00 00
43 83 19 70 65 20 06 18 13 11 12 54
COMMAND firefox-bin firefox-bin
X X Xprt xterm xterm xterm xf s gconfd-2
twm twm
Časté swapování je samozřejmě příznakem nedostatečné velikosti RAM, kterou lze snadno přidat. Nejužším hrdlem brzdícím odezvu jinak rychlého počítače se může stát harddisk. To hle ale samozřejmě závisí na způsobu, jakým budou uživatelé počítač využívat, nebo-li jak často bude docházet ke kolizím při požadavcích na harddisk. V krajním případě se přidá další harddisk zvlášť pro druhého uživatele a nebo se postaví diskové pole typu RAID 0. 9
3.2. PCI KONFIGURAČNÍ HLAVIČKA 3.2
PCI konfigurační hlavička
Po zapnutí počítače systémový BIOS prohledá PCI/AGP sběrnici jestli jsou na ní přítomny nějaké karty, detekuje jejich typ, požadavky na paměť a přiřadí rozsah adres. Tyto údaje jsou pro operační systém a pro aplikace dostupné prostřednictvím PCI konfigurační hlavičky. 31
IE
B
is
Device ID
Uendnr ID
00 h
Status
Command
BHh
class Hode BIST
Header Type
Latency Type
R E 'Ji 5 i D n ID
BBh
Cache Line Size
BĽh iah lHh iah
Ease RddrE55 Registers
ich EBh EHh EBh
Cardbus CIS Painter Subsystem ID
Subsystem Uendnr ID
EBh
Expansinn R D m Base Rddress Capabilities Pninter
Reserved Reserved max_Lat
min_Ent
I n t e r r u p t Pin
ECh
EHh EBh
I n t e r r u p t Line
ECh
Obrázek 3.1: Type OOh Configuration Space Header Konfigurační hlavička dovoluje systému identifikovat a řídit PCI zařízení. V PCI slotu s grafickou kartou typu GF2 lze přečíst na offsetu 0x00 hodnotu OxOllOlODE, což je kód karty a výrobce (Device ID, Vendor ID) 1 . Na základě této hodnoty počítač vygeneruje označení karty a zobrazí ho uživateli. Na offsetu 0x08 lze přečíst třídu do které karta patří (Class Code). Například hodnota 0x03 na pozici [31-23] znamená, že se jedná o grafickou kartu, dotazem na tuto hodnotu nalezne X server všechny grafické karty v počítači. Tyto hodnoty lze jednotlivě přečíst příkazem pcitweak. Hromadný výpis všech konfiguračních hlaviček lze získat následujícím příkazem: 1. Unikátní kód pro každého výrobce udržuje organizace PCI-SIG (www.pci-sig.org), kód karty si určuje sám výrobce.
10
3.2. PCI KONFIGURAČNÍ HLAVIČKA # scanpci
-v
Pokud je možné vzdáleně přistupovat k počítači, pak lze trochu experimentovat. Za mknutí/odemknutí grafické karty v AGP slotu se provede takto: # pcitweak -w 1:0:0 -b 0x04 0x04 # pcitweak -w 1:0:0 -b 0x04 0x07
Stejně zamyká každá instance X serveru při startu všechny grafické karty v počítači. Vynulují se první dva bity na offsetu 0x04 což je umístění pro příkazový registr (Com mand). Způsobí to zákaz přístupu do I / O a do paměti, karta poté ignoruje jakékoliv další požadavky přicházející ze sběrnice, obraz zamrzne. Podrobnosti o dalších registrech jsou ve specifikaci PCI Local Bus Specification [4] 2 . Ve skutečném kódu se zápis do regis tru provádí takovým způsobem, že se napřed přečte jeho hodnota na příslušném offsetu, provede se nastavení příslušných bitů přes bitovou masku a nakonec se zapíše vše zpět. Registry konfiguračních hlaviček pro PCI sloty a pro AGP slot jsou stejné a také stejným způsobem se programují. Ukázkový kód pro odemykání/zamykání primární grafické karty CARD16 C t r l ; / * t y p e d e f u n s i g n e d s h o r t CARD16; * / PCITAG t a g ; / * t y p e d e f u n s i g n e d l o n g PCITAG; */ pciVideoPtr *pPci; #define #define #define #define
PCI_CMD_STAT_REG 0x04 PCI_CMD_IO_ENABLE 0x01 PCI_CMD_MEM_ENABLE 0x02 SETBITS (PCI_CMD_IO_ENABLE
| PCI_CMD_MEM_ENABLE)
/* n a l e z e n i p r i m á r n i g r a f i c k é k a r t y */ f o r ( p P c i = x f 8 6 G e t P c i V i d e o I n f o ( ) ; * p P c i != NULL; pPci++) if (xf86lsPrimaryPci(*pPci)) break; tag = pciTag((*pPci)->bus,
(*pPci)->device,
(*pPci)->func);
/* IO/MEM enable */ Ctrl = pciReadLong(tag, PCI_CMD_STAT_REG); Ctrl |= SETBITS; pciWriteLong(tag, PCI_CMD_STAT_REG, Ctrl); /* IO/MEM disable */ Ctrl = pciReadLong(tag, PCI_CMD_STAT_REG); Ctrl &= ~SETBITS; pciWriteLong(tag, PCI_CMD_STAT_REG, Ctrl); 2. tato specifikace je na přiloženém CD v souboru PCL22.pdf
11
3.3. PCI-TO-PCI BRIDGE V přechozím ukázkovém kódu jsou použity dvě funkce, které jsou obvykle používány v ovladačích grafických karet. Funkce xf 86GetPciVideoInf o() vrací ukazatel na seznam uka zatelů na struktury obsahující údaje o všech grafických kartách, detekované při startu X serveru. Funkce xf86IsPrimaryPci() vrací nenulovou hodnotu pokud ukazatel ukazuje na stukturu s daty primární grafické karty. Podobná část kódu je součástí řídící části pro gra fické karty v ovladači X serveru vtkbd. 3.3
PCI-to-PCI bridge
PCI-to-PCI bridge je součástí integrovaného obvodu na základní desce počítače nazývaný North Bridge, který je fyzickým kořenem sběrnice PCI. Sběrnice AGP je součástí PCI stromu a je připojena k jeho kořeni. Na jakou sběrnici bude přesměrováno VGA určuje bit v řídícím registru (Bridge Control), který je na offsetu 0x3C. X server tento bit nastavuje při svém startu v závislosti na umístění jeho grafické karty. Ve skutečnosti se přesměrované VGA ni jak nepoužije, protože v případě přepnutí X serveru na virtuální terminál se VGA přemapuje zpět na primární grafickou kartu.
Device ID
Vender ID
Státu:
Command
Header Type
Secondary Latency Timer
OJh Rev IstinID
Class Code BIST
OHh
Primary Latency Timer
Cachelne Size
cen ocn
Base .Address Register u
1 on
Base Acttress Register 1
uti
Subordinale Bus Number
Secondary iLHus
Secondary Bus Number
Primary Bus Number
I'D Limit
I/O Basa
18h
icn
Memory Linn
Memory Base
2on
PrelerchaHe Memory Limit
Preletctiable Memory Base
2Jri
Pretetctiable Base Upper 32 Elts
lSt\
Prelefchable Limit Upper .32 Bits
acn
I'D Limit Upper 16 Bits
VO Base Upper K Bits
Reserved
Capablltlas Pointer
iJri
Inrerrupl Line
acn
Expansion ROM Base Address Bridge Conlrzl
Interrupt Pin
Mri
38 ri
Obrázek 3.2: PCI-to-PCI Bridge Configuration Registers Podrobný popis všech registrů je ve specifikaci PCI-to-PCI Bridge Architecture Speci fication [I>] 3 . Samozřejmě lze trochu experimentovat a zkusit přesměrovat VGA na dříve 3. tato specifikace je na přiloženém CD v souboru ppbl2.pdf
12
3.3. PCI-TO-PCI BRIDGE inicializovanou grafickou kartu v AGP slotu a poté zpět na primární grafickou kartu v PCI slotu. Grafickou kartu v AGP slotu je ale napřed nutné odemknout! Po přesměrování je někdy nutné zadat příkaz setf ont protože jinak na monitoru zůstane písmo nečitelné. # pcitweak -w 00:01:0 0x3C 0x880000 # pcitweak -w 00:01:0 0x3C 0x800000
Nastavování registrů se provádí podobně jako v kódu pro PCI konfigurační hlavičku. Ukázkový kód pro přesměrování VGA mezi PCI/AGP sběrnicí typedef unsigned short CARD16; typedef unsigned long PCITAG; CARD16 Ctrl; PCITAG tag = 0x800;/* PCI-to-PCI bridge (AGP bridge) */ #define #define #define #define #define
PCI_PCI_BRIDGE_VGA_EN 0x0 8 PCI_PCI_BRIDGE_CONTROL_REG 0x3E PCI_PCI_BRIDGE_SECONDARY_RESET 0x4 0 PCI_PCI_BRIDGE_MASTER_ABORT_EN 0x2 0 MASKBITS (PCI_PCI_BRIDGE_VGA_EN | PCI_PCI_BRIDGE_MASTER_ABORT_EN)
/* přesměruje VGA na grafickou kartu v PCI slotu */ Ctrl = pciReadWord(tag, PCI_PCI_BRIDGE_CONTROL_REG); if ((Ctrl & MASKBITS) != PCI_PCI_BRIDGE_VGA_EN) { Ctrl = (ctrl | PCI_PCI_BRIDGE_VGA_EN) & ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN | PCI_PCI_BRIDGE_SECONDARY_RESET); pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG, ctrl); } /* přesměruje VGA na grafickou kartu v AGP slotu */ ctrl = pciReadWord(tag, PCI_PCI_BRIDGE_CONTROL_REG); if (Ctrl & MASKBITS) { Ctrl &= ~ (MASKBITS | PCI_PCI_BRIDGE_SECONDARY_RESET) ; pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG, ctrl); }
Předchozí ukázkový kód demonstruje, jak lze ovládat VGA bit. Což přináší zajímavý důsledek, že je možné spustit X server na neprimární grafické kartě v AGP slotu a pak přesměrovat VGA zpět na primární grafickou kartu v PCI slotu. Pak mohou být dostupné virtuální terminály ve VGA a zároveň grafické rozhraní X serveru, což je také základ pro spuštění další instance X serveru na primární grafické kartě. Tato další instance běžící na primární grafické kartě má jako jediná přístup na virtuální terminály. Pro dvě grafické karty typu PCI a AGP je tohle řešení funkční, protože tyto dvě grafické karty jsou fyzicky odděleny mostem, každá má pro sebe vyhrazenou samostatnou větev PCI sběrnice a přepínání do VGA nečiní žádné problémy. Není nutné složitě zjišťovat přes VGA registry, která grafická 13
3.4. START X SERVERU karta byla před spuštěním X serveru aktivní, protože zamčená primární grafická karta na PCI sběrnici byla před spuštěním X serveru zcela určitě aktivní a lze ji jednoduše naleznout mezi ostatními PCI grafickými kartami pomocí funkce xf86IsPrimaryPci(). Další grafickou kartou je karta v AGP slotu, která je v počítači vždy jediná svého druhu, takže stačí testo vat jenom její přítomnost. Takto jednoduše jsou vymezeny právě dvě grafické karty pro dvě instance X serveru, které je potřeba v ovladači pohlídat aby zůstaly odemčené. Pro několik grafických karet typu PCI ale takové řešení nelze použít, protože tyto karty sdílí jedinou větev PCI sběrnice. Na to je nutná úprava zdrojového kódu zajišťující výlučný přístup jednotlivých instancí ke grafickým kartám, protože při pokusu o přepnutí do VGA režimu u jedné karty instance X serveru zapisuje do nesprávných registrů, což končí za tuhnutím počítače. 3.4
Start X serveru
Pro X server X.Org XI 1R6.8.2 a nižší platí následující chování Po spuštění X serveru je detekován nejbližší volný virtuální terminál (obvykle VT7) a uloží se do globální proměnné číslo terminálu ze kterého byl spuštěn. Poté je terminál přepnut do grafického režimu. Spustí-li se další instance X serveru příkazem: $ startx —
:1 vt7 -layout DALSI
Pak první instance zamrzne a na další grafické kartě se spustí další instance s konfi gurací pojmenovanou například DALSI. Implicitní chování X serveru je totiž takové, že se při startu zamkne přístup ke všem grafickým kartám. Na základě údajů z konfiguračního souboru x o r g . c o n f s e provede přesměrování VGA na příslušnou sběrnici k příslušné gra fické kartě. Tato grafická karta se jako jediná odemkne a pokud není primární, proběhne na ní inicializace. Zamykání grafických karet se dělá proto, protože během inicializace gra fických karet je třeba nastavit registry a ty se smí nastavovat jenom tehdy, když grafické karty jsou logicky odpojeny od sběrnice. Jinak by mohlo dojít k havárii celého počítače. Hlavním problémem je, že další spuštěná instance už nechá ostatní grafické karty zamčené. 3.5
Virtuální terminály - přepínání
Zajištění přístupu na virtuální terminály z alespoň jedné z několika běžících instancí X ser veru bylo dalším úkolem. Velkým cílem bylo realizovat úpravu umožňující lokální sdílení do modulu ovladače pro X server bez úpravy jeho zdrojového kódu. Ačkoliv se na X.Org mělo za to, že bez úpravy zdrojového kódu je to nerealizovatelné, tohoto cíle jsem nako nec dosáhl. Shodou okolností, realizace takové úpravy přichází v úvahu pouze v nějakém ovladači vstupní periferie, protože při přepínání X serveru na virtuální terminály se volá handler ovladače, ve kterém dojde k odpojení periferie. Jedině do tohoto handleni je možné umístit kód pro ovládání registrů PCI sběrnice. V X serveru přepínání na virtuální terminály provádí funkce xf 86VTSwitch(). 14
3.5. VIRTUÁLNÍ TERMINÁLY - PŘEPÍNÁNÍ Funkce X serveru - xf86VTSwitch() soubor programs/Xserver/hw/xfree8 6/common/xf8 6Events.c řádek 1312 xf86VTSwitch() { if (xf86Screens[0]->vtSema) { DisableDevice((DevicelntPtr)xf86lnfo.pKeyboard); plnfo = xf86lnputDevs; while (plnfo) { DisableDevice(pInfo->dev);/* odpojeni ostatních periferii */ plnfo = plnfo->next; } } else { EnableDevice((DevicelntPtr)xf86lnfo.pKeyboard); plnfo = xf86lnputDevs; while (plnfo) { EnableDevice(plnfo->dev); plnfo = plnfo->next; } } }
Proto nebylo možné úpravu realizovat jako malý samostatný modul, který dokonale provádí právě jednu věc, protože by se musel tvářit jako nějaká nadbytečná vstupní peri ferie. To už je jednodušší zahrnout úpravu do existujícího ovladače a tak se úprava stala součástí ovladače vtkbd. Uvnitř X serveru se přepnutí na virtuální terminál provádí takovým způsobem, že in stance X serveru prostě přepne na požadované číslo virtuálního terminálu. Způsobí to vy volání signálu SIGUSR1, který způsobí spuštění handleru xf 86VTRequest() uvnitř běžící in stance X serveru. Tento handler nastaví příznak v globální struktuře xf 86Inf o pro přerušení nekonečné (idle) smyčky, do které se X server pokaždé vrací v případě své nečinnosti. Na základě tohoto příznaku se provede výše uvedená funkce xf86VTSwitch(). Handler X serveru pro obsluhu signálu SIGUSR1 - xf86VTRequest()
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / o s - s u p p o r t / l i n u x / V T s w _ u s l . c řádek 42 void xf86VTRequest(int sig) { 4. Všechny ukázky zdrojového kódu uvedené v této práci se vztahují k distribuci X.Org X11R6.8.2.
15
3.5. VIRTUÁLNÍ TERMINÁLY - PŘEPÍNÁNÍ signal(sig, (void(*)(int))xf86VTRequest); xf86lnfo.vtRequestsPending = TRUE; return; }
Možná největším problémem celé úpravy bylo naleznout způsob, jak sdílet signál SI GUSRl mezi několika instancemi X serveru, protože každá instance si chce rezervovat tento signál pro sebe bez ohledu na stav volby DontVTSwitch. Tento signál nakonec spouští han dler patřící poslední instanci X serveru. Přepnutí na virtuální terminál nedopadne dobře, protože dojde ke zmatku při zápisu do registrů. V následující části inicializačního kódu probíhá zaregistrování signálu SIGUSRl a přepnutí virtuálních terminálů do grafického režimu. Funkce X serveru - xf860penConsole()
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / o s - s u p p o r t / l i n u x / l n x _ i n i t . c řádek 84 void xf860penConsole(void) { SYSCALL(result = ioctl(xf86lnfo.consoleFd, VT_GETMODE, &VT)); if (result < 0) { FatalError ( "xf860penConsole: VT_GETMODE failed\n"); } signal(SIGUSRl, xf8 6VTRequest); VT.mode = VT_PROCESS; VT.relsig = SIGUSRl; VT.acqsig = SIGUSRl; if {
(ioctl(xf86lnfo.consoleFd, VT_SETMODE, &VT) < 0) FatalError("xf860penConsole: VT_SETMODE VT_PROCESS
} if {
failed\n");
(ioctl(xf86lnfo.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) FatalError("xf860penConsole: KDSETMODE KD_GRAPHICS
failed\n");
}
VGA výstup na virtuální terminál může být v současném jádru 2.6.13 jen jeden. Zajistit přístup na virtuální terminál z jedné běžící instance je poměrně snadné. Ale není snadné zajistit přístup na virtuální terminály z několika instancí bez podpory ze strany jádra. 16
3.6. PŮVODNÍ ŘEŠENÍ 3.6
Původní řešení
Aby se mohlo zároveň spustit více instancí X serveru, pak se obvykle zabránilo impli citnímu zamykání všech grafických karet, takže registry se s jistým rizikem nastavovaly na odemčených grafických kartách. Na Internetu lze naleznout několik záplat pro lokální sdílení počítače, založené na podobném principu. Na základě dekompozice problému jsem nalezl asi nejjednodušší způsob, který spočívá v prostém zakomentování jednoho řádku, kde se volá funkce DisablePciAccessO během inicializace X serveru. Avšak pro tyto přidané čtyři komentářové znaky se musel zkompilovat celý X server. Tato úprava je postačující, po kud nebyl požadován také přístup na virtuální terminály z jedné instance. Funkce X serveru - xf86AccessInit() soubor programs/Xserver/hw/xfree8 6/common/xf8 6Bus.c řádek 573 void xf86AccessInit(void) { initPciState() ; initPciBusState() ; DisablePciBusAccess() ; /*DisablePciAccess() ; */ xf86ResAccessEnter = TRUE; }
Funkce initPciStateO slouží k uložení stavu registrů grafických karet tak, jak je X server naleznul při svém startu. Funkce initPciBusState() ukládá stav registrů PCI-to-PCI bridge. Tato data jsou zapsána zpět do registrů při přechodu z grafického režimu na virtuální ter minál a nebo při ukončení X serveru 5 . Uvnitř funkce DisablePciAccessO se v cyklu spustí funkce pciIo_MemAccessDisable(), která zápisem do PCI konfiguračních hlaviček postupně zamkne všechny přítomné grafické karty. Funkce X serveru - pciloJMemAccessDisableO soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / c o m m o n / x f 8 6 p c i B u s . c řádek 616 s t a t i c void pciIo_MemAccessDisable(void* arg) { pArg->ctrl &= ~(PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE); pciWriteLong(pArg->tag, PCI_CMD_STAT_REG, pArg->ctrl); }
5. Při násilném ukončení X serveru příkazem kill -9 PID k úklidu registrů nedojde, což může být později zdrojem problémů s počítačem.
17
Kapitola 4
Grafická karta Informace byly čerpány z [6]1 4.1
Režim V G A
Z historických důvodů může být v počítači v režimu VGA aktivní pouze jedna grafická karta. Je to dáno paměťovým modelem x86 ve kterém je po startu dostupný první jeden me gabajt paměti. Systémová paměť pro VGA je umístěna na pozici OxAOOOO-OxBFFFF (128kB). Na kterou část sběrnice bude tato paměť mapována určuje VGA bit v PCI-to-PCI bridge. Většina grafických karet podporuje dva VGA módy: V legacy módu karta replikuje grafické hardwarové rozhraní, které bylo použito v ori ginálním IBM PC/AT. Tento mód musí být podporován každou grafickou kartou a je primárně používán z důvodu kompatibility, aby aplikace a drivery mohly mít jednotné programové rozhraní. V nativním módu grafická karta poskytuje přístup k registrům implementovaných výrobcem. Mohou se lišit pro každého výrobce a dokonce i pro každý model grafické karty. Některé tyto registry nemusí mít volně dostupnou specifikaci, což samozřejmě přináší řadu problémů programátorům svobodného software. Tyto registry jsou umístěny v paměf ovém prostoru MMIO a používají se taktéž ke konfiguraci a k vylepšenému řízení grafické karty. 4.2
Modul INT10
V počítači s více grafickými kartami je po jeho startu inicializována jenom jedna, která je nastavena v BIOSu jako primární, sekundární grafické karty zůstanou neaktivní a zamčené. Tyto sekundární grafické karty musí být inicializovány (soft-boot) ve třicetidvoubitovém prostředí. Takovou inicializaci provádí modul INT10, který je součástí X serveru. Modul INT10 je velký hack, protože byl z velké části naprogramován na základě reverzního engineeringu bez dokumentace k BlOSům grafických karet. A proto ne každý typ grafické karty lze spustit prostřednictvím tohoto modulu. Aby se mohla inicializovat další karta, je nutné vytvořit pro BIOS grafické karty reálné šestnáctibitové prostředí jako je po startu počítače. Modul INT10 je v podstatě emulátor x86, protože VGA BIOS při inicializaci gra fické karty volá systémové rutiny prostřednictvím přerušení INT10, které je nedostupné 1. dokument je na přiloženém CD v souboru vgabios.pdf
18
4.3. KOMPATIBILITA GRAFICKÝCH KARET v třicetidvoubitovém prostředí (architektura x86 používá 256 SW přerušení). Po spuštění modulu se nejdříve odmapuje primární VGA z fyzického I / O a z paměťového prostoru. Děje se tak programováním PCI registrů a dobře známých legacy VGA I / O portů. Poté se namapuje fyzický I / O a paměťový prostor další grafické karty. Dekomprimuje se VGA BIOS do virtuálního paměťového prostoru emulátoru. Emulátor pak spustí kód VGA BIOSu z jeho startovního bodu, přičemž jeho požadavky na přerušení jsou zachyceny a obslouženy emulátorem. Po inicializaci je grafická karta emulátorem přepnuta do VGA legacy módu. 4.3
Kompatibilita grafických karet
Jestli bude možné spustit zároveň dvě grafické karty se zjistí nejjednodušeji následujícím příkazem: # Xorg -configure
Vygeneruje se zároveň konfigurační soubor / r o o t / x o r g . conf .new, který stačí pro další použití jen mírně upravit. Některé typy grafických karet vyžadují spuštění jako primární, protože u těchto typů karet pravděpodobně modul INT10 způsobuje zatuhnutí počítače během inicializace. Je třeba se připravit na to, že je někdy nutné trochu experimentovat s na stavením a nenechat se hned odradit prvním neúspěchem. Tady neexistuje spolehlivé pravi dlo jak rozchodit problémové grafické karty kromě empirické zkušenosti těch, kteří takovou kombinaci karet vyzkoušeli. Byl pozorován problém s kombinací S3 trio + TNT2(AGP). Po odemčení a inicializaci karty S3 trio počítač téměř spolehlivě dříve nebo později zatuhnul. Naopak bezproblémovou kombinací byla fosilní TRIDENT TGUI9440 + TNT2(AGP) a nebo S3 virge + TNT2(AGP). Před nákupem grafické karty je dobré si napřed ověřit její kompati bilitu pokusem!
19
Kapitola 5
Ovladače pro X server 5.1
Hlavní části ovladačů
Po připojení ovladače klávesnice se provádí činnosti, které jsou shodné u všech ovladačů pro X server. Nejdříve X server nalezne exportovanou strukturu ovladače (např. vtkbd) po jmenovanou vtkbdModuleData, ve které jsou nejdůležitější údaje o ovladači. Název této struktury je konstruován uvnitř X serveru jako "jméno ovladače" + ModuleData a jeho přítomnost je očekávána v každém ovladači. Obsah struktury xf86KbdVersionRec obsahuje jméno ovladače s jeho verzí a vypisuje se při startu X serveru do Xorg.N. l o g . Prostřednictvím funkce xf86AddModuleInfo(&KbdInfo, module) se předá X serveru ukazatel na pole pa rametrů podporované ovladačem, části z tohoto výpisu jsou k nalezení v logu. Funkce xf86AddInputDriver(&KBD, module, 0) je specifická pro periferie a předává ukazatel na interní strukturu ovladače obsahující iniciální funkci KbdPrelnitO. Ve funkci KbdPrelnitO dojde k nastavení ukazatelů na handlery ovladače, které pak spouští X server ze své globální struktury. Povinné funkce a struktury ovladače vtkbd soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / v t k b d / v t k b d . c řádek 943 s t a t i c void xf86KbdUnplug(pointer
p)
static pointer xf86KbdPlug(pointer module, pointer options, int *errmaj, int *errmin) { static Bool Initialised = FALSE; if (!Initialised) { Initialised = TRUE; #ifndef REMOVE_LOADER_CHECK_MODULE_INFO if (xf86LoaderCheckSymbol("xf8 6AddModuleInfo"; #endif
20
5.1. HLAVNÍ ČÁSTI OVLADAČŮ xf86AddModuleInfo(SKbdlnfo, module); } xf86AddInputDriver(&KBD, module, 0) ; return module;
static XF86ModuleVersionInfo xf8 6KbdVersionRec = { "vtkbd (MultiSeat + VT support)", MODULEVENDORSTRING, MODINFOSTRINGl, M0DINF0STRING2, XORG_VERSION_CURRENT, 3, 0, 0, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT, {0, 0, 0, 0} /* signature, to be patched into the file by */ /* a tool */
XF8 6ModuleData vtkbdModuleData = { &xf8 6KbdVersionRec, xf86KbdPlug, xf8 6KbdUnplug }; Ovladač klávesnice taktéž řeší ovládání LED na klávesnici zápisem na event interface, neboí klávesnice sama o sobě neví nic o tom jestli jsou psána velká písmena nebo jestli jsou na numerické klávesnici zapnuta čísla či kurzorové klávesy. Klávesnice pouze produkuje sekvenci kódů stisknutých a uvolněných kláves. Handler EvdevKbdCtrlO z ovladače evdev pro ovládání LED na klávesnici
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / e v d e v / e v d e v . c řádek338 s t a t i c void EvdevKbdCtrl(DevicelntPtr device, KeybdCtrl *ctrl) { static struct { int xbit, code; } bits[] = { { CAPSFLAG, LED_CAPSL }, { NUMFLAG, LED_NUML }, { SCROLLFLAG, LED_SCROLLL }, { MODEFLAG, LED_KANA }, { COMPOSEFLAG, LED_COMPOSE }
InputlnfoPtr plnfo; struct input_event ev[ArrayLength(bits)
21
5.2. OVLADAČE PRO EVENT INTERFACE int
i;
plnfo = device->public.devicePrivate; for (i = 0; i < ArrayLength(bits); i++) { ev[i].type = EV_LED; ev[i].code = bits[i].code; ev[i].value = (ctrl->leds & bits[i].xbit) > 0; } /* zápise na event interface stav LED */ write(pInfo->fd, ev, sizeof ev) ; }
Výčet s popisem všech exportovaných funkcí X serveru, které lze použít v ovladačích je v dokumentu XFree86 server 4.x Design (DRAFT) [ ]. Je zde také uvedena vzorová ukázka ovladače pro grafickou kartu. Tento dokument je v podstatě základním manuálem pro napsání jakéhokoliv ovladače pro X server. 5.2
Ovladače pro event interface
1
Výstupem této bakalářské práce je ovladač klávesnice pro event interface a případně i záplata umožňující lokální sdílení jednoho počítače mezi více uživateli. Tento ovladač byl napsán jako úprava existujícího ovladače pro klávesnici kbd a je pojmenován vtkbd. V současné době je to zatím jediný plně funkční ovladač pro event interface. Umožňuje navíc současné použití dvou instancí X serveru, protože je v něm implementován poměrně jednoduchý al goritmus pro ovládání registrů PCI sběrnice. Taktéž je v něm vyřešen přístup na virtuální terminály při současně běžících dvou instancích. V současné době je už ale zahrnuta úprava umožňující lokální sdílení do připravované distribuce X serveru X.Org X11R7. Nicméně pro starší distribuce je to jediné rozumné řešení, protože uživatel nemusí aplikovat jakoukoliv záplatu na zdrojový kód X serveru. Ovladač stačí zkopírovat do adresáře / u s r / X I 1 R 6 / l i b / m o d u l e s / i n p u t / a upravit konfigurační soubor / e t c / X l l / x o r g . conf. Tento ovladač je konzervativní alternativou k novému ovladači evdev (X11R7), protože v konfiguračním souboru se pro něj používají stejné volby jako pro ovladač kbd nebo keyboard. Ovladač evdev je řešen čistě jen pro event interface a je použitelný také pro myš. Zatím je ale ve stavu vývoje, nebude plně funkční ani v připravovaném sedmém vydání X serveru X.Org. Ovladače z principu nepodporují hot-plug, protože zavádění a inicializace ovladačů se provádí pouze při startu. Pokus o otevření neexistujícího zařízení způsobí ukončení startu X serveru. Odpojení klávesnice nebo myši za chodu X serveru, způsobí zánik zařízení, na které ukazuje deskriptor. U jediné myši je hot-plug možný, lze použít jednoznačné vždy existující zařízení / d e v / i n p u t / m i c e . 1. Pro zařazení zdrojového kódu ovladačů vtkbd a evdev do stromu zdrojového kódu distribuce X.Org nebo XFree86 lze použít patch bp.diff z přiloženého CD.
22
5.2. OVLADAČE PRO EVENT INTERFACE 5.2.1 vtkbd Zde jsou uvedeny pouze zkrácené části kódu, které jsem naprogramoval. Na základě podmínky, že grafická karta spuštěné instance X serveru není primární kar tou a zároveň jedna z těchto dvou karet je typu AGP se zruší předchozí vazba signálu SIGUSR1 na virtuální terminály a tyto se přepnou do textového režimu. Na základě rozhod nutí této podmínky příznak v proměnné HckBhv dále ovlivňuje řízení registrů PCI sběrnice ve funkci PCIBusCtrK). Avšak tato neprimární instance může ovládat handler xf86VTRequest() u primární in stance, protože může přepnutím virtuálního terminálu vyvolat signál SIGUSR1. Což může na první pohled vypadat jako bezvýznamná vlastnost, ale jedinému uživateli se může ho dit. Takové chování lze zakázat obvyklou volbou DontVTSwitch. Následující část kódu je nezbytná pro nezávislé virtuální terminály ve VGA na primární grafické kartě, přičemž na sekundární grafické kartě je grafické rozhraní X serveru: Funkce KbdPrelnitO z ovladače vtkbd
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / v t k b d / v t k b d . c řádek 247 s t a t i c InputlnfoPtr K b d P r e l n i t ( I n p u t D r i v e r P t r d r v , IDevPtr dev, i n t f l a g s ) { . . . / * z i s k á n i u k a z a t e l e na g r a f i c k o u k a r t u s e k t e r o u j e s p u š t ě n X s e r v e r pciVideoPtr *pPci, Pcilnfo = xf86GetPciInfoForEntity(0);
*/
/* n a l e z e n i p r i m á r n i g r a f i c k é k a r t y */ f o r ( p P c i = x f 8 6 G e t P c i V i d e o I n f o ( ) ; * p P c i != NULL; pPci++) if (xf86lsPrimaryPci(*pPci)) break; / * i f Xorg má n e p r i m á r n i g r a f i c k o u k a r t u && j e d n a k a r t a j e AGP * / i f ( p c i T a g ( ( * p P c i ) - > b u s , ( * p P c i ) - > d e v i c e , ( * p P c i ) - > f u n c ) != p c i T a g ( P c i l n f o - > b u s , P c i l n f o - > d e v i c e , P c i l n f o - > f u n c ) && ((*pPci)->bus || PciInfo->bus)) { i f ( ( f d = o p e n ( " / d e v / t t y 0 " , O _ W R O N L Y , 0 ) ) >= 0) { s t r u c t vt_mode VT; ioctl(fd,
VT_GETMODE, &VT);
/* zrušeni vazby signálu SIGUSR1 na VT switch */ VT.mode = VT_AUTO; VT.relsig = 0; VT.acqsig = 0; ioctl(fd, VT_SETMODE, &VT); /* přepnuti VT zpět do textového režimu */ ioctl(fd, KDSETMODE, KD_TEXT);
23
5.2. OVLADAČE PRO EVENT INTERFACE close(fd); }
} else HckBhv = 0; return plnfo; }
V handleru KbdProcO se volá funkce PCIBusCtrlO, ve které se dodatečně odemyká/zamyká primární grafická karta. Ovládá se zde také exkluzivní přístup na klávesnici. K vyvolání do jde při startu nebo ukončení X serveru a taktéž při přepnutí na virtuální terminál a zpět. Funkce KbdProcO z ovladače vtkbd soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / v t k b d / v t k b d . c řádek 631 static int KbdProc(DevicelntPtr device, int what) { case DEVICE_ON: PCIBusCtrl(1);/* odemkni prim. grafickou kartu a nastav VGA bit */ /* zapni exkluzivní přistup na klávesnici */ if (ioctl(pInfo->fd, _IOW('E', 0x90, int), (int *) 1) < 0){ xf8 6Msg(X_ERROR, "%s: %s\n", pInfo->name, strerror(errno)); } break; case DEVICE_OFF: PCIBusCtrl(0);/* zamkni primárni grafickou kartu */ /* vypni exkluzivní přistup na klávesnici */ if (ioctl(pInfo->fd, _IOW('E', 0x90, int), (int *) 0) < 0){ xf8 6Msg(X_ERROR, " % s : % s \ n " , p I n f o - > n a m e , s t r e r r o r ( e r r n o ) ) ; } break;
Zde je nejdůležitější část kódu umožňující lokální sdílení počítače dvěma uživateli. V první části se provádí odemčení primární grafické karty ihned poté co X server naběhne do gra fického režimu. Pak se nastaví VGA bit v PCI-to-PCI bridge (Bus:Dev:Func = 00:01:00) tak, aby bylo VGA nasměrováno zpět na část sběrnice s touto primární kartou. Funkce PCIBusCtrlO z ovladače vtkbd soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / v t k b d / v t k b d . c řádek 559 24
5.2. OVLADAČE PRO EVENT INTERFACE s t a t i c void PCIBusCtrl(int DevOn) /* VGA routing AGP<->PCI */ { CARD16 Ctrl; PCITAG tag, agp = 0x10000; pciVideoPtr *pPci; #define MASKBITS (PCI_PCI_BRIDGE_VGA_EN | PCI_PCI_BRIDGE_MASTER_ABORT_EN) #define SETBITS (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE) if (HckBhv) { ... /* pPci uz ukazuje na primárni grafickou kartu */ tag = pciTag((*pPci)->bus, (*pPci)->device, (*pPci)->func); if (DevOn) { /* nastav v Command registru IO/MEM enable */ Ctrl = pciReadLong(tag, PCI_CMD_STAT_REG) ; Ctrl |= SETBITS; pciWriteLong(tag, PCI_CMD_STAT_REG, Ctrl); } else { } /* jestliže prim. graf. karta neni AGP, nasmeruj VGA na PCI */ if (tag & agp) { } else {/* AGP -> PCI */ Ctrl = pciReadWord(0x800, PCI_PCI_BRIDGE_CONTROL_REG); if (Ctrl & MASKBITS) { Ctrl &= ~(MASKBITS | PCI_PCI_BRIDGE_SECONDARY_RESET); pciWriteWord(0x800, PCI_PCI_BRIDGE_CONTROL_REG, Ctrl); } } } }
Funkce eventReadlnput z ovladače vtkbd čte pakety z event interface a předává je handleru PostKbdEventO. soubor programs/Xserver/hw/xfree86/input/vtkbd/vtkbd.c řádek 724 static void eventReadlnput(InputlnfoPtr plnfo) { KbdDevPtr pKbd = (KbdDevPtr) plnfo->private; struct input_event ev; if (read(plnfo->fd, (char *)&ev, sizeof(ev)) > 0) if (ev.type == EV_KEY) pKbd->PostEvent(plnfo, ev.code, ev.value);
25
5.2. OVLADAČE PRO EVENT INTERFACE }
Handler PostKbdEventO provádí remapování KeyCode na XKeyCode (vnitřní forma kódu X serveru), nastavuje LED na klávesnici, zachycuje opakování kláves NumLock/CapsLock/ScrollLock. Nakonec je XKeyCode předán do funkce xf86PostKeyboardEvent(), která je už součástí X serveru. V této funkci je XKeyCode zařazen do fronty, ve které čeká na další zpracování. Z této fronty jsou vstupní data periferií vybírána 2 v idle 3 smyčce X serveru. Funkce PostKbdEventO z ovladače vtkbd
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / v t k b d / v t k b d . c řádek 736 #define KEY_KPENTER #define KEY_RIGHTCTRL #define KEY_KPSLASH
96 97 98
#define KEY_KP_Enter #define KEY_RCtrl #define KEY_KP_Divide
100 101 104
static void PostKbdEvent(InputlnfoPtr plnfo, unsigned int Lkeycode, Bool down) { .../* remapovaci tabulka (KeyCode -> ATKeyCode) */ switch(Lkeycode) { case KEY_KPENTER: Lkeycode = KEY_KP_Enter;break; case KEY_RIGHTCTRL: Lkeycode = KEY_RCtrl;break; case KEY_KPSLASH: Lkeycode = KEY_KP_Divide;break; } Xkeycode = Lkeycode + MIN_KEYCODE; /* #define MIN_KEYCODE
8 */
/* XKeyCode se odešle dal do X serveru */ xf86PostKeyboardEvent(device, Xkeycode, down); } 5.2.2 evdev
V ovladači evdev stojí za pozornost funkce EvdevReadlnputO, ve které se čtou pakety z event interface a posílají se rovnou do X serveru na základě typu periferie. Remapování KeyCode se provádí uvnitř X serveru na základě KeyMap, která je pevnou součástí evdev a je zaregistrována do X serveru při inicializaci ovladače. 2. soubor programs/Xserver/hw/xfree8 6/common/xf8 6Events.c řádek 229 3. soubor programs/Xserver/dix/dispatch.c řádek 376
26
5.2. OVLADAČE PRO EVENT INTERFACE Funkce EvdevReadlnputO z ovladače evdev
soubor p r o g r a m s / X s e r v e r / h w / x f r e e 8 6 / i n p u t / e v d e v / e v d e v . c řádek 103 s t a t i c void EvdevReadlnput(InputlnfoPtr { struct input_event ev; int len, value;
plnfo)
while (xf86WaitForInput (pInfo->fd, 0) > 0) { len = read(plnfo->fd, &ev, sizeof e v ) ; if (len != sizeof ev) { /* The kernel promises that we always only read a complete * event, so len != sizeof ev is an error. */ xf8 6Msg(X_ERROR, "Read error: %s\n", strerror(errno)) ; break; } /* Get the signed value, earlier kernels had this as unsigned */ value = ev.value; switch
(ev.type) {
case EV_KEY: switch (ev.code) { case BTN_LEFT: case BTN_RIGHT: case BTN_MIDDLE: xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 1, value, 0, 0 ) ; break; case case case case case
BTN_SIDE: BTN_EXTRA: BTN_FORWARD: BTN_BACK: BTN_TASK: xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 5, value, 0, 0 ) ; break;
default: xf8 6PostKeyboardEvent(plnfo->dev, ev.code + MIN_KEYCODE, value); } break;
27
5.3. KOMPILACE OVLADAČE
5.3
Kompilace ovladače
Nejjednodušší je stáhnout si zdrojový kód distribuce X serveru. Do příslušné části stromu zkopírovat adresář se zdrojovým kódem ovladače, zařadit jeho název do seznamu kompi lovaných ovladačů a spustit kompilaci X serveru příkazem make World. Poté co proběhne vygenerování všech M a k e f i l e , začne samotný proces kompilace. V tuto chvíli lze kompi laci celého X serveru přerušit a v příslušném adresáři si ručně zkompilovat jen potřebný ovladač. Zařazení ovladače pro event interface do konfiguračního souboru X serveru soubor c o n f i g / c f / l i n u x . c f řádek 766 #ifndef OSXInputDrivers # if HasLinuxJoystick # define OSXInputDriversl # else # define OSXInputDriversl # endif # if HasLinuxInput # define OSXInputDrivers2 # else # define OSXInputDrivers2 # endif # define OSXInputDrivers #endif
ur98 /**/
aiptek evdev vtkbd /**/ OSXInputDriversl OSXInputDrivers2
Adresář ovladače obsahuje soubor se zdrojovým kódem samotného ovladače, soubor Imake f i l e a případně další zdrojový soubor, ze kterého se vygeneruje manuálová stránka. Soubor Imake f i 1 e je v podstatě šablona pro vygenerování souboru Mak e f i 1 e, který se ge neruje na míru dle použité platformy a operačního systému. Tento soubor není příliš složitý, takže ho stačí zkopírovat z adresáře s podobným ovladačem a upravit dle vlastní potřeby. Po úspěšném proběhnutí příkazu make World v kořenovém adresáři distribuce X serveru, bude v adresáři s ovladačem jeho zkompilovaná podoba. Pokud zdrojový kód ovladače vyžaduje dodatečné změny, stačí už jen v adresáři s ovladačem spustit příkaz make. 5.4
Použití ovladače
Ovladače periferií jsou v adresáři / u s r / X H R 6 / l i b / m o d u l e s / i n p u t / , tam by také měl být zkopírován ovladač vtkbd, pokud se tak nestalo automaticky. Počítač bude startován s (primární) grafickou kartou v PCI slotu, grafická karta v AGP slotu bude použita pouze pro X server. Další instance X serveru se spustí na primární grafické kartě v PCI slotu. Počítač lze startovat i z grafické karty v AGP slotu, pak grafická karta v PCI slotu bude pro jediný 28
5.4. POUŽITÍ OVLADAČE X server, pokud je potřeba mít zároveň dostupné virtuální terminály. Virtuální terminály se svážou s jednou připojenou myší editováním souboru / e t c / s y s c o n f i g / m o u s e . Měl by se tam nastavit symlink a nebo přímo zařízení pro PS/2 myš DEVICE=/dev/ i n p u t / m o u s e l . Změna v konfiguračním souboru se uplatní takto: # /etc/init.d/gpm restart
Spustí-li se příkaz: $ startx
pak se implicitně použije konfigurační soubor / e t c / X l l / x o r g . conf a v něm první na lezená hardwarová konfigurace. Spuštění X serveru s určitou hardwarovou konfigurací se provede takto: $ startx —
-layout TNT
Spuštění X serveru navíc s jiným konfiguračním souborem: $ startx —
-layout TNT -config xorg2.conf
Spuštění druhé instance X serveru pro určitou hardwarovou konfiguraci: $ startx —
:1 -layout TRI
Obvyklé chování Po spuštění X serveru se virtuální terminál obvykle přepne na nejbližší volný terminál a VT jsou chvíli nedostupné. Poté co X server naběhne, je možné VT přepnout jeho samostat nou klávesnicí na libovolný terminál a dál normálně používat. Po ukončení běhu X serveru se virtuální terminál ihned přepne na číslo terminálu, ze kterého byla instance spuštěna. Po ukončení instance běžící na sekundární grafické kartě se X server běžící na primární kartě přepne do režimu VGA na číslo terminálu, ze kterého byla instance pro sekundární kartu spuštěna. Je proto nutné ručně zpátky přepnout na terminál s X serverem. Známé chyby/omezení
•
Stav LED po stisku NumLock/CapsLock/ScrollLock na klávesnici svázané s virtuálními terminály se propaguje do obou klávesnic, obráceně ze strany klávesnice svázané s X serverem k propagaci nedochází. Není to problém ovladače ale zatím nevyřešený problém jádra 2.6.13.
•
Simultánní běh dvou instancí X serveru je uspokojivě vyřešen pouze pokud je počítač spuštěn s grafickou kartou v PCI slotu jako primární grafickou kartou, což je doporučené použití ovladače vtkbd.
29
Kapitola 6
Užitečné tipy Nástroj pro registry - pcitweak Přivést počítač k pádu a nebo alespoň způsobit jeho divné chování do nejbližšího rebootu s pomocí tohoto nástroje není žádný problém, stačí zapsat jeden bit do nesprávného regis tru. Následně vzniklý problém obvykle vyřeší tlačítko Reset. Určitě se vyplatí před stiskem klávesyEnter důkladně zkontrolovat parametry příkazu a taktéž předchozí stav registru než ztrácet čas zbytečnýmy rebooty. Až když hardware dělá dle našich představ to co má, pak se napíše odpovídající kód do ovladače. 6.1
Pronikání do hlubin X serveru
Na procházení zdrojového kódu je vhodné použít cscope. Nezbytnou databázi lze vybudo vat v kořeni zdrojového kódu následujícím příkazem: $ c s c o p e -bqR
Editor Vim se pak spustí ve stejném adresáři jako je databáze a jako parametr se mu zadá cesta se souborem. Na procházení zdrojovým kódem se obvykle používají dobře známá makra. 6.2
Trasování X serveru
Jsou dvě možnosti jak lze sledovat vnitřní běh X serveru, každá má své přednosti a nedo statky. První způsob Předpokládá se velmi dobrá znalost jazyka C, protože v opačném případě se nejedná o nejrychlejší způsob jak zmapovat jenom určité významné části kódu v pralese ukazatelů a handlerů. Do zdrojového kódu se umístí zvláštní řádky do míst předpokládaného běhu programu, který způsobí výpis zprávy do log souboru. Výpis obsahuje název oblíbeného editoru, jako parametr je absolutní cesta k souboru a číslo řádku, protože pak už jenom stačí řádek zkopírovat z log souboru a rovnou na příkazové řádce spustit. V konfiguračním souboru pro editor Vim (. vimrc) je proto vhodné mít makro na rychlé vložení takového řádku, který se za běhu X serveru bude vypisovat do Xorg. N. l o g . Výhodou podrobného log souboru s výpisy je možnost archivace, nebo i sdílení s dalšími vývojáři. 30
6.2. TRASOVÁNÍ X SERVERU Příklad makra imap c o s i E r r o r F ( " v i =expand("%:p") + < C - R > = l i n e ( " . " ) < C R >
\n");
Řádek s výpisem je vhodné vkládat do zdrojového kódu takovým způsobem, aby ne docházelo ke změně číslování řádků stávajícího kódu. Při nedodržení tohoto pravidla dochází postupně k nekonzistenci mezi čísly řádků v pomocné databázi cscope a skutečným stavem kódu, což v rozsáhlejších souborech zdrojového kódu nakonec způsobí zmatek. Zkompi lování Xorg se provede v adresáři x c / p r o g r a m s / X s e r v e r / , protože většina úprav zdro jového kódu se týká pouze tohoto podstromu. Z důvodu rychlosti kompilace je dobré buď potlačit výpis kompilačních zpráv přesměrováním do souboru a nebo kompilaci provádět na virtuálním terminálu, protože výpisy v textovém VGA režimu jsou vždy výrazně rych lejší než v grafickém režimu X serveru a kompilace tak není zbytečně bržděna. Rekompilace samotného Xorg obvykle nezabere na mém počítači více než 20 sekund. Skript kompilující Xorg by po jeho zkopírování měl nastavit jeho SUID bit příkazem chmod u+s / u s r / X H R 6 / b i n / X o r g . Druhý způsob Výhodou je okamžité nahlédnutí pod kapotu složitého stroje. Vhodné je taktéž umístit zvláštní řádky do zdrojového kódu zapisující hodnoty do log souboru. Trasování nebo ladění se provádí vzdáleně z dalšího počítače, s použitím debuggeru gdb. Propojení se realizuje přes křížený UTP kabel. Hlavní soubor X serveru - Xorg je samozřejmě nutné přeložit s ladícími informacemi. Vzdálený přístup je nutný, protože během trasování X server neodpovídá, počítač se jeví jako zamrzlý. Od někud je ale potřeba zadávat příkazy pro gdb a sledovat jeho výpis, což na počítači se zkoumaným X serverem není možné.
31
Kapitola 7
Závěr Přínosem této bakalářské práce je ovladač klávesnice vtkbd, který jsem napsal za účelem umožnění lokálního sdílení jednoho počítače typu PC dvěma uživateli při současném za chování původní podoby zdrojového kódu X serveru. Všechny nalezené záplaty na Inter netu, které byly vytvořené za tím samým účelem nemají s mým řešením žádnou souvislost. Jednalo se spíš o povrchní prototypy, zasahující do zdrojového kódu X serveru. Neinvazivní řešení jsem naleznul zcela samostatně na základě důkladného prostudování problému, který bránil lokálnímu sdílení a získané poznatky jsem použil pro napsání speciálních částí kódu v ovladači klávesnice. Tyto části kódu ovladače klávesnice nesouvisí s klávesnicí, protože ovládají registry PCI sběrnice a také umožňují nezávislé použití virtuálních ter minálů vedle grafického rozhraní X serveru. Vymyšlení těchto relativně malých částí kódu nebylo jednoduchým úkolem, protože v tomto případě jediným mým učitelem byl spletitý zdrojový kód X serveru. Mým hlavním cílem bylo neohrozit spolehlivost počítače tak, že do krytického místa zdrojového kódu X serveru jednoduše umístím komentář, protože zamikání všech grafických karet při startu X serveru není samoúčelné. Samotný ovladač klávesnice vtkbd pro event interface vzniknul částečně na základě od laděného ovladače kbd. Od tohoto původního ovladače se ale podstatně liší vstupní částí, do které jsem umístil část kódu pro otevření samotného event interface a také remapovací tabulku převádějící KeyCode z event interface na XKeyCode posílaný do X serveru. Dále se odlišuje částí ovládající LED na klávesnici a několika řádky, které řídí exkluzivní přístup. Tento ovladač zůstane jediným řešením pro uživatele starších distribucí X serveru, protože pro vytvoření lokálního sdílení počítače stačí jenom zkopírovat ovladač a upravit konfi gurační soubory. Nejnovější distribuce X serveru X.Org X11R7 zatím neumožňuje plnohod notné lokální sdílení, protože ovladač evdev je zatím ve stavu vývoje bez možnosti přepnutí na virtuální terminály. Zdrojový kód ovladače lze po drobných úpravách zkompilovat také pro původní implementaci X serveru XFree86, ve které dosud žádný ovladač pro event in terface ani žádná možnost lokálního sdílení počítače neexistuje. Všem průkopníkům patří upřímný dík za objev samotného faktu, že je vůbec možné lokálně sdílet jeden počítač typu PC několika uživateli, přestože původní konstrukční záměr tohoto počítače něco takového nepředpokládal (např. jediný VGA paměťový prostor pouze pro jednu grafickou kartu, pouze dvě zásuvky typu PS/2 pro jedinou klávesnici a myš). Nalezení čistého způsobu implementace bylo už jen otázkou času.
32
Literatura [1]
Freitas, M.: Multiple local XFree users under Linux, 2004, h t t p : / / cambuca.ldhs.cetuc.puc-rio.br/multiuser. 1
[2]
Drake, D.: Writing
udev
rules,
http://www.reactivated.net/
w r i t i n g _ u d e v _ r u l e s . h t m l . 2.4 [3]
Manuálové stránky Linuxu: udev, udeviníb.
[4]
PCI Local Bus Specification, December 18, 1998, h t t p : / / w w w . p c i - s i g . o r g . 3.2 PCI-to-PCI Bridge Architecture Specification Revision 1.2, June 9, 2003, h t t p : / / w w w . p c i - s i g . o r g . 3.3
[5]
2.4
[6]
Li-Ta Lo, N., R. Watson, G., G. Minnich, R.: FreeVGA: Architecture Independent Video Graphics Initialization for LinuxBIOS, Los Alamos National Laboratory, NM 87545. 4
[7]
XFree86 server 4.x Design (DRAFT), December 19, 2003, h t t p : / /www. x . o r g , The XFree86 Project, Inc. 5.1
[8]
D. NealJ.: FreeVGA, 1997,1998, h t t p : //www. o s d e v e r . n e t / F r e e V G A / vga/extreg.htm.
33
Dodatek A
Optimalizace grafické karty Je obecně známo, že grafické karty pro PCI slot nepatří svým výkonem mezi 3D hvězdy. Mají obvykle aktivní chlazení, takže pokud je takových karet v počítači více, produkují nezane dbatelný hukot. Taktéž pohled na postupně se překreslující okna nebývá zrovna povzbu divý (vinou degradace výkonu karty výrobcem). Určitě stojí za to, pokusit se optimalizovat výkonnost takových karet, protože mohou skrývat významné rezervy. Například grafická karta Geforce2 MX-400 64bit 32MB SDRAM PCI, která je jako jedna z mála stále na trhu, skrývá nečekaný potenciál. Změna frekvence Výměnou kódu BIOSu byla karta proměněna z údajných 64 bitů na 128 bitů (3.11.01.26.11 -> 3.11.01.37.00). Zvýšení základní frekvence pamětí ze 143MHz na 190MHz výrazně zlepšilo rychlost překreslování oken. Snížení základní frekvence GPU z 200MHz na 120MHz výrazně nesnížilo výkon ale s klidným svědomím lze odšroubovat ventilátor z chladiče. Výsledek Korekce pracovních frekvencí způsobila celkové zvýšení výkonu z 1090 na 1310 bodů ve srovnávacím testu 3D mark 2001 přičemž grafická karta je zcela tichá. Provedení optimalizace Všechny hodnoty nastavení z původního kódu BIOSu musí být zkopírovány do nového BIOSu. Po provedení výměny BIOSu lze programem např. NVClock korigovat frekvence pamětí a grafického procesoru. Jakmile se začnou v obrazu objevovat chyby, frekvence pamětí se o několik MHz sníží. Frekvence grafického procesoru se sníží na takovou hodnotu, aby výkon karty byl ještě snesitelný. Pokud se nalezené hodnoty frekvencí ukáží jako dlouho době použitelné, zapíší se na pevno jako nové výchozí hodnoty do BIOSu grafické karty. Spatně naprogramovaný BIOS lze "jednoduše" opravit odpájením FLASH paměti z desky grafické karty a přeprogramováním v externím programátoru.
34
Dodatek B
Použitý hardware/software Hardware SDRAM 2x256MB+128MB, Intel Celeron (Tualatin) 1,1GHz, ABIT BF6 (440BX), HPT370, Matrox G200, Matrox G450, TNT2 Ultra, S3 Trio, S3 Virge, Trident TGUI 9440, Inno3D Geforce2 MX-400 PCI 32MB SDRAM, Chicony 2971, Chicony 2961, Logitech M-BT58,USB HUB Card UIH-400 (Planet). Software Fedora Core 3, jádro 2.6.13, X.Org X11R6.8.1-2, XFree86 4.4.0.
35
Dodatek C
Soubory na přiloženém CD —+ | I | | I
>doc |—>vgabios.pdf |—>design.pdf +—>PCI |—>PCI_22.pdf +—>ppbl2.pdf
| | I I I
>src |—>XFree86-4 .4.0 | |—>bp.diff | |—>vtkbd.c | +—>evdev.c
I I I I
+—>X.Org I—>bp.diff I —>vtkbd.c +—>evdev.c
I | I | I | | |
>bin |—>XllR6.8.1-2 | |—>vtkbd_drv.o | +—>evdev_drv.o I +—>XFree86-4.4.0 |—>vtkbd_drv.o +—>evdev_drv.o
| | | | I —>bp.xml +—>bp.pdf
>conf |—>20-udev.rules |—>xorg.conf +—>XF86Config
36