the device tree
On a PC, the kernel can ask the PCI and USB buses 'what is plugged in?' and they answer with a list — the hardware is self-describing. But on many embedded boards (think a phone or a router chip), the hardware just sits there: a UART at some fixed address, an I2C controller at another, wired to specific interrupt lines, with no way to enumerate them. How does the kernel learn what exists and where? The device tree is a data file that describes that non-discoverable hardware to the kernel.
Concretely, the device tree is a tree of nodes, each describing one piece of hardware: its type (a 'compatible' string like "ti,omap4-uart"), the physical address of its registers, which interrupt it uses, its clocks, and so on. It is written in a source format (.dts), compiled to a compact binary blob (.dtb), and handed to the kernel at boot by the bootloader. When the kernel boots, it walks the tree; for each node it finds the driver whose 'compatible' string matches and calls that driver's probe with the node's properties, so the driver learns its register address and IRQ from the tree rather than having them hard-coded. On x86 and many servers, the equivalent role is played by ACPI tables, which the firmware provides for the same purpose of describing fixed hardware and power management.
The device tree matters because it decouples the kernel from board-specific wiring: one kernel binary can run on many boards, each supplying its own device tree, instead of needing the addresses baked into the code. An honest distinction: device tree (and ACPI) are for hardware that cannot announce itself. Discoverable buses like PCI and USB do not need it — they are enumerated at runtime. And the device tree only describes hardware; it is not a driver and contains no code. A wrong address or interrupt in the .dts produces a driver that probes but talks to the wrong place.
// a device-tree node (.dts) describing a UART: uart0: serial@4806a000 { compatible = "ti,omap4-uart"; // which driver matches reg = <0x4806a000 0x100>; // register address, size interrupts = <72>; // which IRQ line }; // the kernel matches 'compatible' to a driver and probes it
A device-tree node tells the kernel a device's type, register address, and IRQ — data, not code — so the matching driver can probe it.
Device tree and ACPI describe only non-discoverable hardware and contain no driver code; discoverable buses (PCI, USB) are enumerated at runtime and need neither. A wrong reg/interrupt in the .dts misdirects an otherwise-correct driver.