设备树是一种描述硬件的数据结构,它起源于OpenFirmware(OF)
。在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx
和arch/arm/mach-xxx
中,采用设备树后,许多硬件的细节可以直接通过它传递给Linux,而不再需要在内核中进行大量的冗余编码。
设备树由一系列被命名的节点(Node
)和属性(Property
)组成,而节点本身可包含子节点。所谓属性,其实就是成对出现的名称和值。在设备树中,可描述的信息包括(原先这些信息大多被硬编码在内核中):
CPU的数量和类别。
内存基地址和大小。
总线和桥。
外设连接。
中断控制器和中断使用情况。
GPIO控制器和GPIO使用情况。
时钟控制器和时钟使用情况。
它基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader
会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device
、i2c_client
、spi_device
等设备,而这些设备用到的内存、IRQ
等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备。
DTS和DTSI
*.dts
文件是一种ASCII文本对Device Tree
的描述,放置在内核的/arch/arm/boot/dts
目录。一般而言,一个*.dts
文件对应一个ARM的machine。
*.dtsi
文件作用:由于一个SOC可能有多个不同的电路板,而每个电路板拥有一个 *.dts
。这些dts势必会存在许多共同部分,为了减少代码的冗余,设备树将这些共同部分提炼保存在*.dtsi
文件中,供不同的dts共同使用。*.dtsi
的使用方法,类似于C语言的头文件,在dts文件中需要进行include *.dtsi
文件。当然,dtsi
本身也支持include 另一个dtsi
文件。
DTC
DTC为编译工具,它可以将.dts文件编译成.dtb文件。DTC的源码位于内核的scripts/dtc目录,内核选中CONFIG_OF,编译内核的时候,主机可执行程序DTC就会被编译出来。 即scripts/dtc/Makefile中
hostprogs-y := dtc always := $(hostprogs-y)
在内核的arch/arm/boot/dts/Makefile
中,若选中某种SOC,则与其对应相关的所有dtb
文件都将编译出来。在linux下,make dtbs
可单独编译dtb
。
DTB
DTC编译*.dts
生成的二进制文件(*.dtb
),bootloader
在引导内核时,会预先读取*.dtb
到内存,进而由内核解析。
Bootloader
Bootloader需要将设备树在内存中的地址传给内核。在ARM中通过bootm
或bootz
命令来进行传递。
bootm [kernel_addr] [initrd_address] [dtb_address]
其中kernel_addr
为内核镜像的地址,initrd_address
为initrd的地址,dtb_address
为dtb所在的地址。若initrd_address
为空,则用“-”来代替。
/dts-v1/; //表示这个dts文件的版本 [memory reservations] // 格式为:/memreserve/ <address> <length>; /{ [property definitions] [child nodes] };
表示的是保存的内存区域:如果你的板子的内存有1G大小,想留一块区域留做它用(比如拿来用作共享内存区域空间)而不想全部都给内核使用的话,就可以使用该定义。如果你想让内核使用全部的内存的花,可以省略该选项。
发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)