Test: Device trees, overlays and kernel drivers
Device Trees, Overlays and Kernel Drivers
Why a device tree: I2C devices cannot introduce themselves
When you plug in a USB or PCIe device, the kernel reads its vendor and product IDs and loads a driver. I2C, SPI and GPIO devices have no way to do that. A DS3231 at 0x68 never says what it is, and an I2C scan only shows that something answers at 0x68 (the IMU lab’s ITG-3205 answers at the same address). So something has to tell the kernel what is wired to the board. On ARM boards that is the device tree: a description of the hardware that the firmware loads and passes to the kernel at boot. Before device trees, each ARM board had its own C “board file” compiled into the kernel. Step through the greenhouse Pi’s boot and watch when the kernel learns about each part.
Challenge: Step through the whole boot until the DS3231 is /dev/rtc0.
Discoverable buses
USB and PCIe devices report vendor and product IDs when asked; the kernel picks a driver from those.
Non-discoverable
I2C, SPI and GPIO have nothing to ask. A device answers its address, and that is all.
The device tree
A description of the hardware, loaded by the firmware and passed to the kernel at boot.
- ▶ Power on. The boot ROM starts the bootloader. Linux is not running, and nothing has been described yet.
- Firmware reads config.txt. It finds dtparam=i2c_arm=on and dtoverlay=i2c-rtc,ds3231. (On a Pi 4 the firmware is start4.elf on the boot partition; on a Pi 5 it is the bootloader in the EEPROM.)
- Loads the base tree. bcm2711-rpi-4-b.dtb describes the SoC and what is soldered to the board: the I2C controllers, the GPIO controller, the ACT LED. Nothing about your header.
- Applies the overlays. i2c-rtc.dtbo adds a ds3231@68 node under I2C1 and the dtparam sets the controller’s status to "okay". The merged tree is handed to the kernel.
- Kernel reads the tree. It creates a device for every enabled node: an I2C client called 1-0068, with compatible "maxim,ds3231". No driver has looked at it yet.
- A driver binds. rtc-ds1307 lists "maxim,ds3231" in its match table; its probe() reads the chip over I2C and registers /dev/rtc0.
Stage
1 of 6
/dev/rtc0
not yet
The relay and the button stay undescribed in this boot. That is fine: user space can use them through libgpiod (the GPIO lab). The kernel only needs a node for hardware a kernel driver will drive.
© 2026 Derek Molloy, Dublin City University. All rights reserved.
Spot an error, omission, or have a suggestion?
Submit an errata report here.