]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Diploma thesis text.
authorRostislav Lisovy <lisovy@gmail.com>
Wed, 30 Mar 2011 22:51:51 +0000 (00:51 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 30 Mar 2011 22:51:51 +0000 (00:51 +0200)
doc/diploma_thesis/text/dip_text.tex

index fe87e55e19a2ff28eca2a4068fa04b3d3cb80a36..4287f79210f2db31a44a464c533c2e31d085b458 100644 (file)
@@ -6,8 +6,9 @@
 \usepackage{graphicx}
 \usepackage{multicol}
 \usepackage{amssymb,amsmath}
+\usepackage{url}
 
-\newcommand{\ibox}[1]{\begin{center} \fbox{\parbox{14cm}{ #1 }} \end{center} }
+\newcommand{\ibox}[1]{ \begin{center}\begin{small} \fbox{\parbox{14cm}{ #1 }} \end{small}\end{center}}
 
 %opening
 \title{\textsf{\begin{huge}Prostředí pro výuku vývoje PCI ovladačů do OS GNU/Linux\end{huge}\\
@@ -24,11 +25,13 @@ Fakulta elektrotechnická ČVUT}
 \newpage
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-\section{Abstrakt}
+\begin{abstract}
 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í (DAC, ADC, DIO) karty Humusoft MF624 do emulátoru Qemu, aby si případný zájemce mohl popsané postupy vyzkoušet, aniž by vlastnil potřebný hardware.
-Od čtenáře se očekává základní znalost používání operačního systému GNU/Linux a dobrá znalost programovacího jazyka C.
+
+Od čtenáře se očekává základní znalost používání operačního systému GNU/Linux, dobrá znalost programovacího jazyka C a základní znalost anglického jazyka.
+\end{abstract}
 \newpage
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -36,17 +39,17 @@ Od čtenáře se očekává základní znalost používání operačního systé
 \section{Komunikace s hardwarem}
 Jak je možné ovládat hardware pomocí programu (software) je nejsnazší ukázat na příkladu jednočipového počítače.
 
-\ibox{Mikrokontrolér, neboli jednočipový počítač má velikost pouze jednoho čipu. Obsahuje přitom procesor, paměť, vstupně-výstupní zařízení jako
+\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é. Příklady zařízení obsažených v mikrokontroléru
 \begin{description}
-\item[GPIO piny (General Purpose Input/Output)] --  u těch je možné nastavit, zda chceme jejich hodnotu číst (a je k nim tedy připojeno jiné zařízení) nebo zda chceme jejich hodnotu nastavovat.
-\item[AD převodníky] -- TODO
-\item[Časovače] -- TODO
+\item[GPIO piny (General Purpose Input/Output)] -- u těch je možné nastavit, zda chceme jejich hodnotu číst (a je k nim tedy připojeno jiné zařízení) nebo zda chceme jejich hodnotu nastavovat.
+\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}
 
 
 %\begin{figure}[h!]
 %      \begin{center}
-       \includegraphics[width=80mm]{img/msp430g2x01.png}
+%      \includegraphics[width=80mm]{img/msp430g2x01.png}
 %      \caption{Architektura velmi jednoduchého mikroprocesoru MSP430G2x01 firmy Texas Instruments.}
 %      \label{microcontroller}
 %      \end{center}
@@ -54,7 +57,7 @@ Jak je možné ovládat hardware pomocí programu (software) je nejsnazší uká
 
 }
 
-V případě, že budeme chtít změnit hodnotu GPIO pinu, je první možností 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ů). Vnitřní uspořádání mikrokontroleru, dle adresy na kterou jsme zapisovali, rozpozná, že provedená operace zápisu nebyla určena pro změnu hodnoty vnitřní paměti, ale je určena pro změnu stavu určité části hardwaru. Námi zapsaná hodnota se tedy projeví změnou výstupní hodnoty 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}.
+V případě, že budeme chtít změnit hodnotu GPIO pinu, je první možností 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 ovliňuje stav hardware. V dokumentaci ke konkrétnímu mikrokontrolerů/\-mikroprocesoru/\-programovatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Vnitřní uspořádání mikrokontroleru, dle adresy na kterou jsme zapisovali, 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. Námi zapsaná hodnota se tedy projeví změnou výstupní hodnoty 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}.
 
 \begin{figure}[h!]
        \begin{center}
@@ -64,11 +67,11 @@ V případě, že budeme chtít změnit hodnotu GPIO pinu, je první možností
        \end{center}
 \end{figure}
 
-Jiným přístupem je při zápisu/čtení do/ze zařízení použití jiné instrukce než kterou používáme pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO, provedeme zápis do tzv. \textbf{vstupně-výstupního prostoru} na adresu (v tomto případě označovanou jako \textbf{port}) odpovídající GPIO pinům. Adresy paměťového a vstupně-výstupního prostoru\footnote{dále v textu bude pro zkrácení občas použito označení \textit{I/O prostor} (z anglického Input/Output)} spolu nijak nesouvisí.
+Jiným přístupem je při zápisu/čtení do/ze zařízení použití jiné instrukce než kterou používáme pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO, provedeme zápis do tzv. \textbf{vstupně-výstupního prostoru} 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\footnote{dále v textu bude pro zkrácení občas použito označení \textit{I/O prostor} (z anglického Input/Output)} spolu nijak nesouvisí. V případě zápisu a čtení do/z portu I/O adresního prostoru je potřeba z dokumentace přesně vědět jak široká (kolikabitová) slova smíme zapisovat/číst. 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \newpage
 \section{PCI sběrnice a komunikační protokol}
-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 ty nejdůležitější principy, které tato sběrnice využívá.
+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í.
 
 \begin{figure}[h!]
        \begin{center}
@@ -98,11 +101,11 @@ Informaci o tom, kolik (a jaké) paměti karta bude potřebovat má před nakonf
 
 Zmínil jsem 6 BAR registrů, které každá z karet obsahuje. Mezi další registry, které budeme při implementaci ovladačů používat, patří:
 \begin{description}
-\item[Device ID] -- FIXME
-\item[Vendor ID] -- 
-\item[Class code] -- 
-\item[Subsystem ID] -- 
-\item[Subsystem Vendor ID] -- 
+\item[Vendor ID] -- Obsahuje unikátní číslo identifikující výrobce zařízení. Za poplatek je udělováno PCI-SIG 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 číslo identifikující model zařízení.
+\item[Class code] -- Označuje druh zařízení (zda se jedná 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 naše karta využívá PCI řadič třetí strany, jako \texttt{Vendor ID} se zobrazí ID výrobce tohoto řadiče. Abychom byli schopni naše zařízení odlišit od jiného, které využívá stejný řadič, ID našeho zařízení bude uloženo v tomot registru. (V případě, že v registru \texttt{Vendor ID} je skutečně naše ID, může být opět i v tomto registru).
+\item[Subsystem ID] -- Opět se jedná o údaj podobný \texttt{Device ID}. 
 \end{description}
 
 Výše popsané registry (a ostatní, které nejsou pro čtenáře podstatné) se nacházejí v tzv. \textbf{konfiguračním adresním prostoru} karty (\textit{ano, po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor}). Do toho je možné na architektuře IA-32 přistupovat pomocí zapsání adresy (kam chceme v konfiguračním prostoru zapisovat) a dat (která chceme do konfiguračního prostoru zapsat) do dvou I/O portů s pevně danou adresou.
@@ -110,12 +113,6 @@ Výše popsané registry (a ostatní, které nejsou pro čtenáře podstatné) s
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Humusoft MF624}
-Měřící karta Humusoft MF624 (dále jen MF624), připojitelná k počítači pomocí PCI sběrnice, má pro účely výkladu psaní ovladačů několik nesporných výhod:
-\begin{itemize}
-\item Komunikace (na úrovni ovladače) s kartou probíhá snadno pochopitelným, přímočarým způsobem (bude vysvětleno dále).
-\item Snadno si ověříme funkci námi napsaného ovladače -- např. připojením LED diody k digitálnímu výstupu.
-\end{itemize}
-
 \begin{figure}[h!]
        \begin{center}
        \includegraphics[width=150mm]{img/mf624.jpg}
@@ -124,44 +121,253 @@ Měřící karta Humusoft MF624 (dále jen MF624), připojitelná k počítači
        \end{center}
 \end{figure}
 
-Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, když potřebujeme 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ě využijeme AD převodníků, resp. digitálních vstupů). Kartu je možné použít pro řízení akčního členu/zařízení -- na výběr máme DA převodníky a digitální výstupy.
+Měřící karta Humusoft MF624 (dále jen MF624), připojitelná k počítači pomocí PCI sběrnice, má pro účely výkladu psaní ovladačů několik nesporných výhod:
+\begin{itemize}
+\item Komunikace (na úrovni ovladače) s kartou probíhá snadno pochopitelným, přímočarým způsobem (bude vysvětleno dále).
+\item Snadno si ověříme funkci námi napsaného ovladače -- např. připojením LED diody k digitálnímu výstupu.
+\end{itemize}
+
+Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, když potřebujeme 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ě využijeme A/D převodníků, resp. digitálních vstupů). Kartu je možné použít pro řízení akčního členu/zařízení -- na výběr máme D/A převodníky a digitální výstupy.
 Kromě výše popsaných funkcí disponuje karta dalšími funkcemi (v popisu implementace ovladačů se omezíme pouze na ADC, DAC a DIO):
 \begin{itemize}
 \item Časovač/čítač
 \item Vstupy inkrementálních snímačů
 \end{itemize}
 
-\subsection{Komunikace s kartou}
+\subsection{Komunikace s kartou}\label{hum_komunikace}
 Komunikace s kartou probíhá celkem přímočarým způsobem:
 \begin{itemize}
 \item V případě, že chceme číst hodnoty digitálních vstupů, přečteme hodnotu registru určeného právě digitálním vstupům -- v případě zápisu na digitální výstupy, zapíšeme do registru určeného digitálním výstupům
-\item V případě čtení AD převodníku nejprve zapíšeme do konfiguračního registru AD převodníku slovo odpovídající požadované konfiguraci. Poté již z registru náležícího AD převodníku vyčteme požadovanou hodnotu.
+\item V případě čtení A/D převodníku nejprve zapíšeme do konfiguračního registru A/D převodníku slovo odpovídající požadované konfiguraci. Poté již z registru náležícího A/D převodníku vyčteme požadovanou hodnotu.
 \end{itemize}
 
-\ibox{Jak se spustí převod. Čtení se side effects}
+Abychom zjistili, které registry karta obsahuje, jakou mají funkci a kde jsou umístěny je nejprve potřeba si z oficiálních stránek výrobce stáhnout\footnote{\url{http://www2.humusoft.cz/www/datacq/manuals/mf624um.pdf}} manál ke kartě.
+
+Na straně 11 je k vidění první důležitá tabulka (zde tab. \ref{tab_bar}):
+
+\begin{table}[h!]
+       \begin{center}
+       \begin{tabular}{|p{2cm}|p{6cm}|c|c|}
+       \hline \textbf{Region} & \textbf{Function} & \textbf{Size (bytes)} & \textbf{Width (bytes)} \\ 
+       \hline BADR0 (memory mapped) & PCI chipset, interrupts, status bits, special functions & 32 & 32 \\ 
+       \hline BADR1 (memory mapped) & A/D, D/A, digital I/O & 128 & 16/32 \\ 
+       \hline BADR2 (memory mapped) & Counter/timer chip & 128 & 32 \\ 
+       \hline 
+       \end{tabular} 
+       \caption{Paměťové regiony, které PCI karta využívá}
+       \label{tab_bar}
+       \end{center}
+\end{table}
+
+Z ní je patrné, že karta využívá 3 paměťové regiony mapované do paměťovém adresním prostoru (sloupec 1) -- o velikostech 32, 128 a 128 bajtů (sloupce 3). Pro čtení/zápis z/do nich je potřeba používat 32-, 16-, 32bitové operace (sloupec 4).\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 umožnuje \textbf{pouze} 16bitový přístup do BAR1 paměťového regionu.}
+
+\subsection{Digitální vstupy a výstupy}
+Z tabulky \ref{tab_bar} jsme se navíc dozvěděli informaci, že registry ovládající digitální vstupy a výstupy budou ležet zřejmě v regionu BAR1 (sloupec 2). Podíváme se 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 \ref{tab_bar1}.
+
+\begin{table}[h!]
+       \begin{center}
+       \begin{tabular}{|c|c|c|}
+       \hline \textbf{Address} & \textbf{Read} & \textbf{Write} \\ 
+       \hline BADR1 + 0x00 & \textbf{ADDATA} -- A/D data & ADCTRL -- A/D control \\ 
+       \hline BADR1 + 0x02 & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x04 & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x06 & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x08 & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x0A & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x0C & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x0E & \textbf{ADDATA} -- A/D data mirror &  \\ 
+       \hline BADR1 + 0x10 & \textbf{DIN} -- Digital input & \textbf{DOUT} -- Digital output \\ 
+       \hline BADR1 + 0x20 & \textbf{ADSTART} -- A/D SW trigger & \textbf{DA0} -- D/A 0 data \\ 
+       \hline BADR1 + 0x22 &  & \textbf{DA1} -- D/A 1 data \\ 
+       \hline BADR1 + 0x24 &  & \textbf{DA2} -- D/A 2 data \\ 
+       \hline BADR1 + 0x26 &  & \textbf{DA3} -- D/A 3 data \\ 
+       \hline BADR1 + 0x28 &  & \textbf{DA4} -- D/A 4 data \\ 
+       \hline BADR1 + 0x2A &  & \textbf{DA5} -- D/A 5 data \\ 
+       \hline BADR1 + 0x2C &  & \textbf{DA6} -- D/A 6 data \\ 
+       \hline BADR1 + 0x2E &  & \textbf{DA7} -- D/A 7 data \\ 
+       \hline 
+       \end{tabular} 
+       \caption{Registry karty obsažené v regionu BAR1}
+       \label{tab_bar1}
+       \end{center}
+\end{table}
+
+Asi uprostřed tabulky je řádek, ve kterém je napsáno \textit{DIN -- Digital input, DOUT -- Digital output} -- ten značí registr, který se stará o nastavování digitálních výstupů a čtení digitálních vstupů (Všimněme si, že registr DIN a DOUT mají stejnou adresu i přesto, že na kartě jsou vstupy a výstupy realizovány oddělenými vodiči). 
+
+Abychom přesně věděli, jak jsou data v registrech reprezentována, podíváme se (v oficiálním manuálu) na stranu 16, kde jsou tyto dva registry podrobně popsány (zde tabulka \ref{tab_din} a \ref{tab_dout}). První sloupec nám 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, tedy vidíme, ž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 8bitů registru DOUT, horních 8 bitů je potřeba ignorovat.
+
+\begin{table}[h!]
+       \begin{center}
+       \begin{tabular}{|c|c|c|}
+       \hline \textbf{Bit} & \textbf{Description} & \textbf{Default} \\ 
+       \hline 7:0 & \textbf{Digital input 7:0.} Reads digital input port. & 1 \\ 
+       \hline 15:8 & Reserved & N/A \\ 
+       \hline 
+       \end{tabular} 
+       \caption{DIN -- Digital Input Register Format}
+       \label{tab_din}
+       \end{center}
+\end{table}
+
+\begin{table}[h!]
+       \begin{center}
+       \begin{tabular}{|c|c|c|}
+       \hline \textbf{Bit} & \textbf{Description} & \textbf{Default} \\ 
+       \hline 7:0 & \textbf{Digital output 7:0.} Writes to digital output port. & 0 \\ 
+       \hline 15:8 & Reserved & N/A \\ 
+       \hline 
+       \end{tabular} 
+       \caption{DOUT -- Digital Output Register Format}
+       \label{tab_dout}
+       \end{center}
+\end{table}
 
-\ibox{AD převod chvíli trvá a buď čekáme nebo přijde přerušení}
 
-\ibox{Co je bitová maska}
+\subsection{A/D převodníky}
+TODO
 
-Jak se dozvíme adresu potřebného registru? 
+Přerušení?
+\subsection{D/A převodníky}
+TODO
 
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \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 ovladačů, byl zvolen GNU/Linux. Hlavním důvodem je jeho otevřenost (a z toho plynoucí velké množství kvalitní dokumentace), rozšířenost (hlavně mezi vestavěnými zařízeními) a vysoká kvalita. Distribucí použitou při vývoji byl  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 ovladačů, 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 jeho otevřenost (a z toho plynoucí velké množství kvalitní dokumentace), rozšířenost (hlavně mezi vestavěnými zařízeními) a vysoká kvalita. Distribucí použitou při vývoji byl  Debian GNU/Linux (verze jádra Linux 2.6.35) -- popsané postupy by však měly fungovat i pro jiné distribuce.
 
 \subsection{Principy psaní jaderných modulů}
+Jádro operačního systému GNU/Linux je monolitické -- to znamená, že po zkompilování a slinkvá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.
+
+Jak se takový jaderný modul může vypadat, je nejlepší si ukázat na příkladu:
+\begin{verbatim}
+ 1 |  #include <linux/init.h>
+ 2 |  #include <linux/module.h>
+ 3 | 
+ 4 |  static int hello_init(void)
+ 5 |  {
+ 6 |      printk("Hello, world!\n");
+ 7 |      return 0;
+ 8 |  }
+ 9 | 
+10 |  static void hello_exit(void)
+11 |  {
+12 |      printk("Goodbye, cruel world!\n");
+13 |  }
+14 | 
+15 |  module_init(hello_init);
+16 |  module_exit(hello_exit);
+17 |  
+18 |  MODULE_LICENSE("Dual BSD/GPL");
+\end{verbatim}
+
+První věc, na kterou je potřeba upozornit je, že většina jaderných modulů (stejně jako zdrojových kódů jádra samotného) je psána v programovacím jazyce C (jedná se o mírně modifikovaný standard C90).
+\begin{description}
+\item[Řádky 1 a 2] obsahují vložení hlavičkových souborů -- obsahují prototypy námi 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()}.
+
+Pro jednoduchost můžeme s funkcí \texttt{printk()} pracovat jako s pro nás známou funkcí \texttt{printf()} -- narozdí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}.\\Jak se zařídí, že se tato funkce vykoná ihned po zavedení modulu do jádra? O to 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[řádcích 10--13.] Tato funkce nemá na starost nic jiného než výpis krátkého textu do logu jádra.
+\end{description}
+
+\subsection{Kompilace modulu}
+Jednoduchý jaderný modul již máme. Teď je potřeba ho 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 buď stáhneme přímo z \texttt{kernel.org} nebo v distribuci Debian nainstalujeme pomocí příkazu\\\texttt{apt-get install ... FIXME}}. K tomu nám poslouží následující \texttt{Makefile}:
+\begin{verbatim}
+1 |  KERNEL_VER=`uname -r`
+2 |  obj-m += hello.o
+3 |
+4 |  all:
+5 |      make -C /lib/modules/$(KERNEL_VER)/build M=$(PWD) modules
+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é čáasti se do jádra zakompilují a které nikoliv. Popis toho systému je mimo rozsah této práce. Stručný popis výše zmíněného Makefile souboru:
+
+\begin{description}
+\item[Na prvním řádku] se do proměnné \texttt{KERNEL\_VAR} 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] nám říká, že chceme vytvořit modul ze zdrojového souboru \texttt{hello.c} (pod tímto názvem jsme uložili náš ukázkový modul)
+\item[Na pátém řádku] (uvozeném tabelátorem) se volá (pomocí přepínače \texttt{-C}) Makefile ze systému \texttt{KBUILD}, který se nachází v adresáří spolu se zdrojovými kódy jádra. Parametrem \texttt{M} říkáme, které moduly si přejeme vytvořit -- v tomto případě jsou to ty, jejichž zdrojové soubory jsou 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:
+\begin{verbatim}
+$ make
+make -C /lib/modules/`uname -r`/build M=/tmp/kernel_module_example modules
+make[1]: Entering directory `/usr/src/linux-headers-2.6.35-28-generic'
+  CC [M]  /tmp/kernel_module_example/hello.o
+  Building modules, stage 2.
+  MODPOST 1 modules
+  CC      /tmp/hello.mod.o
+  LD [M]  /tmp/hello.ko
+make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-28-generic'
+\end{verbatim}
+A v aktuálním adresáři míme kromě různých souborů, které vzniky při překladu i potřebný \texttt{hello.ko}
+
+\begin{verbatim}
+$ ls
+hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  
+Makefile  modules.order  Module.symvers
+\end{verbatim}
+
+\subsection{Zavedení modulu}
+Jaderný modul již máme zkompilovaný a nic nám nebrání v jeho zavedení do jádra. To se provede programem \texttt{insmod} -- ten musí být spouštěn se superuživatelským oprávněním:
+\begin{verbatim}
+$ sudo insmod ./hello.ko 
+\end{verbatim}
+
+V případě, že vše proběhlo správně, měl by být v logu jádra text vypisovaný modulem po jeho zavedení. To ihned zjistíme:
+\begin{verbatim}
+$ dmesg | tail -1
+[ 9245.757491] Hello, world!
+\end{verbatim}
+A skutečně je posledním řádkem v logu náš text.
+
+Abychom plně otestovali funkčnost našeho prvního modulu, zkusíme ho nyní z jádra uvolnit. To uděláme programem \texttt{rmmod} (opšt spouštíme se superuživatelskými privilegii).
+\begin{verbatim}
+$ sudo rmmod hello 
+
+$ dmesg | tail -1
+[ 9612.256929] Goodbye, cruel world!
+\end{verbatim}
+V logu je opět nachází text vypisovaný modulem při uvolňování z jádra.
+
+
+\ibox{V případě, že se chystáme do jádra zavést modul, jehož jsme autoři a nejsme si jisti jeho funkčností, doporučuji si veškerou důležitou práci uložit 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.}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Ovladače PCI zařízení}
+Než začneme implementovat skutečný ovladač pro kartu MF624 je potřeba si vysvětlit základní funkce pro práci s PCI zařízeními a vstupně-výstupním a paměťovým adresním prostorem.
+
+\texttt{pci\_enable\_device()}
+\texttt{pci\_disable\_device()}
+
+\texttt{pci\_request\_regions()}
+\texttt{pci\_release\_regions()}
+
+
+\texttt{pci\_resource\_start(dev, 4)}
+\texttt{pci\_resource\_len(dev, 4)}
+
+\texttt{pci\_ioremap\_bar(dev, 4);}
+\texttt{iounmap()}
+
+\texttt{struct pci\_device\_id}
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{UIO ovladač}
+V kapitole \ref{hum_komunikace} jsme si vysvětlili, jak je z manuálu možné zjistit, jak s kartou správně komunikovat a nyní již víme které registry je potřeba ovládat. 
+
 \subsection{Jaderný modul}
 \subsection{Uživatelský program}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Comedi ovladač}
 
-
+\appendix
+\chapter{Qemu a Humusoft MF624}
+Měřící karta Humusoft MF624 je hardware vhodný pro výklad implementace ovladače, je ale poměrně drahý. Pro účely výuky proto byly do emulačního software Qemu implementovány základní funkce této měřící karty -- konkrétně se jedná o A/D převodníky, D/A převodníky a digitální vstupy a výstupy. 
 \end{document}