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