当前位置: 首页 > 科技观察

IoTEmbeddedLinuxDeviceTree机制

时间:2023-03-15 01:26:56 科技观察

Part01●LinuxDeviceTree机制介绍●1.1概念设备树(devicetree)是一种描述硬件资源的数据结构,起源于OpenFirmware(OF:OpenSourceFirmware)。在Linuxkernelv2.6之前的版本中,ARM架构的板级硬件资源通过.c和.h“死死地”写在arch/arm/plat-xxx和arch/arm/mach-xxx目录下文件,在开发设备时,Linux内核中充满了无用的硬件信息,不利于阅读和维护。LinuxARM内核v3.x之后,正式引入了设备树机制,主要是为了减少这种无用的硬件板级信息被写入Linux内核污染内核。有了设备树,你就可以通过它把安装所需硬件的信息传递给Linux内核。1.2组成设备树主要包括dts(devicetreesource,源文件)、dtc(devicetreecompiler,编译工具)和dtb(devicetreeblob,二进制文件)。dts是设备树描述的源文件。在ARM架构下,一个dts对应一个device,一般位于arch/arm(64)/boot/dts目录下。这个文件一般都有一个.dtsi文件包含相应的名字,类似于c语言的头文件,主要是一些SOC宏定义的公共部分。dtc是一个设备树编译工具,类似于gcc等编译器,但与gcc不同的是,dtc不需要外部安装,由内核构建。.dts文件可以编译成.dtb文件。dtb是设备树二进制文件,可以被linux内核识别解析,也可以被bootloader解析。dtbo是overlay编译出来的二进制文件。dts、dtc、dtb的关系如下:Part02●设备树框架和dts文件语法格式●2.1设备树基本框架一个设备树文件的基本结构主要包括以下几个部分,其形式有点类似于一个xml文件。单根节点(root):/节点名称:图中的“node1”和“node2”子节点:“child-node1”和“child-node2”节点地址:node@xxx属性(property):是一组keys值对,包括属性名(propertyname)和属性值(propertyvalue)标签(label,optional)https://elinux.org/Device_Tree_Usage#Basic_Data_Format值得注意的是“/”是根节点,每个设备tree文件只有一个,当设备树中有多个根节点时,编译时会将这些根节点合并为一个。2.2dts文件的语法格式与C语言类似。dts也支持头文件。头文件扩展名为.dtsi,通常通过#includexxx引用。例如,以全志H616为例,基于Linuxv4.9的orangepi开发板的时钟节点(部分)如下:/dts-v1/;/memreserve/0x00000000480000000x0000000001000000;/{interrupt-parent=<0x1>;#address-cells=<0x2>;#size-cells=<0x2>;model="OrangePiZero2";compatible="allwinner,h616","arm,sun50iw9p1";clocks{compatible="allwinner,clk-init";device_type="clocks";#address-cells=<0x2>;#size-cells=<0x2>;ranges;reg=<0x00x30010000x00x10000x00x70100000x00x4000x00x70000000x0;;其中特别重要的compatible属性,可以指定名字的偏好,格式为“,”。设备树中表示设备的每个节点都必须具有兼容属性,这是操作系统用来确定要绑定到哪个设备驱动程序的关键特征。Part03●修改设备树和内核编译安装●编写模块驱动程序时,为了不影响内核结构,通常在外部目录。生成的.ko可以在系统启动后单独加载运行,不需要和内核一起编译,更新方便。流程一般是:写makefile,然后写驱动源码(可以找个优秀的架构修改,填写细节,比如兼容,读,写操作等),然后编译生成.ko文件,并进一步修改板子相关的Devicetree文件(.dts),在.dts文件中增加或删除相应的设备节点信息,最后编译出整个内核文件。内核编译完成后,使用如下命令卸载旧版本内核,安装新版本内核:aptpurge-ylinux-image-xxx.deb//卸载内核dpkg-ilinux-image(dtb)-xxx.deb//安装内核并重启板子后,使用uname-a命令查看内核信息,在新编译的内核上,使用insmod命令加载生成的.ko模块,使用cat命令查看设备节点信息。需要注意的是,使用设备树需要在编译内核时进行相应的配置,以及bootloader的支持,否则无法将数据结构传递给内核。