1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
\input{confighandout}
\subsection{Memory Technology Devices (MTD)}
\subsubsection{Was sind Memory Technology Devices?}
Prinzipiell kann jedes St\"uck Speicher als MTD dargestellt werden,
es gibt sogar Treiber, die einfach einen RAM-Bereich exportieren.
Unter Linux versteht man aber unter MTD normalerweise Flash-Speicher
in ihren unterschiedlichen Auspr\"agungen, beispielsweise NAND, NOR, DataFlash
oder OneNAND. Dabei werden Flash-spezifische Eigenschaften ber\"ucksichtigt,
wie zum Beispiel Hard- und Software-ECC oder die Tatsache, dass diese
Chips nur Eraseblock-weise gel\"oscht werden k\"onnen.
Die Art, wie der Chip an den Prozessor angeschlossen ist, spielt dabei
keine Rolle. Der Kernel unterst\"utzt direkt am Bus angeschlossene
NOR-Bausteine genauso wie NAND-Chips am NAND-Controller oder SPI-Flash-Chips,
die mit einem SPI-Bus verbunden sind.
\emph{Nicht} zu den MTD geh\"oren USB-Sticks, SD-Karten oder \"ahnliche Ger\"ate.
Diese enthalten zwar auch NAND-Flash, dies wird aber bereits innerhalb
des Ger\"ats von einem eingebauten Controller verwaltet und erscheint f\"ur
den Kernel als normales Block-Device (wie eine Festplatte). NAND-typische
Eigenschaften wie die Gr\"o\ss e eines Eraseblocks bleiben dem Kernel unbekannt.
\subsubsection{Das MTD-Subsystem im Kernel}
Wie im Linux-Kernel \"ublich, werden die Treiber gleichartiger Ger\"ate von
einem eigenen Subsystem verwaltet. Diese Vorgehensweise erm\"oglicht eine
einheitliche Schnittstelle dieser Ger\"ate, ohne dass sich die einzelnen
Treiber darum k\"ummern m\"ussten. Ausserdem vereinfacht es die Entwicklung
von Treibern, da ihre Struktur vorgegeben ist, und sie sich nicht mehr
um immer wiederkehrenden generischen Code oder das Interface zum
Userspace k\"ummern m\"ussen.
\paragraph{Was das MTD-Subsystem im Kernel macht...}
Das MTD-Subsystem verwaltet zun\"achst die physikalische Struktur eines
Chips, kennt also z.B. dessen Zusammensetzung aus einer gewissen Anzahl
von Erasebl\"ocken bestimmter Gr\"o\ss e, wobei jeder Eraseblock wiederum
aus Pages bestimmter Gr\"o\ss e bestehen kann (NAND).
Jeder Chip kann wiederum in mehrere Partitionen aufgeteilt werden. F\"ur
jede Partition legt das MTD-Subsystem ein eigenes Device an, also
bei drei Partitionen \cmd{/dev/mtd0}, \cmd{/dev/mtd1} und \cmd{/dev/mtd2}.
F\"ur den Anwender ergibt sich hier bereits die erste Abstrahierung, da er
nicht mehr wissen muss, ob hinter diesen Devices NAND oder NOR steckt,
oder ob es sich um einen oder mehrere Chips handelt.
Anhand dieser Device-Dateien kann jetzt auf die einzelnen Partitionen
zugegriffen werden. Dabei k\"onnen Datenbl\"ocke gelesen und geschrieben
werden, ausserdem k\"onnen Erasebl\"ocke gel\"oscht werden.
\paragraph{...und was das MTD-Subsystem \emph{nicht} macht...}
Das MTD-Subsystem wurde bewusst als sehr d\"unner Abstraktions-Layer
angelegt. Es geht lediglich um die einheitliche Schnittstelle und
den einfachen Zugriff auf den Flash-Speicher. Aufwendigere Techniken
werden je nach Anwendung von anderen Teilen des Kernels erledigt.
So verf\"ugt ein mtd-Device weder \"uber ein Dateisystem noch \"uber
Wear-Leveling. Bad Blocks werden zwar unterschieden, der Anwender wird
aber nicht daran gehindert, dennoch in diese zu schreiben.
Ausser der NAND-eigenen ECC-Fehlerkorrektur gibt es keine weiteren
Schutzmechanismen, falls beim Schreiben der Strom ausf\"allt, gehen
Daten verloren.
\paragraph{Erweiterungen}
Aus historischen Gr\"unden verf\"ugt der Kernel noch \"uber den \cmd{mtdblock}-
Treiber. Dieser emuliert f\"ur ein mtd-Device \cmd{/dev/mtd0} ein
zugeh\"origes Block-Device \cmd{/dev/mtdblock0}. Da es sich dabei um ein
normales Blockdevice handelt, k\"onnen auch normale Dateisysteme wie
ext2 oder FAT aufgebracht werden. Ausserdem k\"ummert sich \cmd{mtdblock}
beim Schreiben um das L\"oschen der entsprechenden Eraseblocks.
Da \cmd{mtdblock} aber weder Wear-Leveling noch Schutzmassnahmen einf\"uhrt,
und ausserdem vor allem durch schlechte Performance auff\"allt, kann von
seinem Einsatz nur abgeraten werden.
\"Ahnliches gilt f\"ur die ebenfalls vorhandenen Flash-Translation-Layer (FTL).
Obwohl diese teilweise bessere Features mitbringen, gelten sie mangels
Interesse als veraltet und schlecht gewartet.
Durch die Einf\"uhrung von UBI und ubifs sind derartige MTD-Erweiterungen
f\"ur die meisten Anwendungen schlicht \"uberfl\"ussig geworden.
\subsubsection{MTD-Tools}
Um auf mtd-Devices zugreifen zu k\"onnen, haben die MTD-Entwickler eine Reihe
von Tools entwickelt, die von den meisten Distributionen als Paket bereit
gestellt werden. Unter Debian installiert man die Tools beispielsweise mit
\begin{lstlisting}
aptitude install mtd-utils
\end{lstlisting}
Hier eine \"Ubersicht \"uber die wichtigsten Befehle:
L\"oschen einer Partition:
\begin{lstlisting}
flash_eraseall /dev/mtd0
\end{lstlisting}
L\"oschen einer Partition, gleichzeitig jffs2-Dateisystem aufbringen:
\begin{lstlisting}
flash_eraseall -j /dev/mtd0
\end{lstlisting}
Ein Image in eine Partition schreiben:
\begin{lstlisting}
nandwrite -p /dev/mtd0 myimage.bin
\end{lstlisting}
\emph{Beachte:} \cmd{nandwrite} ist das einzige Tool, mit dem man unter
Beachtung von Bad Blocks direkt in ein mtd-Device schreiben kann! Wenn man mit
konventionellen Tools wie \cmd{dd} in ein mtd-Device schreibt, so werden
auch Bad Blocks beschrieben, ohne dass dies zu einem Fehler f\"uhren w\"urde!
Daten aus einer Partition lesen:
\begin{lstlisting}
nanddump -s 0x10000 -l 0x2000 -p -f data.txt /dev/mtd0
\end{lstlisting}
Dieser Befehl liest Daten aus \cmd{/dev/mtd0}, und zwar 0x2000 Bytes ab
Startadresse 0x10000. Die Daten werden als lesbarer Hexdump (-p) in der
Datei \cmd{data.txt} gespeichert.
\emph{Hinweis:} Alle diese Tools kennen die Option \cmd{--help}, die alle
verf\"ugbaren Optionen auflistet und kurz erl\"autert.
\input{tailhandout}
|