+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Přístup k paměti zařízení}
+Poté co se ovladači podařilo získat přístup ke zdrojům zařízení, je nutné využít speciálních volání pro zápis/čtení do/z těchto zdrojů.
+
+\subsection{Vstupně-výstupní adresní prostor}
+Stejně jako program v jazyku symbolických instrukcí využívá pro přístup k vstupně-výstupnímu adresnímu prostoru (tj. I/O portům) zvláštní instrukce, je nutné využít speciální funkce v programech psaných ve \textit{vyšších} programovacích jazycích. V případě čtení jsou v jádře k dispozici tři volání:
+
+\ibox{\texttt{unsigned inb(unsigned port);}}
+
+\ibox{\texttt{unsigned inw(unsigned port);}}
+
+\ibox{\texttt{unsigned inl(unsigned port);}}
+
+Třetí písmeno značí o \textit{kolikabitové} čtení se jedná: b = 8 b, w = 16 b, l = 32 b.
+
+Pro zápis je možné využít volání:
+\ibox{\texttt{void outb(unsigned char byte, unsigned port);}}
+
+\ibox{\texttt{void outw(unsigned char byte, unsigned port);}}
+
+\ibox{\texttt{void outl(unsigned char byte, unsigned port);}}
+
+
+Třetí písmeno, stejně jako u funkcí pro čtení, značí o kolikabitový přístup se jedná.
+
+Stejná volání je možné používat i z uživatelského prostoru (potřebný hlavičkový soubor je \texttt{<sys/io.h>}).
+\subsection{Paměťový adresní prostor}
+I přesto, že se k přístupu k paměti zařízení mapované do paměťového adresního prostoru používá virtuální adresa, stejně jako k přístupu do operační paměti, není možné k paměti zařízení přistupovat přímo \textit{přes ukazatel}. Důvodem je to, že buď překladač (při kompilaci) nebo procesor (za běhu) zoptimalizují\footnote{Tyto optimalizace, v případě přístupu k operační paměti, urychlují vykonávání programu, aniž by negativně ovlivnily jeho funkci. V případě zápisu/čtení do/z registrů, u kterých mohou tyto operace vyvolávat tzv. \textit{side effects}, již může dojít k nesprávné funkci programu.
+
+Příklad optimalizace: V programu se do jedné paměťové buňky ihned po sobě zapíší dvě různé hodnoty, poté se výsledná hodnota přečte -- optimalizace možná u klasického programu je taková, že se ve skutečnosti provede pouze druhý zápis, protože ten první nemá žádný efekt (hodnota je ihned přepsána druhým zápisem). V případě přístupu do registru zařízení může zápis například spouštět převod A/D převodníků -- po optimalizaci se však provede pouze jednou, nikoliv dvakrát.} sekvenci zápisů/čtení do/z paměti zařízení takovým způsobem, že se výsledek bude lišit od toho, jak to bylo v programu zamýšleno.
+
+Těmto optimalizacím lze nejsnáze zabránit použitím volání:
+
+\ibox{\texttt{unsigned int ioread8(void *addr);}}
+
+\ibox{\texttt{unsigned int ioread16(void *addr);}}
+
+\ibox{\texttt{unsigned int ioread32(void *addr);}}
+
+pro čtení a volání
+
+\ibox{\texttt{void iowrite8(u8 value, void *addr);}}
+
+\ibox{\texttt{void iowrite16(u16 value, void *addr);}}
+
+\ibox{\texttt{void iowrite32(u32 value, void *addr);}}
+
+pro zápis. Číslo na konci funkce označuje o kolikabitový přístup se jedná.
+
+V případě, že se na paměť ve vstupně-výstupním adresním prostoru zavolá funkce
+\ibox{\texttt{void *ioport\_map(unsigned long port, unsigned int count);}}
+nebo v případě PCI zařízení funkce
+\ibox{\texttt{void \_\_iomem *pci\_iomap(struct pci\_dev *dev, int bar, unsigned long maxlen);}}
+
+je tato paměť \textit{přemapována} do paměťového adresního prostoru a je nutné pro přístup k ní používat výše popsaná volání.
+
+Z uživatelského prostoru je potřeba používat volání FIXME.