2

我有一个可以很好地编译并加载到 linux 内核中的驱动程序。在这个驱动程序中有一些我想从内核文件'fs/readdir.c'中访问的功能。此外,如何测试是否加载了驱动程序?

我需要类似下面的东西。

if(myDriver is loaded){
    myDriver.functionCall();
}

我在互联网搜索中找到的所有示例都是从用户空间应用程序中完成的。

4

3 回答 3

2

另一种可能性是EXPORT_SYMBOL(functionCall);在您的模块中使用,这将使您的函数出现在内核符号表中。然后,您可以使用它find_symbol("functionCall", blah, blah)来检查符号是否存在并动态查找其值/位置。

见 linux/kernel/module.c 和 module.h

于 2009-11-11T21:25:00.067 回答
1

fs/readdir.c如果functionCall符号不在内核中,则不会链接。你只能通过间接来做到这一点。ops在主内核代码中设置一些结构,将其初始化为虚拟函数,或者只是NULL告诉内核的其余部分您的驱动程序尚未加载。在驱动程序初始化例程中,将该结构中的函数指针设置为模块中的函数(在 de-init 中重置为默认值)。不过,该结构将需要某种形式的种族保护,因此您最终可能会拥有一个信号量作为其成员之一。这可以扩展到每个设备的结构等。

于 2009-11-07T20:49:48.390 回答
0

您可以functionCall在内核中添加一个函数指针,将其初始化为 NULL,然后等待模块将指针设置为非 NULL 值。readdir 中的代码将在取消引用之前检查指针是否为非 NULL。这要求模块通过使指针全局化或类似地易于从模块访问来了解内核中的函数指针。

如果您不希望驱动程序知道对内核的此修改,则可以修改 readdir 以查找要加载的驱动程序,然后使用find_symbol(如@chrisharris 所述)获取 的地址functionCall,并将返回的值分配给readdir 中某处的一些私有函数指针。

回答“驱动程序是否加载”问题的一种方法是使用register_module_notifier()

static int
my_load_notify(struct notifier_block *self, unsigned long val, void *data)
{
 struct module *m = data;
 if (0 == strcmp(m->name, "myDriver")) {
  // set function pointer(s)
 }
}
static struct notifier_block module_load_nb = {
 .notifier_call = my_load_notify,
};

static int
my_init(void)
{
 ...
 register_module_notifier(&module_load_nb);
 ...
}
于 2009-11-12T16:55:01.880 回答