• Linux设备树详解


    设备树的由来

    传统的LINUX内核中,ARM架构的板级硬件细节过多地被硬件编码在arch/arm/plat-xxx和arch/arm-xxx,比如platform设备,resource,
    i2c_board,spi_aboard_info以及各种硬件的platform_data,这些板级细节代码对内核来讲不过是垃圾代码。
    而采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码,
    导致ARM的merge工作量较大。
    之后经过讨论。对ARM平台的相关代码做出如下相关的规范和调整,这个也是引入DTS的原因。
    1.ARM的核心代码仍然保存在arch/arm目录下
    2.ARM SoC core architecture code保存在arch/arm目录下
    3.ARM SoC的周边外设模块的驱动保存在drivers目录下
    4.ARM SoC的特定代码在arch/arm/mach-xxx目录下
    5.ARM SoC board specific的代码被移除,由Device Tree机制来负责硬件拓扑和硬件资源信息
    本质上,Device Tree改变了原来用code的方式将硬件信息嵌入到内核代码的方法,改用bootloader传递一个DB的形式。对于嵌入式系统,
    在系统启动阶段,bootloader会加载内核并将控制权限交给呢耦合,此外,还需要把上述的三个参数信息传递给kernel,以便有较大的灵活性,
    在linux kernel中,Device Tree的设计目标就是如此。
    在device tree中,可描述的信息包括:
    1.CPU的数量和类别
    2.内存基地址和大小
    3.总线和桥
    4.外设连接
    5.中断控制和中断的使用情况。
    6.GPIO控制器和clock使用情况
    7.clock控制器和clock使用情况
    它基本就是一棵电路板上的CPU,总线,设备组成的树,Bootloader会将这棵树传递给内核,然后内核来识别这棵树,
    这根据它展开出Linux内核中的	platform_device,i2c_client,spi_device等设备,而这些设备用到的内存,IRQ等资源,也被传递给内核,
    内核会将这些资源绑定给展开的相应设备。
    Linux内核从3.x开始引入设备树的概念,用于实现驱动代码和设备信息相分离。在设备树出现以前,所有关于设备的具体信息都要写在驱动里,
    一旦外围设备变化,驱动代码就要重写,引入了设备树之后,驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中,
    这样,如果硬件接口信息的变化而没有驱动逻辑的变化,驱动开发者只需要修改设备树文件信息,不需要改驱动代码,
    比如ARM Linux内,一个.dts(device tree source)文件对应一个ARM的machine,一般放置在内核的“arch/arm/booot/dts”目录内,
    比如stm1a-dk1参考板的板级设备文件就是“arch/arm/boot/dts/”目录内,
    比如stm1a-dk1参考板的板级设备树文件就是“arch/arm/boot/stm32mp157a-dk1.dts”。
    这个文件可以通过make ditbs命令编译成二进制的.dtb文件供内核驱动使用。
    基于同样的的软件分层设计的思想,由于一个SoC可能对应多个machine,如果每个machine的设备树都写成一个完全独立的.dts文件,
    那么势必相当一些.dts文件有重复的部分,为了解决这个问题,
    Linux设备树目录把SoC公用的部分或者多个machine共同部分提炼为了相应的.disi文件。这样每个.dts就只有自己差异的部分,
    公有的部分只需要“include”相应的.dtsi文件。这样整个设备树的管理更加有序.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    设备树基础知识

    dts
    硬件的相应信息都会写在.dts为后缀的文件中,每一款硬件可以单独写一份例如stm32mp157a-dk1.dts,一般在Linux源码中存在大量的dts文件,对于arm架构可以在arch/arm/boot/dts,找到相应的dts,一个dts文件对应一个ARM的machine
    dtsi
    对于一些相同的dts配置可以抽象到dtsi文件中,然后类似C语言的方式可以include到dts文件中,对于同一个节点的设置情况,dts中的配置会覆盖dtsi中的配置
    dtc
    dtc是编译dts的工具,可以在Ubuntu系统上通过指令apt-get insatll device-tree-complier安装dtc工具,不过在内核源码scripts/dtc路径下包含了dtc工具;
    dtb
    dtb(Device Tree Blob),dts经过dtc编译之后会得到dtb文件,dtb通过Bootloader引导程序加载到内核。所以Bootloader需要支持设备树才行;
    Kernel也需要加入设备树的支持;

    DTS结构

    /dts-v1/;
    / {
         
    node1 {
         a-string-property = "A string"; 
    a-string-list-property = "first string", "second string"; 
    // hex is implied in byte arrays. no '0x' prefix is required
    a-byte-data-property = [01 23 34 56];
    child-node1 {
        9 first-child-property;
    second-child-property = <1>;
    a-string-property = "Hello, world";
     };
     child-node2 {
       
     };
     };
    
    node2 {
       
     an-empty-property;
     a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
     child-node1 {
       
     };
     };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    device tree的基本单元是一个node。这些node被组织成树状结构,除了root node,每个node都只有一个parent。一个device tree文件中只能有一个root node。每个node中包含了若干的property/value来描述node的一些特性。每个node用节点名字(node name)标识,节点名字的格式node-name@unit-address。如果该node没有reg属性(后面会描述这个property),
    bus上相关。例如对cpu,其unit-address就是寄存器地址。root node的node name是确定的,必须是"/."。

    从上面的设备树可以看到
    1)一个根节点“/”;
    2)根节点下面有可以有多个子节点
    3)子节点可以包含自己的子节点如“child-node1”,“child-node2”
    4)各个几点都有一系列的属性 (property)
    (1)这些属性可能为空,如an-empty-property
    (2) 可能为字符 a-string-proerty
    (3) 可能为字符串树组 a-string-list-property
    (4) 可能为cells(由u32)整型组成,如second-child-property

    DTS语法介绍

    基本数据类型:
    1)text string(以null结束),以双引号括起来,如:string-property=“a string”;
    2)cells是无符号32位无符号整型数,以括号括起来,如cell-proerty=<0xbeef 123 0xabcd1234>;
    3)binary data 以方括号括起来,如:binary-property = [0x01 0x23 0x45 0x67];
    4)不同类型数据可以在同一个属性中存在,以逗号分格,如:mixed-property = “a string”, [0x01 0x23 0x45 0x67],<0x12345678>;
    5)多个字符串组成的列表也使用逗号分格,如:string-list = “red fish”,”blue fish”;

    DTS组成

    compatible

    / {
       
     model = "st FS-MP1A Discovery Board&
    • 1
    • 2
  • 相关阅读:
    解码2022中国网安强星丨注重攻防实战化验证,长亭以安全原子能力打造体系化安全
    css一个图片上面加上遮罩蒙板,只修改img的样式不多写标签
    java基于springboot+nodejs+vue网上投标招标系统ssm项目介绍
    笔记软件 Keep It mac v2.3.3中文版新增功能
    强化学习领域值得关注的国际顶级会议
    提供一个springboot使用h2数据库是无法使用脚本并报错的处理方案
    使用Java解决快手滑块验证码
    ELK企业级日志分析系统
    iMazing2023免费版苹果iPhone手机备份应用软件
    Idea 创建 Spring 项目(保姆级)
  • 原文地址:https://blog.csdn.net/hpx12345678/article/details/126423947