我参考以下内容将我的嵌入式 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系统中使用的所有平台设备(意味着描述了板上使用的所有平台设备)?
平台设备(不是驱动程序,如上所述)在板文件中声明,如
/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,
目标是,当您更改设备或其属性时,您必须重新编译设备树文件,而不是内核本身。