内核对设备树的处理

内核对设备树的处理

从源代码文件 dts 文件开始,设备树的处理过程为:
在这里插入图片描述

  1. dts 在 PC 机上被编译为 dtb 文件;
  2. u-boot 把 dtb 文件传给内核;
  3. 内核解析 dtb 文件,把每一个节点都转换为 device_node 结构体;
  4. 对于某些 device_node 结构体,会被转换为 platform_device 结构体。

dtb 中的每一个节点都被转换为 device_node 结构体

在这里插入图片描述

根节点被保存在全局变量 of_root 中,从 of_root 开始时可以访问到任意节点。

哪些设备树节点会被转换为 platform_device

  1. 根节点下含有 compatible 属性的子节点
  2. 含有特定 compatible 属性的子节点
    如果一个节点的 compatible 属性,它的值是这 4 者之一:“simple-bus”、“simple-mfd”、“isa”、“arm,amba-bus”,那么它的子节点(需含 compatible 属性)也可以转换为 platform_device;
  3. 总线 I2C、SPI 节点下的子节点:不转换为 platform_device
    某个总线下到子节点,应该交给对应的总线驱动程序来处理,它们不应该被转换为 platform_device。
    比如以下的节点中:
  • /mytest 会被转换为 platform_device,因为它兼容“simple-bus”;
    它的子节点/mytest/ mytest@0 也会被转换为 platform_device
  • /i2c 节点一般表示 ic2 控制器,它会被转换为 platform_device,在内核中对应的 platform_driver;
  • /i2c/at24c02 节点不会被转化为 platform_device,它被如何处理完全由父节点的 platform_driver 决定,一般是被创建为一共 i2c_client。
  • 类似的还有/spi 节点,它一般也是用来表示 spi 控制器,它会被转换为 platform_device,在内核中有对应的 platform_device;
  • /spi/ flash@0 节点不会被转换为 platform_device, 它被如何处理完全由父节点的 platform_driver 决定 , 一般是被创建为一个 spi_device。
{
	mytest {
		compatible = "mytest","simple-bus";
		mytest@0 {
			compatible = "mytest_0";
		};
	};

	i2c {
		compatile = "samsung,i2c";
		at24c02 {
			compatile = "at24c02";
		};
	};

	spi {
		compatile = "samsung,spi";
		flash@0 {
			compatible = "winbond,w25q32dw";
			spi max frequency = <25000000>;
			reg = <0>;
		};
	};
};

怎么转换为 platform_device

内核处理设备树的函数调用过程,这里不去分析;只需要得到下列结论:

  • platform_device 中含有 resource 数组,它来自 device_node 的 reg,interrupts 属性;
  • platform_device. dev. of_node 指向 device_node,可以通过它获得其他属性。

platform_device 如何与 platform_driver 配对

从设备树转换得来的 platform_device 会被注册会被注册进内核里,以后当我们每注册一个 platform_driver 时,它们就会两两确定能否配对,如果能配对成功就调用 platform_driver 的 probe 函数。

套路是一样的。我们需要将前面讲过的“匹配规则”再完善一下,先贴源码:
在这里插入图片描述

(1)最先比较:是否强制选择某个 driver
  • 比较:
    platform_device.driver_overrideplatform_driver.driver.name
    可以设置 platform_devicedriver_override,强制选择某个 platform_driver
(2)然后比较:设备树信息
  • 比较:
    platform_device.dev.of_nodeplatform_driver.driver.of_match_table
    由设备树节点转换得来的 platform_device 中,含有一个结构体:of_node。它的类型如下:
    在这里插入图片描述

如果一个 platform_driver 支持设备树,它的 platform_driver.driver.of_match_table 是一个数组,类型如下:
在这里插入图片描述

  1. 首先,如果 of_match_table 中含有 compatible 值,就跟 dev 的 compatible 属性比较,若一致则成功,否则返回失败;
  2. 其次,如果 of_match_table 中含有 type 的值,就跟 dev 的 device_type 属性比较,若一致则成功,否则返回失败;
  3. 最后,如果 of_match_table 中含有 name 的值,就跟 dev 的 name 属性比较,若一致则成功,否则返回失败。
    而设备树中不建议使用 device_type 和 name 属性,所以基本上只使用设备节点的 compatible 属性来寻找匹配的 platform_driver。
(3)接下来比较:platform_device_id

比较 platform_device. name 和 platform_driver.id_table[i].name,id_table 中可能有多项。

platform_driver.id_table 是“platform_device_id”指针,表示该 drv 支持若干个 device,它里面列出了各个 device 的 {.name,.driver_data} ,其中的“name”表示 drv 支持的设备的名字,driver_data 表示提供给该 device 的私有数据。

(4)最后比较
  • platform_device. name 和 platform_driver. driver. name
    可以用一张图概括这个配对过程:
    在这里插入图片描述

没有转换为 platform_device 的节点,如何使用?

任意驱动程序里,都可以直接访问设备树。
可以使用内核里操作设备树的常用函数中介绍的函数找到节点,读出里面的值。


  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值