我在主板上使用嵌入式Linux,主要通过设备树机制(.dts
/ .dtc
文件配置),即设备树文件中的条目指示要注册的设备,从而要加载哪些驱动程序。
有没有办法手动加载动态模块的方式类似于设备树处理程序加载此驱动程序时会发生的情况?
澄清:在我的.dts
文件中没有设备XXX的条目,我可以在用户空间已经启动后“手动”注册此设备(例如通过动态加载包装内核模块)喜欢dts-unaware驱动程序可能吗?
使用简单的modprobe
/ insmod
并不是我认为有效的,因为这只会加载驱动程序,但不会注册设备及其参数(通常来自{{1} }文件)。
答案 0 :(得分: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);
然后,您将需要创建资源,至少一个用于内存映射范围。为此,创建并填充struct resource
数组。 struct resource
非常简单。以下是有关如何填充内存资源的示例:
struct resource res = {
.start = 0x50000000,
.end = 0x50001fff,
.name = "some_name",
.flags = IORESOURCE_MEM,
};
完成后,将其添加到您正在构建的平台设备中:
platform_device_add_resources(pdev, &res, 1);
确保res
不在堆栈中(将其设为全局,或者在卸载模块时kzalloc
和kfree
。)
您现在已准备好添加平台设备:
platform_device_add(pdev);
除了设备树之外,平台设备通过 name 通过“平台总线”(不是真正的实际物理总线)与平台驱动程序匹配。因此,您的平台驱动程序需要提供一个等效的名称(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);
瞧,瞧。如果添加了具有相同名称的平台设备,则应探测您的驱动程序。
使用设备树的驱动程序将另一个成员添加到.driver
,即.of_match_table
。在那里给出匹配表(字符串数组)。然后匹配使用设备树节点的compatible
属性。