在 - Linux 内核中定义平台设备

问题描述 投票:0回答:2

我参考以下内容将我的嵌入式 Arm Linux 板中使用的所有驱动程序描述为平台设备,需要澄清几点。请就这些提出建议。

http://thomas.enix.org/pub/conf/rmll2010/kernel-architecture-for-drivers.pdf

================ 定义平台驱动====================

static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.driver = {
.name = "imx-uart",
.owner = THIS_MODULE,
},
};

================== 定义平台设备==================

static struct platform_device imx_uart1_device = {
.name = "imx-uart",
.id = 0,
.num_resources = ARRAY_SIZE(imx_uart1_resources),
.resource = imx_uart1_resources,
.dev = {
.platform_data = &uart_pdata,
}
};

======== 内核启动代码位置 - /arch/arm/mach-imx/mx1ads.c ===========

static struct platform_device *devices[] __initdata = {
&cs89x0_device,
&imx_uart1_device,
&imx_uart2_device,
};



static void __init mx1ads_init(void)
{
[...]
platform_add_devices(devices, ARRAY_SIZE(devices));
[...]
}
MACHINE_START(MX1ADS, "Freescale MX1ADS")
[...]
.init_machine = mx1ads_init,
MACHINE_END

==================================

在 linux /drivers/ 文件夹中,如果我有 10 个文件夹用于 10 个不同的平台驱动程序。我只想将 6 个驱动程序包含在内核源代码中? 那么我的内核如何知道要包含哪个驱动程序?

平台驱动程序是编译为模块还是静态编译在内核中?

当我们调用

platform_add_devices()
系统调用时会发生什么?

在调用 platform_add_devices() 系统调用之前,内核中包含的所有平台驱动程序是否都已加载到 RAM 中?

在内核源代码中的哪个路径/文件中,我可以定义我的嵌入式Linux系统中使用的所有平台设备(意味着描述了板上使用的所有平台设备)?

linux linux-kernel embedded-linux
2个回答
4
投票

基本上平台驱动程序注册在板文件中(例如

/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
)。现代系统使用设备树方法。

为了编译驱动程序,必须首先选择它(例如通过

make menuconfig
)。因此,如果您选择 6 个驱动程序,则将编译 6 个驱动程序。

platform_add_devices()
注册平台驱动程序(将它们添加到列表中,请参阅
drivers/base/platform.c
),以便内核知道在引导阶段要初始化其中哪些驱动程序。

平台驱动程序是内核的一部分,因此一旦加载内核映像本身,它们就会位于 RAM 中。

请参阅这篇文章了解更多详情。


1
投票

平台设备(不是驱动程序,如上所述)在板文件中声明,如

/arch/arm/mach-*
并通过
platform_add_devices()
告知内核。 该板文件是静态编译并链接到内核的。

platform_add_devices()
不是系统调用。它是内核 API
platform_device_register() 
调用的一部分,用于注册设备,以便它们可以 稍后与司机绑定。

平台驱动程序通常与内核静态链接,当调用

platform_driver_register()
时,内核尝试通过匹配
platform_device
platform_driver
name
属性将驱动程序绑定到设备。

如果匹配,则注册驱动程序并调用驱动程序的

probe()
函数。

显然,在加载驱动程序之前必须先注册设备。

现在使用设备树文件代替板文件。 来自单独设备树 blob 文件的设备由内核注册,并通过

compatible
字符串属性与驱动程序匹配。 所以这个属性必须在
device_driver
结构中声明并且 设备树文件中的设备节点。

设备树文件中的设备树节点:

    xxx@101F0000 {
        compatible = "aaaa,bbbb";
    };

内核驱动程序中的定义:

static const struct of_device_id xxx_match[] = {
{
    .compatible = "aaaa,bbbb",


static struct platform_driver xxx_driver = {
.probe      = xxx_probe,
.remove     = xxx_remove,
.driver     = {
    .name   = "xxx_name",
    ....
    .of_match_table = xxx_match,

目标是,当您更改设备或其属性时,您必须重新编译设备树文件,而不是内核本身。

© www.soinside.com 2019 - 2024. All rights reserved.