[LINUX] Expand devicetree source include to make it easier to read

Happy new year 2020.

For three days, I read the device tree source (dts) of Raspberry Pi 4. I'm still reading it, so I'll give you some information about it somewhere, but this time I'll introduce the tricks I used to read dts.


--dts with #include will be easier to read through cpp and dtc

What is a device tree

devicetree (hereafter dt) describes where and what device is connected to a particular piece of hardware.

In Linux, dt is mainly used to know the configuration of embedded machines using ARM and PowerPC, and Raspberry Pi also uses this dt to teach the Linux Kernel the configuration of the machine.

Like a compiled language, dt compiles a devicetree source (hereafter dts) written in a human-readable format with a devicetree compiler (hereafter dtc) to generate a devicetree blob (hereafter dtb) and use it. To do.

For example, in the Linux kernel (ARM), the address of dtb loaded in memory in advance by a boot loader etc. is received via a register, and the dtb in memory is referenced to know the machine configuration.

For other details about dt, refer to the following.

Why read dts

The BCM2711 SoC installed in the Raspberry Pi 4 has several parts that are different from the SoC up to the Raspberry Pi 3, such as installing the GIC-400 in the interrupt controller.

However, the Peripheral Manual that explains the peripherals installed in the SoC and how to handle them has not been released yet (as of July 2019, "It is almost completed, but it seems that it will take several weeks" Middle Written by a person has not yet appeared as of January 6, 2020) ..

Therefore, in order to do something like bare metal development that directly controls peripherals on Raspberry Pi 4, you can find it in Linux Kernel Source for Raspberry Pi. You need to look at the dts to find out the peripheral configuration and the mapped address of the MMIO.

Create easy-to-read dts by expanding include

Dts for Raspberry Pi 4 is published below.

The first few lines of this dts file are quoted below.

#include "bcm2711.dtsi"
#include "bcm2711-rpi.dtsi"
#include "bcm283x-rpi-csi1-2lane.dtsi"

As you can see from this, bcm2711-rpi-4-b.dts uses the include statement to read multiple dtsi files.

And the bcm2711.dtsi read here also reads bcm2838.dtsi, that is, the include is nested, so it is a little troublesome to read it as it is.

Therefore, I would like to create a dts file for reading with the include expanded in advance.


Bring the Linux kernel for the Raspberry Pi from git and put it in that directory.

$ git clone --depth=1 https://github.com/raspberrypi/linux raspberrypi_linux
$ cd raspberrypi_linux

Find out how to handle include

In dtc used when setting dts to dtb, it is possible to output dts with dts as input. Therefore, I thought, "If you pass dtc, include should be processed properly and you should get dts that is easy to read ...", but when I try to execute it, the following error appears and it does not work.

$ dtc -I dts -O dts -o readable.dts arch/arm/boot/dts/bcm2711-rpi-4-b.dts 
Error: arch/arm/boot/dts/bcm2711-rpi-4-b.dts:3.1-9 syntax error
FATAL ERROR: Unable to parse input tree

See Devicetree Specification Release v0.2 to find the cause. , "6.1 Compiler directives" states that include in dts should be done in the following format.

/include/ "FILE"

On the other hand, in bcm2711-rpi-4-b.dts, dtc seems to give an error because it is not included in the format written in the device tree specification.

From the results of the investigation so far, it should be correct that dts cannot be compiled with the include statement of bcm2711-rpi-4-b.dts. But why is it possible to compile dts on Linux?

Looking up the dtb build rules from the Linux source code for the reason, [scripts / Makefile.lib](https://github.com/raspberrypi/linux/blob/rpi-4.19.y/scripts/ From Makefile.lib # L287), I found that in Linux, dts is passed through the C preprocessor before compiling with dtk. The relevant part of scripts / Makefile.lib is quoted below.

cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
	$(DTC) -O dtb -o $@ -b 0 \
		$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)

Therefore, referring to this rule, it seems that easy-to-read dts can be obtained by passing dts through the preprocessor with appropriate options and then compiling with dtc.

Make easy-to-read dts

From here, let's make dts that is easy to read by referring to the procedure that Linux is doing.

Through the preprocessor

To handle the include, pass it through the preprocessor as follows.

cpp -nostdinc -undef -D__DTS__ -x assembler-with-cpp \
  -I./scripts/dtc/include-prefixes \
  ./arch/arm/boot/dts/bcm2711-rpi-4-b.dts \
  -o ~/bcm2711-rpi-4-b_readable.dts


It is difficult to read because there are many comments attached by the preprocessor just by passing it through the preprocessor, so compile it with dtc to make it easier to read.

dtc -I dts -O dts -o ~/bcm2711-rpi-4-b_readable.dts ~/bcm2711-rpi-4-b_readable.dts

I get a lot of warnings, but if there are no errors, there should be dts that are easier to read in ~ / bcm2711-rpi-4-b_readable.dts.

The end

This concludes the introduction of how to make easy-to-read dts with expanded include.

When reading dts on Raspberry Pi 4,

"The compatible head of gpio is bcm2711-gpio, but since bcm2835-gpio is also included, the code for RasPi3 seems to work thanks to the compatibility. But what's new? Driver. I have to read ... "

It's fun to discover and think about things like that.

I hope you can share this fun with the people who read this article.

Recommended Posts

Expand devicetree source include to make it easier to read
Tips to make Python here-documents easier to read
The background of the characters in the text image is overexposed to make it easier to read.
You who color the log to make it easier to see
One liner that formats JSON to make it easier to see
I wrote Django commands to make it easier to debug Celery tasks
Make it easier to test programs that work with APIs with vcrpy
Note: Improving annoying prompts to make them easier to read. // Linux prompt change
Make it possible to read .eml from your smartphone using discord bot
Gorilla judgment machine, gorilla! !! Tried to make it!
Make SikuliX's click function easier to use
I read "How to make a hacking lab"