DTS设备进入probe前的过程

本文详细介绍了在Linux内核中使用DeviceTree (DTS) 和.dts文件进行设备描述的方法,以及如何通过.of_match_table匹配设备节点的compatible属性来触发驱动的probe函数执行。此外还介绍了字符设备创建流程,包括class_create、alloc_chrdev_region和device_create等关键函数的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DTS及驱动probe

使用Device Tree后,驱动需要与.dts中描述的设备结点进行匹配,从而引发驱动的probe()函数执行。

对于I2C和SPI从设备而言,同样也可以透过of_match_table添加匹配的.dts中的相关结点的compatible属性

dtsi 及 dts

.dts文件是一种ASCII 文本格式的Device Tree描述,此文本格式非常人性化,适合人类的阅读习惯。基本上,在ARM Linux在,一个.dts文件对应一个ARM的machine,一般放置在内核的arch/arm/boot/dts/目录。

由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。

匹配步骤

进入probe:   module_init()-->of_match_table --> ".compatible" --> 进入probe()

添加设备: class_create()  --> alloc_chrdev_region()  --> device_create(class…majorno…)  --> cdev_init() -->cdev_add()

设备号动态申请函数为alloc_chrdev_region,相对应的释放函数为unregister_chrdev_region

/*下面两行是创建了一个总线类型,会在/sys/class下生成cdevdemo目录 
      这里的还有一个主要作用是执行device_create后会在/dev/下自动生成 
      cdevdemo设备节点。而如果不调用此函数,如果想通过设备节点访问设备 
      需要手动mknod来创建设备节点后再访问。*/  
    cdevdemo_class = class_create(THIS_MODULE, "cdevdemo");  
    device_create(cdevdemo_class, NULL, MKDEV(cdevdemo_major, 0), NULL, "cdevdemo");
/*初始化一个字符设备,设备所支持的操作在cdevdemo_fops中*/     
    cdev_init(&dev->cdev, &cdevdemo_fops);  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 3");     
    dev->cdev.owner = THIS_MODULE;  
    dev->cdev.ops = &cdevdemo_fops;  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 4");     
    err = cdev_add(&dev->cdev, devno, 1);  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 5");  


<think>好的,用户之问过设备树每一层是否都会解析成device,现在又问设备树的解析过程。我需要详细解释解析过程,但要注意和之的回答有所区分,不能重复太多内容。用户可能是嵌入式开发者或者内核新手,想深入理解设备树的工作机制。 首先,应该从设备树的基础结构开始,但之已经讲过树状结构,所以这里可以略过,直接进入解析步骤。要分阶段说明,比如启动阶段、展开、匹配驱动、设备创建等。需要强调关键点,比如compatible属性的作用,节点如何转化为设备,以及不同总线的作用。 用户可能想知道解析过程中的细节,比如OF组件的角色,节点与设备的绑定关系,以及实际例子帮助理解。还要注意特殊处理的情况,比如状态属性和动态设备。最后可以加入调试方法,方便用户自己验证。需要确保结构清晰,步骤明确,避免技术术语过于复杂,同时结合代码示例和实际路径,增强实用性。检查是否有遗漏的部分,比如设备树二进制转换、资源分配等,确保覆盖整个流程。</think>设备树(Device Tree)的解析是Linux内核启动过程中的关键环节,其核心目标是将硬件描述转换为内核可识别的设备结构。以下是**分步骤的解析过程详解**: --- ### 一、设备树数据流 1. **原始文件**:`.dts`(文本描述) → **编译** → `.dtb`(二进制) 2. **启动加载**:Bootloader(如U-Boot)将`.dtb`加载到内存,并传递地址给内核 --- ### 二、内核解析阶段 #### 阶段1:**扁平化展开(Flattening)** - 将树形结构转换为线性`device_node`链表 - **关键操作**:解析节点、属性、父子关系,生成`struct device_node` - **存储位置**:`/proc/device-tree`目录映射原始结构 #### 阶段2:**设备绑定(Binding)** - **核心机制**:通过`compatible`属性匹配驱动 ```dts // 设备树节点示例 uart0: serial@ff000000 { compatible = "ns16550a", "snps,dw-apb-uart"; // 驱动匹配优先级 reg = <0xff000000 0x100>; interrupts = <10>; }; ``` - **匹配规则**: - 按`compatible`列表顺序尝试匹配`of_device_id`表 - 匹配成功则调用驱动`probe`函数 #### 阶段3:**设备实例化** - 从`device_node`生成`struct platform_device`(或其他总线设备) ```c // 内核底层简化逻辑 for_each_child_of_node(root, child) { if (of_device_is_available(child)) { // 检查status属性 platform_device_register(child); // 创建设备 } } ``` - **资源分配**: - 自动解析`reg`属性 → 转换为`struct resource` - 解析`interrupts` → 映射为IRQ编号 --- ### 三、关键组件交互 | 组件 | 功能 | |---------------------|----------------------------------------------------------------------| | **OF(Open Firmware)核心** | 提供`of_*`系列API(如`of_get_property()`)解析节点 | | **平台总线(platform bus)** | 管理`platform_device`与`platform_driver`的匹配 | | **特定总线(I2C/SPI等)** | 总线控制器驱动解析子节点,生成对应总线设备(如`i2c_client`) | --- ### 四、特殊场景处理 1. **别名(aliases)解析** ```dts aliases { ethernet0 = &eth0; // 允许通过别名快速访问设备 }; ``` - 生成全局别名表,支持通过`of_alias_get_id()`获取设备ID 2. **覆盖机制(Overlay)** - 动态加载设备树片段(常用于热插拔设备配置) 3. **延迟初始化** - 某些设备依赖父设备先初始化(如GPIO控制器需在总线设备之后创建) --- ### 五、调试验证方法 1. **查看原始结构** ```bash dtc -I fs /proc/device-tree # 反编译内存中的设备树 ``` 2. **跟踪设备创建** ```bash ls /sys/devices/platform/ # 查看已生成的平台设备 dmesg | grep of_ # 观察OF解析日志 ``` --- ### 六、典型解析流程图解 ``` Bootloader加载dtb → 内核解压dtb → 构建device_node树 → 总线驱动扫描子节点 → 生成platform_device/i2c_client等 → 触发驱动probe ``` **关键结论**: 设备树节点**不会全部转换为设备**,只有满足以下条件的节点才会生成设备: 1. 包含有效`compatible`属性 2. 未被`status = "disabled"`标记 3. 父总线支持设备创建 4. 有对应驱动存在
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值