]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Diploma thesis text.
authorRostislav Lisovy <lisovy@gmail.com>
Sat, 23 Apr 2011 23:19:50 +0000 (01:19 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Sat, 23 Apr 2011 23:19:50 +0000 (01:19 +0200)
doc/diploma_thesis/text/dip_text.tex
doc/diploma_thesis/text/lisovy_dip.tex

index be97182b88fdb58a41ce86ae0e94ea1973995a07..a9cb9c13cf2ea77103b41e3504e470f5087d813f 100644 (file)
@@ -3,6 +3,7 @@
 % \item[] a \item s tečkou na konci
 % odsazování zdrojaku ve verbatim: __X_|__  nebo jen __
 % Popisy obrázků bez tečky (i s více větami)
+% Funkce v \ibox{} na konci se středníkem
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Úvod}
@@ -16,7 +17,7 @@ Jako ukázková zařízení na sběrnici PCI byly zvoleny karty Humusoft MF624 a
   
 Výsledkem práce by měly být, kromě popisu vývoje PCI ovladačů, i ovladače typu UIO a Comedi podporující základní funkce (A/D, D/A převodníky a digitální vstupy a výstupy) karet Humusoft MF614 a MF624, které by mohly posloužit jako jednoduché ukázkové ovla\-dače.
 
-Pro maximální možné zhodnocení návodů je cílem práce implementovat některé funkce karty Humusoft MF624 do emulačního programu Qemu tak, aby bylo možné popsané postupy implementace ovladačů vyzkoušet i bez fyzického přístupu ke kartě. (FIXME)
+Pro maximální možné zhodnocení návodů, je cílem práce implementovat některé funkce karty Humusoft MF624 do emulačního programu Qemu tak, aby bylo možné popsané postupy implementace ovladačů vyzkoušet i bez fyzického přístupu ke kartě.
 
 \section{Dostupné materiály}
 V českém jazyce dosud vyšla pouze jedna tištěná kniha, která se zabývá problematikou programování v prostředí jádra Linux. Jedná se o knihu Jádro systému Linux \cite{jadrosystemu} od Lukáše Jelínka. Je dělena do 3 základních částí:
@@ -26,7 +27,7 @@ V českém jazyce dosud vyšla pouze jedna tištěná kniha, která se zabývá
 \item \textit{Pohled dovnitř jádra}
 \end{itemize}
 
-Jednotlivá témata jsou popsána pouze stručně (kniha je koncipována spíše jako příručka než jako učebnice) a pro studenta, neznalého vývoje jaderných ovladačů zařízení nemá příliš velký přínos.
+Jednotlivá témata jsou popsána pouze stručně (kniha je koncipována spíše jako příručka než jako učebnice) a pro čtenáře, neznalého vývoje ovladačů zařízení, nemá příliš velký přínos.
 
 Za nejpřínosnější knihu, zabývající se problematikou jaderného programování, považuji anglicky psanou knihu Linux Device Drivers \cite{devicedriver} od autorů Jonathan Corbet, Alessandro Rubini a Greg Kroah-Hartman. Tato kniha podrobně vysvětluje jak obecné principy a funkce používané u jaderných ovladačů, tak i způsob implementace ovladačů zařízení konkrétních typů.
 
@@ -55,13 +56,13 @@ Jak je možné ovládat hardwarové periferie pomocí programu (software) je nej
 
 \ibox{Mikrokontrolér, neboli jednočipový počítač, má velikost pouze jednoho čipu. Obsahuje přitom procesor, paměť, vstupně-výstupní zařízení a jiné. Je obvyklé, aby mikrokontrolér obsahoval tzv. GPIO piny. 
 \begin{description}
-\item[GPIO piny (General Purpose Input/Output)] -- u těchto pinů je možné nastavit, zda má být jejich hodnota čtena (slouží jako vstupní piny -- skrze ně vstupuje informace) nebo zda chceme jejich hodnotu nastavovat (tj. výstupní piny).%
+\item[GPIO piny (General Purpose Input/Output)] -- u těchto pinů je možné nastavit, zda má být jejich hodnota čtena (slouží jako piny pro vstup informace) nebo zda má být jejich hodnota nastavována (tj. výstupní piny).%
 %\item[A/D převodník] -- Převádí analogový (spojitý) signál na diskrétní (nespojitý). Příklad: Na vstup A/D převodníku přivedeme napětí 2,4 V. Z registru odpovídajícímu tomuto převodníku si v digitální podobě mikroprocesor vyčte hodnotu odpovídající 2,4.
 %\item[D/A převodník] -- Opačně od A/D převodníku převádí digitální signál na analogový. Příklad: Do registru odpovídajícímu D/A převodníku zapíše mikroprocesor hodnotu odpovídající např. 3,5 V. Na výstupu bude možné změřit napětí 3,5 V (s určitou malou odchylkou).
 \end{description}%
 }
 
