Reputation: 1139
I have a driver which compiles and loads into the linux kernel just fine. In this driver are some functions which I would like to access from the kernel file 'fs/readdir.c'. Additionally, how can I test if a driver is loaded?
I need something like the following.
if(myDriver is loaded){
myDriver.functionCall();
}
All examples I've found on internet searches are doing it from userspace applications.
Upvotes: 2
Views: 1912
Reputation: 3580
You could add a function pointer to functionCall
in the kernel, initialize it to NULL, and wait for the module to set the pointer to a non-NULL value. Code in readdir would check for the pointer being non-NULL before dereferencing it. This requires the module to know about the function pointer in the kernel by either making the pointer global or similarly easy to access from a module.
If you don't want the driver to know about this modification to the kernel, you could modify readdir to look for the driver to load, then use find_symbol
(as mentioned by @chrisharris) to get the address of functionCall
, and assign the returned value to some private function pointer somewhere in readdir.
One way to answer the "is the driver loaded" question would be to use 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);
...
}
Upvotes: 0
Reputation: 10129
The other possibility is to use EXPORT_SYMBOL(functionCall);
in your module which will make your function appear in the kernel symbol table. You can then use find_symbol("functionCall", blah, blah)
to check whether the symbol exists and to find its value/location dynamically.
See linux/kernel/module.c and module.h
Upvotes: 2
Reputation: 84239
fs/readdir.c
would not link if the functionCall
symbol is not in the kernel yet. You can only do this through indirection. Setup some ops
structure in the main kernel code, init it to dummy functions, or just NULL
s to tell the rest of the kernel that your driver is not loaded yet. In the driver initialization routine set the function pointers in that structure to functions in your module (reset to defaults in de-init). The structure will need some form of race protection though, so you would probably end up having a semaphore as one of its members. This can be expanded to structure per device, etc.
Upvotes: 1