\input{confighandout}

\subsection{Unsorted Block Images (UBI)}

\subsubsection{Was ist UBI?}

UBI kann am ehesten als Logical Volume Manager (LVM) f\"ur mtd-Devices
bezeichnet werden. Beim Start scanned UBI das mtd-Device und baut eine
Liste der vorhandenen Erasebl\"ocke auf. Dabei werden auch Bad Blocks
richtig behandelt, da das MTD-Subsystem, auf dem UBI aufsetzt, diese
bereits erkennt.

Dieser Gesamtvorrat an physikalischen Erasebl\"ocken wird jetzt im
n\"achsten Schritt an sogenannte UBI-Volumes verteilt.

\subsubsection{UBI-Volumes}

UBI-Volumes entsprechen etwa den Partitionen anderer Systeme. Der von
einem mtd-Device bereitgestellte Speicher wird also in mehrere unabh\"angige
Einheiten aufgeteilt. Im Vergleich zu den Partitionen, die das
MTD-Subsystem auf einem Flash anlegen kann, sind UBI-Volumes aber erheblich
leistungsf\"ahiger und flexibler. Aus diesem Grund empfiehlt es sich, so
wenig wie m\"oglich mtd-Partitionen anzulegen, und UBI eine m\"oglichst gro\ss e
Partition zur Verwaltung zu \"ubergeben.

MTD-Partitionen haben eine strikt festgelegte Zuordnung von physikalischen
Erasebl\"ocken zu Partitionen. UBI kann dagegen Erasebl\"ocke bei Bedarf
beliebig zwischen den Volumes umverteilen. Dies geschieht beispielsweise
beim Wear-Leveling, das UBI ebenfalls durchf\"uhrt. Ebenso k\"onnen defekte
Erasebl\"ocke durch andere Bl\"ocke ersetzt werden.

Durch den von UBI verwendeten Algorithmus ist es selbst beim Neuanlegen
eines Volumes kaum vorhersagbar, welche physikalischen Erasebl\"ocke auf
dem Flash es belegt. W\"ahrend eine MTD-Partition immer in denselben
aufeinanderfolgenden Bl\"ocken liegt, \"andert sich die Zuordnung von
physikalischen Erasebl\"ocken des Flash zu logischen Erasebl\"ocken des
Volumes im laufenden Betrieb dynamisch. Ein UBI-Volume mit drei
Erasebl\"ocken kann also durchaus die Bl\"ocke 814, 27 und 1013 belegen.

Aus diesem Ansatz ergibt sich auch der Name \emph{Unsorted Block Images}.

\emph{Hinweis:} Auf klassischen Festplatten wird ein solches Verhalten
als \emph{Fragmentierung} bezeichnet und ist dort unerw\"unscht, da eine
mechanische Platte signifikante Seek-Zeiten aufweist. Man versucht dort,
Daten m\"oglichst in aufeinander folgenden Bl\"ocken zu speichern, um zu
verhindern, dass der mechanische Schreib-/Lesekopf von einem Ende der
Platte zum anderen bewegt werden muss. Auf Flash-Speichern gibt es keine
Seek-Zeiten, was UBI hier zugunsten eines auf Flash optimierten Designs
ausnutzt.

\paragraph{Statische Volumes}

Statische Volumes sind f\"ur Anwendungen gedacht, die kein Dateisystem
ben\"otigen. Ein praktisches Beispiel ist ein kleines Volume, das lediglich einen
Kernel enth\"alt, der vom Bootloader geladen und gestartet wird. Mit einem
statischen Volume muss der Bootloader keinerlei Dateisystem implementieren.
Er muss lediglich aus den UBI-Headern herausfinden, welche physikalischen
Erasebl\"ocke zu dem statischen Volume geh\"oren. Ausserdem erf\"ahrt er von UBI,
wie viele Bytes tats\"achlich durch Daten belegt sind. Er l\"adt diese Daten,
im Beispiel einen Kernel, ins RAM und springt sie an. Dies ist mit relativ
wenig Code (einige kB) m\"oglich.

Statische Volumes enthalten also immer nur einen einzigen Datenblock, der
in einem Vorgang geschrieben werden muss.

\paragraph{Dynamische Volumes}

Dynamische Volumes sind daf\"ur gedacht, ein Dateisystem zu enthalten.
Man verwendet sie also beispielsweise f\"ur ein Root-Filesystem oder f\"ur
Volumes, die Nutzerdaten enthalten. 

Dynamische Volumes verwendet man am Besten mit dem Dateisystem ubifs.