-Prvním způsobem, jak změnit stav GPIO pinu (ať už nastavení, zda se má jednat o~vstupní/výstupní pin nebo jakou hodnotu má mít v případě, že je výstupní) je provedení operace zápisu na určitou adresu v paměťovém adresním prostoru (ta je pevně daná a liší mezi jednotlivými architekturami mikrokontrolérů), tato adresa odpovídá \textbf{registru}\footnote{Registr může být pro zjednodušení považován za malou paměťovou buňku. Změna její hodnoty přímo ovlivňuje stav hardware. V dokumentaci ke konkrétnímu mikrokontroléru/\-mikroprocesoru/\-programovatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Vnitřní uspořádání mikrokontroléru, dle adresy na kterou bylo zapisováno, rozpozná, že provedená operace zápisu nebyla určena pro změnu hodnoty vnitřní paměti, ale je určena pro změnu hodnoty registru a z toho plynoucí změny stavu určité části hardwaru. Zapsaná hodnota se tedy projeví změnou stavu GPIO pinu. Tato možnost je nejjednodušší a je možná v případě, že jsou hardwarové periferie mapovány do určité části tzv. \textbf{paměťového prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
+Prvním způsobem, jak změnit stav (obecného) GPIO pinu (ať už nastavení, zda se má jednat o~vstupní/výstupní pin nebo jakou hodnotu má mít v případě, že je výstupní) je provedení operace zápisu na určitou adresu v paměťovém adresním prostoru (ta je pevně daná a liší mezi jednotlivými architekturami mikrokontrolérů), tato adresa odpovídá \textbf{registru}\footnote{Registr může být pro zjednodušení považován za malou paměťovou buňku. Změna její hodnoty přímo ovlivňuje stav hardware. V dokumentaci ke konkrétnímu mikrokontroléru/mikroprocesoru/programo\-vatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Vnitřní uspořádání mikrokontroléru, dle adresy na kterou bylo zapisováno, rozpozná, že provedená operace zápisu nebyla určena pro změnu hodnoty vnitřní paměti, ale je určena pro změnu hodnoty registru a z toho plynoucí změny stavu určité části hardwaru. Zapsaná hodnota se tedy projeví změnou stavu GPIO pinu. Tato možnost je nejjednodušší a je možná v případě, že jsou hardwarové periferie mapovány do určité části tzv. \textbf{paměťového adresního prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
 
 \begin{figure}[h!]
        \begin{center}
@@ -72,22 +73,22 @@ Prvním způsobem, jak změnit stav GPIO pinu (ať už nastavení, zda se má je
 \end{figure}
 
 
-Jiným způsobem změny stavu registru je použití jiné instrukce než která se používá pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO registr, se provede zápis do tzv. \textbf{vstupně-výstupního prostoru}\footnote{Také označován zkratkou PIO -- \textit{Programmed input/output} nebo jako I/O adresní prostor} na adresu (v tomto případě označovanou jako \textbf{port}) odpovídající registru GPIO pinů. Adresy paměťového a~vstupně-výstupního prostoru spolu nijak nesouvisí. V případě zápisu a čtení do/z portu I/O adresního prostoru je potřeba z dokumentace \textbf{přesně vědět} jak široká (kolikabitová) slova je možné zapisovat/číst. 
+Jiným způsobem změny stavu registru je použití jiné instrukce než která se používá pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO registr, se provede zápis do tzv. \textbf{vstupně-výstupního adresního prostoru}\footnote{Také označován zkratkou PIO -- \textit{Programmed input/output} nebo jako I/O adresní prostor} na adresu (v~tomto případě označovanou jako \textbf{port}) odpovídající registru GPIO pinů. Adresy paměťového a~vstupně-výstupního prostoru spolu nijak nesouvisí. V případě zápisu a čtení do/z portu I/O adresního prostoru je potřeba z dokumentace \textbf{přesně vědět} jak široká (kolikabitová) slova je možné zapisovat/číst. 
 
-\ibox{V případě architektury IA-32 (označované také jako x86) máme k dispozici paměťový a vstupně-výstupní adresní prostor. Vstupně výstupní adresní prostor je pouze 16bitový, zatímco paměťový je (\textit{pro zjednodušení nebereme ohled na PAE -- Physical Address Extension}) 32bitový. Toto rozdělení přetrvává z historických důvodů -- i~přesto je již možné některá zařízení mapovat do paměťového prostoru. (Znázorněno na obrázku \ref{mmio}.)}
+\ibox{V případě architektury IA-32 (označované také jako x86) máme k dispozici paměťový a vstupně-výstupní adresní prostor. Vstupně výstupní adresní prostor je pouze 16bitový, zatímco paměťový je (\textit{pro zjednodušení není brán ohled na PAE -- Physical Address Extension}) 32bitový. Toto rozdělení přetrvává z historických důvodů -- i~přesto je již možné některá zařízení mapovat do paměťového prostoru. (Znázorněno na obrázku \ref{mmio}.)}
 
 Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \begin{itemize}
 \item Změnou hodnoty registru je možné měnit stav zařízení/periferie odpovídající danému registru.
 \item V případě zápisu do registru a jeho okamžitém čtení, nemusí být přečtená hodnota shodná se zapisovanou -- v tom případě byla hodnota registru změněna hardwarem.
-\item V případě čtení z registru může být spuštěn tzv. \textbf{side effect}, kdy hardware na toto čtení reaguje změnou stavu, podobně jako by byl proveden zápis do registru (Příklad: Ihned po vyčtení hodnoty registru A/D převodníku se spustí nový převod a původní hodnota se přepíše novou). Side effects mohou nastat i při zápisu do registru. 
+\item V případě čtení z registru může být spuštěn tzv. \textbf{side effect}, kdy hardware na toto čtení reaguje změnou stavu, podobně jako by byl proveden zápis do registru (Příklad: ihned po vyčtení hodnoty registru A/D převodníku se spustí nový převod a původní hodnota se přepíše novou). Side effects mohou nastat i při zápisu do registru. 
 \item Při zápisu a čtení do/z registru si je nutné přesně rozlišovat, kolika-bitové operace zápisu/čtení smějí být použity (8-, 16-, 32bitové).
 \end{itemize}
 
 \begin{figure}[h!]
        \begin{center}
        \includegraphics[width=100mm]{img/mmio.pdf}
-       \caption{Paměťový a vstupně-výstupní prostor u architektury IA-32}
+       \caption{Paměťový a vstupně-výstupní adresní prostor u architektury IA-32}
        \label{mmio}
        \end{center}
 \end{figure}
@@ -98,7 +99,7 @@ Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \section{PCI sběrnice}\label{pcich}
 %Přesný popis PCI sběrnice je mimo rozsah a zaměření této práce. Pokusím se však zmínit a názorně vysvětlit principy využívané touto sběrnicí, které je nutné alespoň částečně znát při implementaci ovladačů PCI zařízení.
 
-PCI (\textit{Peripheral Component Interconnect}) je standard paralelní sběrnice využívaný v~počí\-ta\-čích různých architektur. Šířka paralelně přenášených dat je 32 nebo v modernější, méně často používané verzi, 64 bitů. Sběrnice je orientována na přenos zpráv oproti přímé komunikaci mezi zařízeními.\footnote{T.j. místo toho, aby PCI most přistupoval přímo k paměti jednotlivých zařízení, vyšle se na sběrnici zpráva s požadavkem. V případě, že je zařízení schopno požadavek obsloužit, umístí na datovou sběrnici požadovaná data.}
+PCI (\textit{Peripheral Component Interconnect}) je standard paralelní sběrnice využívaný v~počí\-ta\-čích různých architektur. Šířka paralelně přenášených dat je 32 nebo v modernější, méně často používané verzi, 64 bitů. Sběrnice je orientována na přenos zpráv oproti přímé komunikaci mezi zařízeními.\footnote{Tj. místo toho, aby PCI most přistupoval přímo k paměti jednotlivých zařízení, vyšle se na sběrnici zpráva s požadavkem. V případě, že je některé zařízení schopno požadavek obsloužit, umístí na datovou sběrnici požadovaná data.}
 
 Komunikace mezi zařízeními připojenými na sběrnici a procesorem zajišťuje tzv. \textit{PCI most} (PCI bridge). Propojení více nezávislých sběrnic v jednom počítači jsou zajištěny také PCI mosty.
 
@@ -107,7 +108,7 @@ V roce 1990 začala práce na specifikaci PCI v laboratořích firmy Intel. Prvn
 
 V pozdějších letech se původní standard dočkal vylepšení -- zvýšení šířky paralelní sběrnice z 32 bitů na 64 bitů a zrychlení z 33 MHz na 66 Mhz a výše. Tyto pokročilejší verze se však příliš neujaly.
 \subsection{Konektory}
-Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sběrnice -- tzv. slot. V závislosti na napájecím napětí (3,3 V nebo 5 V) jsou na kartách klíčovací zářezy -- tyto zářezy znemožňují zasunutí \textit{napěťově} nekompatibilní karty do slotu. Jsou však karty, které mají tyto zářezy oba, díky čemuž může být karta použita v libovolném slotu (obr. \ref{pci}).
+Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sběrnice -- tzv. slot. V závislosti na napájecím napětí (3,3 V nebo 5 V) jsou na kartách \textit{klíčovací} zářezy -- tyto zářezy znemožňují zasunutí \textit{napěťově nekompatibilní} karty do slotu. Existují však univerzální karty, které mají tyto zářezy oba, díky čemuž mohou být použity v libovolném slotu (obr. \ref{pci}).
 
 \begin{figure}[h!]
        \begin{center}
@@ -124,7 +125,7 @@ Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sbě
 
 
 \subsection{Dynamická konfigurace a konfigurační adresní prostor}\label{pci_conf}
-Mezi hlavní výhody PCI sběrnice (oproti její předchůdkyni -- sběrnici ISA) patří dynamická konfigurace připojených zařízení: Ve většině případů probíhá komunikace mezi hostitelským systémem a připojenou (a nakonfigurovanou) PCI kartou zápisem/čtením do určité paměťové (nebo vstupně-výstupní) oblasti. U starší sběrnice ISA si každá karta pevně určila, kam se její část paměti namapuje -- v takovém případě mohl nastat problém, že více než jedna karta mapovala svoji paměť na stejnou adresu (nebo se jednotlivá mapování překrývala). PCI sběrnice tomuto problému předchází takovým způsobem, že každá z karet nese informaci o~tom, kolik jak velkých paměťových nebo I/O regionů potřebuje namapovat -- o samotné mapování se poté postará PCI most.
+Mezi hlavní výhody PCI sběrnice (oproti její předchůdkyni -- sběrnici ISA) patří dynamická konfigurace připojených zařízení: Ve většině případů probíhá komunikace mezi hostitelským systémem a připojenou (a nakonfigurovanou) PCI kartou zápisem/čtením do určité paměťové (nebo vstupně-výstupní) oblasti. U starší sběrnice ISA si každá karta pevně určila, kam se její část paměti namapuje -- v takovém případě mohl nastat problém, že více než jedna karta mapovala svoji paměť na stejnou adresu (nebo se jednotlivá mapování překrývala). PCI sběrnice tomuto problému předchází takovým způsobem, že každá z karet nese informaci o~tom, kolik jak velkých paměťových nebo I/O regionů potřebuje namapovat -- o samotné mapování se poté dynamicky postará PCI most.
 
 Informaci o tom, kolik (a jaké) paměti karta bude potřebovat má před nakonfigurováním uloženu v tzv. \textbf{Base Address Registrech} -- BAR0--BAR5\footnote{Informace o velikosti požadované oblasti je v registru uložena takovým způsobem, že je pouze jeho část určena k zápisu a zbytek je pouze pro čtení. PCI most se pokusí do registru zapsat hodnotu 0xFFFFFFFF, poté je hodnota zpět vyčtena -- z bitů náležejících do zapisovatelné části registru, je přečtena $1_2$, zbývající část obsahuje hodnoty $0_2$.}. Poté co se PCI mostu podaří tuto hodnotu přečíst a požadovanou paměť alokovat, zapíše zpět do daného registru adresu, na které se alokovaná paměť nachází. Tu si poté pro potřeby komunikace vyčte ovladač zařízení, který je součástí operačního systému.
 
@@ -134,26 +135,26 @@ Kromě výše zmíněných 6 BAR registrů, obsahují PCI zařízení i následu
 \item[Vendor ID]~\\Obsahuje unikátní 16bitové číslo identifikující výrobce zařízení. Za poplatek je udělo\-váno PCI-SIG (\textit{PCI Special Interest Group}) organizací.\footnote{V Debianu, po nainstalování balíčku \texttt{hwdata}, se seznam těchto identifikátorů nachází v souboru \texttt{/usr/share/hwdata/pci.ids}}
 \item[Device ID]~\\Obsahuje 16bitové číslo identifikující model zařízení. Hodnotu tohoto identifikátoru si volí sám výrobce zařízení.
 \item[Class code]~\\Označuje (ve 24 bitech) druh zařízení -- zda se jedná např. o grafickou kartu, zvukovou kartu nebo kartu zpracovávající signál.
-\item[Subsystem Vendor ID] -- Podobá se \texttt{Vendor ID}. V případě, že karta využívá PCI řadič třetí strany, jako \texttt{Vendor ID} se zobrazí ID výrobce tohoto řadiče. Aby bylo možné zařízení odlišit od jiného, které využívá stejný řadič, skutečné ID zařízení bude uloženo v tomto registru.
-\item[Subsystem ID]~\\Opět se jedná o údaj podobný \texttt{Device ID} sloužící k rozlišení karet postavených na univerzálním řadiči.
+\item[Subsystem Vendor ID]~\\Podobá se Vendor ID. V případě, že karta využívá PCI řadič třetí strany, jako Vendor ID se zobrazí ID výrobce tohoto řadiče. Aby bylo možné zařízení odlišit od jiného, které využívá stejný řadič, skutečné ID zařízení bude uloženo v tomto registru.
+\item[Subsystem ID]~\\Opět se jedná o údaj podobný Device ID sloužící k rozlišení karet postavených na univerzálním řadiči.
 \end{description}
 
-Registry \texttt{Vendor ID}, \texttt{Device ID} (příp. ještě \texttt{Subsystem Vendor ID} a \texttt{Subsystem ID}) slouží operačnímu systému k jednoznačné identifikaci zařízení, při volbě správného ovladače.
+Registry Vendor ID, Device ID (příp. ještě Subsystem Vendor ID a Subsystem ID) slouží operačnímu systému k jednoznačné identifikaci zařízení, při volbě správného ovladače.
 
 
 \begin{figure}[h!]
        \begin{center}
-       \includegraphics[width=80mm]{img/pci-config-space2.pdf}
-       \caption{Obsah 256 bajtů konfiguračního prostoru PCI karty (zvýrazněny jsou nejdůležitější registry)}
+       \includegraphics[width=100mm]{img/pci-config-space2.pdf}
+       \caption{Obsah 256 bajtů konfiguračního prostoru PCI karty (zvýrazněny jsou nejdůle\-žitější registry)}
        \label{sa1}
        \end{center}
 \end{figure}
 
-Výše popsané registry (spolu s ostatními, které zde nebyly popsány) se nacházejí v~256bito\-vém tzv. \textbf{konfiguračním adresním prostoru} karty\footnote{Po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor.}. Přístup do konfiguračního adresního prostoru je na architektuře IA-32 možný pomocí zapsání adresy (\textit{kam má být v~konfiguračním prostoru zapisováno}) a dat (\textit{která mají být do konfiguračního prostoru zapsána}) do dvou speciálních I/O portů, které jsou pro tuto operaci vyhrazeny.
+Výše popsané registry (spolu s ostatními, které zde nebyly popsány) se nacházejí v~256bito\-vém tzv. \textbf{konfiguračním adresním prostoru} karty (obr. \ref{sa1}).\footnote{Po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor.} Pro \textit{konfigurační} adresní prostor není hardwarová podpora v téměř žádné procesorové architektuře -- přístup do něj je například na architektuře IA-32 možný pomocí zapsání adresy (\textit{kam má být v~konfiguračním prostoru zapisováno}) a dat (\textit{která mají být do konfiguračního prostoru zapsána}) do dvou speciálních I/O portů, které jsou pro tuto operaci vyhrazeny.
 
 
 \subsection{Přerušení}
-Sběrnice PCI obsahuje čtyři linky přerušení a všechny z nich jsou dostupné každému zařízení. Přerušení mohou být sdílená, tudíž o jedno přerušení se může dělit více zařízení. Pro snazší sdílení přerušení jsou úrovňově spouštěná (oproti hranovému spouštění nedochází k promeškání přerušení).
+Sběrnice PCI obsahuje čtyři linky přerušení a všechny z nich jsou dostupné každému zařízení. Přerušení mohou být sdílená, tudíž o jedno přerušení se může dělit více zařízení. Pro snazší sdílení, jsou přerušení úrovňově spouštěná (oproti hranovému spouštění nedochází k promeškání přerušení).
 
 V pozdějších revizích PCI specifikací je přidána podpora pro přerušení signalizované zprávou. V tomto případě zařízení oznamuje svůj požadavek na obsloužení zápisem do paměti PCI mostu -- ten poté tento požadavak směruje dále k procesoru.
 
@@ -176,7 +177,7 @@ Měřící karta Humusoft MF624 (obr. \ref{mf624}), připojitelná k počítači
 \item Je možné si ověřit správnou funkci napsaného ovladače -- např. připojením LED diody k digitálnímu výstupu nebo měřením napětí na výstupu D/A převodníku.
 \end{itemize}
 
-Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, když je potřeba vytvořit styk mezi počítačem a senzorem/jiným zařízením, které poskytuje analogový, resp. digitální signál (v tom případě jsou použity A/D převodníky, resp. digitální vstupy). Kartu je možné použít pro řízení akčního členu/zařízení -- k dispozici jsou D/A převodníky a digitální výstupy.
+Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, když je potřeba vytvořit styk mezi počítačem a senzorem/jiným zařízením, které poskytuje analogový, resp. digitální signál (v tom případě jsou použity A/D převodníky, resp. digitální vstupy). Kartu je možné použít pro řízení akčního členu/zařízení -- k dispozici jsou D/A převodníky a digitální výstupy.
 
 Karta disponuje následujícícmi funkcemi (v popisu implementace ovladačů se omezím pouze na A/D, D/A převodníky a digitální vstupy/výstupy):
 \begin{itemize}
@@ -195,9 +196,9 @@ Komunikace s kartou není nijak složitá -- zjednodušeně by se dala popsat n
 \item V případě čtení hodnoty A/D převodníku, se nejprve zapíše do konfiguračního registru A/D převodníku hodnota odpovídající požadované konfiguraci. Poté se již z registru náležícího A/D převodníku vyčte požadovaná hodnota.
 \end{itemize}
 
-Které registry karta obsahuje, jakou mají funkci a kde jsou umístěny je možné zjistit z manuálu ke kartě -- ten je možné stáhnout z oficiálních internetových stránek výrobce: \url{http://www2.humusoft.cz/www/datacq/manuals/mf624um.pdf}.
+Které registry karta obsahuje, jakou mají funkci a na jakých adresách jsou umístěny je možné zjistit z oficiálního manuálu ke kartě -- ten je možné stáhnout z internetových stránek výrobce: \url{http://www2.humusoft.cz/www/datacq/manuals/mf624um.pdf}.
 
-Na straně 11 je k vidění první důležitá tabulka (zde tab. \ref{tab_bar}):
+Po jeho otevření je na straně 11 k vidění první důležitá tabulka (zde tab. \ref{tab_bar}):
 
 \begin{table}[h!]
        \begin{center}
@@ -213,10 +214,11 @@ Na straně 11 je k vidění první důležitá tabulka (zde tab. \ref{tab_bar}):
        \end{center}
 \end{table}
 
-Z ní je patrné, že karta využívá 3 regiony\footnote{V manuálu je uvedeno, že se jedná o regiony odpovídající BAR0, BAR1 a BAR2 registrům -- na počítačích s procesorem rodiny IA-32 a s operačním systémem GNU/Linux však karta využívá BAR0, BAR2 a BAR4. Důvod rozdílu mezi skutečností a manuálem není jasný. Na tuto skutečnost se musí při implementaci ovladače brát zřetel.} mapované do paměťového adresního prostoru -- o velikostech 32, 128 a 128 bajtů. Pro čtení/zápis z/do nich je potřeba používat 32-, 16-, 32bitové operace\footnote{V manuálu je uvedeno, že za určitých podmínek je možné k BAR1 přistupovat i pomocí 32bitových operací. V této práci bych se tomuto složitějšímu přístupu rád vyhnul. Částečná implementace karty MF624 do emulátoru Qemu (Popsaná v příloze \ref{qemu}) umožňuje \textbf{pouze} 16bitový přístup do BAR1 paměťového regionu.}
+Z ní je patrné, že karta využívá 3 regiony\footnote{V manuálu je uvedeno, že se jedná o regiony odpovídající BAR0, BAR1 a BAR2 registrům -- na počítačích s procesory rodiny IA-32 a s operačním systémem GNU/Linux však karta využívá BAR0, BAR2 a BAR4. Důvod rozdílu mezi skutečností a manuálem není jasný. Skutečné použití BAR registrů musí být před implementací ovladače zkontrolováno na konkrétním systému.} mapované do paměťového adresního prostoru -- o velikostech 32, 128 a 128 bajtů. \\
+Pro čtení/zápis z/do nich je potřeba používat 32-, 16- a 32bitové operace.\footnote{V manuálu je uvedeno, že za určitých podmínek je možné k BAR1 přistupovat i pomocí 32bitových operací. V této práci bych se tomuto složitějšímu přístupu raději vyhnul. Částečná implementace karty MF624 do emulátoru Qemu (popsaná v kapitole \ref{qemu}) umožňuje \textbf{pouze} 16bitový přístup do BAR1 paměťového regionu.}
 
 \subsection{Digitální vstupy a výstupy}
-Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digitální vstupy a výstupy leží v regionu BAR1 (sloupec 2). Dále je potřeba se podívat na přehled registrů náležejících tomuto paměťovému regionu (v oficiálním manuálu na straně 12) -- tomu odpovídá tabulka (s menšími úpravami) \ref{tab_bar1}.
+Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digitální vstupy a výstupy leží v regionu BAR1 (sloupec 2). Dále je potřeba se podívat na přehled registrů náležejících tomuto paměťovému regionu -- tomu odpovídá tabulka (s menšími úpravami) \ref{tab_bar1}.
 
 \begin{table}[h!]
        \begin{center}
@@ -246,7 +248,7 @@ Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digit
        \end{center}
 \end{table}
 
-Na devátém řádku jsou zmíněny \texttt{DIN} (Digital input) a \texttt{DOUT} (Digital output) registry. Z~této tabulky je patrná pozice těchto registrů v paměťovém prostoru (t.j. offset v bytech vůči adrese BAR1).
+Na devátém řádku jsou zmíněny \texttt{DIN} (Digital input) a \texttt{DOUT} (Digital output) registry. Z~této tabulky je zřejmá pozice těchto registrů v paměťovém prostoru (tj. offset v bytech vůči adrese BAR1).
 
 Jak jsou data v registrech reprezentována, je možné si přečíst (v oficiálním manuálu) na straně 16, kde jsou tyto dva registry podrobně popsány (zde tabulka \ref{tab_din} a \ref{tab_dout}). 
 První sloupec určuje, kterých bitů se daný řádek týká. V druhém sloupci je informace o funkci. Třetí sloupec udává výchozí hodnotu. Z toho, co je v tabulkách uvedeno, plyne, že pro čtení 8bitového digitálního vstupu stačí přečíst spodních 8 bitů DIN registru, horních 8 bitů je potřeba ignorovat. Stejně tak pro nastavení 8bitového digitálního výstupu se zapíše požadovaná hodnota do spodních 8 bitů registru DOUT, horních 8 bitů je potřeba ignorovat.
@@ -279,13 +281,13 @@ První sloupec určuje, kterých bitů se daný řádek týká. V druhém sloupc
 
 
 \subsection{A/D převodníky}
-Karta MF624 obsahuje osm 14bitových A/D převodníků s pevně stanoveným rozsahem $\pm$10 V. Jejich vyčtení může probíhat následujícím způsobem:
+Karta MF624 obsahuje osm 14bitových A/D převodníků s pevně stanoveným měřeným rozsahem $\pm$10 V. Jejich vyčtení může probíhat následujícím způsobem:
 
 \begin{itemize}
 \item Nejprve se v registru ADCTRL zvolí, které A/D převodníky mají být čteny. 
 Každý z~A/D převodníků je reprezentován jedním bitem. Zápisem 1 do daného bitu se nastaví, že bude daný A/D převodník aktivní -- 0 ho deaktivuje. Je možné zvolit více než jeden A/D převodník.
 \item Čtením registru ADSTART se spustí převod na zvolených A/D převod\-nících. Přečtená hodnota se dále nepoužívá.
-\item V případě, že se provedl převod na všech zvolených A/D převodnících, je EOLC bit (17. bit) GPIOC registru nastaven na 0 (jinak je v 1).
+\item V případě, že se úspěšně provedl převod na všech zvolených A/D převodnících, je EOLC bit (17. bit) GPIOC registru nastaven na 0 (jinak je v 1).
 \item Výslednou hodnotu je možné přečíst z registru ADDATA, který je typu FIFO. To znamená, že opětovným čtením jednoho registru jsou vyčítány jednotlivé naměřené hodnoty z měřených A/D převodníků v pořadí od 0 do 7.
 
 Jinou možností je místo čtení registru ADDATA číst některý z jeho \textit{zrcadlených registrů} (celkem je jich 7, v manuálu jsou označeny jako \textit{BADR1 + 0x02} až \textit{BADR1 + 0x0E}). Tyto registry se chovají \textbf{zcela stejně} jako registr ADDATA, pouze leží na jiných adresách. Příklad: pokud byly aktivovány první čtyři A/D převodníky, po převodu je možné výslednou hodnotu vyčíst opakovaným čtením registru ADDATA nebo čtením registru ADDATA, ADDATA1, ADDATA2, ADDATA3 přesně v tomto pořadí. Čtení z registrů v jiném pořadí bude stále vracet hodnoty převodníků 0--4.
@@ -294,6 +296,18 @@ Jinou možností je místo čtení registru ADDATA číst některý z jeho \text
 Hodnota vyčtená z A/D převodníků je ve formátu dvojkového doplňku -- příklad konkrét\-ních hodnot je v tabulce \ref{tab_adval}.
 
 
+\subsection{D/A převodníky}
+Karta MF624 obsahuje také osm 14bitových D/A převodníků s rozsahem $\pm$10 V.
+
+Nastavení výstupních hodnot D/A převodníků může probíhat následujícím způsobem:
+
+\begin{itemize}
+\item Hodnota v aditivním kódu (tabulka \ref{tab_daval}) se zapíše do jednoho z osmi registrů DA0--DA7 odpovídajícího D/A převodníku, který má být nastaven.
+\item Bit DACEN (26. bit) registru GPIOC je potřeba nastavit na 1, jinak jsou výstupy D/A převodníků připojeny na \textit{zem}.
+\item Bit LDAC (23. bit) registru GPIOC je potřeba nastavit na 0, aby byl spuštěn samotný převod D/A převodníků (jinak zůstane zapsaná hodnota pouze v registru, výstupní hodnota D/A převodníku zůstane nezměněna).
+\end{itemize}
+
+
 \begin{table}[h!]
        \begin{center}
        \begin{tabular}{|c|c|}
@@ -309,17 +323,6 @@ Hodnota vyčtená z A/D převodníků je ve formátu dvojkového doplňku -- př
        \end{center}
 \end{table}
 
-\subsection{D/A převodníky}
-Karta MF624 obsahuje také osm 14bitových D/A převodníků s rozsahem $\pm$10 V.
-
-Nastavení výstupních hodnot D/A převodníků může probíhat následujícím způsobem:
-
-\begin{itemize}
-\item Hodnota v aditivním kódu (tabulka \ref{tab_daval}) se zapíše do jednoho z osmi registrů DA0--DA7 odpovídajícího D/A převodníku, který má být nastaven.
-\item Bit DACEN (26. bit) registru GPIOC je potřeba nastavit na 1, jinak jsou výstupy D/A převodníků připojeny na \textit{zem}.
-\item Bit LDAC (23. bit) registru GPIOC je potřeba nastavit na 0, aby byl spuštěn samotný převod D/A převodníků (jinak zůstane zapsaná hodnota pouze v registru, výstupní hodnota D/A převodníku zůstane nezměněna).
-\end{itemize}
-
 
 \begin{table}[h!]
        \begin{center}
@@ -420,12 +423,12 @@ Jednotlivé registry v těchto regionech jsou 8bitové, proto je potřeba při 
 \end{verbatim}
 
 \subsection{Digitální vstupy a výstupy}
-Pro nastavení hodnoty digitálních výstupů se zapíše požadovaná hodnota do registru DOUT, kde jeden bit odpovídá jednomu digitálnímu výstupu. Pro čtení digitálních vstupů je potřeba přečíst registr DIN.
+Pro nastavení hodnoty digitálních výstupů se zapíše požadovaná hodnota do registru DOUT, kde jeden bit odpovídá jednomu digitálnímu výstupu. Pro čtení digitálních vstupů je potřeba přečíst hodnotu registru DIN.
 
 \subsection{A/D převodníky}
 Čtení A/D převodníků je u karty MF614 oproti MF624 trochu složitější, hlavně díky tomu, že je u převodníků potřeba nastavit, v jakém rozsahu bude provedeno měření. Je možné vybírat mezi rozsahy -10--10 V, -5--5 V, 0--10 V, 0--5 V. 
 
-K nastavení vlastností A/D převodníků slouží registr ADCTRL (přeložená tab. \ref{tab_mf614_adctrl}). Bity 2:0 slouží k volbě jednoho z osmi A/D převodníků, které budou při příštím měření použity. Dekadická hodnota určující pořadí A/D převodníku je uložena ve třech bitech jako binární číslo (t.j. $0_{10} = 000_{2}$, $1_{10} = 001_{2}$, $2_{10} = 010_{2}$, $3_{10} = 011_{2}$, $4_{10} = 100_{2}$, \ldots). 
+K nastavení vlastností A/D převodníků slouží registr ADCTRL (přeložená tab. \ref{tab_mf614_adctrl}). Bity 2:0 slouží k volbě jednoho z osmi A/D převodníků, které budou při příštím měření použity. Dekadická hodnota určující pořadí A/D převodníku je uložena ve třech bitech jako binární číslo (tj. $0_{10} = 000_{2}$, $1_{10} = 001_{2}$, $2_{10} = 010_{2}$, $3_{10} = 011_{2}$, $4_{10} = 100_{2}$, \ldots). 
 
 Bity 3 a 4 slouží k nastavení použitého rozsahu (způsob nastavení viz tabulka \ref{tab_mf614_rng}).
 
@@ -468,8 +471,8 @@ Vyčtení hodnoty A/D převodníku může probíhat následujícím způsobem:
 \begin{itemize}
 \item Nejprve se v registru ADCRTL zvolí, který A/D převodník bude čten a který měřící rozsah bude použit.
 \item Zápis do registru ADCTRL automaticky spouští převod.
-\item Je-li CC bit (2. bit) registru STAT nastaven na 0, převod již byl ukončen.
-\item Data je poté možné přečíst z registru ADLO a ADHI -- jedná se o 8bitové registry, které je potřeba pro získání 12 bitové výsledné hodnoty \textit{složit} dohromady. Je-li nastaven unipolární rozsah měření (t.j. 0--5 V nebo 0--10 V) je měřená hodnota kódována jako binární číslo. V případě bipolárního rozsahu je hodnota kódována pomocí dvojkového doplňku.
+\item Je-li CC bit (2. bit) registru STATUS nastaven na 0, převod již byl ukončen.
+\item Data je poté možné přečíst z registru ADLO a ADHI -- jedná se o 8bitové registry, které je potřeba pro získání 12 bitové výsledné hodnoty \textit{složit} dohromady. Je-li nastaven unipolární rozsah měření (tj. 0--5 V nebo 0--10 V) je měřená hodnota kódována jako binární číslo. V případě bipolárního rozsahu je hodnota kódována pomocí dvojkového doplňku.
 \end{itemize}
 
 \subsection{D/A převodníky}
@@ -477,7 +480,7 @@ Karta MF614 obsahuje 4 D/A převodníky. Ty mají pevně nastavený výstupní r
 
 Nastavení výstupu D/A převodníků může probíhat následujícím způsobem:
 \begin{itemize}
-\item Do registru DA$x$LO a DA$x$HI (kde $x$ může nabývat hodnot 0, 1, 2, 3 a určuje, ke kterému D/A převodníku registr patří) se zapíše hodnota k převodu. 12bitová hodnota je do 8bitových registrů rozdělena takovým způsobem, že 8 LSB je zapsáno do DA$x$LO a zbývající čtyři jsou zapsány do DA$x$HI na 4 nejnižší bity, nepoužité 4 MSB registru DA$x$HI jsou vyplněny nulami.
+\item Do registru DA$x$LO a DA$x$HI (kde $x$ může nabývat hodnot 0, 1, 2, 3 a určuje, ke kterému D/A převodníku registr patří) se zapíše hodnota k převodu. 12bitová hodnota je do 8bitových registrů rozdělena takovým způsobem, že 8 LSB je zapsáno do DA$x$LO a zbývající čtyři bity jsou zapsány do DA$x$HI na 4 nejnižší bity, nepoužité 4 MSB registru DA$x$HI jsou vyplněny nulami.
 
 Hodnota je zapsána v aditivním kódu (tab. \ref{tab_mf614_dac}).
 
@@ -501,7 +504,8 @@ Hodnota je zapsána v aditivním kódu (tab. \ref{tab_mf614_dac}).
 
 \ibox{
 \textbf{MSB} (Most Significant Bit) je označení pro bit s nejvyšší hodnotou v binárním vyjádření čísla. V obvyklém dvojkovém zápisu jde o bit nejvíce vlevo.
-\\~\\
+%\\~\\
+\\
 \textbf{LSB} (Least Significant Bit) je bit s nejnižší hodnotou. Jde o bit nejvíce vpravo.
 
 \begin{center}
@@ -512,13 +516,13 @@ Hodnota je zapsána v aditivním kódu (tab. \ref{tab_mf614_dac}).
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Implementace ovladačů}
 \section{Operační systém GNU/Linux}
-Jako cílový operační systém, na kterém bude vysvětlena implementace základních ovla\-da\-čů, byl zvolen GNU/Linux\footnote{Operační systém sestávající z GNU nástrojů a jádra Linux je označován jako GNU/Linux.}. Hlavním důvodem je dostupnost zdrojových kódů, velké množství kvalitní dokumentace, rozšířenost a vysoká kvalita. Distribucí použitou při vývoji je Debian GNU/Linux (verze jádra Linux 2.6.35) -- popsané postupy by však měly fungovat i pro jiné distribuce.
+Jako cílový operační systém, na kterém bude vysvětlena implementace základních ovla\-da\-čů, byl zvolen GNU/Linux\footnote{Operační systém sestávající z GNU nástrojů a jádra Linux je označován jako GNU/Linux.}. Hlavním důvodem je svobodné šíření zdrojových kódů, velké množství kvalitní dokumentace, rozšířenost a vysoká kvalita. \textit{Distribucí} použitou při vývoji je Debian GNU/Linux (verze jádra Linux 2.6.35) -- popsané postupy by však měly fungovat i pro jiné distribuce.
 
 \subsection{Práce s PCI zařízeními z uživatelského prostoru}
-Pro výpis všech zařízení v systému připojených pomocí sběrnice PCI slouží program \texttt{lspci}.
+Pro výpis všech zařízení připojených pomocí sběrnice PCI k počítači slouží program \texttt{lspci}.
 Po jeho spuštění bez udání parametrů bude vypsán základní seznam PCI zařízení. 
 
-Mezi důležité parametry, použitelné při spuštění programu, patří:
+Mezi důležité parametry patří:
 \begin{description}
 \item[\texttt{-t}] Zobrazí diagram znázorňující jednotlivé PCI sběrnice a mosty.
 \item[\texttt{-v}, \texttt{-vv}, \texttt{-vvv}]
@@ -558,7 +562,7 @@ Informace o PCI zařízeních se nacházejí ve složce \texttt{/sys/bus/pci/dev
 \item[\texttt{class}] -- Obsahuje 24bitový identifikátor třídy zařízení.
 \item[\texttt{subsystem\_vendor}] -- Obsahuje Subsystem Vendor ID.
 \item[\texttt{subsystem\_device}] -- Obsahuje Subsystem ID.
-\item[\texttt{resource}] -- Soubor obsahuje popis jednotlivých regionů (reprezentovaných BAR registry) využívaných zařízením.
+\item[\texttt{resource}] -- Soubor obsahuje popis jednotlivých regionů využívaných zařízením (také označováno jako \textit{obsah} BAR registrů).
 \end{description}
 
 Struktura souboru \texttt{resource} může vypadat následovně:
@@ -577,7 +581,7 @@ První sloupec označuje adresu začátku regionu, druhý jeho konec. Třetí sl
 
 
 \subsection{Základní jaderný modul}\label{kern_mod}
-Jádro operačního systému GNU/Linux je monolitické -- to znamená, že po zkompilování a slinkování je tvořeno jedním kusem kódu. Tento druh jádra je léty prověřen a mezi výhody patří jeho snadná implementace. Aby běžící jádro nemuselo obsahovat veškeré dostupné ovladače zařízení (nebo abychom v případě potřeby přidat do jádra ovladač pro nový hardware nemuseli celé jádro znovu kompilovat), existuje mechanismus načítání jaderných modulů za běhu, tzv. LKM -- Loadable Kernel Module. V praxi to vypadá tak, že jsou v~běžícím jádře zakompilovány pouze nejnutnější ovladače, všechny ostatní si může systém nebo uživatel za běhu do jádra načíst -- v případě, že již nejsou potřeba, je možné je z jádra uvolnit.
+Jádro operačního systému GNU/Linux je monolitické -- to znamená, že po zkompilování a slinkování je tvořeno jedním kusem kódu. Tento druh jádra je léty prověřen a mezi výhody patří hlavně jeho snadná implementace a stabilita. Aby běžící jádro nemuselo obsahovat veškeré dostupné ovladače zařízení (nebo aby v případě potřeby přidat do jádra ovladač pro nový hardware nebylo nutné celé jádro znovu kompilovat), existuje mechanismus načítání jaderných modulů za běhu, tzv. LKM -- \textit{Loadable Kernel Module}. V praxi to vypadá tak, že jsou v~běžícím jádře zakompilovány pouze nejnutnější ovladače, všechny ostatní si může systém nebo uživatel za běhu do jádra načíst -- v případě, že již nejsou potřeba, je možné je z jádra uvolnit.
 
 Jak se takový jaderný modul může vypadat, je nejlepší si ukázat na příkladu:
 \begin{verbatim}
@@ -601,19 +605,22 @@ Jak se takový jaderný modul může vypadat, je nejlepší si ukázat na přík
  18 |  MODULE_LICENSE("Dual BSD/GPL");
 \end{verbatim}
 
-Z příkladu je patrné, že je modul napsán v programovacím jazyce C. To platí pro většinu všech jaderných modulů (stejně jako zdrojových kódů jádra samotného). Ve skutečnosti se jedná o mírně modifikovaný standard C90.
+Z příkladu je patrné, že je modul napsán v programovacím jazyce C. To platí pro většinu jaderných modulů (stejně jako zdrojových kódů jádra samotného). Ve skutečnosti se jedná o mírně modifikovaný standard ANSI C90.
+
+Z čeho se modul skládá:
 \begin{description}
 \item[Řádky 1 a 2] obsahují vložení hlavičkových souborů -- obsahují prototypy volaných funkcí a jsou nutné pro tvorbu jaderného modulu.
-\item[Na řádcích 4--8] je funkce, která bude spuštěna ihned po zavedení našeho modulu do jádra. Ta obsahuje pouze volání funkce \texttt{printk()}.
+\item[Na řádcích 4--8] je funkce, která bude spuštěna ihned po zavedení modulu do jádra. Ta obsahuje pouze volání funkce \texttt{printk()}.
 
 Pro jednoduchost je možné s funkcí \texttt{printk()} pracovat jako s, jistě známou, funkcí \texttt{printf()} dostupnou v uživatelském prostoru -- na rozdíl od standardního výstupu se však text vypsaný funkcí \texttt{printk()} zapíše do \textit{logu} jádra. Jedním ze způsobů, jak ho zobrazit je pomocí programu \texttt{dmesg}.\\O to, že se tato funkce vykoná ihned po zavedení modulu do jádra, se postará příkaz na $\rightarrow$
-\item[řádku 15] -- ten obsahuje makro \texttt{module\_init()}, kterému řekneme právě to, která funkce se má po načtení spustit.
-\item[Řádek 16] obsahuje naopak makro, které udává, která funkce se má zavolat v případě, že se bude modul uvolňovat z jádra. V našem případě je to funkce na $\rightarrow$
+\item[řádku 15] -- ten obsahuje makro \texttt{module\_init()}, kterému je sděleno právě to, která funkce se má po načtení spustit.
+\item[Řádek 16] obsahuje naopak makro, které udává, která funkce se má zavolat v případě, že se bude modul uvolňovat z jádra. V tomto případě je to funkce na $\rightarrow$
 \item[řádcích 10--13.] Tato funkce nemá na starost nic jiného než výpis krátkého textu do logu jádra.
+\item[Na řádku 18] je použito makro udávající licenci definující práva a povinnosti pro šíření/ používání zdrojových kódů daného modulu. Uvedení licence je důležité z toho důvodu, že jaderné moduly nevyužívající některou z opensource licencí nemají dostupná všechna jaderná volání (to platí i pro případ, že není uvedena žádná licence).
 \end{description}
 
 \subsubsection{Kompilace modulu}
-Dále je potřeba jaderný modul přeložit\footnote{Před samotným překladem jádra je potřeba mít k dispozici zdrojové kódy jádra. Ty je možné stáhnout z \texttt{kernel.org} nebo v distribuci Debian nainstalovat pomocí příkazu \texttt{apt-get install linux-source}}. K tomu poslouží následující \texttt{Makefile}:
+Poté co je vytvořen zdrojový kód modulu, je třeba jej přeložit\footnote{Před samotným překladem modulu je potřeba mít k dispozici zdrojové kódy jádra. Ty je možné stáhnout z \url{http://kernel.org/} nebo v distribuci Debian nainstalovat pomocí příkazu \texttt{apt-get install linux-source}.}. K tomu poslouží následující \texttt{Makefile}:
 \begin{verbatim}
   1 |  KERNEL_VER=`uname -r`
   2 |  obj-m += hello.o
@@ -623,15 +630,16 @@ Dále je potřeba jaderný modul přeložit\footnote{Před samotným překladem
   6 |  clean:
   7 |      make -C /lib/modules/$(KERNEL_VER)/build M=$(PWD) clean
 \end{verbatim}
-Linux využívá při kompilaci systému \texttt{KBUILD}. Ten je tvořen množstvím Makefile souborů a~jeho smyslem je umožnit uživateli snadnou konfiguraci před kompilací -- určující, které části se do jádra zakompilují a které nikoliv. Výše uvedený (základní) Makefile soubor je tvořen následovně:
+
+Linux využívá při kompilaci systému \texttt{KBUILD}. Ten je tvořen větším množstvím samostat\-ných Makefile souborů a~jeho smyslem je umožnit uživateli snadnou konfiguraci před kompilací -- určující, které části se do jádra zakompilují a které nikoliv. Výše uvedený (základní) Makefile soubor je tvořen následovně:
 
 \begin{description}
 \item[Na prvním řádku] se do proměnné \texttt{KERNEL\_VER} přiřadí verze aktuálně běžícího jádra (po zavolání příkazu \texttt{uname -r}, který tuto informaci vrací).
-\item[Druhý řádek] říká, že modul bude vytvářen ze zdrojového souboru \texttt{hello.c} (t.j. modul popisovaný v kapitole \ref{kern_mod}).
+\item[Druhý řádek] říká, že modul bude vytvářen ze zdrojového souboru \texttt{hello.c} (tj. modul popisovaný v kapitole \ref{kern_mod}).
 \item[Na pátém řádku] (uvozeném tabelátorem) se volá (pomocí přepínače \texttt{-C}) Makefile ze sys\-tému \texttt{KBUILD}, který se nachází v adresáři spolu se zdrojovými kódy jádra. Parametr \texttt{M} určuje, které moduly mají být vytvořeny -- v tomto případě jsou to ty, které jsou uvedeny v Makefile, nacházejícím se v aktuálním adresáři (tj. \texttt{PWD}).
 \end{description}
 
-V případě, že v adresáři, ve kterém se nachází zdrojový soubor modulu \texttt{hello.c} a výše popsaný soubor \texttt{Makefile}, spustí příkaz \texttt{make}, měl by proběhnout samotný překlad:
+V případě, že se v adresáři, ve kterém se nachází zdrojový soubor modulu \texttt{hello.c} a výše popsaný soubor \texttt{Makefile}, spustí příkaz \texttt{make}, měl by proběhnout samotný překlad:
 \begin{verbatim}
   $ make
   make -C /lib/modules/`uname -r`/build M=/tmp/kernel_module_example modules
@@ -643,7 +651,8 @@ V případě, že v adresáři, ve kterém se nachází zdrojový soubor modulu
     LD [M]  /tmp/hello.ko
   make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-28-generic'
 \end{verbatim}
-V aktuálním adresáři by se měl nacházet kromě různých souborů, které vzniky při překladu, i potřebný \texttt{hello.ko} -- t.j. zkompilovaný jaderný modul připravený na zavedení do jádra.
+
+V aktuálním adresáři by se měl nacházet kromě různých souborů, které vzniky při překladu, i potřebný \texttt{hello.ko} -- tj. zkompilovaný jaderný modul připravený na zavedení do jádra.
 
 \begin{verbatim}
   $ ls
@@ -662,7 +671,7 @@ V případě, že vše proběhlo správně, měl by být v logu jádra text vypi
   $ dmesg | tail -1
   [ 9245.757491] Hello, world!
 \end{verbatim}
-A skutečně je posledním řádkem v logu text vypsaný úspěšně zavedeným modulem.
+%A skutečně je posledním řádkem v logu text vypsaný úspěšně zavedeným modulem.
 
 Pro plné otestování funkčnosti ukázkového modulu, je potřeba ho ještě z jádra uvolnit. K tomu slouží program \texttt{rmmod} (opět je potřeba spouštět se superuživatelskými privilegii).
 \begin{verbatim}
@@ -674,14 +683,14 @@ Pro plné otestování funkčnosti ukázkového modulu, je potřeba ho ještě z
 V logu je opět nachází text vypisovaný modulem při uvolňování z jádra.
 
 
-\ibox{V případě, že má být do jádra zaveden modul, jehož funkčnost a stabilita není jistá, je vhodné si uložit veškerou práci a před zavedením/uvolněním modulu do/z jádra spustit program \texttt{sync}, který uloží obsah diskových bufferů na disky.}
+\ibox{V případě, že má být do jádra zaveden modul, jehož funkčnost a stabilita není jistá, je vhodné si veškerou práci uložit (případně zálohovat) a před zavedením/uvolněním modulu do/z jádra spustit program \texttt{sync}, který uloží obsah diskových bufferů na disky.}
 
 \subsubsection{Na co si dávat pozor}
 Při psaní základního modulu pro jádro Linux nejsou patrné větší rozdíly oproti psaní programů pro uživatelský prostor. I~přesto, že tyto rozdíly nejsou vidět, stále tady jsou. Mezi ty nejdůležitější, kterých si má být programátor vědom, patří:
 
 \begin{description}
-\item[Žádná ochrana paměti]~\\Libovolný jaderný modul má přístup k veškeré paměti počítače. V případě, že se chybně pokusí zapsat do paměti, do které by zapisovat neměl, není zde žádný mechanismus, který by mu v tom zabránil nebo ho na to alespoň upozornil.
-\item[Uvolňování paměti]~\\Stejně jako pro programy psané v uživatelském prostoru platí, že nepotřebná dynamicky alokovaná paměť by měla být dealokována. V případě neuvolňování paměti programem v uživatelském prostoru je zde stále operační systém, který po skončení programu veškerou paměť uvolní. Nic takového však v jádře operačního systému nefunguje -- po uvolnění modulu z jádra není nic, co by se postaralo o alokovanou.
+\item[Žádná ochrana paměti]~\\Libovolný jaderný modul má přístup k veškeré paměti počítače. V případě, že se chybně pokusí zapsat do paměti, do které by zapisovat neměl, není zde žádný mechanismus, který by mu v tom zabránil.
+\item[Uvolňování paměti]~\\Stejně jako pro programy psané v uživatelském prostoru platí, že nepotřebná dynamicky alokovaná paměť by měla být dealokována. V případě neuvolňování paměti programem v uživatelském prostoru je zde stále operační systém, který po skončení programu veškerou paměť uvolní. Nic takového však v jádře operačního systému nefunguje -- po uvolnění modulu z jádra není nic, co by se postaralo o alokovanou paměť.
 \item[Přímý přístup k hardwaru]~\\Základní jaderný modul psaný například nezkušeným studentem má zcela stejné možno\-sti přístupu k hardware jako subsystémy jádra, které se starají o správnou funkci jednotlivých ovladačů. V lepším případě může špatný ovladač způsobit pád systému, v~horším např. zničení dat na disku nebo dokonce zničení hardware\footnote{Například velmi těžko opravitelné poškození firmware síťových karet Intel e1000e: \\ \url{http://www.abclinuxu.cz/clanky/jaderne-noviny/jaderne-noviny-22.-10.-2008\#pricina-chyby-poskozujici-e1000e}}.
 \item[Globální proměnné]~\\Každý ovladač může být spuštěn ve více instancích, proto by v kódu neměly být globální proměnné. Proměnné, které je potřeba zpřístupnit z více míst ovladače se vloží do jedné struktury, která je poté přístupná skrze ukazatel na \textit{privátní data} ovladače. Struktura reprezentující daný ovladače většinou obsahuje ukazatel s názvem \texttt{private} nebo \texttt{priv}, který slouží k~tomuto účelu.
 
@@ -715,7 +724,7 @@ Příklad pro lepší názornost:
 
 Na řádcích 3, 6 a 9 jsou volány funkce, které mají za následek alokaci zdrojů zařízení. Po skončení funkce ovladače je potřeba zavolat jiné funkce, které tyto zdroje uvolní.
 
-V případě, že by volání na řádku 6 skončilo neúspěchem, musela by být zavolána funkce \texttt{pci\_disable\_device()}, která deaktivuje zařízení (aktivované příkazem na řádku 3). V případě, že by poslední volání proběhlo neúspěšně, musela by být zavolána jak funkce \texttt{pci\_disable\_device()}, tak funkce \texttt{pci\_release\_regions()} -- to způsobuje duplikaci kódu, která vede k nepřehlednosti a může způsobovat chyby (v případě, že se omylem změní volání funkce pouze na jednom místě).
+V případě, že by volání na řádku 6 skončilo neúspěchem, musela by být zavolána funkce \texttt{pci\_disable\_device()}, která deaktivuje zařízení (aktivované příkazem na řádku 3). V případě, že by poslední volání proběhlo neúspěšně, musela by být zavolána jak funkce \texttt{pci\_disable\_device()}, tak funkce \texttt{pci\_release\_regions()}. V případě, že by tyto funkce byly volány z více míst, došlo by k duplikaci kódu, která vede k nepřehlednosti a může způsobovat chyby (v případě, že se omylem místo všech výskytů dealokační sekvence opraví pouze některé).
 
 Za pomoci volání \texttt{goto} je výše popsaný problém elegantně vyřešen.
 
@@ -1057,11 +1066,11 @@ Příklad, jak taková jednoduchá inicializace struktury \texttt{struct uio\_in
  20 |  pci_set_drvdata(dev, info);
 \end{verbatim}
 
-\ibox{\texttt{void pci\_set\_drvdata(struct pci\_dev *pdev, void *data)}}
+\ibox{\texttt{void pci\_set\_drvdata(struct pci\_dev *pdev, void *data);}}
 
 Na posledním řádku je, dosud nepopsané, volání \texttt{pci\_set\_drvdata()}. To (v tomto případě) zajistí, že struktura \texttt{struct uio\_info} se stane součástí struktury reprezentující zařízení (\texttt{struct pci\_dev}) -- což umožní pozdější přístup ke struktuře \texttt{struct uio\_info} z funkcí jako je například \texttt{remove()}, která jako parametr získá ukazatel na strukturu \texttt{struct pci\_dev}.
 
-\ibox{\texttt{static inline void *pci\_get\_drvdata(struct pci\_dev *pdev)}}
+\ibox{\texttt{static inline void *pci\_get\_drvdata(struct pci\_dev *pdev);}}
 
 Funkce \texttt{pci\_get\_drvdata()} slouží k \textit{získání} dat uložených do struktury \texttt{struct pci\_dev} pomocí volání \texttt{pci\_set\_drvdata()}.
 
@@ -1144,7 +1153,7 @@ Comedi se skládá ze tří částí:
 
 
 \subsection{Registrace ovladače}
-Pro správnou funkci je potřeba, aby byl ovladač ihned po načtení modulu (t.j. v \textit{init} funkci) zaregistrován, jak do PCI subsystému, tak do subsystému Comedi. Registrace mezi PCI zařízení je popsána v kapitole \ref{pci_reg}. Registrace mezi Comedi ovladače se provede voláním \texttt{comedi\_driver\_register(struct comedi\_driver *driver)}, kde jako parametr se předá ukazatel na strukturu \texttt{struct comedi\_driver}.
+Pro správnou funkci je potřeba, aby byl ovladač ihned po načtení modulu (tj. v \textit{init} funkci) zaregistrován, jak do PCI subsystému, tak do subsystému Comedi. Registrace mezi PCI zařízení je popsána v kapitole \ref{pci_reg}. Registrace mezi Comedi ovladače se provede voláním \texttt{comedi\_driver\_register(struct comedi\_driver *driver)}, kde jako parametr se předá ukazatel na strukturu \texttt{struct comedi\_driver}.
 
 \subsection{Struktura \texttt{struct comedi\_driver}}
 Nejdůležitější položky, které tato struktura obsahuje jsou ukazatele na funkce volané při aktivaci Comedi ovladače.
@@ -1193,7 +1202,7 @@ Poslední čtyři funkce mají parametry: \\ \texttt{(struct comedi\_device *, s
  
 \end{description}
 
-\ibox{\texttt{int alloc\_subdevices(struct comedi\_device *dev, unsigned int num\_subdevices)}}
+\ibox{\texttt{int alloc\_subdevices(struct comedi\_device *dev, unsigned int num\_subdevices);}}
 
 Alokace paměti pro struktury se provede voláním \texttt{alloc\_subdevices()}, které je poskytováno Comedi subsystémem. Prvním parametrem je předán ukazatel na strukturu \texttt{struct comedi\_device}, pro kterou má být alokace provedena. Alokovaná paměť je přístupná skrze proměnnou \texttt{subdevices} náležící struktuře \texttt{struct comedi\_device}. 
 
@@ -1231,7 +1240,7 @@ V případě, že proběhlo načtení modulu a spuštění funkce \textit{attach
 Pro přístup k zařízení je potřeba zavolat na soubor \texttt{/dev/comedi0} funkci \texttt{comedi\_open()}. Ta vrací ukazatel datového typu \texttt{comedi\_t}, reprezentujícího dané zařízení. K němu je možné přistupovat pomocí funkcí: \texttt{comedi\_data\_read()}, \texttt{comedi\_data\_write()}, \texttt{comedi\_dio\_read()}, \texttt{comedi\_dio\_write()}.
 
 První dvě slouží pro zápis/čtení A/D a D/A převodníků, zatímco poslední dvě slouží pro přístup k digitálním vstupům/výstupům.
-Prvním parametrem všech funkcí je ukazatel na \texttt{comedi\_t}. Druhým je číslo \textit{podzařízení}. Třetí parametr určuje kanál (t.j. např. který z osmi A/D převodníků má být čten). Posledním parametrem je ukazatel na proměnnou, kam mají být zapsána přečtena data nebo hodnota, která má být zapsána.
+Prvním parametrem všech funkcí je ukazatel na \texttt{comedi\_t}. Druhým je číslo \textit{podzařízení}. Třetí parametr určuje kanál (tj. např. který z osmi A/D převodníků má být čten). Posledním parametrem je ukazatel na proměnnou, kam mají být zapsána přečtena data nebo hodnota, která má být zapsána.
 
 Ukázka jednoduchého userspace programu:
 \begin{verbatim}
index 62b4a99ae32a568f26766ad1df21043c97d819f9..49865c0eb1596223676091ca3736ce4d1c13c677 100644 (file)
@@ -22,6 +22,9 @@
 \setlength{\@fptop}{0pt}
 \makeatother
 
+% Against footnote breaking into more pages
+\interfootnotelinepenalty=10000
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Zvolte jednu z moznosti 
 % Choose one of the following options
@@ -204,10 +207,9 @@ FIXME
 \noindent{\Huge \textbf{Abstrakt}}
 \vspace{8ex}
 
+Cílem této práce je popsat základní principy implementace ovladače PCI zařízení pro operační systém GNU/Linux. Kromě obecného popisu je zmíněna implementace ovladačů typu UIO a Comedi.
 
-Cílem této práce je vysvětlit základní principy komunikace ovladače operačního systému s hardwarem. Pro názornost jsou v práci popsány postupy implementace UIO a Comedi ovladače pro měřící kartu Humusoft MF624 pro operační systém GNU/Linux.
-
-Součástí této práce je i implementace základních funkcí (D/A, A/D převodníky, digitální vstupy a výstupy) karty Humusoft MF624 do emulátoru Qemu, aby si případný zájemce mohl popsané postupy vyzkoušet, aniž by vlastnil potřebný hardware.
+Jako ukázková zařízení byly zvoleny karty Humusoft MF624 a MF614. Základní funkce (D/A, A/D převodníky, digitální vstupy a výstupy) karty Humusoft MF624 byly implementovány do emulátoru Qemu tak, aby bylo možné popsané postupy vyzkoušet bez fyzického přístupu ke kartě.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  Obsah / Table of Contents