|
1 \documentclass[a4paper,twocolumn]{article} |
|
2 |
|
3 \usepackage{abstract} |
|
4 \usepackage{xspace} |
|
5 \usepackage{amssymb} |
|
6 \usepackage{latexsym} |
|
7 \usepackage{tabularx} |
|
8 \usepackage[T1]{fontenc} |
|
9 \usepackage{calc} |
|
10 \usepackage{listings} |
|
11 \usepackage{color} |
|
12 \usepackage{url} |
|
13 |
|
14 \title{Device trees everywhere} |
|
15 |
|
16 \author{David Gibson \texttt{<{dwg}{@}{au1.ibm.com}>}\\ |
|
17 Benjamin Herrenschmidt \texttt{<{benh}{@}{kernel.crashing.org}>}\\ |
|
18 \emph{OzLabs, IBM Linux Technology Center}} |
|
19 |
|
20 \newcommand{\R}{\textsuperscript{\textregistered}\xspace} |
|
21 \newcommand{\tm}{\textsuperscript{\texttrademark}\xspace} |
|
22 \newcommand{\tge}{$\geqslant$} |
|
23 %\newcommand{\ditto}{\textquotedbl\xspace} |
|
24 |
|
25 \newcommand{\fixme}[1]{$\bigstar$\emph{\textbf{\large #1}}$\bigstar$\xspace} |
|
26 |
|
27 \newcommand{\ppc}{\mbox{PowerPC}\xspace} |
|
28 \newcommand{\of}{Open Firmware\xspace} |
|
29 \newcommand{\benh}{Ben Herrenschmidt\xspace} |
|
30 \newcommand{\kexec}{\texttt{kexec()}\xspace} |
|
31 \newcommand{\dtbeginnode}{\texttt{OF\_DT\_BEGIN\_NODE\xspace}} |
|
32 \newcommand{\dtendnode}{\texttt{OF\_DT\_END\_NODE\xspace}} |
|
33 \newcommand{\dtprop}{\texttt{OF\_DT\_PROP\xspace}} |
|
34 \newcommand{\dtend}{\texttt{OF\_DT\_END\xspace}} |
|
35 \newcommand{\dtc}{\texttt{dtc}\xspace} |
|
36 \newcommand{\phandle}{\texttt{linux,phandle}\xspace} |
|
37 \begin{document} |
|
38 |
|
39 \maketitle |
|
40 |
|
41 \begin{abstract} |
|
42 We present a method for booting a \ppc{}\R Linux\R kernel on an |
|
43 embedded machine. To do this, we supply the kernel with a compact |
|
44 flattened-tree representation of the system's hardware based on the |
|
45 device tree supplied by Open Firmware on IBM\R servers and Apple\R |
|
46 Power Macintosh\R machines. |
|
47 |
|
48 The ``blob'' representing the device tree can be created using \dtc |
|
49 --- the Device Tree Compiler --- that turns a simple text |
|
50 representation of the tree into the compact representation used by |
|
51 the kernel. The compiler can produce either a binary ``blob'' or an |
|
52 assembler file ready to be built into a firmware or bootwrapper |
|
53 image. |
|
54 |
|
55 This flattened-tree approach is now the only supported method of |
|
56 booting a \texttt{ppc64} kernel without Open Firmware, and we plan |
|
57 to make it the only supported method for all \texttt{powerpc} |
|
58 kernels in the future. |
|
59 \end{abstract} |
|
60 |
|
61 \section{Introduction} |
|
62 |
|
63 \subsection{OF and the device tree} |
|
64 |
|
65 Historically, ``everyday'' \ppc machines have booted with the help of |
|
66 \of (OF), a firmware environment defined by IEEE1275 \cite{IEEE1275}. |
|
67 Among other boot-time services, OF maintains a device tree that |
|
68 describes all of the system's hardware devices and how they're |
|
69 connected. During boot, before taking control of memory management, |
|
70 the Linux kernel uses OF calls to scan the device tree and transfer it |
|
71 to an internal representation that is used at run time to look up |
|
72 various device information. |
|
73 |
|
74 The device tree consists of nodes representing devices or |
|
75 buses\footnote{Well, mostly. There are a few special exceptions.}. |
|
76 Each node contains \emph{properties}, name--value pairs that give |
|
77 information about the device. The values are arbitrary byte strings, |
|
78 and for some properties, they contain tables or other structured |
|
79 information. |
|
80 |
|
81 \subsection{The bad old days} |
|
82 |
|
83 Embedded systems, by contrast, usually have a minimal firmware that |
|
84 might supply a few vital system parameters (size of RAM and the like), |
|
85 but nothing as detailed or complete as the OF device tree. This has |
|
86 meant that the various 32-bit \ppc embedded ports have required a |
|
87 variety of hacks spread across the kernel to deal with the lack of |
|
88 device tree. These vary from specialised boot wrappers to parse |
|
89 parameters (which are at least reasonably localised) to |
|
90 CONFIG-dependent hacks in drivers to override normal probe logic with |
|
91 hardcoded addresses for a particular board. As well as being ugly of |
|
92 itself, such CONFIG-dependent hacks make it hard to build a single |
|
93 kernel image that supports multiple embedded machines. |
|
94 |
|
95 Until relatively recently, the only 64-bit \ppc machines without OF |
|
96 were legacy (pre-POWER5\R) iSeries\R machines. iSeries machines often |
|
97 only have virtual IO devices, which makes it quite simple to work |
|
98 around the lack of a device tree. Even so, the lack means the iSeries |
|
99 boot sequence must be quite different from the pSeries or Macintosh, |
|
100 which is not ideal. |
|
101 |
|
102 The device tree also presents a problem for implementing \kexec. When |
|
103 the kernel boots, it takes over full control of the system from OF, |
|
104 even re-using OF's memory. So, when \kexec comes to boot another |
|
105 kernel, OF is no longer around for the second kernel to query. |
|
106 |
|
107 \section{The Flattened Tree} |
|
108 |
|
109 In May 2005 \benh implemented a new approach to handling the device |
|
110 tree that addresses all these problems. When booting on OF systems, |
|
111 the first thing the kernel runs is a small piece of code in |
|
112 \texttt{prom\_init.c}, which executes in the context of OF. This code |
|
113 walks the device tree using OF calls, and transcribes it into a |
|
114 compact, flattened format. The resulting device tree ``blob'' is then |
|
115 passed to the kernel proper, which eventually unflattens the tree into |
|
116 its runtime form. This blob is the only data communicated between the |
|
117 \texttt{prom\_init.c} bootstrap and the rest of the kernel. |
|
118 |
|
119 When OF isn't available, either because the machine doesn't have it at |
|
120 all or because \kexec has been used, the kernel instead starts |
|
121 directly from the entry point taking a flattened device tree. The |
|
122 device tree blob must be passed in from outside, rather than generated |
|
123 by part of the kernel from OF. For \kexec, the userland |
|
124 \texttt{kexec} tools build the blob from the runtime device tree |
|
125 before invoking the new kernel. For embedded systems the blob can |
|
126 come either from the embedded bootloader, or from a specialised |
|
127 version of the \texttt{zImage} wrapper for the system in question. |
|
128 |
|
129 \subsection{Properties of the flattened tree} |
|
130 |
|
131 The flattened tree format should be easy to handle, both for the |
|
132 kernel that parses it and the bootloader that generates it. In |
|
133 particular, the following properties are desirable: |
|
134 |
|
135 \begin{itemize} |
|
136 \item \emph{relocatable}: the bootloader or kernel should be able to |
|
137 move the blob around as a whole, without needing to parse or adjust |
|
138 its internals. In practice that means we must not use pointers |
|
139 within the blob. |
|
140 \item \emph{insert and delete}: sometimes the bootloader might want to |
|
141 make tweaks to the flattened tree, such as deleting or inserting a |
|
142 node (or whole subtree). It should be possible to do this without |
|
143 having to effectively regenerate the whole flattened tree. In |
|
144 practice this means limiting the use of internal offsets in the blob |
|
145 that need recalculation if a section is inserted or removed with |
|
146 \texttt{memmove()}. |
|
147 \item \emph{compact}: embedded systems are frequently short of |
|
148 resources, particularly RAM and flash memory space. Thus, the tree |
|
149 representation should be kept as small as conveniently possible. |
|
150 \end{itemize} |
|
151 |
|
152 \subsection{Format of the device tree blob} |
|
153 \label{sec:format} |
|
154 |
|
155 \begin{figure}[htb!] |
|
156 \centering |
|
157 \footnotesize |
|
158 \begin{tabular}{r|c|l} |
|
159 \multicolumn{1}{r}{\textbf{Offset}}& \multicolumn{1}{c}{\textbf{Contents}} \\\cline{2-2} |
|
160 \texttt{0x00} & \texttt{0xd00dfeed} & magic number \\\cline{2-2} |
|
161 \texttt{0x04} & \emph{totalsize} \\\cline{2-2} |
|
162 \texttt{0x08} & \emph{off\_struct} & \\\cline{2-2} |
|
163 \texttt{0x0C} & \emph{off\_strs} & \\\cline{2-2} |
|
164 \texttt{0x10} & \emph{off\_rsvmap} & \\\cline{2-2} |
|
165 \texttt{0x14} & \emph{version} \\\cline{2-2} |
|
166 \texttt{0x18} & \emph{last\_comp\_ver} & \\\cline{2-2} |
|
167 \texttt{0x1C} & \emph{boot\_cpu\_id} & \tge v2 only\\\cline{2-2} |
|
168 \texttt{0x20} & \emph{size\_strs} & \tge v3 only\\\cline{2-2} |
|
169 \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} |
|
170 \emph{off\_rsvmap} & \emph{address0} & memory reserve \\ |
|
171 + \texttt{0x04} & ...& table \\\cline{2-2} |
|
172 + \texttt{0x08} & \emph{len0} & \\ |
|
173 + \texttt{0x0C} & ...& \\\cline{2-2} |
|
174 \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} |
|
175 & \texttt{0x00000000}- & end marker\\ |
|
176 & \texttt{00000000} & \\\cline{2-2} |
|
177 & \texttt{0x00000000}- & \\ |
|
178 & \texttt{00000000} & \\\cline{2-2} |
|
179 \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} |
|
180 \emph{off\_strs} & \texttt{'n' 'a' 'm' 'e'} & strings block \\ |
|
181 + \texttt{0x04} & \texttt{~0~ 'm' 'o' 'd'} & \\ |
|
182 + \texttt{0x08} & \texttt{'e' 'l' ~0~ \makebox[\widthof{~~~}]{\textrm{...}}} & \\ |
|
183 \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} |
|
184 \multicolumn{1}{r}{+ \emph{size\_strs}} \\ |
|
185 \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} |
|
186 \emph{off\_struct} & \dtbeginnode & structure block \\\cline{2-2} |
|
187 + \texttt{0x04} & \texttt{'/' ~0~ ~0~ ~0~} & root node\\\cline{2-2} |
|
188 + \texttt{0x08} & \dtprop & \\\cline{2-2} |
|
189 + \texttt{0x0C} & \texttt{0x00000005} & ``\texttt{model}''\\\cline{2-2} |
|
190 + \texttt{0x10} & \texttt{0x00000008} & \\\cline{2-2} |
|
191 + \texttt{0x14} & \texttt{'M' 'y' 'B' 'o'} & \\ |
|
192 + \texttt{0x18} & \texttt{'a' 'r' 'd' ~0~} & \\\cline{2-2} |
|
193 \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} |
|
194 & \texttt{\dtendnode} \\\cline{2-2} |
|
195 & \texttt{\dtend} \\\cline{2-2} |
|
196 \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} |
|
197 \multicolumn{1}{r}{\emph{totalsize}} \\ |
|
198 \end{tabular} |
|
199 \caption{Device tree blob layout} |
|
200 \label{fig:blob-layout} |
|
201 \end{figure} |
|
202 |
|
203 The format for the blob we devised, was first described on the |
|
204 \texttt{linuxppc64-dev} mailing list in \cite{noof1}. The format has |
|
205 since evolved through various revisions, and the current version is |
|
206 included as part of the \dtc (see \S\ref{sec:dtc}) git tree, |
|
207 \cite{dtcgit}. |
|
208 |
|
209 Figure \ref{fig:blob-layout} shows the layout of the blob of data |
|
210 containing the device tree. It has three sections of variable size: |
|
211 the \emph{memory reserve table}, the \emph{structure block} and the |
|
212 \emph{strings block}. A small header gives the blob's size and |
|
213 version and the locations of the three sections, plus a handful of |
|
214 vital parameters used during early boot. |
|
215 |
|
216 The memory reserve map section gives a list of regions of memory that |
|
217 the kernel must not use\footnote{Usually such ranges contain some data |
|
218 structure initialised by the firmware that must be preserved by the |
|
219 kernel.}. The list is represented as a simple array of (address, |
|
220 size) pairs of 64 bit values, terminated by a zero size entry. The |
|
221 strings block is similarly simple, consisting of a number of |
|
222 null-terminated strings appended together, which are referenced from |
|
223 the structure block as described below. |
|
224 |
|
225 The structure block contains the device tree proper. Each node is |
|
226 introduced with a 32-bit \dtbeginnode tag, followed by the node's name |
|
227 as a null-terminated string, padded to a 32-bit boundary. Then |
|
228 follows all of the properties of the node, each introduced with a |
|
229 \dtprop tag, then all of the node's subnodes, each introduced with |
|
230 their own \dtbeginnode tag. The node ends with an \dtendnode tag, and |
|
231 after the \dtendnode for the root node is an \dtend tag, indicating |
|
232 the end of the whole tree\footnote{This is redundant, but included for |
|
233 ease of parsing.}. The structure block starts with the \dtbeginnode |
|
234 introducing the description of the root node (named \texttt{/}). |
|
235 |
|
236 Each property, after the \dtprop, has a 32-bit value giving an offset |
|
237 from the beginning of the strings block at which the property name is |
|
238 stored. Because it's common for many nodes to have properties with |
|
239 the same name, this approach can substantially reduce the total size |
|
240 of the blob. The name offset is followed by the length of the |
|
241 property value (as a 32-bit value) and then the data itself padded to |
|
242 a 32-bit boundary. |
|
243 |
|
244 \subsection{Contents of the tree} |
|
245 \label{sec:treecontents} |
|
246 |
|
247 Having seen how to represent the device tree structure as a flattened |
|
248 blob, what actually goes into the tree? The short answer is ``the |
|
249 same as an OF tree''. On OF systems, the flattened tree is |
|
250 transcribed directly from the OF device tree, so for simplicity we |
|
251 also use OF conventions for the tree on other systems. |
|
252 |
|
253 In many cases a flat tree can be simpler than a typical OF provided |
|
254 device tree. The flattened tree need only provide those nodes and |
|
255 properties that the kernel actually requires; the flattened tree |
|
256 generally need not include devices that the kernel can probe itself. |
|
257 For example, an OF device tree would normally include nodes for each |
|
258 PCI device on the system. A flattened tree need only include nodes |
|
259 for the PCI host bridges; the kernel will scan the buses thus |
|
260 described to find the subsidiary devices. The device tree can include |
|
261 nodes for devices where the kernel needs extra information, though: |
|
262 for example, for ISA devices on a subsidiary PCI/ISA bridge, or for |
|
263 devices with unusual interrupt routing. |
|
264 |
|
265 Where they exist, we follow the IEEE1275 bindings that specify how to |
|
266 describe various buses in the device tree (for example, |
|
267 \cite{IEEE1275-pci} describe how to represent PCI devices). The |
|
268 standard has not been updated for a long time, however, and lacks |
|
269 bindings for many modern buses and devices. In particular, embedded |
|
270 specific devices such as the various System-on-Chip buses are not |
|
271 covered. We intend to create new bindings for such buses, in keeping |
|
272 with the general conventions of IEEE1275 (a simple such binding for a |
|
273 System-on-Chip bus was included in \cite{noof5} a revision of |
|
274 \cite{noof1}). |
|
275 |
|
276 One complication arises for representing ``phandles'' in the flattened |
|
277 tree. In OF, each node in the tree has an associated phandle, a |
|
278 32-bit integer that uniquely identifies the node\footnote{In practice |
|
279 usually implemented as a pointer or offset within OF memory.}. This |
|
280 handle is used by the various OF calls to query and traverse the tree. |
|
281 Sometimes phandles are also used within the tree to refer to other |
|
282 nodes in the tree. For example, devices that produce interrupts |
|
283 generally have an \texttt{interrupt-parent} property giving the |
|
284 phandle of the interrupt controller that handles interrupts from this |
|
285 device. Parsing these and other interrupt related properties allows |
|
286 the kernel to build a complete representation of the system's |
|
287 interrupt tree, which can be quite different from the tree of bus |
|
288 connections. |
|
289 |
|
290 In the flattened tree, a node's phandle is represented by a special |
|
291 \phandle property. When the kernel generates a flattened tree from |
|
292 OF, it adds a \phandle property to each node, containing the phandle |
|
293 retrieved from OF. When the tree is generated without OF, however, |
|
294 only nodes that are actually referred to by phandle need to have this |
|
295 property. |
|
296 |
|
297 Another complication arises because nodes in an OF tree have two |
|
298 names. First they have the ``unit name'', which is how the node is |
|
299 referred to in an OF path. The unit name generally consists of a |
|
300 device type followed by an \texttt{@} followed by a \emph{unit |
|
301 address}. For example \texttt{/memory@0} is the full path of a memory |
|
302 node at address 0, \texttt{/ht@0,f2000000/pci@1} is the path of a PCI |
|
303 bus node, which is under a HyperTransport\tm bus node. The form of |
|
304 the unit address is bus dependent, but is generally derived from the |
|
305 node's \texttt{reg} property. In addition, nodes have a property, |
|
306 \texttt{name}, whose value is usually equal to the first path of the |
|
307 unit name. For example, the nodes in the previous example would have |
|
308 \texttt{name} properties equal to \texttt{memory} and \texttt{pci}, |
|
309 respectively. To save space in the blob, the current version of the |
|
310 flattened tree format only requires the unit names to be present. |
|
311 When the kernel unflattens the tree, it automatically generates a |
|
312 \texttt{name} property from the node's path name. |
|
313 |
|
314 \section{The Device Tree Compiler} |
|
315 \label{sec:dtc} |
|
316 |
|
317 \begin{figure}[htb!] |
|
318 \centering |
|
319 \begin{lstlisting}[frame=single,basicstyle=\footnotesize\ttfamily, |
|
320 tabsize=3,numbers=left,xleftmargin=2em] |
|
321 /memreserve/ 0x20000000-0x21FFFFFF; |
|
322 |
|
323 / { |
|
324 model = "MyBoard"; |
|
325 compatible = "MyBoardFamily"; |
|
326 #address-cells = <2>; |
|
327 #size-cells = <2>; |
|
328 |
|
329 cpus { |
|
330 #address-cells = <1>; |
|
331 #size-cells = <0>; |
|
332 PowerPC,970@0 { |
|
333 device_type = "cpu"; |
|
334 reg = <0>; |
|
335 clock-frequency = <5f5e1000>; |
|
336 timebase-frequency = <1FCA055>; |
|
337 linux,boot-cpu; |
|
338 i-cache-size = <10000>; |
|
339 d-cache-size = <8000>; |
|
340 }; |
|
341 }; |
|
342 |
|
343 memory@0 { |
|
344 device_type = "memory"; |
|
345 memreg: reg = <00000000 00000000 |
|
346 00000000 20000000>; |
|
347 }; |
|
348 |
|
349 mpic@0x3fffdd08400 { |
|
350 /* Interrupt controller */ |
|
351 /* ... */ |
|
352 }; |
|
353 |
|
354 pci@40000000000000 { |
|
355 /* PCI host bridge */ |
|
356 /* ... */ |
|
357 }; |
|
358 |
|
359 chosen { |
|
360 bootargs = "root=/dev/sda2"; |
|
361 linux,platform = <00000600>; |
|
362 interrupt-controller = |
|
363 < &/mpic@0x3fffdd08400 >; |
|
364 }; |
|
365 }; |
|
366 \end{lstlisting} |
|
367 \caption{Example \dtc source} |
|
368 \label{fig:dts} |
|
369 \end{figure} |
|
370 |
|
371 As we've seen, the flattened device tree format provides a convenient |
|
372 way of communicating device tree information to the kernel. It's |
|
373 simple for the kernel to parse, and simple for bootloaders to |
|
374 manipulate. On OF systems, it's easy to generate the flattened tree |
|
375 by walking the OF maintained tree. However, for embedded systems, the |
|
376 flattened tree must be generated from scratch. |
|
377 |
|
378 Embedded bootloaders are generally built for a particular board. So, |
|
379 it's usually possible to build the device tree blob at compile time |
|
380 and include it in the bootloader image. For minor revisions of the |
|
381 board, the bootloader can contain code to make the necessary tweaks to |
|
382 the tree before passing it to the booted kernel. |
|
383 |
|
384 The device trees for embedded boards are usually quite simple, and |
|
385 it's possible to hand construct the necessary blob by hand, but doing |
|
386 so is tedious. The ``device tree compiler'', \dtc{}\footnote{\dtc can |
|
387 be obtained from \cite{dtcgit}.}, is designed to make creating device |
|
388 tree blobs easier by converting a text representation of the tree |
|
389 into the necessary blob. |
|
390 |
|
391 \subsection{Input and output formats} |
|
392 |
|
393 As well as the normal mode of compiling a device tree blob from text |
|
394 source, \dtc can convert a device tree between a number of |
|
395 representations. It can take its input in one of three different |
|
396 formats: |
|
397 \begin{itemize} |
|
398 \item source, the normal case. The device tree is described in a text |
|
399 form, described in \S\ref{sec:dts}. |
|
400 \item blob (\texttt{dtb}), the flattened tree format described in |
|
401 \S\ref{sec:format}. This mode is useful for checking a pre-existing |
|
402 device tree blob. |
|
403 \item filesystem (\texttt{fs}), input is a directory tree in the |
|
404 layout of \texttt{/proc/device-tree} (roughly, a directory for each |
|
405 node in the device tree, a file for each property). This is useful |
|
406 for building a blob for the device tree in use by the currently |
|
407 running kernel. |
|
408 \end{itemize} |
|
409 |
|
410 In addition, \dtc can output the tree in one of three different |
|
411 formats: |
|
412 \begin{itemize} |
|
413 \item blob (\texttt{dtb}), as in \S\ref{sec:format}. The most |
|
414 straightforward use of \dtc is to compile from ``source'' to |
|
415 ``blob'' format. |
|
416 \item source (\texttt{dts}), as in \S\ref{sec:dts}. If used with blob |
|
417 input, this allows \dtc to act as a ``decompiler''. |
|
418 \item assembler source (\texttt{asm}). \dtc can produce an assembler |
|
419 file, which will assemble into a \texttt{.o} file containing the |
|
420 device tree blob, with symbols giving the beginning of the blob and |
|
421 its various subsections. This can then be linked directly into a |
|
422 bootloader or firmware image. |
|
423 \end{itemize} |
|
424 |
|
425 For maximum applicability, \dtc can both read and write any of the |
|
426 existing revisions of the blob format. When reading, \dtc takes the |
|
427 version from the blob header, and when writing it takes a command line |
|
428 option specifying the desired version. It automatically makes any |
|
429 necessary adjustments to the tree that are necessary for the specified |
|
430 version. For example, formats before 0x10 require each node to have |
|
431 an explicit \texttt{name} property. When \dtc creates such a blob, it |
|
432 will automatically generate \texttt{name} properties from the unit |
|
433 names. |
|
434 |
|
435 \subsection{Source format} |
|
436 \label{sec:dts} |
|
437 |
|
438 The ``source'' format for \dtc is a text description of the device |
|
439 tree in a vaguely C-like form. Figure \ref{fig:dts} shows an |
|
440 example. The file starts with \texttt{/memreserve/} directives, which |
|
441 gives address ranges to add to the output blob's memory reserve table, |
|
442 then the device tree proper is described. |
|
443 |
|
444 Nodes of the tree are introduced with the node name, followed by a |
|
445 \texttt{\{} ... \texttt{\};} block containing the node's properties |
|
446 and subnodes. Properties are given as just {\emph{name} \texttt{=} |
|
447 \emph{value}\texttt{;}}. The property values can be given in any |
|
448 of three forms: |
|
449 \begin{itemize} |
|
450 \item \emph{string} (for example, \texttt{"MyBoard"}). The property |
|
451 value is the given string, including terminating NULL. C-style |
|
452 escapes (\verb+\t+, \verb+\n+, \verb+\0+ and so forth) are allowed. |
|
453 \item \emph{cells} (for example, \texttt{<0 8000 f0000000>}). The |
|
454 property value is made up of a list of 32-bit ``cells'', each given |
|
455 as a hex value. |
|
456 \item \emph{bytestring} (for example, \texttt{[1234abcdef]}). The |
|
457 property value is given as a hex bytestring. |
|
458 \end{itemize} |
|
459 |
|
460 Cell properties can also contain \emph{references}. Instead of a hex |
|
461 number, the source can give an ampersand (\texttt{\&}) followed by the |
|
462 full path to some node in the tree. For example, in Figure |
|
463 \ref{fig:dts}, the \texttt{/chosen} node has an |
|
464 \texttt{interrupt-controller} property referring to the interrupt |
|
465 controller described by the node \texttt{/mpic@0x3fffdd08400}. In the |
|
466 output tree, the value of the referenced node's phandle is included in |
|
467 the property. If that node doesn't have an explicit phandle property, |
|
468 \dtc will automatically create a unique phandle for it. This approach |
|
469 makes it easy to create interrupt trees without having to explicitly |
|
470 assign and remember phandles for the various interrupt controller |
|
471 nodes. |
|
472 |
|
473 The \dtc source can also include ``labels'', which are placed on a |
|
474 particular node or property. For example, Figure \ref{fig:dts} has a |
|
475 label ``\texttt{memreg}'' on the \texttt{reg} property of the node |
|
476 \texttt{/memory@0}. When using assembler output, corresponding labels |
|
477 in the output are generated, which will assemble into symbols |
|
478 addressing the part of the blob with the node or property in question. |
|
479 This is useful for the common case where an embedded board has an |
|
480 essentially fixed device tree with a few variable properties, such as |
|
481 the size of memory. The bootloader for such a board can have a device |
|
482 tree linked in, including a symbol referring to the right place in the |
|
483 blob to update the parameter with the correct value determined at |
|
484 runtime. |
|
485 |
|
486 \subsection{Tree checking} |
|
487 |
|
488 Between reading in the device tree and writing it out in the new |
|
489 format, \dtc performs a number of checks on the tree: |
|
490 \begin{itemize} |
|
491 \item \emph{syntactic structure}: \dtc checks that node and property |
|
492 names contain only allowed characters and meet length restrictions. |
|
493 It checks that a node does not have multiple properties or subnodes |
|
494 with the same name. |
|
495 \item \emph{semantic structure}: In some cases, \dtc checks that |
|
496 properties whose contents are defined by convention have appropriate |
|
497 values. For example, it checks that \texttt{reg} properties have a |
|
498 length that makes sense given the address forms specified by the |
|
499 \texttt{\#address-cells} and \texttt{\#size-cells} properties. It |
|
500 checks that properties such as \texttt{interrupt-parent} contain a |
|
501 valid phandle. |
|
502 \item \emph{Linux requirements}: \dtc checks that the device tree |
|
503 contains those nodes and properties that are required by the Linux |
|
504 kernel to boot correctly. |
|
505 \end{itemize} |
|
506 |
|
507 These checks are useful to catch simple problems with the device tree, |
|
508 rather than having to debug the results on an embedded kernel. With |
|
509 the blob input mode, it can also be used for diagnosing problems with |
|
510 an existing blob. |
|
511 |
|
512 \section{Future Work} |
|
513 |
|
514 \subsection{Board ports} |
|
515 |
|
516 The flattened device tree has always been the only supported way to |
|
517 boot a \texttt{ppc64} kernel on an embedded system. With the merge of |
|
518 \texttt{ppc32} and \texttt{ppc64} code it has also become the only |
|
519 supported way to boot any merged \texttt{powerpc} kernel, 32-bit or |
|
520 64-bit. In fact, the old \texttt{ppc} architecture exists mainly just |
|
521 to support the old ppc32 embedded ports that have not been migrated |
|
522 to the flattened device tree approach. We plan to remove the |
|
523 \texttt{ppc} architecture eventually, which will mean porting all the |
|
524 various embedded boards to use the flattened device tree. |
|
525 |
|
526 \subsection{\dtc features} |
|
527 |
|
528 While it is already quite usable, there are a number of extra features |
|
529 that \dtc could include to make creating device trees more convenient: |
|
530 \begin{itemize} |
|
531 \item \emph{better tree checking}: Although \dtc already performs a |
|
532 number of checks on the device tree, they are rather haphazard. In |
|
533 many cases \dtc will give up after detecting a minor error early and |
|
534 won't pick up more interesting errors later on. There is a |
|
535 \texttt{-f} parameter that forces \dtc to generate an output tree |
|
536 even if there are errors. At present, this needs to be used more |
|
537 often than one might hope, because \dtc is bad at deciding which |
|
538 errors should really be fatal, and which rate mere warnings. |
|
539 \item \emph{binary include}: Occasionally, it is useful for the device |
|
540 tree to incorporate as a property a block of binary data for some |
|
541 board-specific purpose. For example, many of Apple's device trees |
|
542 incorporate bytecode drivers for certain platform devices. \dtc's |
|
543 source format ought to allow this by letting a property's value be |
|
544 read directly from a binary file. |
|
545 \item \emph{macros}: it might be useful for \dtc to implement some |
|
546 sort of macros so that a tree containing a number of similar devices |
|
547 (for example, multiple identical ethernet controllers or PCI buses) |
|
548 can be written more quickly. At present, this can be accomplished |
|
549 in part by running the source file through CPP before compiling with |
|
550 \dtc. It's not clear whether ``native'' support for macros would be |
|
551 more useful. |
|
552 \end{itemize} |
|
553 |
|
554 \bibliographystyle{amsplain} |
|
555 \bibliography{dtc-paper} |
|
556 |
|
557 \section*{About the authors} |
|
558 |
|
559 David Gibson has been a member of the IBM Linux Technology Center, |
|
560 working from Canberra, Australia, since 2001. Recently he has worked |
|
561 on Linux hugepage support and performance counter support for ppc64, |
|
562 as well as the device tree compiler. In the past, he has worked on |
|
563 bringup for various ppc and ppc64 embedded systems, the orinoco |
|
564 wireless driver, ramfs, and a userspace checkpointing system |
|
565 (\texttt{esky}). |
|
566 |
|
567 Benjamin Herrenschmidt was a MacOS developer for about 10 years, but |
|
568 ultimately saw the light and installed Linux on his Apple PowerPC |
|
569 machine. After writing a bootloader, BootX, for it in 1998, he |
|
570 started contributing to the PowerPC Linux port in various areas, |
|
571 mostly around the support for Apple machines. He became official |
|
572 PowerMac maintainer in 2001. In 2003, he joined the IBM Linux |
|
573 Technology Center in Canberra, Australia, where he ported the 64 bit |
|
574 PowerPC kernel to Apple G5 machines and the Maple embedded board, |
|
575 among others things. He's a member of the ppc64 development ``team'' |
|
576 and one of his current goals is to make the integration of embedded |
|
577 platforms smoother and more maintainable than in the 32-bit PowerPC |
|
578 kernel. |
|
579 |
|
580 \section*{Legal Statement} |
|
581 |
|
582 This work represents the view of the author and does not necessarily |
|
583 represent the view of IBM. |
|
584 |
|
585 IBM, \ppc, \ppc Architecture, POWER5, pSeries and iSeries are |
|
586 trademarks or registered trademarks of International Business Machines |
|
587 Corporation in the United States and/or other countries. |
|
588 |
|
589 Apple and Power Macintosh are a registered trademarks of Apple |
|
590 Computer Inc. in the United States, other countries, or both. |
|
591 |
|
592 Linux is a registered trademark of Linus Torvalds. |
|
593 |
|
594 Other company, product, and service names may be trademarks or service |
|
595 marks of others. |
|
596 |
|
597 \end{document} |