搜索
首页系统教程LINUXLinux设备驱动之devicetree:一种描述和管理硬件设备的高效方法

Linux设备驱动之devicetree:一种描述和管理硬件设备的高效方法

Feb 10, 2024 pm 05:33 PM
linuxlinux教程linux系统linux命令外壳脚本内存占用嵌入式linuxlinux入门linux学习

你是否想过如何在Linux系统中为你的硬件设备编写驱动程序?你是否想过如何在Linux系统中让你的驱动程序适应不同的硬件平台和配置?你是否想过如何在Linux系统中让你的驱动程序实现一些高级的功能,比如热插拔、电源管理、设备共享等?如果你对这些问题感兴趣,那么本文将为你介绍一种实现这些目标的有效方法——Linux设备驱动之devicetree。devicetree是一种用于描述硬件设备的数据结构,它可以让你用一种简单而统一的方式,将硬件设备的信息和属性传递给内核,从而实现设备的识别和驱动。devicetree也是一种用于实现硬件无关性的机制,它可以让你用一种灵活而可移植的方式,将硬件设备的配置和管理从驱动程序代码中分离出来,从而实现多平台的支持。devicetree还是一种用于实现高级功能的框架,它可以让你用一种标准而通用的方式,定义和使用各种硬件设备的接口和协议,从而实现热插拔、电源管理、设备共享等功能。本文将从devicetree的基本概念、语法规则、编写方法、编译过程、加载方式等方面,为你详细地介绍devicetree在Linux设备驱动中的应用和作用,帮助你掌握这种有用而强大的方法。

Devicetree(设备树)是用来描述系统硬件信息的树模型,其旨在unify内核。通过bootloader将devicetree的信息传给kernel,然后kernel根据这些设备描述初始化相应的板级驱动,达到一个内核多个平台共享的目的。


Overview

Devicetree主要为描述不可插拔(非动态)设备的板级硬件信息而设计的。它由分层的描述设备信息的节点(node)组成树结构。每个node包含的内容通过property/value对来表示。除root节点外,每个节点都有parent。如图所示:
Linux设备驱动之devicetree:一种描述和管理硬件设备的高效方法

Node Names

除root节点名用’/’表示外,其余节点都由node-name@unit-address来命名,且同一层级必须是唯一的。

  • node-name

    表示节点名,由1-31个字符组成。如非必须,推荐使用以下通用的node-name: 
    cpu、memory、memory-controller、gpio、serial、watchdog、flash、compact-flash、
    
    rtc、interrupt-controller、dma-controller、ethernet、ethernet-phy、timer、
    
    mdio、spi、i2c、usb、can、keyboard、ide、disk、display、sound、atm、cache-
    
    controller、crypto、fdc、isa、mouse、nvram、parallel、pc-card、pci、pcie、sata、
    scsi、vme。
    
  • unit-address

    表示这个节点所在的bus类型。它必须和节点中reg属性的第一个地址一致。如果这个节点没有
    
    reg属性,则不需“@unit-address”。
    

Path Names

表示一个节点的完整路径(full path)。型如:

    /node-name-1/node-name-2/node-name-N

Properties

每个节点包含的主要内容就是这个所描述的设备的属性信息,由name和value组成:

  • Property Names

    1-31个字符,可包含字母、数字、及‘,’,‘.’,‘_’,‘+’,‘?’,‘#’。
    
  • Property Values

Value Description
empty 属性值为空,用来表示true-false信息
u32/u64 32/64位大端字节序的无符号整形,表示时需加
string,stringlist null-terminated字符串或其组成的列表

