Creating a custom dtb outside of the kernel build tree.

I’m working on a camera driver for custom hardware.

I need to modify the device tree.

In the past I’ve done this by decompiling the dtb, editing the dts, and recompiling. This
is not optimal because labels and such are removed, and if distributed .dtsi files change
the decompiled dts won’t be valid any more. So I want to create the device tree from the
existing .dts, .dtsi, and .h files.

In general we try to avoid modifying unpacked build trees if at all possible, so I’m trying
to do this outside of the kernel build tree. There’s a cpp step, followed by a dtc compile.

I’m pretty close except there is a forward reference problem – /bpmp/bpmpthermal is referenced
before it is defined. I’m doing this starting with an unmodified tegra186-quill-p3310-1000-c03-00-base.dts

I guess I don’t understand how forward (or circular) references work in a device tree (dts). I
understand it could be done with phandle entries, but the problem here is a refernce
like this: thermal-sensors = <&{/bpmp/bpmpthermal} 2>; that fails. It seems to be an
order problem in tegra186-soc-base.dtsi, but these compile with a kernel “make dtbs” just fine.

Any ideas? Commands and output are below.

I’m sure I’ll have more questions, and I’ll try to answer where I can.



cpp -nostdinc -x assembler-with-cpp
-I …/…/Build/Kernel/source/hardware/nvidia/soc/tegra/kernel-include
-I …/…/Build/Kernel/source/hardware/nvidia/soc/tegra/kernel-include/kernel-4.4
-I …/…/Build/Kernel/source/hardware/nvidia/platform/tegra/common/kernel-dts
-I …/…/Build/Kernel/source/hardware/nvidia/soc/t18x/kernel-include
-I …/…/Build/Kernel/source/hardware/nvidia/soc/t18x/kernel-dts
-I …/…/Build/Kernel/source/hardware/nvidia/platform/t18x/common/kernel-dts
-I …/…/Build/Kernel/source/hardware/nvidia/platform/t18x/quill/kernel-dts
tegra186-quill-p3310-1000-c03-00-base.dts intermediate.dts
dtc --in-format dts --out-format dtb -o ssve.dtb intermediate.dts
ssve.dtb: ERROR (phandle_references): Reference to non-existent node or label “/bpmp/bpmpthermal”
ssve.dtb: ERROR (phandle_references): Reference to non-existent node or label “/bpmp/bpmpthermal”
ssve.dtb: ERROR (phandle_references): Reference to non-existent node or label “/bpmp/bpmpthermal”
ssve.dtb: ERROR (phandle_references): Reference to non-existent node or label “/bpmp/bpmpthermal”
ssve.dtb: ERROR (phandle_references): Reference to non-existent node or label “/bpmp/bpmpthermal”

ERROR: Input tree has errors, aborting (use -f to force output)

Could you tell what reason not used kernel “make dtbs” ?
You can try to replace the error part from the decompile dtb if you still insist not use the default build method.
Like replace the
thermal-sensor = <${/bpmp/bpmpthermal THERAML_ZONE_CPU>;
thermal-sensor = <0x37 0x2>

We try to avoid modifying external source distributions wherever possible, it seems to make
maintenance easier (based on some bad experiences in the past). I’m also trying to
understand device trees better. We could work from a decompiled dtb, but then a lot of
information is lost, all the connections between devices get changed to numeric phandle’s
so it’s hard to see what is connected to what, and future updates might break it.
Plus it seems that the camera platform might need references to camera devices
for the cameras that we add, which means more changes.

I did get it to work by copying a few key files out of


And removing some ‘disabled’ entries. I’m not sure if I’m going to stick with this
way going forward.

It works now.

I dug into this some more. The problem is that you have to use the dtc
supplied with the kernel (in out/scripts/dtc, Version: DTC 1.4.1-g9d3649bd),
rather than the one provided. I can build using the kernel source files
unmodified, and just add my own sections at the end of the top-level
dts (i.e tegra186-quill-p3310-1000-c03-00-base.dts intermediate.dts).

Seems to boot fine with this dtb.