00.目录
文章目录
01.概述
Linux3.x之后的版本才引入了设备树,设备树用于描述一个硬件平台的板级细节。前面我们写的驱动须要依赖设备树,所以在这儿先演示怎么编译设备树、加载设备树。
具体原理请参考Linux设备树相关博客。
02.设备树编译2.1使用内核中的dtc工具编译
首先我们须要编译好内核(一般只需一次编译好内核红帽linux系统下载,编译内核的时侯会生成的dtc工具),内核编译的位置在kernel目录中,内核中的dtc工具位置在kernel/scripts/dtc/dtc。
dtc工具用法如下
deng@local:~/code/x3399$ ./kernel/scripts/dtc/dtc --help
Usage: dtc [options] <input file>
Options: -[qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv]
-q, --quiet
Quiet: -q suppress warnings, -qq errors, -qqq all
-I, --in-format <arg>
Input formats are:
dts - device tree source text
dtb - device tree blob
fs - /proc/device-tree style directory
-o, --out <arg>
Output file
-O, --out-format <arg>
Output formats are:
dts - device tree source text
dtb - device tree blob
asm - assembler source
-V, --out-version <arg>
Blob version to produce, defaults to 17 (for dtb and asm output)
-d, --out-dependency <arg>
Output dependency file
-R, --reserve <arg>
Make space for <number> reserve map entries (for dtb and asm output)
-S, --space <arg>
Make the blob at least <bytes> long (extra space)
-p, --pad <arg>
Add padding to the blob of <bytes> long (extra space)
-a, --align <arg>
Make the blob align to the <bytes> (extra space)
-b, --boot-cpu <arg>
Set the physical boot cpu
-f, --force
Try to produce output even if the input tree has errors
-i, --include <arg>
Add a path to search for include files
-s, --sort
Sort nodes and properties before outputting (useful for comparing trees)
-H, --phandle <arg>
Valid phandle formats are:
legacy - "linux,phandle" properties only
epapr - "phandle" properties only
both - Both "linux,phandle" and "phandle" properties
-W, --warning <arg>
Enable/disable warnings (prefix with "no-")
-E, --error <arg>
Enable/disable errors (prefix with "no-")
-@, --symbols
Enable generation of symbols
-A, --auto-alias
Enable auto-alias of labels
-h, --help
Print this help and exit
-v, --version
Print version and exit
deng@local:~/code/x3399$
dtc工具使用示例如下:
# 编译 dts 为 dtb
kernel/scripts/dtc/dtc -I dts -O dtb -o xxx.dtb xxx.dts
实际使用示例,此处为伪代码,仅供参考使用,了解即可:
kernel/scripts/dtc/dtc -I dts -O dtb -o x3399-linux.dtb x3399-linux.dts
内核使用dtc工具的命令大致如上所示,实际上设备树中有特别多的依赖关系,这种依赖关系通过Makefile文件去处理,所以通常情况下,设备树不仅仅只是通过一个dtc命令能够将编译下来的。
2.2在内核源码中编译设备树(推荐使用)
我们可以尝试着通过内核的建立脚本去编译设备树,我们所要用到的设备树文件都储存在/home/deng/code/x3399/kernel/arch/arm64/boot/dts/上面。
后面提及了编译内核时会手动去编译设备树,并且编译内核很历时,所以我们推荐使用如下命令只编译设备树。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig
make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
示例:
deng@local:~/code/x3399/kernel$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- i3399_defconfig
deng@local:~/code/x3399/kernel$ make ARCH=arm64 -j4 CROSS_COMPILE=aarch64-linux-gnu- dtbs
若果在内核源码中执行了makedistclean则必须执行第一条命令,它用于生成默认配置文件,倘若执行过一次就没有必要再度执行,其实再度执行也没有哪些问题。第二条命令开始编译设备树,参数“-j4”指定多少个线程编译,按照自己笔记本实际情况设置,越大编译越快,其实也可以不设置,设备树编译原本就很快。
编译成功后生成的设备树文件(.dtb)坐落源码目录下的内核源码/arch/arm64/boot/dts,开发板适配的设备树文件名为x3399-linux.dtb。
/home/deng/code/x3399/kernel/arch/arm64/boot/dts/rockchip
03.加载设备树3.1设备树加载方式
替换设备树有下边几种方式。
我们只介绍第二种,将编译好的新设备树文件,替换开发板对应目录下的旧设备树文件即可。
3.2检测设备树加载情况
我们在原先的设备树上添加了新的节点,led_test,在该节点下有一个设备为rgb_led_red,我们可以通过以下的形式加载并查看新的设备树是否生效了,新节点是否添加。
通过SCP或NFS将编译的设备树拷贝到开发板上。替换/usr/lib/linux-image-4.19.35-imx6/imx6ull-mmc-npi.dtb。
uboot在启动的时侯负责该目录的设备文件加载到显存,供内核解析使用。输入sudoreboot命令重启开发板即可。
设备树中的设备树节点在文件系统中有与之对应的文件,坐落“/proc/device-tree”目录。步入“/proc/device-tree”目录如下所示。
[root@rk3399:/]# ls /proc/device-tree/
'#address-cells' power-management@ff310000
'#size-cells' psci
__symbols__ pwm@ff420000
adc-keys pwm@ff420010
aliases pwm@ff420020
amba pwm@ff420030
backlight qos@ffa58000
chosen qos@ffa5c000
cif_isp@ff910000 qos@ffa60080
cif_isp@ff920000 qos@ffa60100
clock-controller@ff760000 qos@ffa60180
compatible qos@ffa70000
cpuinfo qos@ffa70080
cpus qos@ffa74000
ddr_timing qos@ffa76000
dfi@ff630000 qos@ffa90000
display-subsystem qos@ffa98000
dmc qos@ffaa0000
dp-sound qos@ffaa0080
dp@fec00000 qos@ffaa8000
dsi@ff960000 qos@ffaa8080
dsi@ff968000 qos@ffab0000
dummy-codec qos@ffab0080
dummy_cpll qos@ffab8000
dummy_vpll qos@ffac0000
dw-hdmi-audio qos@ffac0080
dwmmc@fe310000 qos@ffac8000
dwmmc@fe320000 qos@ffac8080
edp@ff970000 qos@ffad0000
efuse@ff690000 qos@ffad8080
energy-costs qos@ffae0000
es8323-sound ramoops
ethernet@fe300000 reserved-memory
external-camera-clock rga@ff680000
external-gmac-clock rkisp1@ff910000
fiq-debugger rkisp1@ff920000
gpio-keys rktimer@ff850000
gpu@ff9a0000 rkvdec@ff660000
hdmi-hdcp2@ff988000 rockchip-i2s-sound
hdmi-sound rockchip-suspend
hdmi@ff940000 rockchip-system-monitor
i2c@ff110000 saradc@ff100000
i2c@ff120000 sdhci@fe330000
i2c@ff130000 sdio-pwrseq
i2c@ff140000 serial-number
i2c@ff150000 serial@ff180000
i2c@ff160000 serial@ff190000
i2c@ff3c0000 serial@ff1a0000
i2c@ff3d0000 serial@ff1b0000
i2c@ff3e0000 serial@ff370000
i2s@ff880000 spdif-out
i2s@ff890000 spdif-sound
i2s@ff8a0000 spdif@ff870000
iep@ff670000 spi@ff1c0000
interrupt-controller@fee00000 spi@ff1d0000
interrupt-parent spi@ff1e0000
iommu@ff650800 spi@ff1f0000
iommu@ff660480 spi@ff200000
iommu@ff670800 spi@ff350000
iommu@ff8f3f00 syscon@ff320000
iommu@ff903f00 syscon@ff770000
iommu@ff914000 test-power
iommu@ff924000 thermal-zones
leds timer
memory tsadc@ff260000
mipi-dphy-tx1rx1@ff968000 usb0
model usb1
name usb@fe340000
nocp-cci-msch0@ffa86000 usb@fe380000
nocp-cci-msch1@ffa8e000 usb@fe3a0000
nocp-gpu-msch0@ffa86400 usb@fe3c0000
nocp-gpu-msch1@ffa8e400 usb@fe3e0000
nocp-hp-msch0@ffa86800 vcc-phy-regulator
nocp-hp-msch1@ffa8e800 vcc-sd
nocp-lp-msch0@ffa86c00 vcc3v3-sys
nocp-lp-msch1@ffa8ec00 vcc5v0-host-regulator
nocp-video-msch0@ffa87000 vcc5v0-sys
nocp-video-msch1@ffa8f000 vccadc-ref
nocp-vio0-msch0@ffa87400 vdd-log
nocp-vio0-msch1@ffa8f400 vop@ff8f0000
nocp-vio1-msch0@ffa87800 vop@ff900000
nocp-vio1-msch1@ffa8f800 voppwm@ff8f01a0
opp-table0 voppwm@ff9001a0
opp-table1 vpu_service@ff650000
opp-table2 watchdog@ff848000
opp-table3 wireless-bluetooth
pcie-phy wireless-wlan
pcie@f8000000 xgpio_beep
phy@ff7c0000 xgpio_fan
phy@ff800000 xgpio_hdmiin_spken
pinctrl xgpio_pwr4g
pmu-clock-controller@ff750000 xin24m
pmu_a53 xin32k
pmu_a72
[root@rk3399:/]#
接着步入xgpio_beep文件夹,可以发觉beep节点中定义的属性以及它的子节点,如下所示。
[root@rk3399:/sys/firmware/devicetree/base/xgpio_beep]# pwd
/proc/device-tree/xgpio_beep
[root@rk3399:/sys/firmware/devicetree/base/xgpio_beep]# ls
compatible gpio name pinctrl-0 pinctrl-names status
[root@rk3399:/sys/firmware/devicetree/base/xgpio_beep]#
在节点属性中多了一个name,我们在led节点中并没有定义name属性,保存节点名。
这儿的属性是一个文件,而子节点是一个文件夹,我们再度步入“xgpio_beep”文件夹。上面有compatiblenameregstatus四个属性文件。我们可以使用“cat”命令查看这种属性文件,如下所示。
[root@rk3399:/sys/firmware/devicetree/base/xgpio_beep]# cat name
xgpio_beep
至此,设备树加载成功。
04.设备树插件的编译和加载
Linux4.4之后引入了动态设备树(DynamicDeviceTree)。设备树插件被动态的加载到系统中,供被内核辨识。编译设备树插件的时侯无需重新编译整个设备树插件,只须要编译我们更改的部份即可。
注意设备树插件和设备树不是相互取代的关系,而是互补的关系。设备树插件可以在主设备树定型的情况下,再对主设备树未描述的功能进行动态的拓展。诸如A板的设备树没有开启并口1的功能,但B板须要开启并口1的功能,这么可以直接承袭A板的设备树,并用设备树插件拓展出并口1,满足B板的需求。
4.1在内核编译设备树插件
设备树插件与设备树一样都是使用DTC工具编译,只不过设备树编译为.dtb。而设备树插件须要编译为.dtbo。我们可以使用DTC编译命令编译生成.dtbolinux移植时需要编译设备树文件吗,然而这样比较冗长、容易出错。
我们将设备树插件dtbo的编译工作也放到了内核编译时来完成,其实我们单独编译设备树的时侯也是可以编译出设备树插件dtbo的。
我们在内核中提供了大量的设备树插件,有些开发板许多外设硬件描述都是以dtbo插件的方式提供的。这样使用上去十分灵活。
deng@local:~/code/x3399/kernel/arch/arm64/boot/dts/rockchip$ pwd
/home/deng/code/x3399/kernel/arch/arm64/boot/dts/rockchip
deng@local:~/code/x3399/kernel/arch/arm64/boot/dts/rockchip$ ls Makefile
Makefile
deng@local:~/code/x3399/kernel/arch/arm64/boot/dts/rockchip$
当你们尝试写设备树插件的时侯,可以将自己的设备树插件添加到:arch/arm/boot/dts/overlays目录下,并更改arch/arm/boot/dts/overlays/Makefile文件,添加编译选项linux移植时需要编译设备树文件吗deepin linux,形如imx-rgb-led.dtbo的添加方式。将imx-rgb-led.dtbo追加到imx-uart8.dtbo旁边即可。
添加好后,可以执行设备树的编译命令,设备树插件的编译也会同步完成。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig
make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
可以看见,编译输出时,dtbo文件也有对应的复印信息。
4.2内核编译设备树插件过程
编译设备树插件和编译设备树类似,这儿介绍内核中的dtc工具编译编译设备树插件的过程。
内核上将xxx.dts编译为xxx.dtbo的过程示例,仅供参考:
内核构建目录/scripts/dtc/dtc -I dts -O dtb -o xxx.dtbo xxx.dts
比如,将rgb-led-overlay.dts编译为rgb.dtbo
../ebf_linux_kernel/build_image/build/scripts/dtc/dtc -I dts -O dtb -o rgb.dtbo rgb-led-overlay.dts
编译好的设备树插件为rgb.dtbo。
其实和编译设备树一样,设备树插件的编译也涉及到依赖关系,所以编译过程也比较复杂。不仅仅是使用一条命令就可以完成编译的。
05.讨论06.附表