根节点下的compatible属性

前言:
参考自正点原子
正文:

/ {
    model = "Freescale i.MX6 ULL 14x14 EVK Board";
	compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
	……
}

设备下的compatible属性,是用来找驱动文件的。
跟节点下的compatible属性,用于内核查找,本内核是不是支持这个平台/设备。

1、使用设备树之前,设备匹配的方法

在没有使用设备树之前,uboot会向内核传递一个machine id的值,也就是设备id。告诉linux内核,自己是做什么设备,看linux内核是否支持。linux内核针对他支持的每一个设备,都会用MACHINE_START和MACHINE_END来定义一个 machine_desc 结构体来描述这个设备。eg: arch/arm/mach-imx/machmx35_3ds.c文件

MACHINE_START(MX35_3DS, "Freescale MX35PDK")
    /* Maintainer: Freescale Semiconductor, Inc */
    .atag_offset = 0x100,
    .map_io = mx35_map_io,
    .init_early = imx35_init_early,
    .init_irq = mx35_init_irq,
    .init_time  = mx35pdk_timer_init,
    .init_machine = mx35_3ds_init,
    .reserve = mx35_3ds_reserve,
    .restart    = mxc_restart,
MACHINE_END

Freescale MX35PDK就是这个板子的机器id,Freescale MX35PDK定义在了include/generated/mach-types.h中,此文件定义了大量的machine id。eg:
在这里插入图片描述
前面说了, uboot 会给 Linux 内核传递 machine id 这个参数, Linux 内核会检查这个 machine id,其实就是将 machine id 与示例代码 43.3.4.3 中的这些 MACH_TYPE_XXX 宏进行对比,看看有没有相等的,如果相等的话就表示 Linux 内核支持这个设备,如果不支持的话那么这个设备就没法启动 Linux 内核。

2、使用个设备树以后,设备的匹配方法

引入设备树以后,我们不在使用machine id,而是使根节点下面的compatible属性值。
对于每一个linux内核支持的设备,也同样会有一个MACHINE_START和MACHINE_END来定义一个 machine_desc 结构体。(相当于machine_desc结构体兼容支持设备树和不支持设备树两个版本的linux)只不过,这个结构体不再说由MACHINE_START和MACHINE_END来定义,而是由DT_MACHINE_START和MACHINE_END来定义。DT_MACHINE_START和MACHINE_START差不多,只是有一项的是.nr = ~0,,表示不使用机器id。
(这是正点原子开发版的machine_desc 结构体):
在这里插入图片描述
在结构体machine_desc里面,有一个成员变量是.dt_compat = imx6ul_dt_compat,,他的内容是(兼容属性列表):
在这里插入图片描述
“fsl,imx6ul"和"fsl,imx6ull”,就是本设备/开发板的兼容属性。如果内核(设备树)中,跟根节点下面的compatible属性值和imx6ul_dt_compat 表中的任何一个值相等,那么就表示 Linux 内核支持此设备。
如果我们将设备树根节点下的compatible属性值进行修改,我们就会发现,这个内核无法支持我们的alifiph开发板,内核无法启动!!!
在这里插入图片描述
接下来我们简单看一下 Linux 内核是如何根据设备树根节点的 compatible 属性来匹配出对应的 machine_desc:
1)、Linux 内核调用 start_kernel 函数来启动内核, start_kernel 函数会调用setup_arch 函数
2)、setup_arch 函数会调用setup_machine_fdt 函数来获取匹配的 machine_desc,参数就是就是 uboot 传递给 Linux 内核的 dtb 文件首地址(0x83000000), setup_machine_fdt 函数的返回值就是找到的最匹配的 machine_desc。
3)、setup_machine_fdt 函数调用函数 of_flat_dt_match_machine 来获取匹配的 machine_desc。
参数1: mdesc_best是 默 认 的 machine_desc;
参 数2: arch_get_next_mach 是 个 函 数 ,此函数的工作就是获取 Linux 内核中下一个 machine_desc 结构体,返回其中的dt_compat成员,每调用一次arch_get_next_mach()函数,返回下一个machine_desc的dt_compat成员。

找到匹配的 machine_desc 的过程就是用设备树根节点的compatible 属性值和 Linux 内核中保存的所以 machine_desc 结构的. dt_compat 中的值比较,看看那个相等,如果相等的话就表示找到匹配的 machine_desc。
查找匹配设备的过程:
在这里插入图片描述
橙框部分讲解:
1)、通过函数 of_get_flat_dt_root 获取设备树根节点。
2)、循环将根节点 compatible 属性的值和每个 machine_desc 结构体中. dt_compat 的值进行比较,直至找到匹配的那个 machine_desc。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One Piece&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值