KEMBAR78
Linux Device Tree | PPTX
Open Firmware Device Tree
May 31 , 2017
Device Tree
A device tree is a tree data structure and
language for describing hardware.
Device Tree File For Different Board
Unique device tree binary file required by the
kernel.
The purpose of Linux Device Tree
Given the correct device tree, the same
compiled kernel can support different
hardware configurations within a wider
architecture family.
To move a significant part of the hardware
description out of the kernel binary, and into
the compiled device tree blob, which is
handed to the kernel by the boot loader,
replacing a range of board-specific C source
files and compile-time options in the kernel.
Linux Device Tree (DT)
Board
SoC
.dtsi
.dts
Device
Tree Blob
.dtb
DT-enable
kernel
zImage
boot loader
(start.elf)
pass to kernel
DTS source :
arch/arm/boot/dts/bcm2710-rpi-3-b.dts
arch/arm/boot/dts/bcm2710.dtsi
Overlay source
arch/arm/boot/dts/overlays/yyy-overlay.dts
/boot
Device
Tree
Overlay
yyy.dtbo
Device
yyy-overlay.dts
DT Compiler
DT Compiler
Linux DT Files
.dtb - a compiled device tree. (Binary Blob)
.dts - device tree source.
.dtsi - device tree source to be included by
a .dts or .dtsi file.
dtc - Device tree compiler.
EDT Expanded Device Tree - A copy of an FDT,
but converted to kernel data structures, in the
kernel memory space.
FDT Flattened Device Tree - A copy of a binary
blob in the kernel memory space.
Device Tree Syntax
Device Tree Basics /
cpus: its each sub-nodes describing each CPU in
the system.
memory : defines location and size of the RAM.
chosen : defines parameters chosen or defined by
the system firmware at boot time.
• In practice, one of its usage is to pass the kernel
command line.
aliases: shortcuts to certain nodes.
One or more nodes defining the buses in the SoC
One or more nodes defining on-board devices
Skeleton of Device Tree
Dump dts currently used by the kernel
sudo apt-get install device-tree-compiler
dtc -I fs -O dts /sys/firmware/devicetree/base
Device Tree和Driver的關連性
The driver loaded by the kernel when the
hardware is present (i.e. declared in the
device tree)
The driver needs to know the physical
addresses allocated to the device
The driver needs to know which interrupt(s)
the device will trigger, so it can register
interrupt handlers
Application-specific information needs to be
retrieved
node in DT
Every device in the system is represented by a device
node.
Node Names : <name>[@<unit-address>]
In DT, a node has been added for each device in the
system, and the hierarchy reflects the how devices
are connected to the system
A node in the device tree can be uniquely identified
by specifying the full path from the root node
RTC devices are
children of the i2c bus
controller node
Property: compatible
Every node in the tree that represents a device
is required to have the compatible property.
• the link between the hardware and its driver.
• decides which device driver to bind to a device.
• compatible= "<manufacturer>,<model>“
more than one driver will be eligible for a
certain peripheral entry
• compatible = “fsl,mpc8641-uart”, “ns16550";
Making the driver autoload
When the kernel starts up, it kicks off
compiled-in drivers that match “compatible”
entries it finds in the device tree.
At a later stage (when /lib/modules/kernel-
version/ is available), all kernel modules that
match “compatible” entries in the device tree
are loaded.
Driver Probe
.dts
.driver
struct …. {
…..
.of_match_table= xxx;
}
struct of_device_id xxx[]= {
….
.compatible=“ ”,
}
OF? Open Firmware
Memory Mapped Devices
說明sublayer對於位址
的描述格式
Reg Format (Address information )
• The #address-cells property indicate how many cells (i.e 32 bits values) are
needed to form the base address part in the reg property.
• The #size-cells is the same, for the size part of the reg property.
#address-cells = <3>;
#size-cells = <1>;
address-cells size-cells
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0a>;
i2c0: i2c@80058000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx28-i2c";
reg = <0x80058000 0x2000>;
interrupts = <111>;
[...]
sgtl5000: codec@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
VDDA-supply = <&reg_3p3v>;
VDDIO-supply = <&reg_3p3v>;
clocks = <&saif0>;
};`
Non Memory Mapped Devices
說明sublayer對於位址
的描述格式
i2c0: i2c@80058000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx28-i2c";
reg = <0x80058000 0x2000>;
interrupts = <111>;
[...]
sgtl5000: codec@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
VDDA-supply = <&reg_3p3v>;
VDDIO-supply = <&reg_3p3v>;
clocks = <&saif0>;
};
at24@51 {
compatible = "at24,24c32";
pagesize = <32>;
reg = <0x51>;
};
};
a device can be attached to an external bus with
discrete chip select lines.
chipselect number, the offset, and the length.
Property: Ranges
The ranges property can describe an address translation
between the child bus and the parent bus
serial device node can be addressed by a load or store at address 0xe0004600
aliases node
Each property of the /aliases node defines an
alias. The property name specifies the alias
name.
An alias value is a device path and is encoded
as a string. The value represents the full path
to a node
/
simple-bus@fe000000
serial@11c500
ethernet@31c000
The alias node shall be at the root of the
device tree and have the node name aliases.
&audio {
pinctrl-names = "default";
pinctrl-0 = <&audio_pins>;
};
Property: phandle
Value type: <u32>
The phandle property specifies a numerical
identifier for a node that is unique within the
device tree.
The phandle property value is used by other
nodes that need to refer to the node
associated with the property.
Labels and Phandls
Label is just like label in C gives a name to a
place in the code.
Syntax:
label_name: node_name {
………….
}
a integer phandle
26
Labels and Phandls
It’s often necessary for one part of the tree to refer from
another.
Path strings : /soc/i2s@7e203000.
the status property: /soc/i2s@7e203000/status
Terrible to type full path every time when use it
phandle : think it as kind of pointer of the node
27
It’s possible for the same node to appear twice in a
DTS file ( and its inclusions) : the properties are
combined.
What happen when nodes have the same name ?
28
共同需要的property 可
以寫在dtsi內,讓不同的
dts include
相同property 的值若不同,
後面的取代前面的設定
Device tree in user space
The /proc/device-tree will be created if
CONFIG_PROC_FS is set to ‘Y’
Reading information that dtb loaded.
Verify if setting something wrong in dts
29
Device tree overlay
a system like Raspberry Pi supports optional
plug-in accessories
a way to describe these optional components
using a partial Device Tree, and then to be
able to build a complete tree by taking a base
DT and adding a number of optional elements.
These optional elements are called "overlays".
Example : Enable the I2S interface by DT overlay
31
Fragment的編號
從0開始順序增加
target 宣告那一個node要被overlay
Overlay { }內宣告要被改值或增加的properties
綁定的目標
This overlay is used to enable i2c interface by changing its status to okay
overlay的module一定要寫
A DT overlay comprises a number of fragments,
each of which targets one node and its subnodes.
Device Tree (DT)
bcm2710-rpi-3-b.dts
SoC
bcm2710.dtsi Device
Tree Blob
.dtb
DT-enable
kernel
zImage
boot loader
(start.elf)
pass to kernel
/boot
Device
Tree
Overlay
yyy.dtbo
Device
yyy-overlay.dts
DT Compiler
DT Compiler
bcm2708_common.dtsi
drivers/of/base.c
trace "drivers/of/base.c"
Lab: 如何取得Tree node的property
cd DeviceTree; make
insmod dt.ko
dmesg Passing platform_data from
device tree to i2c driver
see DeviceTree/dt.c
Hands-on
方法一: 在pi上修改.dts, 並重新產生dtb
vim arch/arm/boot/dts/bcm2710-rpi-3-b.dts
make ARCH=arm dtbs -j 4
cp arch/arm/boot/dts/bcm2710-rpi-3-b.dtb /boot
#Dump dts used in kernel
dtc -I fs -O dts /sys/firmware/devicetree/base
方法二:使用Overlap 方法
dtc -@ -I dts -O dtb -o at24.dtbo at24.dts
cp at24.dtbo /boot/overlays
vim /boot/config.txt
#Ucomment this to enable the I2C EEPROM (24LC02)
module (I2C 0x50)
dtoverlay=at24
reboot
37
整理
Linux Device Tree
Linux Device Driver
.compatible=“ , ”
Step 1:
修改整個.dts .dtb 或
使用Overlap 方法  xxx.dtbo
(.dtbo要放在/boot/overlays)
Step2:
修改config.txt , 加入 dtoverlay=xxx
Pi-driver/DeviceTree/dt.c
Pi-driver/dts_overlay
xxx_probe(struct i2c_client *client, …)
{
struct device_node *matched_node=client->dev.of_node;
val = of_get_property (matched_node, "reg", NULL); ….
}
of_device_id={
.compatible = “ "
}
.dtb or .dtbo
.ko
Device Tree for ADC (MCP3008)
39
kernel version: 4.4.y
device tree overlay
40
device tree for MCP3008
dtc -@ -I dts -O dtb -o mcp300x.dtbo mcp300x.dts
cp mcp300x.dtbo /boot/overlays
vim /boot/config.txt
dtoverlay=mcp300x
reboot
41
Generate .dtbo
cd 12_MCP3008
make ; insmod mcp320x.ko
42
ADC Driver for MCP3008
將 mcp320x.ko 複製到/lib/modules下
cp mcp320x.ko /lib/modules/4.4.35-v7/kernel/drivers/iio/adc/
43
mcp320x Driver 自動載入
Devices Driver --->
Industrial I/O support--->
Analog to digital converters --->
<M> Microchip Technology MCP3x01/02/04/08
• cd /sys/bus/iio/devices/iio:device0
• cat in_voltage0_raw
• voltage : 0~3.3v, ADC value: 0~1023
44
Test ADC (請接上光敏電阻在TH1)
Utility programs associate with the Linux
kernel industrial I/O framework.
• Similar in purpose to lsusb.
Source Download:
• https://sourceforge.net/projects/iioutils/?source=typ_redirect
• ./configure; make ; make install
you may need to do "apt-get install libsysfs-
dev"
• interface library to sysfs
45
Industrial I/O Utils
46
MCP3008
linux-rpi-4.4.y/drivers/iio/adc/mcp320x.c
47
Trace MCP3008 原始碼
Kernel 如何自動載入Driver(kernel module ) ?
check that the module is exporting the correct aliases by
searching / lib/modules/<version>/modules.alias
for the compatible value.
compatible <drivrer.ko>

Linux Device Tree

  • 1.
    Open Firmware DeviceTree May 31 , 2017
  • 2.
    Device Tree A devicetree is a tree data structure and language for describing hardware.
  • 3.
    Device Tree FileFor Different Board Unique device tree binary file required by the kernel.
  • 4.
    The purpose ofLinux Device Tree Given the correct device tree, the same compiled kernel can support different hardware configurations within a wider architecture family. To move a significant part of the hardware description out of the kernel binary, and into the compiled device tree blob, which is handed to the kernel by the boot loader, replacing a range of board-specific C source files and compile-time options in the kernel.
  • 5.
    Linux Device Tree(DT) Board SoC .dtsi .dts Device Tree Blob .dtb DT-enable kernel zImage boot loader (start.elf) pass to kernel DTS source : arch/arm/boot/dts/bcm2710-rpi-3-b.dts arch/arm/boot/dts/bcm2710.dtsi Overlay source arch/arm/boot/dts/overlays/yyy-overlay.dts /boot Device Tree Overlay yyy.dtbo Device yyy-overlay.dts DT Compiler DT Compiler
  • 6.
    Linux DT Files .dtb- a compiled device tree. (Binary Blob) .dts - device tree source. .dtsi - device tree source to be included by a .dts or .dtsi file. dtc - Device tree compiler. EDT Expanded Device Tree - A copy of an FDT, but converted to kernel data structures, in the kernel memory space. FDT Flattened Device Tree - A copy of a binary blob in the kernel memory space.
  • 7.
  • 8.
    Device Tree Basics/ cpus: its each sub-nodes describing each CPU in the system. memory : defines location and size of the RAM. chosen : defines parameters chosen or defined by the system firmware at boot time. • In practice, one of its usage is to pass the kernel command line. aliases: shortcuts to certain nodes. One or more nodes defining the buses in the SoC One or more nodes defining on-board devices
  • 9.
  • 10.
    Dump dts currentlyused by the kernel sudo apt-get install device-tree-compiler dtc -I fs -O dts /sys/firmware/devicetree/base
  • 11.
    Device Tree和Driver的關連性 The driverloaded by the kernel when the hardware is present (i.e. declared in the device tree) The driver needs to know the physical addresses allocated to the device The driver needs to know which interrupt(s) the device will trigger, so it can register interrupt handlers Application-specific information needs to be retrieved
  • 12.
    node in DT Everydevice in the system is represented by a device node. Node Names : <name>[@<unit-address>] In DT, a node has been added for each device in the system, and the hierarchy reflects the how devices are connected to the system A node in the device tree can be uniquely identified by specifying the full path from the root node
  • 13.
    RTC devices are childrenof the i2c bus controller node
  • 14.
    Property: compatible Every nodein the tree that represents a device is required to have the compatible property. • the link between the hardware and its driver. • decides which device driver to bind to a device. • compatible= "<manufacturer>,<model>“ more than one driver will be eligible for a certain peripheral entry • compatible = “fsl,mpc8641-uart”, “ns16550";
  • 15.
    Making the driverautoload When the kernel starts up, it kicks off compiled-in drivers that match “compatible” entries it finds in the device tree. At a later stage (when /lib/modules/kernel- version/ is available), all kernel modules that match “compatible” entries in the device tree are loaded.
  • 16.
    Driver Probe .dts .driver struct ….{ ….. .of_match_table= xxx; } struct of_device_id xxx[]= { …. .compatible=“ ”, } OF? Open Firmware
  • 17.
  • 18.
    Reg Format (Addressinformation ) • The #address-cells property indicate how many cells (i.e 32 bits values) are needed to form the base address part in the reg property. • The #size-cells is the same, for the size part of the reg property. #address-cells = <3>; #size-cells = <1>; address-cells size-cells #address-cells = <1>; #size-cells = <0>; reg = <0x0a>; i2c0: i2c@80058000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx28-i2c"; reg = <0x80058000 0x2000>; interrupts = <111>; [...] sgtl5000: codec@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; VDDA-supply = <&reg_3p3v>; VDDIO-supply = <&reg_3p3v>; clocks = <&saif0>; };`
  • 19.
    Non Memory MappedDevices 說明sublayer對於位址 的描述格式
  • 20.
    i2c0: i2c@80058000 { #address-cells= <1>; #size-cells = <0>; compatible = "fsl,imx28-i2c"; reg = <0x80058000 0x2000>; interrupts = <111>; [...] sgtl5000: codec@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; VDDA-supply = <&reg_3p3v>; VDDIO-supply = <&reg_3p3v>; clocks = <&saif0>; }; at24@51 { compatible = "at24,24c32"; pagesize = <32>; reg = <0x51>; }; };
  • 21.
    a device canbe attached to an external bus with discrete chip select lines. chipselect number, the offset, and the length.
  • 22.
    Property: Ranges The rangesproperty can describe an address translation between the child bus and the parent bus serial device node can be addressed by a load or store at address 0xe0004600
  • 23.
    aliases node Each propertyof the /aliases node defines an alias. The property name specifies the alias name. An alias value is a device path and is encoded as a string. The value represents the full path to a node / simple-bus@fe000000 serial@11c500 ethernet@31c000
  • 24.
    The alias nodeshall be at the root of the device tree and have the node name aliases. &audio { pinctrl-names = "default"; pinctrl-0 = <&audio_pins>; };
  • 25.
    Property: phandle Value type:<u32> The phandle property specifies a numerical identifier for a node that is unique within the device tree. The phandle property value is used by other nodes that need to refer to the node associated with the property.
  • 26.
    Labels and Phandls Labelis just like label in C gives a name to a place in the code. Syntax: label_name: node_name { …………. } a integer phandle 26
  • 27.
    Labels and Phandls It’soften necessary for one part of the tree to refer from another. Path strings : /soc/i2s@7e203000. the status property: /soc/i2s@7e203000/status Terrible to type full path every time when use it phandle : think it as kind of pointer of the node 27
  • 28.
    It’s possible forthe same node to appear twice in a DTS file ( and its inclusions) : the properties are combined. What happen when nodes have the same name ? 28 共同需要的property 可 以寫在dtsi內,讓不同的 dts include 相同property 的值若不同, 後面的取代前面的設定
  • 29.
    Device tree inuser space The /proc/device-tree will be created if CONFIG_PROC_FS is set to ‘Y’ Reading information that dtb loaded. Verify if setting something wrong in dts 29
  • 30.
    Device tree overlay asystem like Raspberry Pi supports optional plug-in accessories a way to describe these optional components using a partial Device Tree, and then to be able to build a complete tree by taking a base DT and adding a number of optional elements. These optional elements are called "overlays".
  • 31.
    Example : Enablethe I2S interface by DT overlay 31 Fragment的編號 從0開始順序增加 target 宣告那一個node要被overlay Overlay { }內宣告要被改值或增加的properties 綁定的目標 This overlay is used to enable i2c interface by changing its status to okay overlay的module一定要寫 A DT overlay comprises a number of fragments, each of which targets one node and its subnodes.
  • 32.
    Device Tree (DT) bcm2710-rpi-3-b.dts SoC bcm2710.dtsiDevice Tree Blob .dtb DT-enable kernel zImage boot loader (start.elf) pass to kernel /boot Device Tree Overlay yyy.dtbo Device yyy-overlay.dts DT Compiler DT Compiler bcm2708_common.dtsi
  • 33.
  • 34.
    Lab: 如何取得Tree node的property cdDeviceTree; make insmod dt.ko dmesg Passing platform_data from device tree to i2c driver
  • 35.
  • 36.
    Hands-on 方法一: 在pi上修改.dts, 並重新產生dtb vimarch/arm/boot/dts/bcm2710-rpi-3-b.dts make ARCH=arm dtbs -j 4 cp arch/arm/boot/dts/bcm2710-rpi-3-b.dtb /boot #Dump dts used in kernel dtc -I fs -O dts /sys/firmware/devicetree/base
  • 37.
    方法二:使用Overlap 方法 dtc -@-I dts -O dtb -o at24.dtbo at24.dts cp at24.dtbo /boot/overlays vim /boot/config.txt #Ucomment this to enable the I2C EEPROM (24LC02) module (I2C 0x50) dtoverlay=at24 reboot 37
  • 38.
    整理 Linux Device Tree LinuxDevice Driver .compatible=“ , ” Step 1: 修改整個.dts .dtb 或 使用Overlap 方法  xxx.dtbo (.dtbo要放在/boot/overlays) Step2: 修改config.txt , 加入 dtoverlay=xxx Pi-driver/DeviceTree/dt.c Pi-driver/dts_overlay xxx_probe(struct i2c_client *client, …) { struct device_node *matched_node=client->dev.of_node; val = of_get_property (matched_node, "reg", NULL); …. } of_device_id={ .compatible = “ " } .dtb or .dtbo .ko
  • 39.
    Device Tree forADC (MCP3008) 39 kernel version: 4.4.y
  • 40.
  • 41.
    dtc -@ -Idts -O dtb -o mcp300x.dtbo mcp300x.dts cp mcp300x.dtbo /boot/overlays vim /boot/config.txt dtoverlay=mcp300x reboot 41 Generate .dtbo
  • 42.
    cd 12_MCP3008 make ;insmod mcp320x.ko 42 ADC Driver for MCP3008
  • 43.
    將 mcp320x.ko 複製到/lib/modules下 cpmcp320x.ko /lib/modules/4.4.35-v7/kernel/drivers/iio/adc/ 43 mcp320x Driver 自動載入 Devices Driver ---> Industrial I/O support---> Analog to digital converters ---> <M> Microchip Technology MCP3x01/02/04/08
  • 44.
    • cd /sys/bus/iio/devices/iio:device0 •cat in_voltage0_raw • voltage : 0~3.3v, ADC value: 0~1023 44 Test ADC (請接上光敏電阻在TH1)
  • 45.
    Utility programs associatewith the Linux kernel industrial I/O framework. • Similar in purpose to lsusb. Source Download: • https://sourceforge.net/projects/iioutils/?source=typ_redirect • ./configure; make ; make install you may need to do "apt-get install libsysfs- dev" • interface library to sysfs 45 Industrial I/O Utils
  • 46.
  • 47.
  • 48.
    Kernel 如何自動載入Driver(kernel module) ? check that the module is exporting the correct aliases by searching / lib/modules/<version>/modules.alias for the compatible value. compatible <drivrer.ko>

Editor's Notes

  • #28 #clock-cells =0 單一clock輸出 Clockslist of phandles,兩個中之一為這個裝置的clock輸出
  • #29 Child nodes must be uniquely named, but can alternatively be addressed by a “unit name,” which is used to differentiate nodes with the same name (for example, multiple I2C devices in the same SoC) at the same level. Unit names are made of the node names, the “@” symbol, and a unit address (for example, i2c@3000, i2c@4000, and so on).
  • #30 For newer kernels where the CONFIG_PROC_DEVICETREE option does not exist, /proc/device-tree will be created if CONFIG_PROC_FS is set to 'Y'. 進到某一個node的目錄下,用hexdump –C property-name,就可以將值讀出來 若你要寫一個user space driver,必須要知道一些hardware的狀況,可以從這裡讀取