This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement: ------------------
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
Current state of the art (downstream): --------------------------------------
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
The issues I'm aware of with the current state of the art are:
1. In order for the base device tree to pass schema validation on its own we'd need to document the top-level compatible strings in the device tree. It is the opinion of at least some device tree maintainers that a SoC doesn't qualify as a top-level compatible string. This prevents the device trees from landing in an officially sanctioned location.
2. It is also possible we may fail schema validation for the base SoC tree if the schema marks a property as "required" but that property needs to be filled out by the board (perhaps a "-supply" is marked as "required", since most "-supply" properties are filled in by the board. I'm not sure this is a big issue, but it's something to think about.
3. It's unclear if there is any official "ABI" promised here once we've compiled and validated the base device tree on its own. Will people assume that they can have out-of-tree overlays derived from the base SoC tree and that those out-of-tree overlays will continue to work across changes / cleanups to the base? NOTE: this is a pre-existing question for existing device tree overlay usage, but the sheer quantity of nodes/properties that a board would be expected to overlay/modify in the base make the problem more prominent.
4. We want the final device tree's top-level compatible to be all the compatible strings from the board followed by all of the compatible strings for the SoC. When the board's overlay is applied to the base SoC tree, though, the board's top-level compatible fully replaces the compatible from the base SoC tree. This can be solved today for non-socketed boards by just duplicating the SoC compatible strings in the board overlays. We can't solve this today for socketed boards, though we can simply make sure that no software drivers rely on the specific SoC compatible string being present and thus we can ignore the problem.
None of the above problems are big enough to have prevented widespread use of this scheme in downstream Android.
Current state of the art (upstream): ------------------------------------
Upstream if we have a pile of related boards, we do allow deduplicating things at a source-code level with "dtsi" files. We can have a SoC "dtsi" file and that file is included by all boards that use that SoC. When it comes time to validate or ship things, though, we only work with full devices trees. This means that we ship duplicated information.
Proposal: ---------
1. Allow the top-level compatible string of an "incomplete" device tree to be documented so it can be validated on its own by tools. It's understood that this SoC is not a board by itself and we'd never boot a full OS with this device tree without adding an overlay that changes the top-level compatible. Add a top-level property to the device tree (perhaps "incomplete-compatible;") to indicate that the tree is not complete without an overlay.
2. If it turns out to be needed (hopefully it's not), allow some type of syntax in yaml files that allows a property to be marked as "required" in a "complete" device tree but not in an "incomplete" device tree. Alternatively, we could discourage marking properties as "required" if they're expected to be filled in by a board.
3. Define that there is no promised ABI between "incomplete" device trees and anything not stored with them. Specifically, all valid combinations of "incomplete" device trees with overlays to complete them should be enumerated together with the "incomplete" device tree.
4. When applying an overlay to a device tree that's "incomplete", the top level overlay will be merged instead of replaced.
Example for 2 levels:
base (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc"; overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard"; merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc";
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename"; overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", "socvendor,mysoc-rev1", "socvendor,mysoc";
Obviously in the 3-level scheme we need to know the order that overlays are applied, but that's true for overlays today anyway.
The above proposal takes the current downstream "state of the art" and addresses the known issues, solving the original problem statement.
Other thoughts: ---------------
If you don't like the proposal, I'd be interested in knowing if you have other ideas for solving the original problem statement, or if you simply think the problem we're trying to solve here is an invalid one.
I'm happy to post up another revision of my Pixel 10 device trees following this proof of concept (or other ones). My v1 was _very_ close to this, but didn't have the "incomplete-compatible;" property and didn't implement top-level compatible merging.
[1] https://lore.kernel.org/r/20251111112158.1.I72a0b72562b85d02fee424fed939fea9... [2] https://source.android.com/docs/core/architecture/dto/partitions
- When applying an overlay to a device tree that's "incomplete", the
top level overlay will be merged instead of replaced.
Example for 2 levels:
base (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc"; overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard"; merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc";
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename"; overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", , "socvendor,mysoc";
Sorry, I only cursorily followed the previous discussion so I may have missed the exact need for this part. But I would caution against any proposal that changes the basic rules of how an overlay is applied. The definition of how overlays work has (I think?) been stable for over a decade now, and is implemented in bootloaders that often cannot easily be updated. I absolutely support your effort to get more upstream standardization for managing base device trees and overlays (which I think need to be flexible for arbitrary layers, not just SoC and board), but let's not break the overlay code in old bootloaders while doing it.
Is there really a need to merge the compatible strings in your case? I think in the vast majority of platform identification cases, code only cares about matching the most precise string (i.e. "boardvendor,myboard-rev1"). If we do feel like having the whole chain of identification is necessary, it could be achieved by just copy&pasting the extra strings into the overlay file. If we have cross-validation between base and overlay source files we could also have the validation check that the overlays correctly contain all compatible strings from their base tree. If we know that the base trees aren't standalone anyway, we could also just invent other property names that identify them (e.g. `soc-compatible = "socvendor,mysoc";`). Anything other than breaking the overlay format would be preferable in my opinion.
I also feel like we need a better standardized way to tie base device trees to overlays, like your `/loaders` node proposal in an earlier email, although maybe that's an orthogonal discussion (but related, especially if there's supposed to be cross-validation between base trees and overlays). The compatible string is just not a scalable way for bootloaders to make this determination, there may be a lot more differentiation than just "SoC" and "board", and the scheme almost certainly needs to be platform/bootloader-specific because every hardware vendor has their own ideas about how to group and reuse parts of a platform. This information doesn't necessarily need to be *in* the device tree, it could also just be in a separate YAML file in the same repo (since bootloaders will almost certainly want to have it transformed into their own out-of-band descriptor at build-time anyway, so that they can compress the device tree itself and don't have to decompress each one for matching), but it needs to be somewhere.
Hi,
On Tue, Nov 18, 2025 at 3:48 PM Julius Werner jwerner@chromium.org wrote:
- When applying an overlay to a device tree that's "incomplete", the
top level overlay will be merged instead of replaced.
Example for 2 levels:
base (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc"; overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard"; merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc";
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename"; overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", , "socvendor,mysoc";
Sorry, I only cursorily followed the previous discussion so I may have missed the exact need for this part. But I would caution against any proposal that changes the basic rules of how an overlay is applied. The definition of how overlays work has (I think?) been stable for over a decade now, and is implemented in bootloaders that often cannot easily be updated. I absolutely support your effort to get more upstream standardization for managing base device trees and overlays (which I think need to be flexible for arbitrary layers, not just SoC and board), but let's not break the overlay code in old bootloaders while doing it.
Is there really a need to merge the compatible strings in your case? I think in the vast majority of platform identification cases, code only cares about matching the most precise string (i.e. "boardvendor,myboard-rev1"). If we do feel like having the whole chain of identification is necessary, it could be achieved by just copy&pasting the extra strings into the overlay file. If we have cross-validation between base and overlay source files we could also have the validation check that the overlays correctly contain all compatible strings from their base tree. If we know that the base trees aren't standalone anyway, we could also just invent other property names that identify them (e.g. `soc-compatible = "socvendor,mysoc";`). Anything other than breaking the overlay format would be preferable in my opinion.
I'm certainly not dead-set on it and I definitely realize it would be a pain. ...though it wouldn't necessarily "break" the format--you just wouldn't be able to use any "incomplete" DTBs unless you implemented this new feature.
From my point of view, the main issue the merging solves is handling "socketed" boards that could have any of a small number of SoCs plugged into them (usually minor revs of the same SoC). It's not the absolutely most critical use case in the world, but I know that we will need it in-house and I'm trying to come up with a solution that will work everywhere. Once we decide to go with a downstream solution just for that one use case then there's no reason not to do everything else in a downstream manner.
Personally, I've never really loved that the SoC compatible strings are conventionally just jammed onto the end of the top-level compatible and I'm totally happy with it being elsewhere (a different property, a different node, etc). Mostly I ended up with this merging scheme because I thought that was what DT folks were pushing for. If I'm wrong then I'm more than happy with a different scheme.
I also feel like we need a better standardized way to tie base device trees to overlays, like your `/loaders` node proposal in an earlier email, although maybe that's an orthogonal discussion (but related, especially if there's supposed to be cross-validation between base trees and overlays). The compatible string is just not a scalable way for bootloaders to make this determination, there may be a lot more differentiation than just "SoC" and "board", and the scheme almost certainly needs to be platform/bootloader-specific because every hardware vendor has their own ideas about how to group and reuse parts of a platform. This information doesn't necessarily need to be *in* the device tree, it could also just be in a separate YAML file in the same repo (since bootloaders will almost certainly want to have it transformed into their own out-of-band descriptor at build-time anyway, so that they can compress the device tree itself and don't have to decompress each one for matching), but it needs to be somewhere.
Yes, I totally agree and this is an important conversation to have too. I still like the "/loaders" proposal but I'm not dead-set on it.
That being said, the two problems are separate even if they're related to each other. I was attempting to focus on allowing the base DTBs to land first and once we get agreement then move onto the second. I'll also note that Chen-Yu is talking about the problem at Linux Plumbers. I won't be there, but I'm going to try to attend that session remotely.
-Doug
Hi,
On Tue, Nov 18, 2025 at 2:43 PM Doug Anderson dianders@chromium.org wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
It's been roughly two weeks since I sent out this proposal. Do DT folks have any comments? Are the goals I have stated understood? Do people agree that these goals are reasonable? Is there any question that there is a need to solve these problems not just for Google, but for the community as a whole? I'm happy to reach out to people and have them reply "yes, I have this problem too" if it would somehow help. I don't doubt that there are still people at Qualcomm who would like a solution even if I think Elliot isn't driving it there anymore...
How do we make forward progress? Does anyone have any comments on Julius's reply? At the moment, I think there are some conflicts with what Julius would like to see (no changes to the rules for how overlays are applied) and what Rob said previously (we need to find some way to combine the compatible strings). Did I misunderstand? Can we find a common ground?
Thanks!
-Doug
On Mon, Dec 01, 2025 at 09:42:40AM -0800, Doug Anderson wrote:
Hi,
On Tue, Nov 18, 2025 at 2:43 PM Doug Anderson dianders@chromium.org wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
It's been roughly two weeks since I sent out this proposal. Do DT folks have any comments? Are the goals I have stated understood? Do people agree that these goals are reasonable? Is there any question that there is a need to solve these problems not just for Google, but for the community as a whole? I'm happy to reach out to people and have them reply "yes, I have this problem too" if it would somehow help. I don't doubt that there are still people at Qualcomm who would like a solution even if I think Elliot isn't driving it there anymore...
How do we make forward progress? Does anyone have any comments on Julius's reply? At the moment, I think there are some conflicts with what Julius would like to see (no changes to the rules for how overlays are applied) and what Rob said previously (we need to find some way to combine the compatible strings). Did I misunderstand? Can we find a common ground?
My feeling on this (and I don't have much time to consider it tonight) is that this isn't going to get a quick answer.
This answer is based on my authorship of various device trees, and is solely my own opinion, and in no way represents any position by my employer.
While the DT files are dual-licensed, the license that applies to the copy in the kernel is GPL v2, because the kernel as a whole is GPL v2 licensed. The dual-licensing of the DT files is to permit them to be taken from the kernel and used in e.g. boot loaders etc.
However, as the license that applies to the kernel copy is GPL v2, and GPL v2 requires distribution in source code form, or an offer valid for two years of the corresponding source code etc (check the GPL v2 for the exact terms) it could be inappropriate for the kernel tree to distribute binary DT blobs without their corresponding source.
It seems to me that this is a problem for lawyers, and you're probably not going to get a quick answer on it.
So, I'd suggest patience, and don't expect this topic to move quickly.
Hi,
On Mon, Dec 1, 2025 at 10:28 AM Russell King (Oracle) linux@armlinux.org.uk wrote:
On Mon, Dec 01, 2025 at 09:42:40AM -0800, Doug Anderson wrote:
Hi,
On Tue, Nov 18, 2025 at 2:43 PM Doug Anderson dianders@chromium.org wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
It's been roughly two weeks since I sent out this proposal. Do DT folks have any comments? Are the goals I have stated understood? Do people agree that these goals are reasonable? Is there any question that there is a need to solve these problems not just for Google, but for the community as a whole? I'm happy to reach out to people and have them reply "yes, I have this problem too" if it would somehow help. I don't doubt that there are still people at Qualcomm who would like a solution even if I think Elliot isn't driving it there anymore...
How do we make forward progress? Does anyone have any comments on Julius's reply? At the moment, I think there are some conflicts with what Julius would like to see (no changes to the rules for how overlays are applied) and what Rob said previously (we need to find some way to combine the compatible strings). Did I misunderstand? Can we find a common ground?
My feeling on this (and I don't have much time to consider it tonight) is that this isn't going to get a quick answer.
This answer is based on my authorship of various device trees, and is solely my own opinion, and in no way represents any position by my employer.
While the DT files are dual-licensed, the license that applies to the copy in the kernel is GPL v2, because the kernel as a whole is GPL v2 licensed. The dual-licensing of the DT files is to permit them to be taken from the kernel and used in e.g. boot loaders etc.
However, as the license that applies to the kernel copy is GPL v2, and GPL v2 requires distribution in source code form, or an offer valid for two years of the corresponding source code etc (check the GPL v2 for the exact terms) it could be inappropriate for the kernel tree to distribute binary DT blobs without their corresponding source.
It seems to me that this is a problem for lawyers, and you're probably not going to get a quick answer on it.
So, I'd suggest patience, and don't expect this topic to move quickly.
It seems like perhaps I wasn't clear enough in my description of the problem I'm trying to solve. I'm not trying to change anything about the licensing or where the device tree source is stored / distributed. This is all about packaging. As you can see further in the original patch series I pointed at [1] that I include both the base and the overlay source code [2]. I just want to organize things such that SoC-related nodes and properties are in the base device tree (whether "dts" or "dtb") and then we use an overlay ("dtso" or "dtbo") to end up with a combined device tree that represents a complete board.
Today, there are no technical reasons stopping people from doing this and many phones (including Google Pixel phones) ship their device trees like this.
That being said, we can't land device trees like this upstream because the base device tree for the SoC is not "complete" and can't pass yaml validation.
According to Krzysztof, this is simply policy. As he says: "SoC does not meet this criteria, therefore it is not suitable for DTS" [3]
If I read his response properly, Rob wasn't dead-set on this being against policy. He said "I think it is worth having the discussion" [4]. He was concerned that the final compatible string needed to be a combination of the base and the overlay.
My goal is to find a solution where upstream would accept device trees that are split into a base for the SoC and an overlay to "complete" the board..
There are no legal questions here. I don't even believe that there is any true technical complexity, really. There are a few small differences in the way we can slice a solution and how we do it will certainly have impacts, but I don't believe that some magic solution is going to come up and make everyone happy (someone should feel free to prove me wrong, though!). This means we have to either decide this isn't a problem worth solving or we have to pick some compromise about how this works. At this point, I'm fine with any answer (even a definitive statement that this isn't a problem that upstream wants to solve). I'm not terribly happy with just ignoring it for another year or three.
[1] https://lore.kernel.org/r/20251111112158.1.I72a0b72562b85d02fee424fed939fea9... [2] https://lore.kernel.org/r/20251111112158.4.I5032910018cdd7d6be7aea78870d04c0... [3] https://lore.kernel.org/all/20251114-elite-refined-yak-bf9e64@kuoka/ [4] https://lore.kernel.org/all/20251113022719.GA2281498-robh@kernel.org/
-Doug
Hi Dough,
thanks for your mail!
Let me just see if I understand correctly what you're trying to do (and apparently actively doing in production):
On Tue, Nov 18, 2025 at 11:43 PM Doug Anderson dianders@chromium.org wrote:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
(...)
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
So in the kernel we have several arch/*/boot/dts/vendor/ folders where they have:
soc.dtsi included by board.dtsi included by system.dts and the top system.dts is all that get compiled.
So what you say is that you do the same thing but at runtime?
Can you just describe why this is done like this with overlays?
I can only guess that you have one bootloader that needs to compose device trees to many systems and the bootloader only discovers the system it is running on and its constraints at runtime, so shipping the static system.dtb as many people do is not an option for you?
And the reason the bootloader doesn't already know what it is running on and doesn't just pass that one device tree or is just prepared with that one device tree has something to do with manufacturing or so?
Sorry it just evades me.
Probably becayse even U-Boot these days use the provided device tree dtb, for the system targeted, to initialize itself. I suppose your bootloader is generic enough to avoid that chicken-and-egg problem, right?
I guess if I had this problem:
soc.dtsi board-a.dtsi board-b.dtsi system-board-a-v1.dts system-board-a-v2.dts system-board-b-v1.dts
etc having to be combined at runtime, in a bootloader, I would consider shipping exactly these files in a memory-based filesystem in my bootloader, and bake a DTS compiler into my bootloader so it can just build a device tree for what it detects.
But I guess you didn't want to hear that :D
Anyway, please describe how you ended up in this situation, I'm trying to understand this.
It is quite clear that device tree overlays were intended for say plug-n-play additions and minor fragments to be added to a basically complete device tree, what you are doing was probably not how it was intended. (Or let's see if someone proves me wrong on that.)
Yours, Linus Walleij
Hi,
On Mon, Dec 1, 2025 at 3:52 PM Linus Walleij linusw@kernel.org wrote:
Hi Dough,
thanks for your mail!
Let me just see if I understand correctly what you're trying to do (and apparently actively doing in production):
Thanks for your thoughts. Just to be clear, even though I've dealt with device trees on a lot of ChromeOS boards, this is something that _Android_ phones are doing in production and is what I'm focusing on here. The whole scheme is at least roughly documented at:
https://source.android.com/docs/core/architecture/dto/partitions
This is all stuff that predates me looking at Android. I'm just coming in and trying to make sense of what's there and trying to upstream what I can.
Separately, it can be noted that we always _wanted_ a similar solution for ChromeOS, but we never quite got there... ;-)
On Tue, Nov 18, 2025 at 11:43 PM Doug Anderson dianders@chromium.org wrote:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
(...)
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
So in the kernel we have several arch/*/boot/dts/vendor/ folders where they have:
soc.dtsi included by board.dtsi included by system.dts and the top system.dts is all that get compiled.
So what you say is that you do the same thing but at runtime?
Essentially. In this case, we don't ship the device tree _sources_ but ship _compiled_ device tree. We compile the SoC into a "dtb" and then combine anything above the SoC into a single "dtbo". We ship several "dtb" files and several "dtbo" files and combine them at runtime after we identify which hardware we're running on.
Can you just describe why this is done like this with overlays?
I can only guess that you have one bootloader that needs to compose device trees to many systems and the bootloader only discovers the system it is running on and its constraints at runtime, so shipping the static system.dtb as many people do is not an option for you?
And the reason the bootloader doesn't already know what it is running on and doesn't just pass that one device tree or is just prepared with that one device tree has something to do with manufacturing or so?
Sorry it just evades me.
Our builder creates a single "image" that can be flashed onto any number of devices. Users (or manufacturers) can download and install this single image and it will work on a wide variety of devices. So you can download a single "Pixel 10" image that can be installed on any of the Pixel 10 devices (Pixel 10, Pixel 10 Pro, and Pixel 10 Pro XL). It will also work on our development board and early pre-production variants of those boards.
In order for this to work, we need a lot of device trees and _something_ needs to pick the correct one. Right now, the bootloader is in charge of this task.
If we had less variety of products that we needed to ship then, yes, we could just ship the one device tree and have a separate build for each product. ...but that doesn't scale terribly well.
Probably becayse even U-Boot these days use the provided device tree dtb, for the system targeted, to initialize itself. I suppose your bootloader is generic enough to avoid that chicken-and-egg problem, right?
FWIW: I believe even U-boot supports shipping a pile of device trees and detecting things at runtime. See the "FIT" image:
https://docs.u-boot.org/en/latest/usage/fit/index.html
I guess if I had this problem:
soc.dtsi board-a.dtsi board-b.dtsi system-board-a-v1.dts system-board-a-v2.dts system-board-b-v1.dts
etc having to be combined at runtime, in a bootloader, I would consider shipping exactly these files in a memory-based filesystem in my bootloader, and bake a DTS compiler into my bootloader so it can just build a device tree for what it detects.
But I guess you didn't want to hear that :D
You're saying to just ship device tree source instead of binary? Hmmm, it's an interesting idea. It wouldn't be _terrible_ since "dtb" stores a lot of strings to begin with, but I think it would still add enough of a bloat to make it a no-go for us... I would also imagine it would be a pain to deal with #include of header files with #defines. Do we somehow partially pre-process the device tree files but don't apply the #include files. It might be possible to solve some specific cases, but having this work in a generic way seems miserable.
Anyway, please describe how you ended up in this situation, I'm trying to understand this.
The main goal is just building/shipping one image to support a variety of similar products and trying to save space by not repeating the SoC bits over and over again.
It is quite clear that device tree overlays were intended for say plug-n-play additions and minor fragments to be added to a basically complete device tree, what you are doing was probably not how it was intended. (Or let's see if someone proves me wrong on that.)
Not sure what makes that so clear, since it's not clear to me. In any case, even if device tree overlays weren't intended for such a usage, they actually seem to work fairly well for it, even if upstream currently rejects device tree usage like this.
FWIW, the fact that bootloaders (like U-Boot) have the ability to apply overlays makes me think that _someone_ intended them to be used similar to how Android is using them. ;-) If it was just expansion cards then (presumably) someone would boot to Linux and just apply overlays from there. See:
https://docs.u-boot.org/en/latest/usage/fit/overlay-fdt-boot.html
-Doug
On Tue, Nov 18, 2025 at 5:48 PM Julius Werner jwerner@chromium.org wrote:
- When applying an overlay to a device tree that's "incomplete", the
top level overlay will be merged instead of replaced.
Example for 2 levels:
base (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc"; overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard"; merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc";
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename";
I don't understand this one...
overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", , "socvendor,mysoc";
Sorry, I only cursorily followed the previous discussion so I may have missed the exact need for this part. But I would caution against any proposal that changes the basic rules of how an overlay is applied. The definition of how overlays work has (I think?) been stable for over a decade now, and is implemented in bootloaders that often cannot easily be updated. I absolutely support your effort to get more upstream standardization for managing base device trees and overlays (which I think need to be flexible for arbitrary layers, not just SoC and board), but let's not break the overlay code in old bootloaders while doing it.
I think merging compatibles is orthogonal to splitting SoC and board DTs. Doug needs to merge because there is more than 1 SoC version or base DT to pick. In many cases (SoC revision compatibles are the exception upstream), there is only 1 SoC DT and N board DTs. So we should consider both and define them separately. In the simple case, you'd have something like:
SoC (incomplete) compatible: "socvendor,mysoc" Board overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc"
Then you just apply the overlay and it overwrites the incomplete compatible. That works with existing overlay applying (overwriting) for multiple steps as long as each step is a superset (compatible list) of the prior steps.
In Doug's case, I think you need code to decide which base to pick and then fixup the final compatible.
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" Board overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc"
And then after applying, you do the merge to insert the SoC rev compatible:
"boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc"
You need SoC specific code to know what SoC revision you are running on, so SoC specific post apply code should be fine too. There's not any existing bootloader problem because you need code to handle this.
Maybe that fixup will end up being generic enough that it's not platform specific, but that's an optimization of the implementation.
Is there really a need to merge the compatible strings in your case?
Well, you could just require duplicating an overlay N times for N bases, but that doesn't scale
I think in the vast majority of platform identification cases, code only cares about matching the most precise string (i.e. "boardvendor,myboard-rev1"). If we do feel like having the whole chain of identification is necessary, it could be achieved by just copy&pasting the extra strings into the overlay file. If we have cross-validation between base and overlay source files we could also have the validation check that the overlays correctly contain all compatible strings from their base tree. If we know that the base trees aren't standalone anyway, we could also just invent other property names that identify them (e.g. `soc-compatible = "socvendor,mysoc";`). Anything other than breaking the overlay format would be preferable in my opinion.
There's also a use case I'm aware of where the base DT is just for a SoM and then the bootloader applies an expansion board overlay. So it is not always "not standalone". And of course, this could be combined with what Doug wants to do.
Note that for any new property (or an incomplete compatible) like soc-compatible, you will need to consider how we validate it.
I also feel like we need a better standardized way to tie base device trees to overlays, like your `/loaders` node proposal in an earlier email, although maybe that's an orthogonal discussion (but related, especially if there's supposed to be cross-validation between base trees and overlays). The compatible string is just not a scalable way for bootloaders to make this determination, there may be a lot more differentiation than just "SoC" and "board", and the scheme almost certainly needs to be platform/bootloader-specific because every hardware vendor has their own ideas about how to group and reuse parts of a platform. This information doesn't necessarily need to be *in* the device tree, it could also just be in a separate YAML file in the same repo (since bootloaders will almost certainly want to have it transformed into their own out-of-band descriptor at build-time anyway, so that they can compress the device tree itself and don't have to decompress each one for matching), but it needs to be somewhere.
There is a proposal here[1]. It's simple, but I do wonder if looking at the root compatible only is too narrow of a view. An overlay could target a connector compatible for example.
We kind of have this information in the kernel build already as well. The requirement for overlays in the kernel tree is overlays get applied to at least one target at build time. It would be nice for any solution to this problem to replace those build rules.
Rob
[1] https://lore.kernel.org/all/20250911151436.2467758-1-raymond.mao@linaro.org/
On Mon, Dec 1, 2025 at 5:52 PM Linus Walleij linusw@kernel.org wrote:
Hi Dough,
thanks for your mail!
Let me just see if I understand correctly what you're trying to do (and apparently actively doing in production):
On Tue, Nov 18, 2025 at 11:43 PM Doug Anderson dianders@chromium.org wrote:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
(...)
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
So in the kernel we have several arch/*/boot/dts/vendor/ folders where they have:
soc.dtsi included by board.dtsi included by system.dts and the top system.dts is all that get compiled.
So what you say is that you do the same thing but at runtime?
Can you just describe why this is done like this with overlays?
I can only guess that you have one bootloader that needs to compose device trees to many systems and the bootloader only discovers the system it is running on and its constraints at runtime, so shipping the static system.dtb as many people do is not an option for you?
And the reason the bootloader doesn't already know what it is running on and doesn't just pass that one device tree or is just prepared with that one device tree has something to do with manufacturing or so?
Sorry it just evades me.
Probably becayse even U-Boot these days use the provided device tree dtb, for the system targeted, to initialize itself. I suppose your bootloader is generic enough to avoid that chicken-and-egg problem, right?
I guess if I had this problem:
soc.dtsi board-a.dtsi board-b.dtsi system-board-a-v1.dts system-board-a-v2.dts system-board-b-v1.dts
This is the easy case. The harder one is you have soc-rev1.dtsi and soc-rev2.dtsi and you just doubled the combinations.
etc having to be combined at runtime, in a bootloader, I would consider shipping exactly these files in a memory-based filesystem in my bootloader, and bake a DTS compiler into my bootloader so it can just build a device tree for what it detects.
We don't want to do that for the same reasons we don't pass a dts to the kernel...
But I guess you didn't want to hear that :D
Anyway, please describe how you ended up in this situation, I'm trying to understand this.
It is quite clear that device tree overlays were intended for say plug-n-play additions and minor fragments to be added to a basically complete device tree, what you are doing was probably not how it was intended. (Or let's see if someone proves me wrong on that.)
Board DTs are relatively minor compared to the SoC DT.
I would be interested in some experiments around making this change with existing DTs. Take a board DT and add the overlay boilerplate (that may be nothing more than add '/plugin/') and remove the SoC include. Does that apply to a compiled SoC DTB and is the result the same as before?
Think of it as moving from building C code using a #include of every .c file to build a single .o to linking multiple individual .o files. No one would argue the former is better.
Rob
On Tue, Dec 2, 2025 at 8:44 AM Doug Anderson dianders@chromium.org wrote:
Hi,
On Mon, Dec 1, 2025 at 3:52 PM Linus Walleij linusw@kernel.org wrote:
Hi Dough,
thanks for your mail!
Let me just see if I understand correctly what you're trying to do (and apparently actively doing in production):
Thanks for your thoughts. Just to be clear, even though I've dealt with device trees on a lot of ChromeOS boards, this is something that _Android_ phones are doing in production and is what I'm focusing on here. The whole scheme is at least roughly documented at:
https://source.android.com/docs/core/architecture/dto/partitions
This is all stuff that predates me looking at Android. I'm just coming in and trying to make sense of what's there and trying to upstream what I can.
Separately, it can be noted that we always _wanted_ a similar solution for ChromeOS, but we never quite got there... ;-)
FTR ChromeOS is moving in that direction: splitting SKU differences based on components into overlays that get applied to the base by the bootloader.
In the simplest example we could have one base dts and two overlays for two different DSI panel models:
- base.dtb - panel-model-a.dtbo - panel-model-b.dtbo
The problem we then run into is that the base.dtb will only have the generic model compatible "google,foo", not the sku and revision specific ones like "google,foo-sku1-rev2".
And we'd really like to avoid having _more_ overlays just to add the final specific compatible string, as that kind of defeats the purpose of using overlays to reduce the number of dts files.
I proposed internally maybe having the bootloader fix up the final compatible string, but I think we need some rough consensus upstream whether this is acceptable or not.
On Tue, Nov 18, 2025 at 11:43 PM Doug Anderson dianders@chromium.org wrote:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
(...)
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
So in the kernel we have several arch/*/boot/dts/vendor/ folders where they have:
soc.dtsi included by board.dtsi included by system.dts and the top system.dts is all that get compiled.
So what you say is that you do the same thing but at runtime?
Essentially. In this case, we don't ship the device tree _sources_ but ship _compiled_ device tree. We compile the SoC into a "dtb" and then combine anything above the SoC into a single "dtbo". We ship several "dtb" files and several "dtbo" files and combine them at runtime after we identify which hardware we're running on.
Can you just describe why this is done like this with overlays?
I can only guess that you have one bootloader that needs to compose device trees to many systems and the bootloader only discovers the system it is running on and its constraints at runtime, so shipping the static system.dtb as many people do is not an option for you?
And the reason the bootloader doesn't already know what it is running on and doesn't just pass that one device tree or is just prepared with that one device tree has something to do with manufacturing or so?
Sorry it just evades me.
Our builder creates a single "image" that can be flashed onto any number of devices. Users (or manufacturers) can download and install this single image and it will work on a wide variety of devices. So you can download a single "Pixel 10" image that can be installed on any of the Pixel 10 devices (Pixel 10, Pixel 10 Pro, and Pixel 10 Pro XL). It will also work on our development board and early pre-production variants of those boards.
In order for this to work, we need a lot of device trees and _something_ needs to pick the correct one. Right now, the bootloader is in charge of this task.
If we had less variety of products that we needed to ship then, yes, we could just ship the one device tree and have a separate build for each product. ...but that doesn't scale terribly well.
Probably becayse even U-Boot these days use the provided device tree dtb, for the system targeted, to initialize itself. I suppose your bootloader is generic enough to avoid that chicken-and-egg problem, right?
FWIW: I believe even U-boot supports shipping a pile of device trees and detecting things at runtime. See the "FIT" image:
https://docs.u-boot.org/en/latest/usage/fit/index.html
I guess if I had this problem:
soc.dtsi board-a.dtsi board-b.dtsi system-board-a-v1.dts system-board-a-v2.dts system-board-b-v1.dts
etc having to be combined at runtime, in a bootloader, I would consider shipping exactly these files in a memory-based filesystem in my bootloader, and bake a DTS compiler into my bootloader so it can just build a device tree for what it detects.
But I guess you didn't want to hear that :D
You're saying to just ship device tree source instead of binary? Hmmm, it's an interesting idea. It wouldn't be _terrible_ since "dtb" stores a lot of strings to begin with, but I think it would still add enough of a bloat to make it a no-go for us... I would also imagine it would be a pain to deal with #include of header files with #defines. Do we somehow partially pre-process the device tree files but don't apply the #include files. It might be possible to solve some specific cases, but having this work in a generic way seems miserable.
Anyway, please describe how you ended up in this situation, I'm trying to understand this.
The main goal is just building/shipping one image to support a variety of similar products and trying to save space by not repeating the SoC bits over and over again.
I think that's a valid goal. ChromeOS ships all DTBs for the same SoC in a unified kernel FIT image. It used to be all DTBs for the same SoC vendor (arch/arm64/boot/dts/mediatek/*.dtb), but we ran out of space on an old device that had a pretty small kernel image partition.
And given that the devices built on one SoC are mostly derived from the same reference hardware design, maybe 90~95% of the resulting DTBs are the same. It would be nice to even have the reference design as the base DTB, but again that would require either having a bunch of DTBOs just to fix the board compatible, or have the bootloader fix it up.
It is quite clear that device tree overlays were intended for say plug-n-play additions and minor fragments to be added to a basically complete device tree, what you are doing was probably not how it was intended. (Or let's see if someone proves me wrong on that.)
Not sure what makes that so clear, since it's not clear to me. In any case, even if device tree overlays weren't intended for such a usage, they actually seem to work fairly well for it, even if upstream currently rejects device tree usage like this.
FWIW, the fact that bootloaders (like U-Boot) have the ability to apply overlays makes me think that _someone_ intended them to be used similar to how Android is using them. ;-) If it was just expansion cards then (presumably) someone would boot to Linux and just apply overlays from there. See:
https://docs.u-boot.org/en/latest/usage/fit/overlay-fdt-boot.html
FWIW Simon also mentioned this as a possibility in his "FIT support for extension boards / overlays" proposal [1], but maybe I'm misreading it.
Thanks ChenYu
[1] https://lore.kernel.org/all/CAPnjgZ06s64C2ux1rABNAnMv3q4W++sjhNGCO_uPMH_9sTF...
On Tue, Nov 18, 2025 at 02:43:20PM -0800, Doug Anderson wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
Having worked on the SolidRun i.MX6 platforms, I agree with this. Within these platforms there are:
SoC SOM Platform imx6dl pre-v1.5 cubox imx6q v1.5 hummingboard v1.5 + emmc hummingboard2
On top of these, I have specific "user" extensions for hardware that I've connected - e.g. - the NoIR RPi camera needs DT modification. - for monitoring a mechanical church clock, a "gps" variant that allowed PPS to be used with a GPIO pin, and a "capture" variant that configured the hardware to allow precise event stamping. - 1-wire, for ds18b20 temperature sensors.
Without the user extensions, this adds up to 18 DTB files: arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2.dts
basically, every combination needs to be enumerated. So, having two SoC dt files, three for the SOM, and three for the platform that the boot loader combines would significantly cut this down - to 8.
However, it isn't that simple. For example, when the Hummingboard2 is used with the iMX6Q SoC, there's a SATA device present in the SoC level that needs Hummingboard2 specific properties to tune the signal waveform. However, iMX6DL doesn't have this SATA device in silicon, so the node doesn't exist in the base SoC DT file. The situation is the same for Hummingboard, but the tuning parameters, being board specific, are different.
This means is that there are DT properties that are dependent on the SoC DT component and the platform DT component which do not fit with splitting the DT files into their individual "component" levels.
The other issue would be the /model property - for example:
model = "SolidRun HummingBoard2 Solo/DualLite"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som+emmc)"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som)"; model = "SolidRun HummingBoard Solo/DualLite"; model = "SolidRun HummingBoard2 Dual/Quad"; model = "SolidRun Cubox-i Solo/DualLite";
as a set of examples. I don't see a clear way to generate these from a fragmented scheme. There's a similar problem with the board-level compatible:
compatible = "solidrun,cubox-i/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
These don't include the SoM information.
Maybe what would work would be a high-level DT file that contains paths to the lower levels that need to be combined, along with properties that need to be merged. E.g.
/ { model = "SolidRun HummingBoard2 Dual/Quad"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
dts-components { compatible = "boot/dt"; component@1 { compatible = "dt"; path = "imx6q.dtbo"; };
component@2 { compatible = "dt"; path = "imx6qdl-sr-som-v1.5.dtbo"; };
component@3 { compatible = "dt"; path = "imx6qdl-hummingboard2.dtbo"; };
component@4 { compatible = "dt"; path = "imx6ql-hummingboard2-emmc.dtbo"; }; };
soc { sata@2200000 { .. sata tuning properties .. }; }; };
Or something similar. However, this would mean we would still need the 18 or so top level DT files, but also each component as well, which will increase the number of files we're having to manage on a target platform - so I'm wondering whether it's worth it.
I don't think we'll be able to get away from this problem: it's likely that there will continue to be properties that are specific across several "levels" of a split DT setup, and apart from something like the above, I don't really see a way to handle them.
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
I would have liked to use overlays for these platforms, but ISTR they either weren't supported at the time, or frowned upon, and even so I can only see them working for the simplest of cases due to the issue I mention above.
Hi,
On Mon, Dec 1, 2025 at 7:31 PM Chen-Yu Tsai wenst@chromium.org wrote:
Separately, it can be noted that we always _wanted_ a similar solution for ChromeOS, but we never quite got there... ;-)
FTR ChromeOS is moving in that direction: splitting SKU differences based on components into overlays that get applied to the base by the bootloader.
In the simplest example we could have one base dts and two overlays for two different DSI panel models:
- base.dtb
- panel-model-a.dtbo
- panel-model-b.dtbo
The problem we then run into is that the base.dtb will only have the generic model compatible "google,foo", not the sku and revision specific ones like "google,foo-sku1-rev2".
And we'd really like to avoid having _more_ overlays just to add the final specific compatible string, as that kind of defeats the purpose of using overlays to reduce the number of dts files.
I think you may have simplified the above a little too much to the point where it's confusing. At least I'm a bit confused. I _think_ the problems you're talking about are the kinds of things we run into when we take overlays above just two levels. I'm imagining:
- base.dtb - board1-rev1.dtbo - board2-rev1.dtbo - board1-rev2.dtbo - board2-rev2.dtbo - panel-a.dtbo - panel-b.dtbo
So I think you're saying that you'd start with the "base.dtb" and then extend it with exactly one of the "board" overlays and then exactly one of the "panel" overlays. Is that right?
So I'd imagine that each of the "board" overlays could have "full" compatible strings. For instance, I'd imagine "board2-rev2" could have:
compatible = "google,booard2-rev2", "socVendor,soc"
The problem you're struggling with (I think) is that the panel overlays won't be represented in the compatible string (and "model") even though (historically) we always did in ChromeOS (they were included in the "sku" part of the compatible string).
Did I get that right?
I proposed internally maybe having the bootloader fix up the final compatible string, but I think we need some rough consensus upstream whether this is acceptable or not.
Maybe we need to come to some agreement about when the top-level compatible string needs to be changed. In the above, I'd perhaps argue that the panel isn't a major enough change that it needs to change the top-level compatible string. That would solve the problem, right? What do others think? Certainly for "probe-able" components we don't change the top-level compatible string. Can anyone point to any official documentation about the top-level compatible string?
-Doug
On Mon, Dec 01, 2025 at 12:58:57PM -0800, Doug Anderson wrote:
Hi,
On Mon, Dec 1, 2025 at 10:28 AM Russell King (Oracle) linux@armlinux.org.uk wrote:
On Mon, Dec 01, 2025 at 09:42:40AM -0800, Doug Anderson wrote:
Hi,
On Tue, Nov 18, 2025 at 2:43 PM Doug Anderson dianders@chromium.org wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
It's been roughly two weeks since I sent out this proposal. Do DT folks have any comments? Are the goals I have stated understood? Do people agree that these goals are reasonable? Is there any question that there is a need to solve these problems not just for Google, but for the community as a whole? I'm happy to reach out to people and have them reply "yes, I have this problem too" if it would somehow help. I don't doubt that there are still people at Qualcomm who would like a solution even if I think Elliot isn't driving it there anymore...
How do we make forward progress? Does anyone have any comments on Julius's reply? At the moment, I think there are some conflicts with what Julius would like to see (no changes to the rules for how overlays are applied) and what Rob said previously (we need to find some way to combine the compatible strings). Did I misunderstand? Can we find a common ground?
My feeling on this (and I don't have much time to consider it tonight) is that this isn't going to get a quick answer.
This answer is based on my authorship of various device trees, and is solely my own opinion, and in no way represents any position by my employer.
While the DT files are dual-licensed, the license that applies to the copy in the kernel is GPL v2, because the kernel as a whole is GPL v2 licensed. The dual-licensing of the DT files is to permit them to be taken from the kernel and used in e.g. boot loaders etc.
However, as the license that applies to the kernel copy is GPL v2, and GPL v2 requires distribution in source code form, or an offer valid for two years of the corresponding source code etc (check the GPL v2 for the exact terms) it could be inappropriate for the kernel tree to distribute binary DT blobs without their corresponding source.
It seems to me that this is a problem for lawyers, and you're probably not going to get a quick answer on it.
So, I'd suggest patience, and don't expect this topic to move quickly.
It seems like perhaps I wasn't clear enough in my description of the problem I'm trying to solve.
I didn't have time last night to properly read your proposal - certainly not to go back to your original post, but from what I did read in your follow up, it seemed that you were proposing that e.g. the SoC level should be in binary form.
The confusion came from "build a "base" device tree" which implied to me taking the e.g. SoC .dtsi and turning that into its binary form.
Sorry for misunderstanding.
Hi,
On Tue, Dec 2, 2025 at 2:07 AM Russell King (Oracle) linux@armlinux.org.uk wrote:
Having worked on the SolidRun i.MX6 platforms, I agree with this. Within these platforms there are:
SoC SOM Platform imx6dl pre-v1.5 cubox imx6q v1.5 hummingboard v1.5 + emmc hummingboard2
On top of these, I have specific "user" extensions for hardware that I've connected - e.g.
- the NoIR RPi camera needs DT modification.
- for monitoring a mechanical church clock, a "gps" variant that allowed PPS to be used with a GPIO pin, and a "capture" variant that configured the hardware to allow precise event stamping.
- 1-wire, for ds18b20 temperature sensors.
Without the user extensions, this adds up to 18 DTB files: arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2.dts
basically, every combination needs to be enumerated. So, having two SoC dt files, three for the SOM, and three for the platform that the boot loader combines would significantly cut this down - to 8.
However, it isn't that simple. For example, when the Hummingboard2 is used with the iMX6Q SoC, there's a SATA device present in the SoC level that needs Hummingboard2 specific properties to tune the signal waveform. However, iMX6DL doesn't have this SATA device in silicon, so the node doesn't exist in the base SoC DT file. The situation is the same for Hummingboard, but the tuning parameters, being board specific, are different.
This means is that there are DT properties that are dependent on the SoC DT component and the platform DT component which do not fit with splitting the DT files into their individual "component" levels.
Wow, it sounds complicated! Yeah, in your specific case where you need specific tuning parameters for each combination of SoC and SoM the easiest might be to just keep things separate as you have it. If you're looking to optimize the total size of the distributed device trees instead of the total number of files, overlays still could possibly help you out, though. I could imagine a case where you first apply the "coarse" overlays (SoC, SoM, board) and then you look for finer-grained overlays that are applied atop that. You'd still need a bunch of these "finer grained" overlays (one for each unique combination) but each one would be tiny.
To make it concrete, I'd imagine: - imx6q - base dtb - som1.5 - overlay - hummingboard2 - overlay - hummingboard2-with-imx6q - overlay
...and the "hummingboard2-with-imx6q" could _just_ have the SATA tunings in it. I think that would be possible, right?
The other issue would be the /model property - for example:
model = "SolidRun HummingBoard2 Solo/DualLite"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som+emmc)"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som)"; model = "SolidRun HummingBoard Solo/DualLite"; model = "SolidRun HummingBoard2 Dual/Quad"; model = "SolidRun Cubox-i Solo/DualLite";as a set of examples. I don't see a clear way to generate these from a fragmented scheme. There's a similar problem with the board-level compatible:
compatible = "solidrun,cubox-i/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";These don't include the SoM information.
Right. This is the question many of the messages in this thread have been struggling with.
Things become a bit easier if you simply don't expect the top-level "compatible" to describe everything. ...but in your case it sounds like things are _very_ dynamic (everything can be combined with everything), so if we want to solve your problem it seems like we truly do need a way to "combine" compatible strings.
As per one of my earlier replies, it's possible we'll postpone this and start with simpler cases where we don't need to do any top-level compatible/model munging, but it's good to know that there's a use case that really needs it.
Maybe what would work would be a high-level DT file that contains paths to the lower levels that need to be combined, along with properties that need to be merged. E.g.
/ { model = "SolidRun HummingBoard2 Dual/Quad"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
dts-components { compatible = "boot/dt"; component@1 { compatible = "dt"; path = "imx6q.dtbo"; }; component@2 { compatible = "dt"; path = "imx6qdl-sr-som-v1.5.dtbo"; }; component@3 { compatible = "dt"; path = "imx6qdl-hummingboard2.dtbo"; }; component@4 { compatible = "dt"; path = "imx6ql-hummingboard2-emmc.dtbo"; }; }; soc { sata@2200000 { .. sata tuning properties .. }; };};
Or something similar.
Yeah, the question of how to know which files to combine is an important and related point, but I've been trying to keep it separate so we don't have to solve every complex problem at once. This is, I believe, also the subject of one of Chen-Yu's talks at Plumbers.
However, this would mean we would still need the 18 or so top level DT files, but also each component as well, which will increase the number of files we're having to manage on a target platform - so I'm wondering whether it's worth it.
I don't think we'll be able to get away from this problem: it's likely that there will continue to be properties that are specific across several "levels" of a split DT setup, and apart from something like the above, I don't really see a way to handle them.
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
Right, this kind of thing would be a judgement call. How you'd want to organize things / use overlays would be up to you.
I would have liked to use overlays for these platforms, but ISTR they either weren't supported at the time, or frowned upon, and even so I can only see them working for the simplest of cases due to the issue I mention above.
The fact that you have similar needs at least makes me continue to be confident that this is an important problem to try to solve.
-Doug
Hi Doug!
On Tue, 18 Nov 2025 at 22:43, Doug Anderson dianders@chromium.org wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
A secondary reason for wanting to break device trees like this is to more nicely handle when a board has a socketed SoC that can be replaced with a finite (and small) number of different SoCs (usually revisions of the same SoC). Even if this secondary reason is considered invalid or too difficult, the primary reason still describes a compelling need.
In order to make this proposal work, it's expected that a bootloader will understand the scheme and will know how to combine the overlay atop the base before passing a complete device tree to the main OS.
Current state of the art (downstream):
In Android, we do a pretty good job of solving the stated problem using device tree overlays. We describe the SoCs in "dts" files and compile them into "dtb"s. We describe boards in "dtso" files and compile them into "dtbo" files. A bootloader can handle identifying the correct base and overlay (the scheme for doing this is a separate but related topic) and applying the overlay atop the base "dtb". This solution is fully implemented downstream for Android phones and is well documented [2].
The issues I'm aware of with the current state of the art are:
- In order for the base device tree to pass schema validation on its
own we'd need to document the top-level compatible strings in the device tree. It is the opinion of at least some device tree maintainers that a SoC doesn't qualify as a top-level compatible string. This prevents the device trees from landing in an officially sanctioned location.
- It is also possible we may fail schema validation for the base SoC
tree if the schema marks a property as "required" but that property needs to be filled out by the board (perhaps a "-supply" is marked as "required", since most "-supply" properties are filled in by the board. I'm not sure this is a big issue, but it's something to think about.
- It's unclear if there is any official "ABI" promised here once
we've compiled and validated the base device tree on its own. Will people assume that they can have out-of-tree overlays derived from the base SoC tree and that those out-of-tree overlays will continue to work across changes / cleanups to the base? NOTE: this is a pre-existing question for existing device tree overlay usage, but the sheer quantity of nodes/properties that a board would be expected to overlay/modify in the base make the problem more prominent.
- We want the final device tree's top-level compatible to be all the
compatible strings from the board followed by all of the compatible strings for the SoC. When the board's overlay is applied to the base SoC tree, though, the board's top-level compatible fully replaces the compatible from the base SoC tree. This can be solved today for non-socketed boards by just duplicating the SoC compatible strings in the board overlays. We can't solve this today for socketed boards, though we can simply make sure that no software drivers rely on the specific SoC compatible string being present and thus we can ignore the problem.
None of the above problems are big enough to have prevented widespread use of this scheme in downstream Android.
Current state of the art (upstream):
Upstream if we have a pile of related boards, we do allow deduplicating things at a source-code level with "dtsi" files. We can have a SoC "dtsi" file and that file is included by all boards that use that SoC. When it comes time to validate or ship things, though, we only work with full devices trees. This means that we ship duplicated information.
Proposal:
- Allow the top-level compatible string of an "incomplete" device
tree to be documented so it can be validated on its own by tools. It's understood that this SoC is not a board by itself and we'd never boot a full OS with this device tree without adding an overlay that changes the top-level compatible. Add a top-level property to the device tree (perhaps "incomplete-compatible;") to indicate that the tree is not complete without an overlay.
or be more description, e.g.: compatible-scope = "soc" - or just scope = "soc"
In other words, I don't think we should be frightened to define some levels (soc, som, carrier, exxpansion, chassis?)
- If it turns out to be needed (hopefully it's not), allow some type
of syntax in yaml files that allows a property to be marked as "required" in a "complete" device tree but not in an "incomplete" device tree. Alternatively, we could discourage marking properties as "required" if they're expected to be filled in by a board.
Another option would be to validate the soc DT with a chosen board, just as a workaround. It would probably be good enough.
- Define that there is no promised ABI between "incomplete" device
trees and anything not stored with them. Specifically, all valid combinations of "incomplete" device trees with overlays to complete them should be enumerated together with the "incomplete" device tree.
This seems important, yes.
- When applying an overlay to a device tree that's "incomplete", the
top level overlay will be merged instead of replaced.
Example for 2 levels:
base (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc"; overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard"; merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc";
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename"; overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", "socvendor,mysoc-rev1", "socvendor,mysoc";
Obviously in the 3-level scheme we need to know the order that overlays are applied, but that's true for overlays today anyway.
The above proposal takes the current downstream "state of the art" and addresses the known issues, solving the original problem statement.
Other thoughts:
If you don't like the proposal, I'd be interested in knowing if you have other ideas for solving the original problem statement, or if you simply think the problem we're trying to solve here is an invalid one.
I'm happy to post up another revision of my Pixel 10 device trees following this proof of concept (or other ones). My v1 was _very_ close to this, but didn't have the "incomplete-compatible;" property and didn't implement top-level compatible merging.
This proposal seems good to me.
We don't need to worry about old bootloaders since they presumably are not installed on new hardware. Assuming Linux adopts this proposal, I am sure people will implement it in bootloaders when they need to.
Chen-Yu, thank you for the reminder re my extensions thing for FIT. I had forgotten about that. Here are some current proposed FIT additions, BTW, in case anyone is interested in taking a look:
https://github.com/open-source-firmware/flat-image-tree/pulls
Regards, Simon
[1] https://lore.kernel.org/r/20251111112158.1.I72a0b72562b85d02fee424fed939fea9... [2] https://source.android.com/docs/core/architecture/dto/partitions
Hi Simon!
On Tue, Dec 2, 2025 at 12:07 PM Simon Glass sjg@chromium.org wrote:
- Allow the top-level compatible string of an "incomplete" device
tree to be documented so it can be validated on its own by tools. It's understood that this SoC is not a board by itself and we'd never boot a full OS with this device tree without adding an overlay that changes the top-level compatible. Add a top-level property to the device tree (perhaps "incomplete-compatible;") to indicate that the tree is not complete without an overlay.
or be more description, e.g.: compatible-scope = "soc" - or just scope = "soc"
In other words, I don't think we should be frightened to define some levels (soc, som, carrier, exxpansion, chassis?)
Sure, I'd be OK with this if this is what DT folks want. I don't have any strong opinions here. NOTE: something like this would only make sense if we're going to introduce new variants on how we apply overlays (like merging compatible strings).
- If it turns out to be needed (hopefully it's not), allow some type
of syntax in yaml files that allows a property to be marked as "required" in a "complete" device tree but not in an "incomplete" device tree. Alternatively, we could discourage marking properties as "required" if they're expected to be filled in by a board.
Another option would be to validate the soc DT with a chosen board, just as a workaround. It would probably be good enough.
Sure, though I think Rob and Krzysztof are pretty interested in being able to validate the SoC DTB by itself. I'd like to at least set that as a goal. If we find some reason why we _truly_ can't achieve that then we can talk about relaxing it, but I'd like to start with the more aggressive goal.
We don't need to worry about old bootloaders since they presumably are not installed on new hardware. Assuming Linux adopts this proposal, I am sure people will implement it in bootloaders when they need to.
Right. IMO if we have to make changes to the way overlays are applied and we can do it in a simple and backward compatible way, it should be OK. Only new bootloaders would be able to take advantage of it, but presumably we'll have to modify bootloaders a little anyway when we standardize on ways to pick the right overlays to apply...
Is there really a need to merge the compatible strings in your case?
Well, you could just require duplicating an overlay N times for N bases, but that doesn't scale
I think my question was more along the lines of "is there actually a reason why the combined compatible string needs to be that accurate" (i.e. contain the right "socvendor,mysoc-rev1" or "socvendor,mysoc-rev2"). What is the purpose of having that string in there? It wouldn't be used for matching which DTB(O) to load in this case because we're already past that step. It's not used by the kernel directly for anything as far as I know. Is it used by userspace programs which parse /proc/device-tree/compatible in order to detect which SoC revision they're running on? Because that's the only use case I could think of that really remains, but I'd argue that the compatible string is a pretty poor vehicle for things like that (it would be easier to parse and use to just put a `soc-revision = <1>` property somewhere). So if this is the only problem I'd say maybe just don't use the board compatible string for that, don't expect to be able to find such details in there accurately. But if we do think it needs to be that accurate for some reason, then I'd suggest platforms like this (which should be rather few, e.g. only those that really have a socketable SoC with differentiations that are so compatible that other than this identification information itself it doesn't require any device tree differences) should simply have their bootloaders rewrite the compatible string into the right format with all the necessary information manually, rather than expect the overlay application process to create it correctly.
There is a proposal here[1]. It's simple, but I do wonder if looking at the root compatible only is too narrow of a view. An overlay could target a connector compatible for example.
This seems to just assume that every overlay matches exactly one base tree, that kinda defeats the purpose of overlays in this case (sharing data between multiple base trees). For our purposes we need a much more complicated system that is able to stitch together an arbitrary number of overlays based on identifiers specific to our platform.
However, it isn't that simple. For example, when the Hummingboard2 is used with the iMX6Q SoC, there's a SATA device present in the SoC level that needs Hummingboard2 specific properties to tune the signal waveform. However, iMX6DL doesn't have this SATA device in silicon, so the node doesn't exist in the base SoC DT file. The situation is the same for Hummingboard, but the tuning parameters, being board specific, are different.
I think you would solve this simply by having more overlays? In that situation you can have a imx6q.dtbo, imx6dl.dtbo and hummingboard2.dtbo for the generic nodes and properties relating to each of these components, and then a imx6q-hummingboard2.dtbo specifically for the SATA tuning parameters of that SoC+board combination. Your bootloader then just needs to figure out which of those to load for which platform. (Of course there also has to be a toplevel DTB, so if you don't have any further revision or SKU differentiation above that then imx6q-hummingboard2.dtb could simply be your toplevel DTB, containing those tuning parameters, and the rest could be overlays. imx6dl-hummingboard2.dtb would then be an empty toplevel DTB (save for the compatible string) if everything else that makes up the platform gets provided by the overlays.)
The other issue would be the /model property - for example:
model = "SolidRun HummingBoard2 Solo/DualLite"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som+emmc)"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som)"; model = "SolidRun HummingBoard Solo/DualLite"; model = "SolidRun HummingBoard2 Dual/Quad"; model = "SolidRun Cubox-i Solo/DualLite";
These can also go in the toplevel DTB. Basically, the toplevel DTB can always refer to the most specific cross product of components and contain properties like these that only make sense for the specific combination. There will be a lot of toplevel DTB files, but they will be for the most part very small. The "meat" of the device tree is factored out into overlays that can be shared by multiple toplevel DTBs. The benefit is smaller image size for platforms that need to bundle DTBs for all possible variations in their kernel image (and whether that's worth it or not is up to each platform, we're not asking to make these overlays mandatory, we're just saying that we have platforms that do need (and are in part already using) something like this in order to deal with the sheer scale of supported platform variations, and we'd like there to be an upstream standard for it).
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
I think platform identification and matching which overlays to apply should remain outside the scope of the device tree itself. The main reason is that you usually want to compress DTB(O) files for efficiency, and when you have a large list of overlays in a kernel image you don't want to have to decompress them all just to determine which ones to load for the current platform. So I think it's generally better to let bootloaders come up with their own scheme to store this information inside their file systems or whatever other data structures they use to find these DTB(O) files.
Hi,
On Tue, Dec 2, 2025 at 1:58 PM Julius Werner jwerner@chromium.org wrote:
Is there really a need to merge the compatible strings in your case?
Well, you could just require duplicating an overlay N times for N bases, but that doesn't scale
I think my question was more along the lines of "is there actually a reason why the combined compatible string needs to be that accurate" (i.e. contain the right "socvendor,mysoc-rev1" or "socvendor,mysoc-rev2"). What is the purpose of having that string in there?
Yes, this matches what I just sent in several of my replies. What exactly is the top-level compatible supposed to represent? I think different people have different ideas. Is it documented somewhere? I guess I could start a new thread to solve just this one question, though I suspect not everyone (not even core DT folks) will agree. If they don't, how do we solve that? Who is "the decider"?
It wouldn't be used for matching which DTB(O) to load in this case because we're already past that step. It's not used by the kernel directly for anything as far as I know.
It has _sometimes_ been used by the Linux kernel. Specifically the fact that the SoC is represented in the top-level compatible is used to "blocklist" the generic cpufreq driver (drivers/cpufreq/cpufreq-dt-platdev.c). I've never loved this, but it is an example.
Occasionally, I have also seen random software workarounds that rely on the top-level string. See Linux commit 127068abe85b ("i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630"), which added:
+ if (!of_machine_is_compatible("lenovo,yoga-c630")) + dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
...that's been since removed, but it's one example I can think of where the top-level string was temporarily relied upon.
There are certainly lots of hits for `of_machine_is_compatible()` in Linux today. I don't know if these are all for good reasons, but they are examples of people relying on it. In my experience it's mostly used for things that are a bit hacky, to avoid an unexplained bug, or to work around the fact that someone didn't add a specific enough compatible string somewhere else in the device tree.
Is it used by userspace programs which parse /proc/device-tree/compatible in order to detect which SoC revision they're running on? Because that's the only use case I could think of that really remains, but I'd argue that the compatible string is a pretty poor vehicle for things like that
Agreed. This type of thing has always been broken on Chromebooks which have more than one revision/sku listed since a single device tree works on more than one device. We had long arguments about this in the past and I think DT folks finally threw in the towel and let us land these, though I think they still don't really like it to this day.
(it would be easier to parse and use to just put a `soc-revision = <1>` property somewhere). So if this is the only problem I'd say maybe just don't use the board compatible string for that, don't expect to be able to find such details in there accurately. But if we do think it needs to be that accurate for some reason, then I'd suggest platforms like this (which should be rather few, e.g. only those that really have a socketable SoC with differentiations that are so compatible that other than this identification information itself it doesn't require any device tree differences) should simply have their bootloaders rewrite the compatible string into the right format with all the necessary information manually, rather than expect the overlay application process to create it correctly.
Yeah, trying to stuff the world into the top-level compatible never seemed amazing to me. Given that today's advice is to have a top-level `soc@0` node, IMO SoC-specific details ought to be under that. This is something that Stephen Boyd suggested a while ago but it never gained traction.
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
I think platform identification and matching which overlays to apply should remain outside the scope of the device tree itself. The main reason is that you usually want to compress DTB(O) files for efficiency, and when you have a large list of overlays in a kernel image you don't want to have to decompress them all just to determine which ones to load for the current platform. So I think it's generally better to let bootloaders come up with their own scheme to store this information inside their file systems or whatever other data structures they use to find these DTB(O) files.
IMO it's still nice to be able to store some of the metadata that the loader will use in the overlay files, just so we don't need a parallel set of files. The current Android way of doing things is that the metadata in the "dtbo" is parsed by the packaging tool (`mktdimg`) and that creates the tables that the bootloader needs. This seems reasonable, even though I'll argue that the metadata needs to be documented under a specific node (one for `mkdtimg`). I wouldn't want to have to maintain a separate file mapping overlays to their metadata.
-Doug
Hi,
On Mon, Dec 1, 2025 at 4:48 PM Rob Herring robh@kernel.org wrote:
Possible example if we support 3 levels:
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" overlay1 (incomplete) compatible: "referencevendor,referencecodename";
I don't understand this one...
overlay2 compatible: "boardvendor,myboard-rev1", "boardvendor,myboard" merged compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "referencevendor,reference-codename", , "socvendor,mysoc";
I was just trying to come up with an example with 3 levels. Usually a whole pile of boards are based on a reference design, so the reference board could be an extra level of overlays. Thinking about this with the sc7180 Chromebooks, you might have:
SoC: qcom,sc7180 (base DTB) Reference design: google,trogdor Actual board: google,lazor-rev1, google,lazor
So final compatible could be: "google,lazor-rev1", "google-lazor", "google-trogdor", "qcom,sc7180"
In the case of what we ended up with upstream for sc7180 Chromebooks, we actually _didn't_ include the reference design (google,trogdor) in the list of compatibles in the final board. I think this was because the name of the reference design ("trogdor") was also the name of the reference _board_ and it would have been confusing. ...but I can also see how one might want the reference board to show up here. I don't feel super strongly either way.
In any case, I'm OK with not focusing on 3-levels right now and I'm not actually planning to use it in the short term, I just want to make sure that anything we do doesn't preclude it...
Sorry, I only cursorily followed the previous discussion so I may have missed the exact need for this part. But I would caution against any proposal that changes the basic rules of how an overlay is applied. The definition of how overlays work has (I think?) been stable for over a decade now, and is implemented in bootloaders that often cannot easily be updated. I absolutely support your effort to get more upstream standardization for managing base device trees and overlays (which I think need to be flexible for arbitrary layers, not just SoC and board), but let's not break the overlay code in old bootloaders while doing it.
I think merging compatibles is orthogonal to splitting SoC and board DTs. Doug needs to merge because there is more than 1 SoC version or base DT to pick. In many cases (SoC revision compatibles are the exception upstream), there is only 1 SoC DT and N board DTs. So we should consider both and define them separately. In the simple case, you'd have something like:
SoC (incomplete) compatible: "socvendor,mysoc" Board overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc"
Then you just apply the overlay and it overwrites the incomplete compatible. That works with existing overlay applying (overwriting) for multiple steps as long as each step is a superset (compatible list) of the prior steps.
In Doug's case, I think you need code to decide which base to pick and then fixup the final compatible.
SoC (incomplete) compatible: "socvendor,mysoc-rev1", "socvendor,mysoc" Board overlay compatible: "boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc"
And then after applying, you do the merge to insert the SoC rev compatible:
"boardvendor,myboard-rev1", "boardvendor,myboard", "socvendor,mysoc-rev1", "socvendor,mysoc"
You need SoC specific code to know what SoC revision you are running on, so SoC specific post apply code should be fine too. There's not any existing bootloader problem because you need code to handle this.
Maybe that fixup will end up being generic enough that it's not platform specific, but that's an optimization of the implementation.
Is there really a need to merge the compatible strings in your case?
Well, you could just require duplicating an overlay N times for N bases, but that doesn't scale
I'm actually OK with deferring the "pluggable SoC" problem for now. Even for the Google Pixel team, it's a bit of an edge case. If we have to solve it by duplicating "dtbo" files for socketed boards (or any board which could have more than one SoC) that's probably OK for now. Once other problems are solved, we can perhaps come back to the idea of merging compatible strings and/or other properties.
In v1 of my Pixel 10 series I wasn't even trying to support multiple SoC revisions, I was just trying to look forward to the future based on what I saw downstream. ;-)
If I drop the idea of merging compatible strings and just duplicate the "SoC" parts of the compatible in each of the overlays, then do we have something that's landable to get things off the ground? I think Krzysztof will still NAK my base "dtb" that represents just the SoC since it's not "complete". I certainly wouldn't want to just steamroll over his concerns. Krzysztof: Do you have any thoughts? Do you understand my goal here and agree that it's something worth solving? If you don't agree it's worth solving, would it help to hear more people express their interest in a solution? If you agree it's worth solving, can you provide a suggestion for how we can move forward?
I think in the vast majority of platform identification cases, code only cares about matching the most precise string (i.e. "boardvendor,myboard-rev1"). If we do feel like having the whole chain of identification is necessary, it could be achieved by just copy&pasting the extra strings into the overlay file. If we have cross-validation between base and overlay source files we could also have the validation check that the overlays correctly contain all compatible strings from their base tree. If we know that the base trees aren't standalone anyway, we could also just invent other property names that identify them (e.g. `soc-compatible = "socvendor,mysoc";`). Anything other than breaking the overlay format would be preferable in my opinion.
There's also a use case I'm aware of where the base DT is just for a SoM and then the bootloader applies an expansion board overlay. So it is not always "not standalone". And of course, this could be combined with what Doug wants to do.
Note that for any new property (or an incomplete compatible) like soc-compatible, you will need to consider how we validate it.
I also feel like we need a better standardized way to tie base device trees to overlays, like your `/loaders` node proposal in an earlier email, although maybe that's an orthogonal discussion (but related, especially if there's supposed to be cross-validation between base trees and overlays). The compatible string is just not a scalable way for bootloaders to make this determination, there may be a lot more differentiation than just "SoC" and "board", and the scheme almost certainly needs to be platform/bootloader-specific because every hardware vendor has their own ideas about how to group and reuse parts of a platform. This information doesn't necessarily need to be *in* the device tree, it could also just be in a separate YAML file in the same repo (since bootloaders will almost certainly want to have it transformed into their own out-of-band descriptor at build-time anyway, so that they can compress the device tree itself and don't have to decompress each one for matching), but it needs to be somewhere.
There is a proposal here[1]. It's simple, but I do wonder if looking at the root compatible only is too narrow of a view. An overlay could target a connector compatible for example.
Yeah, I'm still not really a fan of that proposal. I think different loaders are going to need different information to know which overlays to apply, so we need to define "yaml" files for different loaders and define the formats for a few different loaders.
From a validation point of view, I'd imagine we'd want to (if possible) validate all different combinations, but (if it's well-defined in a binding) we could potentially include rules in the kernel that understand different loaders and could come up with different things to validate.
-Doug
On Tue, Dec 2, 2025 at 4:07 AM Russell King (Oracle) linux@armlinux.org.uk wrote:
On Tue, Nov 18, 2025 at 02:43:20PM -0800, Doug Anderson wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
Having worked on the SolidRun i.MX6 platforms, I agree with this. Within these platforms there are:
SoC SOM Platform imx6dl pre-v1.5 cubox imx6q v1.5 hummingboard v1.5 + emmc hummingboard2
On top of these, I have specific "user" extensions for hardware that I've connected - e.g.
- the NoIR RPi camera needs DT modification.
- for monitoring a mechanical church clock, a "gps" variant that allowed PPS to be used with a GPIO pin, and a "capture" variant that configured the hardware to allow precise event stamping.
- 1-wire, for ds18b20 temperature sensors.
Without the user extensions, this adds up to 18 DTB files: arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2.dts
basically, every combination needs to be enumerated. So, having two SoC dt files, three for the SOM, and three for the platform that the boot loader combines would significantly cut this down - to 8.
However, it isn't that simple. For example, when the Hummingboard2 is used with the iMX6Q SoC, there's a SATA device present in the SoC level that needs Hummingboard2 specific properties to tune the signal waveform. However, iMX6DL doesn't have this SATA device in silicon, so the node doesn't exist in the base SoC DT file. The situation is the same for Hummingboard, but the tuning parameters, being board specific, are different.
If that is a separate overlay fragment (i.e. not under another node in the overlay), we could solve this by having some way to mark the fragment as optional. Apply it if the base node is present, but don't fail if not. Could be a need for this without overlays as well. Something like this:
#include <soc.dtsi>
/optional/ &sata { foo = <0>; };
Normally if 'sata' isn't found, that's an error.
To make that work for overlays, we'd have to transform /optional/ into a property. "target-optional" alongside "target-path" perhaps.
This means is that there are DT properties that are dependent on the SoC DT component and the platform DT component which do not fit with splitting the DT files into their individual "component" levels.
The other issue would be the /model property - for example:
model = "SolidRun HummingBoard2 Solo/DualLite"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som+emmc)"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som)"; model = "SolidRun HummingBoard Solo/DualLite"; model = "SolidRun HummingBoard2 Dual/Quad"; model = "SolidRun Cubox-i Solo/DualLite";
I think you just give up and generalize it: "SolidRun HummingBoard/Cubox"
as a set of examples. I don't see a clear way to generate these from a fragmented scheme. There's a similar problem with the board-level compatible:
compatible = "solidrun,cubox-i/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";These don't include the SoM information.
So we're back to needing to merge compatible even though Doug was willing to drop it. Or to put it another way, there's usecases for the base to be different SoC revisions and variants. So I don't think we should give up on solving that.
Maybe what would work would be a high-level DT file that contains paths to the lower levels that need to be combined, along with properties that need to be merged. E.g.
/ { model = "SolidRun HummingBoard2 Dual/Quad"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
dts-components { compatible = "boot/dt"; component@1 { compatible = "dt"; path = "imx6q.dtbo"; }; component@2 { compatible = "dt"; path = "imx6qdl-sr-som-v1.5.dtbo"; }; component@3 { compatible = "dt"; path = "imx6qdl-hummingboard2.dtbo"; }; component@4 { compatible = "dt"; path = "imx6ql-hummingboard2-emmc.dtbo"; }; }; soc { sata@2200000 { .. sata tuning properties .. }; };};
Or something similar. However, this would mean we would still need the 18 or so top level DT files, but also each component as well, which will increase the number of files we're having to manage on a target platform - so I'm wondering whether it's worth it.
Looks like FIT...
I don't think we'll be able to get away from this problem: it's likely that there will continue to be properties that are specific across several "levels" of a split DT setup, and apart from something like the above, I don't really see a way to handle them.
I tend to agree your cases might be the tip of the iceberg. I think someone has to take some existing platforms and see what happens splitting them.
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
We've generally resisted making filenames significant/ABI.
Rob
Hi,
On Mon, Dec 1, 2025 at 5:07 PM Rob Herring robh@kernel.org wrote:
I would be interested in some experiments around making this change with existing DTs. Take a board DT and add the overlay boilerplate (that may be nothing more than add '/plugin/') and remove the SoC include. Does that apply to a compiled SoC DTB and is the result the same as before?
Think of it as moving from building C code using a #include of every .c file to build a single .o to linking multiple individual .o files. No one would argue the former is better.
I suspect it would work some of the time, but it wouldn't be guaranteed. In the very least, the base SoC "dtb" would fail to validate because it would be missing a documented top-level compatible. :-P ...but if we ignore that, I'd imagine these things could break:
1. If a SoC is relying on a "label" that's provided by the boards, it could break.
2. If any of the boards "delete" things from the SoC, it could break.
3. Board files could have been relying on the "bindings" #includes in the base SoC file.
I guess the first two things are much more common between all of the "dtsi" files included to make up a board than they are between the main SoC "dtsi" file and the others, and the third one is "easily" fixed.
OK, so I did a quick experiment and quickly found an example of #2. Take a look at "sc7180-acer-aspire1.dts" and you'll find:
/delete-node/ &tz_mem; /delete-node/ &ipa_fw_mem;
Those delete nodes from the SoC tree.
I also found an example of #3. sc7180-trogdor.dtsi refers to "GCC_MSS_CFG_AHB_CLK", but it doesn't include "dt-bindings/clock/qcom,gcc-sc7180.h".
All of the above could be fixed, but it stops being a "quick" experiment. ;-) Essentially, if people weren't trying to follow the rules of the overlay-to-base boundary it's likely they've crossed them, as in the above case. :-P
If continuing the above experiment would help convince someone, I could certainly continue it. I guess I just don't have too much of a doubt that it could be made to work OK. I think it would be _less_ efficient overall to ship full DTBs generated like that because we'll have compiled the base device tree with "-@". The only way to become more efficient would be to actually ship the base DTB + overlays.
-Doug
On Wed, Dec 3, 2025 at 6:11 AM Doug Anderson dianders@chromium.org wrote:
Hi,
On Mon, Dec 1, 2025 at 7:31 PM Chen-Yu Tsai wenst@chromium.org wrote:
Separately, it can be noted that we always _wanted_ a similar solution for ChromeOS, but we never quite got there... ;-)
FTR ChromeOS is moving in that direction: splitting SKU differences based on components into overlays that get applied to the base by the bootloader.
In the simplest example we could have one base dts and two overlays for two different DSI panel models:
- base.dtb
- panel-model-a.dtbo
- panel-model-b.dtbo
The problem we then run into is that the base.dtb will only have the generic model compatible "google,foo", not the sku and revision specific ones like "google,foo-sku1-rev2".
And we'd really like to avoid having _more_ overlays just to add the final specific compatible string, as that kind of defeats the purpose of using overlays to reduce the number of dts files.
I think you may have simplified the above a little too much to the point where it's confusing. At least I'm a bit confused. I _think_ the problems you're talking about are the kinds of things we run into when we take overlays above just two levels. I'm imagining:
- base.dtb
- board1-rev1.dtbo
- board2-rev1.dtbo
- board1-rev2.dtbo
- board2-rev2.dtbo
- panel-a.dtbo
- panel-b.dtbo
So I think you're saying that you'd start with the "base.dtb" and then extend it with exactly one of the "board" overlays and then exactly one of the "panel" overlays. Is that right?
For now I think we just experiment with having one end "model" or "product" as the base.dtb. The panel-*.dtbo selected describe the optional components, while the board-rev??.dtbo just provides the top level compatible and model.
In an example that I plan to send out this week, I would rework:
- arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri.dtsi - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku0.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku1.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku2.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku3.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku4.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku5.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku6.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku7.dts
into:
- arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri.dts - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-audio-max98390-es8326.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-audio-max98390-rt5682s.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-audio-tas2563-es8326.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-audio-tas2563-rt5682s.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-panel-boe.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-panel-ivo.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku0.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku1.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku2.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku3.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku4.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku5.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku6.dtso - arch/arm64/boot/dts/mediatek/mt8188-geralt-ciri-sku7.dtso
The "mt8188-geralt-ciri-sku?.dtso" files only contain the following boilerplate:
/dts-v1/; /plugin/;
&{/} { model = "Google Ciri sku? board (rev4)"; compatible = "google,ciri-sku?", "google,ciri", "mediatek,mt8188"; };
The base "mt8188-geralt-ciri.dts" would already have a generic board- specific compatible:
model = "Google Ciri board"; compatible = "google,ciri", "mediatek,mt8188";
So I'd imagine that each of the "board" overlays could have "full" compatible strings. For instance, I'd imagine "board2-rev2" could have:
compatible = "google,booard2-rev2", "socVendor,soc"
The problem you're struggling with (I think) is that the panel overlays won't be represented in the compatible string (and "model") even though (historically) we always did in ChromeOS (they were included in the "sku" part of the compatible string).
Did I get that right?
In a sense you've generalized the problem I was describing.
In my example, the top level compatible gets fixed up by the final SKU-specific overlay. But that's 8 extra files to do one bit of fixup that supposedly the bootloader could be taught to do, and could do even better. The bootloader knows exactly which SKU and revision it's running on and can insert the information appropriately. We could get rid of those awkwardly long compatible string sequences:
compatible = "google,tentacruel-sku262147", "google,tentacruel-sku262146", "google,tentacruel-sku262145", "google,tentacruel-sku262144", "google,tentacruel", "mediatek,mt8186";
Going back to what I think you're describing, is that instead of one base board DTB for each product, we could have one base DTB for the reference design (in place of the .dtsi file we currently have), and make products and component selection all use overlays.
If we do that, then inserting the correct top level compatible and model becomes more important, since we do have things such as the ChromeOS OF component prober working based on top level compatible. Also, the model is present in logs, and would be very misleading to say one device name while in reality it is a different one.
I proposed internally maybe having the bootloader fix up the final compatible string, but I think we need some rough consensus upstream whether this is acceptable or not.
Maybe we need to come to some agreement about when the top-level compatible string needs to be changed. In the above, I'd perhaps argue that the panel isn't a major enough change that it needs to change the top-level compatible string. That would solve the problem, right? What do others think? Certainly for "probe-able" components we don't change the top-level compatible string. Can anyone point to any official documentation about the top-level compatible string?
I'd certainly like more documentation as well.
ChenYu
boot-architecture@lists.linaro.org