Linux 驱动开发 十五:Linux内核设备匹配方法

以下内容从正点原子文档种摘取。

一、使用设备树之前设备匹配方法

在没有使用设备树以前,uboot 会向 Linux 内核传递一个叫做 machine id 的值,machine id 也就是设备 ID,告诉 Linux 内核自己是个什么设备,看看 Linux 内核是否支持。Linux 内核是 支持很多设备的,针对每一个设备(板子),Linux 内核都用 MACHINE_STARTMACHINE_END 来定义一个 machine_desc 结构体来描述这个设备。比如在文件 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” 这个设备,其中 MACHINE_STARTMACHINE_END 定义在文件arch/arm/include/asm/mach/arch.h 中,内容如下:

#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

根据 MACHINE_STARTMACHINE_END 的宏定义,将示例代码展开后如下所示:

static const struct machine_desc __mach_desc_MX35_3DS	\
__used	\
__attribute__((__section__(".arch.info.init"))) = {
	.nr = MACH_TYPE_MX35_3DS,
    .name = "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_desc 类型的结构体变量 __mach_desc_MX35_3DS , 这 个 变 量 存 储 在 “ .arch.info.init ” 段 中 。4 行的 MACH_TYPE_MX35_3DS 就 是 “ Freescale MX35PDK ” 这 个 板 子 的 machine idMACH_TYPE_MX35_3DS 定义在文件 include/generated/mach-types.h 中,此文件定义了大量的 machine id,内容如下所示:
在这里插入图片描述
287 行就是 MACH_TYPE_MX35_3DS 的值,为 1645

前面说了,uboot 会给 Linux 内核传递 machine id 这个参数Linux 内核会检查这个 machine id,其实就是将 machine id 与示例代码中的这些 MACH_TYPE_XXX 宏进行对比,看 看有没有相等的,如果相等的话就表示 Linux 内核支持这个设备,如果不支持的话那么这个设 备就没法启动 Linux 内核。

二、使用设备树以后的设备匹配方法

Linux 内核引入设备树以后就不再使用 MACHINE_START 了,而是换为了 DT_MACHINE_STARTDT_MACHINE_START 也定义在文件 arch/arm/include/asm/mach/arch.h 里面,定义如下:

#define DT_MACHINE_START(_name, _namestr)		\
static const struct machine_desc __mach_desc_##_name	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= ~0,				\
	.name		= _namestr,

#endif

可以看出,DT_MACHINE_STARTMACHINE_START 基本相同,只是 .nr 的设置不同,在 DT_MACHINE_START 里面直接将 .nr 设置为 ~0。说明引入设备树以后不会再根据 machine id 来检查 Linux 内核是否支持某个设备了。

打开文件 arch/arm/mach-imx/mach-imx6ul.c,有如下所示内容:

static const char *imx6ul_dt_compat[] __initconst = {
	"fsl,imx6ul",
	"fsl,imx6ull",
	NULL,
};

DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
	.map_io		= imx6ul_map_io,
	.init_irq	= imx6ul_init_irq,
	.init_machine	= imx6ul_init_machine,
	.init_late	= imx6ul_init_late,
	.dt_compat	= imx6ul_dt_compat,
MACHINE_END

machine_desc 结构体中有个 .dt_compat 成员变量,此成员变量保存着本设备兼容属性,示例代码中设置 .dt_compat = imx6ul_dt_compatimx6ul_dt_compat 表里面有 "fsl,imx6ul""fsl,imx6ull" 这两个兼容值

只要某个设备(板子)根节点 “/”compatible 属性值与 imx6ul_dt_compat 表中的任何一个值相等,那么就表示 Linux 内核支持此设备。

三、Linux根据设备树compatible属性匹配machine_desc

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值