Standard Properties

  • compatible

    Value type: 
    Description:
        表示兼容的设备类型,内核据此选择合适的驱动程序。由多个字符串组成,从左到由列出
    
    这个设备兼容的驱动(from most specific to most general)。
        推荐的格式为:“制造商名,具体型号”。
    Example:
        compatible = "fsl,mpc8641-uart", "ns16550";
        内核先搜索支持“fsl,mpc8641-uart”的驱动,如未找到,则搜索支持更通用的“ns16550”
    
    
    设备类型的驱动。
    
  • model

    Value type: 
    Description:
        表明设备型号。
        推荐的格式为:“制造商名,具体型号”。
    Example:
        model = "fsl,MPC8349EMITX";
    
  • phandle

    Value type: 
    Description:
        用一个树内唯一的数字标识所在的这个节点,其他节点可以直接通过这个数字标识来引用
    
    这个节点。
    Example:
        pic@10000000 {
            phandle = ;
            interrupt-controller;
        };
        interrupt-parent = ;
    
  • status

    Value type: 
    Description:
        表示设备的可用状态:
        "okay" -> 设备可用
        "disabled" -> 目前不可用,但以后可能会可用
        "fail" -> 不可用。出现严重问题,得修一下
        "fail-sss" -> 不可用。出现严重问题,得修一下。sss指明错误类型。
    
  • #address-cells and #size-cells

    Value type: 
    Description:
        在拥有子节点的节点中使用,来描述它的字节点的地址分配问题。即分别表示子节点中使
    
    用多少个u32大小的cell来编码reg属性中的address域和size域。
    
        这两个属性不会继承,必须明确指出。如未指出,默认#address-cells=2,#size-
    cells=1。
    Example:
        soc {
            #address-cells = ;
            #size-cells = ;
            serial {
                reg = ;
            };
        };
    
  • reg

    Value type:  encoded as an arbitraty number of (address, length) pairs.
    Description:
        描述该设备在parent bus定义的地址空间中的地址资源分配。
    Example:
        reg = ;
        a 32-byte block at offset 0x3000 and a 256-byte block at offset 0xFE00。
    
  • virtual-reg

    Value type: 
    Description:
        表示映射到reg第一个物理地址对应的effective address。使bootloader能够提供给内
    
    核它所建立的virtual-to-physical mappings。
    
  • ranges

    Value type:  or  encoded as an arbitrary number of (child-bus-address,parent-bus-
    
    address, length) triplets.
    Description:
        提供了子地址空间与父地址空间的映射关系,如果值为空则父子地址相等,无需转换。
    Example:
        soc {
            compatible = "simple-bus";
            #address-cells = ;
            #size-cells = ;
            ranges = ;
    
            serial {
                compatible = "ns16550";
                reg = ;
            };
        };
        将子节点serial的0x0地址映射到父节点soc的0xe0000000,映射长度为0x100000。此时
    
    reg的实际物理地址就为0xe0004600。
    
  • dma-ranges

    Value type:  or  encoded as an arbitrary number of (child-bus-address,parent-bus-address, length) triplets.
    Description:
        提供了dma地址的映射方法。
    

Interrupts

