我在主板上使用嵌入式
Linux,主要通过设备树机制(.dts / .dtc文件)进行配置,即设备树文件中的条目指示要注册的设备以及要加载的驱动程序.
有没有办法手动加载动态模块的方式类似于设备树处理程序加载此驱动程序时会发生的情况?
为了澄清:在我的.dts文件中没有设备XXX的条目,我可以在用户空间已经启动后“手动”注册该设备(例如通过动态加载包装器内核模块)(就像dts一样) – 银行司机)?
使用简单的modprobe / insmod并不是我认为有效的,因为这只会加载驱动程序,但不会注册设备及其参数(通常来自.dts文件).
解决方法
动态修改加载的设备树不是我们通常做的事情,尽管它是可能的.
我知道你并不真正关心这个新设备的设备树.
我建议你创建一个新的模块来添加你的设备,一旦它被加载(在修改它之后),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资源数组. struct资源非常简单.这是一个如何填充内存资源的示例:
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);
除了设备树,平台设备通过名称“平台总线”(不是真正的实际物理总线)与平台驱动器匹配.因此,您的平台驱动程序需要提供等效名称(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.在那里给出匹配表(字符串数组).然后匹配使用设备树节点的兼容属性.