关于.dts与.dtsi文件的区别、DTB生成差异及适用场景的咨询
Hey there! Let's break down the differences between .dts and .dtsi files, how they play into generating Device Tree Blobs (DTBs), and when to reach for each—this is a common point of confusion for folks getting into embedded Linux device trees, so I’m glad you asked.
Core Differences
At their core, these two file types serve distinct purposes, much like C source files vs. header files:
.dts(Device Tree Source): This is a board-specific device tree file. It holds all the hardware configurations unique to a single, specific board—think custom pin assignments for a particular LCD screen, board-specific button mappings, or tweaks to enable an on-board sensor that only this model has. Each unique hardware board typically gets its own.dtsfile..dtsi(Device Tree Source Include): This is a reusable device tree snippet, analogous to a C header. It’s meant to store shared hardware descriptions that multiple boards can use—like the core peripherals of an SoC (UART controllers, SPI buses, GPIO banks), or common bus definitions that apply to every board built on that chip. You’ll include.dtsifiles in.dts(or even other.dtsi) files using the#includedirective.
DTB Generation: Are There Differences?
Short answer: No, not in the final DTB output. When you compile device trees using the dtc (Device Tree Compiler) tool, the process works like this:
- The preprocessor first expands all included
.dtsifiles, merging their content with the main.dtsfile into a single, complete device tree source. - This merged source is then compiled into a single DTB binary.
So .dts and .dtsi are just organizational tools for humans—from the compiler’s perspective, they’re all just source fragments that get combined before building the DTB.
When to Use Each File Type
Reach for .dtsi when:
- You have multiple boards based on the same SoC: Extract the shared SoC-level hardware definitions into a
.dtsito avoid duplicating code across every board’s.dts. For example, all Raspberry Pi models using the BCM2711 chip would share abcm2711.dtsifile with core peripheral definitions. - You have reusable configuration snippets: If several boards or modules share a common peripheral setup (like a standard SPI flash configuration), put that in a
.dtsito keep your code DRY.
Reach for .dts when:
- You’re defining a specific, unique board: Use it to add board-only configurations on top of a shared
.dtsi. For example, if you have a custom BCM2711-based board with a unique LED array, you’d includebcm2711.dtsiand then add the LED setup in your custommy-custom-pi.dts. - You need a compilation entry point: The
dtctool expects a main source file to compile, and.dtsfiles are the standard choice for this (you can compile a.dtsidirectly, but that’s not typical since they’re meant to be reusable fragments).
Here’s a quick example to tie it all together:
// my-custom-board.dts (the main board file) #include "bcm2711.dtsi" / { model = "My Custom BCM2711 Board"; compatible = "my-company,bcm2711-custom", "brcm,bcm2711"; // Board-specific LED setup leds { compatible = "gpio-leds"; status-led { gpios = <&gpio 16 GPIO_ACTIVE_HIGH>; label = "my-board:green:status"; } }; }; // Override a peripheral from the .dtsi to enable it for this board &uart0 { status = "okay"; pinctrl-0 = <&uart0_tx_rx>; };
内容的提问来源于stack exchange,提问作者Leos313




