设备树和手动注册 [英] Device Tree and manual registration

查看:294
本文介绍了设备树和手动注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在嵌入式Linux上使用主板,主要通过设备树机制( .dts / .dtc 文件),即设备树文件中的条目指示要注册的设备,从而加载哪些驱动程序。



有没有办法手动加载动态模块这样的方式类似于这个驱动程序将被设备树处理程序加载会发生什么?



澄清:而不是在我的 .dts 文件,我可以手动注册此设备(例如通过在用户空间已经启动后动态加载包装内核模块)(就像dts-unaware一样)驱动程序)?



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

解决方案

Dynami我们通常会修改加载的设备树,尽管这是可能的。



我明白你不太在乎这个新设备的设备树。 / p>

我建议您创建一个新模块来添加您的设备,一旦加载(在$ code> insmod 之后)您的驱动程序模块 insmod 其实订单并不重要。当您添加设备时,将检查所有驱动程序,并检测匹配的驱动程序,并在添加驱动程序时检查所有设备。



创建设备,首先分配它:

  struct platform_device * pdev; 
int inst_id = 1; / * instance unique ID:基地址将是一个不错的选择* /
pdev = platform_device_alloc(unique_name_here,inst_id);

然后,您将需要创建资源,至少有一个用于内存映射范围。为此,创建并填充 struct资源的数组。一个 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); 

设备树放在一边,平台设备通过平台总线与平台驱动程序匹配(不是真实的实际物理总线)由名称。所以你的平台驱动程序需要提供一个等价的名称( 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);

和voilà。如果添加了具有相同名称的平台设备,则应检测您的驱动程序。



使用设备树的驱动程序将另一个成员添加到 .driver ,这是 .of_match_table 。那里给出一个匹配表(字符串数组)。然后,该匹配将使用设备树节点的兼容属性。


I'm using Embedded Linux on a board that is mainly configured via the device tree mechanism (.dts/.dtc files), i.e. entries in the device tree file indicate which devices to register and thereby which drivers to load.

Is there a way to manually load a dynamic module in a way that resembles what would happen when this driver would be loaded by the device tree handler?

To clarify: instead of having an entry for device XXX in my .dts file, can I "manually" register this device (for example by loading a wrapper kernel module dynamically) after the user space is already up (like it is possible with dts-unaware drivers)?

Using a simple modprobe/insmod is not what I think works, since this would just load the driver, but not register a device and its parameters (that usually come from the .dts file).

解决方案

Dynamically modifying the loaded device tree is not something we usually do, although it's possible.

I understand you don't really care about the device tree for this new device.

I suggest you create a new module to add your device and, once it's loaded (after insmoding it), insmod your driver module. In fact, the order doesn't matter. When you add a device, all drivers will be checked and the ones that match will be probed, and when you add a driver, all devices are checked against it.

To create the device, you first allocate it:

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);

Then, you will want to create resources, at least one for the memory mapped range. For this, create and fill an array of struct resource. A struct resource is pretty simple. Here's an example on how to fill a memory resource:

struct resource res = {
    .start = 0x50000000,
    .end = 0x50001fff,
    .name = "some_name",
    .flags = IORESOURCE_MEM,
};

Once you have that, add it to the platform device you're building:

platform_device_add_resources(pdev, &res, 1);

Make sure res is not on the stack, though (make it global, or kzalloc it and kfree when unloading the module).

You're now ready to add the platform device:

platform_device_add(pdev);

Device tree aside, platform devices are matched to platform drivers by the "platform bus" (not a real actual physical bus) by name. So your platform driver will need to provide an equivalent name (unique_name_here hereabove). Your platform driver will have something like:

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);

and voilà. Your driver should be probed if a platform device with the same name was added.

Drivers using the device tree add another member to .driver, which is .of_match_table. A match table (array of strings) is given there. The match is then using the compatible property of device tree nodes.

这篇关于设备树和手动注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