linux内核设备树及编译

1、设备树的概念在内核源码中,存在大量对板级细节信息描述的代码 。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录,对内核而言这些platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data绝大多数纯属垃圾冗余代码 。为了解决这一问题,ARM内核版本3.x之后引入了原先在Power PC等其他体系架构已经使用的Flattened Device Tree 。
开源文档中对设备树的描述是,一种描述硬件资源的数据结构,它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立 。
Device Tree可以描述的信息包括CPU的数量和类别、内存基地址和大小、总线和桥、外设连接、中断控制器和中断使用情况、GPIO控制器和GPIO使用情况、Clock控制器和Clock使用情况 。
另外,设备树对于可热插拔的设备不进行具体描述,它只描述用于控制该热插拔设备的控制器 。
设备树的主要优势:对于同一SOC的不同主板,只需更换设备树文件.dtb即可实现不同主板的无差异支持,而无需更换内核文件 。
(注:要使得3.x之后的内核支持使用设备树,除了内核编译时需要打开相对应的选项外,bootloader也需要支持将设备树的数据结构传给内核 。)
2、设备树的组成和使用设备树包含DTC(device tree compiler),DTS(device tree source和DTB(device tree blob) 。其对应关系如下图所示:

linux内核设备树及编译

文章插图
 
2.1 DTS和DTSI(源文件)
.dts文件是一种ASCII文本对Device Tree的描述,放置在内核的/arch/arm/boot/dts目录 。一般而言,一个.dts文件对应一个ARM的machine 。
由于一个SOC可能有多个不同的电路板( .dts文件为板级定义,.dtsi文件为SoC级定义),而每个电路板拥有一个 .dts 。这些dts势必会存在许多共同部分,为了减少代码的冗余,设备树将这些共同部分提炼保存在.dtsi文件中,供不同的dts共同使用 。.dtsi的使用方法,类似于C语言的头文件,在dts文件中需要进行include .dtsi文件 。当然,dtsi本身也支持include 另一个dtsi文件 。
2.2 DTC (编译工具)
DTC为编译工具,dtc编译器可以把dts文件编译成为dtb,也可把dtb编译成为dts文件 。在3.x内核版本中,DTC的源码位于内核的scripts/dtc目录,内核选中CONFIG_OF,编译内核的时候,主机可执行程序DTC就会被编译出来 。即scripts/dtc/Makefile中
hostprogs-y := dtcalways := $(hostprogs-y) 在内核的
arch/arm/boot/dts/Makefile中,若选中某种SOC,则与其对应相关的所有dtb文件都将编译出来 。在linux下,make dtbs可单独编译dtb 。以下截取了TEGRA平台的一部分 。
ifeq ($(CONFIG_OF),y)dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb tegra30-beaver.dtb tegra114-dalmore.dtb tegra124-ardbeg.dtb 在2.6.x版本内核中,只在powerpc架构下使用了设备树,DTC的源码位于内核的arch/powerpc/boot/dtc-src目录,编译内核后,可将DTC编译出来,DTC编译工具位于arch/powerpc/boot目录下 。
2.3 DTB (二进制文件)
DTC编译.dts生成的二进制文件(.dtb),bootloader在引导内核时,会预先读取.dtb到内存,进而由内核解析 。
在2.6.x版本内核中,在powerpc架构下,dtb文件可以单独进行编译,编译命令格式如下:
dtc [-I input-format] [-O output-format][-o output-filename] [-V output_version] input_filename参数说明
input-format:- “dtb”: “blob” format- “dts”: “source” format.- “fs” format.output-format:- “dtb”: “blob” format- “dts”: “source” format- “asm”: assembly language fileoutput_version:定义”blob”的版本,在dtb文件的字段中有表示,支持1 2 3和16,默认是3,在16版本上有许多特性改变
(1) Dts编译生成dtb
./dtc -I dts -O dtb -o B_dtb.dtb A_dts.dts把A_dts.dts编译生成B_dtb.dtb
(2) Dtb编译生成dts
./dtc -I dtb -O dts -o A_dts.dts A_dtb.dtb把A_dtb.dtb反编译生成为A_dts.dts
在linux 3.x内核中,可以使用make的方式进行编译 。
2.4 Bootloader(boottloader支持)
Bootloader需要将设备树在内存中的地址传给内核 。在ARM中通过bootm或bootz命令来进行传递 。
bootm [kernel_addr] [initrd_address] [dtb_address],其中kernel_addr为内核镜像的地址,initrd为initrd的地址,dtb_address为dtb所在的地址 。若initrd_address为空,则用“-”来代替 。
(小编自己整理了一些个人觉得比较好的学习书籍、视频资料有需要的可以私信回复【内核】自行免费领取哦!!)


推荐阅读