设备树和手动注册

pmf*_*pmf 6 linux embedded device-tree

我在主板上使用嵌入式Linux主要通过设备树机制(.dts/ .dtcfiles)配置,即设备树文件中的条目指示要注册的设备,以及要加载的驱动程序.

有没有办法手动加载动态模块的方式类似于设备树处理程序加载此驱动程序时会发生的情况?

为了澄清:在我的.dts文件中没有设备XXX的条目,我可以在用户空间已经启动之后"手动"注册该设备(例如通过动态加载包装器内核模块)(就像dts-unaware一样)驱动程序)?

使用简单modprobe/ insmod不是我认为有效的,因为这只会加载驱动程序,但不会注册设备及其参数(通常来自.dts文件).

eep*_*epp 11

动态修改加载的设备树不是我们通常做的事情,尽管它是可能的.

我知道你并不真正关心这个新设备的设备树.

我建议你创建一个新的模块来添加你的设备,一旦它被加载(在insmod它之后),insmod你的驱动程序模块.实际上,顺序并不重要.添加设备时,将检查所有驱动程序并检测匹配的驱动程序,并在添加驱动程序时检查所有设备.

要创建设备,首先要分配它:

struct platform_device *pdev;
int inst_id = 1; /* instance unique ID: base address would be a good choice */
pdev = platform_device_alloc("unique_name_here", inst_id);
Run Code Online (Sandbox Code Playgroud)

然后,您将需要创建资源,至少一个用于内存映射范围.为此,创建并填充一个数组struct resource.A struct resource非常简单.这是一个如何填充内存资源的示例:

struct resource res = {
    .start = 0x50000000,
    .end = 0x50001fff,
    .name = "some_name",
    .flags = IORESOURCE_MEM,
};
Run Code Online (Sandbox Code Playgroud)

完成后,将其添加到您正在构建的平台设备中:

platform_device_add_resources(pdev, &res, 1);
Run Code Online (Sandbox Code Playgroud)

确保res不在栈上,虽然(使全球性的,或者kzalloc它和kfree卸载模块时).

您现在已准备好添加平台设备:

platform_device_add(pdev);
Run Code Online (Sandbox Code Playgroud)

除了设备树,平台设备通过名称 "平台总线"(不是真正的实际物理总线)与平台驱动器匹配.因此,您的平台驱动程序需要提供一个等效的名称(以上unique_name_here).您的平台驱动程序将具有以下内容:

static struct platform_driver my_platform_driver = {
    .probe = my_probe,
    .remove = my_remove,
    .driver = {
        .name = "unique_name_here",
        .owner = THIS_MODULE,
    },
};

module_platform_driver(my_platform_driver);
Run Code Online (Sandbox Code Playgroud)

瞧.如果添加了具有相同名称的平台设备,则应探测您的驱动程序.

使用设备树的驱动程序添加另一个成员.driver,即.of_match_table.在那里给出匹配表(字符串数组).然后匹配使用compatible设备树节点的属性.

  • 谢谢你这个非常好的答案! (3认同)