|
|
Subscribe / Log in / New account

ELCE: Grant Likely on device trees

By Jake Edge
November 10, 2010

Device trees are a fairly hot topic in the embedded Linux world as a means to more easily support multiple system-on-chip (SoC) devices with a single kernel image. Much of the work implementing device trees for the PowerPC architecture, as well as making that code more generic so that others could use it, has been done by Grant Likely. He spoke at the recent Embedded Linux Conference Europe (ELCE) to explain what device trees are, what they can do, and to update the attendees on efforts to allow the ARM architecture use them.

[Grant Likely]

All of the work that is going into adding device tree support for various architectures is not being done for an immediate benefit to users, Likely said. It is, instead, being done to make it easier to manage embedded Linux distributions, while simplifying the boot process. It will also make it easier to port devices (i.e. components and "IP blocks") to different SoCs. But it is "not going to make your Android phone faster".

A device tree is just a data structure that came from OpenFirmware. It represents the devices that are part of particular system, such that it can be passed to the kernel at boot time, and the kernel can initialize and use those devices. For architectures that don't use device trees, C code must be written to add all of the different devices that are present in the hardware. Unlike desktop and server systems, many embedded SoCs do not provide a way to enumerate their devices at boot time. That means developers have to hardcode the devices, their addresses, interrupts, and so on, into the kernel.

The requirement to put all of the device definitions into C code is hard to manage, Likely said. Each different SoC variant has to have its own, slightly tweaked kernel version. In addition, the full configuration of the device is scattered over multiple C files, rather than kept in a single place. Device trees can change all of that.

A device tree consists of a set of nodes with properties, which are simple key-value pairs. The nodes are organized into a tree structure, unsurprisingly, and the property values can store arbitrary data types. In addition, there are some standard usage conventions for properties so that they can be reused in various ways. The most important of these is the compatible property that uniquely defines devices, but there are also conventions for specifying address ranges, IRQs, GPIOs, and so forth.