描述中断的属性有4个:

  • interrupt-controller

    一个空的属性用来指示这个节点设备是接收中断信号的控制器。
    
  • #interrupt-cells

    这是上面所说中断控制器中的一个属性,用来描述需要用多少个cell来描述这个中断控制器的
    
    interrupt specifier(类似#address-cells和#size-cells)。
    
  • interrupt-parent

    常出现在根节点的一个属性,它的属性值是指向interrupt-controller的一个phandle。可从
    
    parent继承。
    
  • interrupts

    包含interrupt specifiers列表,每一个specifier表示一个中断输出信号。
    

Example

/ {
    interrupt-parent = ;

    intc: interrupt-controller@10140000 {        
              compatible = "arm,pl190";        
              reg = ;        
              interrupt-controller;        
                #interrupt-cells = ;    
    };
    serial@101f0000 {        
        interrupts = ;    
    };
};

Base Device Node Types

所有的设备树都必须有一个root节点,且root节点下必须包含一个cpus节点和至少一个memory节点。

  • root node

    root节点须包含 #address-cells、#size-cells、model、compatible等属性。
    
  • /cpus node

    是cpu子节点的父节点容器。须包含 #address-cells、#size-cells属性。
    
  • /cpus/cpu* node

    是描述系统cpu的节点。
    
  • /memory node

    描述系统物理内存的layout。须包含reg节点。
    Example:
    假如一个64位系统有如下两块物理内存:
    - RAM: starting address 0x0, length 0x80000000 (2GB)
    - RAM: starting address 0x100000000, length 0x100000000 (4GB)
    则我们可以有下面两种描述方法(#address-cells =  and #size-cells =):
    Example #1
        memory@0 {
            reg = ;
        };
    Example #2
        memory@0 {
            reg = ;
        };
        memory@100000000 {
            reg = ;
        };
    
  • /chosen node

    根节点下的一个子节点,不是描述设备而是描述运行时参数。常用来给内核传递bootargs:
    chosen {
        bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
    };
    
  • /aliases node

    由1-31个字母、数字或下划线组成的设备节点full path的别名。它的值是节点的全路径,因此最终会被编码成字符串。
    aliases {
        serial0 = "/simple-bus@fe000000/serial@llc500";
    }
    

Device Bindings

更多具体设备具体类别的描述信息:内核源代码/Documentation/devicetree/bindings。


DTS是描述devicetree的源文本文件,它通过内核中的DTC(Devicetree Compiler)编译后生成相应平台可烧写的二进制DTB。

Devicetree Blob (DTB) Structure

DTB又称Flattened Devicetree(FDT),在内存中的结构如下图所示:
Linux设备驱动之devicetree:一种描述和管理硬件设备的高效方法

Header

大端字节序结构体:

struct fdt_header {
    uint32_t magic; /* contain the value 0xd00dfeed (big-endian) */
    uint32_t totalsize; /* the total size of the devicetree data structure */
    uint32_t off_dt_struct; /* offset in bytes of the structure block */
    uint32_t off_dt_strings; /* offset in bytes of the strings block */
    uint32_t off_mem_rsvmap; /* offset in bytes of the memory reservation block */
    uint32_t version; /* the version of the devicetree data structure */
    uint32_t last_comp_version; /* the lowest version used is backwards compatible */
    uint32_t boot_cpuid_phys; /* the physical ID of the system’s boot CPU */
    uint32_t size_dt_strings; /* the length in bytes of the strings block */
    uint32_t size_dt_struct; /* the length in bytes of the structure block */
};

Memory Reservation Block

  • Purpose

    为系统保留一些特殊用途的memory。这些保留内存不会进入内存管理系统。
    
  • Format

    struct fdt_reserve_entry {
        uint64_t address;
        uint64_t size;
    };
    

Structure Block

Devicetree结构体存放的位置。由一行行“token+内容”片段线性组成。

  • token
    每一行内容都由一个32位的整形token起始。token指明了其后内容的属性及格式。共有以下5种token:
token Description
FDT_BEGIN_NODE (0x00000001) 节点起始,其后内容为节点名
FDT_END_NODE (0x00000002) 节点结束
FDT_PROP (0x00000003) 描述属性
FDT_NOP (0x00000004) nothing,devicetree解析器忽略它
FDT_END (0x00000009) block结束
  • tree structure
    • (optionally) any number of FDT_NOP tokens
    • FDT_BEGIN_NODE
      • The node’s name as a null-terminated string
      • [zeroed padding bytes to align to a 4-byte boundary]
    • For each property of the node:
      • (optionally) any number of FDT_NOP tokens
      • FDT_PROP token
        • property information
        • [zeroed padding bytes to align to a 4-byte boundary]
    • Representations of all child nodes in this format
    • (optionally) any number of FDT_NOP tokens
    • FDT_END_NODE token

Devicetree Source (DTS) Format

Node and property definitions

    [label:] node-name[@unit-address] {
        [properties definitions]
            [child nodes]
    };

File layout

Version 1 DTS files have the overall layout:

/dts-v1/; /* dts 版本1 */
[memory reservations] /* DTB中内存保留表的入口 */
    / {
        [property definitions]
        [child nodes]
    };

通过本文,我们了解了devicetree在Linux设备驱动中的应用和作用,学习了如何编写、编译、加载、修改和调试devicetree。我们发现,devicetree是一种非常适合嵌入式系统开发的方法,它可以让我们方便地描述和管理硬件设备,实现硬件无关性和高级功能。当然,devicetree也有一些注意事项和限制,比如需要遵循语法规范、需要注意兼容性问题、需要注意内存占用和性能影响等。因此,在使用devicetree时,我们需要有一定的硬件知识和经验,以及良好的编程习惯和调试技巧。希望本文能够为你提供一个入门级的指导,让你对devicetree有一个初步的认识和理解。如果你想深入学习devicetree,建议你参考更多的资料和示例,以及自己动手实践和探索。

以上是Linux设备驱动之devicetree:一种描述和管理硬件设备的高效方法的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:良许Linux教程网。如有侵权,请联系admin@php.cn删除
Linux操作是什么?Linux操作是什么?Apr 13, 2025 am 12:20 AM

Linux操作系统的核心是其命令行界面,通过命令行可以执行各种操作。1.文件和目录操作使用ls、cd、mkdir、rm等命令管理文件和目录。2.用户和权限管理通过useradd、passwd、chmod等命令确保系统安全和资源分配。3.进程管理使用ps、kill等命令监控和控制系统进程。4.网络操作包括ping、ifconfig、ssh等命令配置和管理网络连接。5.系统监控和维护通过top、df、du等命令了解系统运行状态和资源使用情况。

使用Linux别名提高自定义命令快捷方式的生产率使用Linux别名提高自定义命令快捷方式的生产率Apr 12, 2025 am 11:43 AM

介绍 Linux是一个强大的操作系统,由于其灵活性和效率,开发人员,系统管理员和电源用户都喜欢。但是,经常使用长而复杂的命令可能是乏味的

Linux实际上有什么好处?Linux实际上有什么好处?Apr 12, 2025 am 12:20 AM

Linux适用于服务器、开发环境和嵌入式系统。1.作为服务器操作系统,Linux稳定高效,常用于部署高并发应用。2.作为开发环境,Linux提供高效的命令行工具和包管理系统,提升开发效率。3.在嵌入式系统中,Linux轻量且可定制,适合资源有限的环境。

在Linux上掌握道德黑客的基本工具和框架在Linux上掌握道德黑客的基本工具和框架Apr 11, 2025 am 09:11 AM

简介:通过基于Linux的道德黑客攻击数字边界 在我们越来越相互联系的世界中,网络安全至关重要。 道德黑客入侵和渗透测试对于主动识别和减轻脆弱性至关重要

如何学习Linux基础知识?如何学习Linux基础知识?Apr 10, 2025 am 09:32 AM

Linux基础学习从零开始的方法包括:1.了解文件系统和命令行界面,2.掌握基本命令如ls、cd、mkdir,3.学习文件操作,如创建和编辑文件,4.探索高级用法如管道和grep命令,5.掌握调试技巧和性能优化,6.通过实践和探索不断提升技能。

Linux最有用的是什么?Linux最有用的是什么?Apr 09, 2025 am 12:02 AM

Linux在服务器、嵌入式系统和桌面环境中的应用广泛。1)在服务器领域,Linux因其稳定性和安全性成为托管网站、数据库和应用的理想选择。2)在嵌入式系统中,Linux因其高度定制性和高效性而受欢迎。3)在桌面环境中,Linux提供了多种桌面环境,满足不同用户需求。

Linux的缺点是什么?Linux的缺点是什么?Apr 08, 2025 am 12:01 AM

Linux的缺点包括用户体验、软件兼容性、硬件支持和学习曲线。1.用户体验不如Windows或macOS友好,依赖命令行界面。2.软件兼容性不如其他系统,缺乏许多商业软件的原生版本。3.硬件支持不如Windows全面,可能需要手动编译驱动程序。4.学习曲线较陡峭,掌握命令行操作需要时间和耐心。

Linux难以学习吗?Linux难以学习吗?Apr 07, 2025 am 12:01 AM

Linuxisnothardtolearn,butthedifficultydependsonyourbackgroundandgoals.ForthosewithOSexperience,especiallycommand-linefamiliarity,Linuxisaneasytransition.Beginnersmayfaceasteeperlearningcurvebutcanmanagewithproperresources.Linux'sopen-sourcenature,bas

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具