\paragraph{UBIGLUEBI}

UBIGLUEBI ist ein Aufsatz auf UBI, der f\"ur jedes Volume wieder ein
mtd-Device bereitstellt. Dies klingt zun\"achst \"uberraschend, da UBI ja schon
auf einem mtd-Device aufsetzt. Der Hintergrund ist, dass \"altere
Flash-Dateisysteme wie jffs2 ein mtd-Device ben\"otigen. Um deren Einsatz
zu erm\"oglichen, wurde dieser Zusatz geschaffen.

Heute gibt es ubifs, das direkt auf UBI aufsetzt und folglich kein
mtd-Device ben\"otigt. Da ubifs ohnehin in allen Bereichen deutliche Vorteile
gegen\"uber jffs2 hat, wird UBIGLUEBI in der Regel nicht mehr ben\"otigt.

\includegraphics[width=8cm]{images/ubi-big-picture.png}

\subsubsection{UBI-Tools}

Da UBI von den MTD-Entwicklern implementiert wurde, sind die UBI-Tools
Bestandteil der MTD-Tool-Kollektion. Diese gibt es mittlerweile als
Paket in den meisten Distributionen. Unter Debian installiert man das
Paket \cmd{mtd-utils}:

\begin{lstlisting}
aptitude install mtd-utils
\end{lstlisting}

Hier die wichtigsten UBI-Aktionen in Kurzform:

Die Kontrolle \"uber ein mtd-Device an UBI \"ubertragen:
\begin{lstlisting}
ubiattach /dev/ubi_ctrl -m 2
\end{lstlisting}
Dies verbindet \cmd{/dev/mtd2} mit UBI.

Ein Volume anlegen:
\begin{lstlisting}
ubimkvol /dev/ubi0 -s 3MiB -t static -N kernel -n 1
\end{lstlisting}
Hier wird ein 3MiB gro\ss es statisches Volume mit dem Namen \cmd{kernel}
angelegt. Das Volume erh\"alt die Nummer 1.

Daten in ein statisches Volume schreiben:
\begin{lstlisting}
ubiupdatevol /dev/ubi0_1 zImage
\end{lstlisting}
Die Daten aus der Datei \cmd{zImage} werden in das statische Volume mit der
Nummer 1 geschrieben.

Nat\"urlich lassen sich komplette Volumes auch wieder entfernen:
\begin{lstlisting}
ubirmvol/dev/ubi0 -n 1
\end{lstlisting}
Das Volume mit der Nummer 1 wird entfernt.

Der mit Abstand aufwendigste Befehl ist \cmd{ubinize}. Damit lassen sich
vollst\"andige UBI-Images f\"ur ein mtd-Device anfertigen. Diese k\"onnen
anschlie\ss end mit \cmd{nandwrite} in das mtd-Device geschrieben werden.
Alternativ kann das Image nat\"urlich auch mit einem geeigneten JTAGer
in das Flash \"ubertragen werden. Da \cmd{ubinize} sehr vielseitig ist und
relativ viele Flash- und Layout-Parameter ber\"ucksichtigt werden m\"ussen,
kann hier nur ein einfaches Beispiel gegeben werden.

Zun\"achst ist eine Konfigurationsdatei erforderlich, in der die einzelnen
Volumes sowie die in ihnen unterzubringenden Images beschrieben werden. 
Diese Datei folgt in ihrer Syntax dem bekannten INI-Format. Ein Volume
wird beispielsweise so angegeben:

\begin{lstlisting}
[rootfs-volume]
mode=ubi
image=../my-ubifs.img
vol_id=1
vol_size=100MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
vol_alignment=1
\end{lstlisting}

Unter der Annahme, dass alle Volumes in der oben angegebenen Weise in der
Datei \cmd{ubi-cfg.ini} beschrieben wurden, kann man das UBI-Image mit
einem Befehl erzeugen, der etwa so aussieht:
\begin{lstlisting}
ubinize -o ubi.img -p 128KiB -m 2048 -s 512 ubi-cfg.ini
\end{lstlisting}
Im Beispiel wird eine Eraseblock-Gr\"o\ss e von 128k angegeben, ausserdem eine
Pagegr\"o\ss e von 2048 Bytes sowie eine Subpage-Gr\"o\ss e von 512 Bytes. Das
fertige Image landet in der Datei \cmd{ubi.img}.

Weitere Informationen sind unter folgender URL erh\"altlich:

\begin{lstlisting}
http://www.linux-mtd.infradead.org/doc/general.html
\end{lstlisting}

\input{tailhandout}
