Linux Driver Development Fifteen: Linux Kernel Device Matching Method

The following is extracted from the Positive Atom Document species.

1. Device matching methods before using the device tree

Before the device tree is used, uboot passes a value called machine id, or device ID, to the Linux kernel to tell it what device it is and see if the Linux kernel supports it. The Linux kernel supports many devices, and for each device (board), the Linux kernel uses MACHINE_START and MACHINE_END to define a machine_ The desc structure describes this device. For example, in the file arch/arm/mach-imx/machmx35_3ds.c has the following definitions:

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

The above code defines the device "Freescale MX35PDK", where MACHINE_START and MACHINE_END is defined in the file arch/arm/include/asm/mach/arch.h, as follows:

#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				\
};

According to MACHINE_START and MACHINE_ The macro definition of END, which expands the sample code as follows:

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,
}

As you can see from the sample code, a machine_is defined here Structural variable of type desc_u mach_desc_MX35_3DS, which is stored in the ".arch.info.init" section. Line 4 MACH_ TYPE_ MX35_ The 3DS is the machine id of the "Freescale MX35PDK" board. MACH_ TYPE_ MX35_ The 3DS is defined in the file include/generated/mach-types. In h, this file defines a number of machine IDs as follows:

Line 287 is MACH_ TYPE_ MX35_ The value of 3DS is 1645.

As mentioned earlier, uboot passes the machine ID parameter to the Linux kernel, which checks the machine id, which is actually a combination of the machine ID and these MACH_s in the sample code TYPE_ XXX macros are compared to see if they are equal. If they are equal, the Linux kernel supports the device. If they are not, the device cannot start the Linux kernel.

2. Matching methods for devices after using the device tree

When the Linux kernel introduces the device tree, MACHINE_is no longer used START instead of DT_MACHINE_START. DT_MACHINE_START is also defined in the file arch/arm/include/asm/mach/arch.h, defined as follows:

#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

As you can see, DT_MACHINE_START and MACHINE_START is basically the same, just. nr is set differently, in DT_MACHINE_START will be directly inside. nr is set to ~0. This means that after the introduction of the device tree, you will no longer check whether the Linux kernel supports a device based on the machine id.

Open the file arch/arm/mach-imx/mach-imx6ul.c, as shown below:

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_ There is one in the desc structure. dt_compat member variable, which holds the compatibility properties of the device, set in the sample code. dt_compat = imx6ul_dt_compat, imx6ul_ Dt_ The compat table contains two compatible values, "fsl,imx6ul" and "fsl,imx6ull".

As long as the compatible property value of the root node'/'of a device (board) and imx6ul_ Dt_ Any of the values in the compat table are equal, which means that the Linux kernel supports this device.

3. Linux matches machine_according to device tree compatible attribute Desc

Keywords: Linux

Added by Alicia on Thu, 16 Dec 2021 20:58:52 +0200