Likely used a simplified example from devicetree.org to show what these trees look like. They are defined with an essentially C-like syntax:

    / {
	compatible = "acme,coyotes-revenge";

	cpus {
	    cpu@0 {
		compatible = "arm,cortex-a9";
	    };
	    cpu@1 {
		compatible = "arm,cortex-a9";
	    };
	};

	serial@101F0000 {
	    compatible = "arm,pl011";
	};
        ...
	external-bus {
	    ethernet@0,0 {
		compatible = "smc,smc91c111";
	    };

	    i2c@1,0 {
		compatible = "acme,a1234-i2c-bus";
		rtc@58 {
		    compatible = "maxim,ds1338";
		};
	    };
            ...

The compatible tags allow companies to define their own namespace ("acme", "arm", "smc", and "maxim" in the example) that they can manage however they like. The kernel already knows how to attach an ethernet device to a local bus or a temperature sensor to an i2c bus, so why redo it in C for every different SoC, he asked. By parsing the device tree (or the binary "flattened" device tree), the kernel can set up the device bindings that it finds in the tree.

One of the questions that he often gets asked is: "why bother changing what we already have?" That is a "hard question to answer" in some ways, because for a lot of situations, what we have in the kernel currently does work. But in order to support large numbers of SoCs with a single kernel (or perhaps a small set of kernels), something like device tree is required. Both Google (for Android) and Canonical (for Linaro) are very interested in seeing device tree support for ARM.

Beyond that, "going data-driven to describe our platforms is the right thing to do". There is proof that it works in the x86 world as "that's how it's been done for a long time". PowerPC converted to device trees five years ago or so and it works well. There may be architectures that won't need to support multiple devices with a single kernel, and device trees may not be the right choice for those, but for most of the architectures that Linux supports, Likely clearly thinks that device trees are the right solution.

He next looked at what device trees aren't. They don't replace board-specific code, and developers will "still have to write drivers for weird stuff". Instead, device trees simplify the common case. Device tree is also not a boot architecture, it's "just a data structure". Ideally, the firmware will pass a device tree to the kernel at boot time, but it doesn't have to be done that way. The device tree could be included into the kernel image. There are plenty of devices with firmware that doesn't know about device trees, Likely said, and they won't have to.

There is currently a push to get ARM devices into servers, as they can provide lots of cores at low power usage. In order to facilitate that, there needs to be one CD that can boot any of those servers, like it is in the x86 world. Device trees are what will be used to make that happen, Likely said.

Firmware that does support device trees will obtain a .dtb (i.e. flattened device tree binary) file from somewhere in memory, and either pass it verbatim to the kernel or modify it before passing. Another option would be for the firmware to create the .dtb on-the-fly, which is what OpenFirmware does, but that is a "dangerous" option. It is much easier to change the kernel than the firmware, so any bugs in the firmware's .dtb creation code will inevitably be worked around in the kernel. In any case, the kernel doesn't care how the .dtb is created.

For ARM, the plan is to pass a device tree, rather than the existing, rather inflexible ARM device configuration known as ATAGs. The kernel will set up the memory for the processor and unflatten the .dtb into memory. It will unpack it into a "live tree" that can then be directly dereferenced and used by the kernel to register devices.

The Linux device model is also tree-based, and there is some congruence between device tree and the device model, but there is not a direct 1-to-1 mapping between them. That was done "quite deliberately" as the design goal was "not to describe what Linux wants", instead it was meant to describe the hardware. Over time, the Linux device model will change, so hardcoding Linux-specific values into the device tree has been avoided. The device tree is meant to be used as support data, and the devices it describes get registered using the Linux device model.

Device drivers will match compatible property values with device nodes in a device tree. It is the driver that will determine how to configure the device based on its description in a device tree. None of that configuration code lives in the device tree handling, it is part of the drivers which can then be built as loadable kernel modules.

Over the last year, Likely has spent a lot of time making the device tree support be generic. Previously, there were three separate copies of much of the support code (for Microblaze, SPARC, and PowerPC). He has removed any endian dependencies so that any architecture can use device trees. Most of that work is now done and in the mainline. There is some minimal board support that has not yet been mainlined. The MIPS architecture has added device tree support as of 2.6.37-rc1 and x86 was close to getting it for 2.6.37, but some last minute changes caused the x86 device tree support to be held back until 2.6.38.

The ARM architecture still doesn't have device tree support and ARM maintainer Russell King is "nervous about merging an unmaintainable mess". King is taking a wait-and-see approach until a real ARM board has device tree support. Likely agreed with that approach and ELCE provided an opportunity for him and King to sit down and discuss the issue. In the next six months or so (2.6.39 or 2.6.40), Likely expects that the board support will be completed and he seems confident that ARM device tree support in the mainline won't be far behind.

There are other tasks to complete in addition to the board support, of course, with documentation being high on that list. There is a need for documentation on how to use device trees, and on the property conventions that are being used. The devicetree.org wiki is a gathering point for much of that work.

There were several audience questions that Likely addressed, including the suitability of device tree for Video4Linux (very suitable and the compatible property gives each device manufacturer its own namespace), the performance impact (no complaints, though he hasn't profiled it — device trees are typically 4-8K in size, which should minimize their impact), and licensing or patent issues (none known so far, the code is under a BSD license so it can be used by proprietary vendors — IBM's lawyers don't seem concerned). Overall, both Likely and the audience seemed very optimistic about the future for device trees in general and specifically for their future application in the ARM architecture.


Index entries for this article
KernelDevice tree


to post comments

ELCE: Grant Likely on device trees

Posted Nov 11, 2010 5:40 UTC (Thu) by glikely (subscriber, #39601) [Link]

Thanks for the coverage Jake.

A few words of clarification: First off, while I was peripherally involved with the initial migration of all powerpc support to use a device tree, the credit for most of the heavy lifting goes to others like Paul Mackerras, Ben Herrenschmidt, Becky Bruce, David Gibson and others. I'm building on their work, and many thanks go to tbem.

Second, while I know that Canonical and Linaro are both committed to device tree support, I cannot comment on Google's plans. As it stands, Brian Swetland from Android has eloquently expressed his skepticism about the device tree approach and has no intention of using it (which is fine; the current code allows dt and non-dt platforms to coexist. Board ports are not forced to use a dt).

ELCE: Grant Likely on device trees

Posted Nov 11, 2010 11:10 UTC (Thu) by etienne (guest, #25256) [Link] (2 responses)

I still would like to know what is better using a device tree than using a standard relocatable (common to all ARM) kernel and running a last linker command for each ARM configuration.
Anyway, if the bus cannot be queried for what it contains and at which address - that means that those address are constant and at some point the kernel has to know them.
So the same kernel with few relocations would be distributed to all ARMs targets, and each target would have to do a partial and final "ld" with a linker command file containning something like:

smc91c111_base = 0x1532000;
rtc_ds1338_v1 = 0;
rtc_ds1338_v2 = 0x15325000;
memcpy = memcopy_cortex_a9;

Each driver should check that the base address of its device is not null before trying to initialise itself.
If a higher level description is needed, a tool can be used to generate that linker command file.
Maybe there is something I am missing?

ELCE: Grant Likely on device trees

Posted Nov 11, 2010 11:39 UTC (Thu) by kronos (subscriber, #55879) [Link] (1 responses)

You can add information about addresses and interrupts (and also device specific data) to the tree. There are example on http://devicetree.org

ELCE: Grant Likely on device trees

Posted Nov 11, 2010 12:16 UTC (Thu) by etienne (guest, #25256) [Link]

Well, I do not see the problem of having:
serial_irq = 3;
network_irq = 4;
in the linker microcontroller-dependant-file,
and you can include explicit data in this file too:
http://sourceware.org/binutils/docs-2.20/ld/Output-Sectio...
You could even include binary blob if that is your aim.

ELCE: Grant Likely on device trees

Posted Nov 12, 2010 23:48 UTC (Fri) by giraffedata (guest, #1954) [Link]

The most important of these is the compatible property that uniquely defines devices

It does nothing of the kind. compatible classifies the device according to how you use it -- it essentially tells you what device driver to use for it. Lots of devices have the same compatible property and it normally takes additional properties to completely and uniquely define any one of these.

ELCE: Grant Likely on device trees

Posted Nov 23, 2010 22:35 UTC (Tue) by jgg (subscriber, #55211) [Link] (1 responses)

I recently converted some old PPC code from the 'C' way to the device tree way and for the most part things were about the same.

However, what really made a big difference was how much device tree cleans up the mess of GPIO, MDIO, I2C and other ancillary stuff.

For instance our SOCs have a ethernet MAC driver that needs to speak to the PHY using MDIO over a certain bus. The bus, address and PHY chip changes depending on the platform, and several ethernet MACs often have to share the same MDIO. With device tree we specify all these relationships in the DT and things work great. The proper phy driver is loaded and attached to the MDIO, the proper MAC attaches to that, etc.

Something similar happens with I2C as well, I2C auto probing doesn't work for real embedded systems, DTS cleans that up wonderfully. The C version it replaced was horrid.

Frankly, I'm surprised at the reluctance from the ARM community. Just expressing the existing C code to setup each unique platform as a device tree and hard-wiring the tree into the kernel would clean things up a lot, without really changing how anything functions.

The arguments I've seen for DT seem to think all the world is an eval board. I've never implemented an embedded CPU that matched an eval board exactly - we *always* change things. Generally we've had to #ifdef through the BSP for the eval board to get things working, it is an ugly mess that won't be upstreamed.

ELCE: Grant Likely on device trees

Posted Nov 23, 2010 22:45 UTC (Tue) by dlang (guest, #313) [Link]

I'm confused, the arguments against device trees seem to be that they have C code to document every eval board so they don't need device trees.

the arguments _for_ device trees seems to be that real-world devices largely contain the same types of devices as you find on eval boards, but hooked up in different ways, so the device tree tells the system how they are hooked up without having to have every system be it's own defineition in C.


Copyright © 2010, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds