In depth Device Tree Questions

I have some fundamental questions understanding the Device Tree syntax.

Question One:

Device Node numbers. Like this snippet:

Code:
     uart@20000000 {
              interrupt-parent = < 1 >;
      };

Where is the number 20000000 coming from? Where is this assigned from?
I don't see it in the dts or dtsi source code.
It is shown in ofwdump -a output from the board.
 
A specific device tree describes real hardware so uart@20000000 says there is a uart device at address 0x20000000 -- that number comes from the processor or board spec. The device tree format is pretty simple. I wrote a minimal decompiler (dtb -> dts but doesn't deal with overlays) that I can put up on github. It won't teach you much about dt but you can experiment and read the code. The dtb reading code is about 350 LoC, the decompiler code about 250 LoC
 
says there is a uart device at address 0x20000000
OK really simple. What is address is that? A machine register address? A pointer? A memory address.
I understand that it is common among CPU devices. For example iMX6 would all use the same unit number for devices like uart and i2c.
 
A machine register address? A pointer? A memory address.
That depends on what it is! AFAIK the DT spec doesn’t help there or care. All it does is basically give you a symbolic way to use various h/w facilities but you still have to know from other sources what a number means in a given context. It could be a register or a memory or device address or an interrupt vector or just a flip flop.
 
OK I want to move on to a second question.

Compiling Device Tree Overlays.

Commonly I find overlays that have an #include /dt-bindings/gpio/gpio.h or similar includes needed.
How do you compile these overlays with the includes?
Device Tree Compiler? Gmake? make_dtbs ?
Do you have to compile from a certain directory to use includes?
For example the following directory contains overlays.
/usr/src/sys/dts/arm64/overlays/

Yet the device tree bindings are here:
/usr/src/sys/gnu/dts/include/dt-bindings/gpio/gpio.h
With Clang I would use an Include on the command line but I am not sure with dtc.
 
#include are processed by cpp, while /include/ are processed by dtc. So for #include cpp rules apply. /include/ seems to look in the current directory but I think you can specify -i flag for include dir path. Do a make -n in the overlays dir. and follow the breadcrumbs from there. In particular sys/tools/fdt/make_dtbo.sh
 
Thanks for all the wise advice bakul
I have another procedural question.

What do 'symbols' do in the dtc -@ flag context? The handbook seems to indicate they denote an overlay.
I thought the flag had something to do with including symbols. Later in the document it says this:
When the -@ flag is used to write symbols, nodes with labels will be con-
sidered referenced

What does writing symbols here mean?
 
I find it interesting to use a u-boot ports build to look at the dts build procedure. The *.pre files are kept.
 
A __symbols__ node will be included so that overlays
may be applied to it.
What is a symbols node? Is this just a branch in the tree? Is there content or a stub?
Is this debugging information?
 
A specific device tree describes real hardware so uart@20000000 says there is a uart device at address 0x20000000 -

That is not exactly the case, @unit address acts as an id. It's an address within the device tree.
The common way to define a register address is to setup the reg property in the device node.

However, as one usually do, @unit address follows the register address.
 
I wanted to Thank bakul and covacat for thier great leads.

Covacat here:
do it like
cpp -I /sys/contrib/device-tree/include/ -x assembler-with-cpp /sys/contrib/device-tree/src/arm/sun8i-h2-plus-orangepi-zero.dts |dtc -I dts > my-new-dtb.dtb

And Bakul above. Also Bakul mentioning make -n really helped.

I was deep in the directory and unsure where to compile from. By chasing make -n up until it found a Makefile.
/usr/src/sys/contrib/device-tree/src/arm64/marvell

So compile from there. Top most Makefile location.
/usr/src/sys/contrib/device-tree/
make -n still complained but I had some output.

I found a great stackexchange that helped.

Here is my espressobin compile.

cd /usr/src/sys/contrib/device-tree/

cpp -I /sys/contrib/device-tree/include/ -x assembler-with-cpp /sys/contrib/device-tree/src/arm64/marvell/armada-3720-espressobin-v7-emmc.dts | dtc -I dts -O dtb -o armada-3720-espressobin-v7-emmc.dtb
 
Well it appears when you get the directories right you don't need cpp for these dts in base.
I was simply compiling from wrong directory.

cd /usr/src/sys/contrib/device-tree

dtc -@ -O dtb -I dts -o ./src/arm64/marvell/armada-3720-espressobin.dtb ./src/arm64/marvell/armada-3720-espressobin.dts
 
Struck that. I could see from the file size it was not correct.
The dtsi in this case is the bulk of the work. So if missing dtb is small.
 
I see another method to checkout here:

MACHINE=arm64 DTC=/usr/bin/dtc tools/fdt/make_dtb.sh /usr/src/sys
gnu/dts/arm64/rockchip/rk3399-rockpro64.dts /tmp


EDIT:
The FreeBSD source tree has been changed since this post
and paths need to be adjusted to dts.
 
Last edited:
Back
Top