1

I have a loadable module(driver) function that linux kernel source need to use.

The function has already opened by EXPORT_SYMBOL_GPL().

The linux kernel source is one of c file in linux-3.16.1/mm.

However, I add extern function in c file and recompile entire Linux kernel source.

The error message print undefined reference to fun.

I think the error is occured at link time.

It could not find the function reference from the driver.

How can I solve this problem?

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
wayne
  • 33
  • 6
  • 3
    I belive there's a pretty well-established API for drivers to use, you "can't" just add random functions willy-nilly but should stick to the proper driver family's interface. – unwind Feb 10 '16 at 13:48
  • 2
    You cannot do it the way you are trying to do it. One solution is to have your module set a function pointer variable in the kernel to point to a function in your module, and have the kernel call your function through the pointer. I don't really know what you are trying to achieve, but it seems really messy and dangerous. – Ian Abbott Feb 10 '16 at 13:59
  • 1
    If you're changing some memory management code to use your routine, then you would have to compile your module as part of the kernel every time. It doesn't really make much sense doing it. The modules are supposed to use the symbols exported from the core subsystems, not the other way around ... – dragosht Feb 10 '16 at 14:23
  • Possible duplicate of [How to invoke any kernel function?](http://stackoverflow.com/questions/34977233/how-to-invoke-any-kernel-function) – Jeyaram Feb 10 '16 at 15:48
  • @unwind,I hope there's a API to solve the problem.But I still can't find it now,thx! – wayne Feb 11 '16 at 08:50
  • @Ian,thanks for your advise.I will try that way. – wayne Feb 11 '16 at 08:53
  • @dragosht, yeh I think the worst way is to compile driver into part of linux kernel.But I don't know whether it's illegal or not? – wayne Feb 11 '16 at 09:02
  • @Jeyaram, thanks for your link. I have read it. But there is a little different with my problem. The point is that my source is part of linux kernel, not a module. – wayne Feb 11 '16 at 09:17

2 Answers2

2

I have a loadable module(driver) function that linux kernel source need to use.

Yes. This is possible. But Not in straight forward way you looking for. Most of the drivers works in the same way being as a loadable kernel module(LKM).

Consider a sample GPIO driver(CONFIG_ATH79).

In the following link, we can see the functions are assigned to a structure of function pointers.
http://lxr.free-electrons.com/source/drivers/gpio/gpio-ath79.c#L124

Structure is defined here
http://lxr.free-electrons.com/source/include/linux/gpio/driver.h#L90

Similar way, it can be done. Declare a structure in corresponding header file which should be included in LKM.

Fill that structure from LKM and use it on linux-3.16.1/mm/fileX.c

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • I'm appreciated for your completely explain. I will try it this way. Hope it works! – wayne Feb 11 '16 at 14:50
  • sorry, may I ask a stupid question. How can I use that variable defined in LKM. Shared memory ? – wayne Feb 16 '16 at 13:06
  • Simple.. Write a function in LKM which fills up variable's value and returns a structure. If you already implemented to call functions from LKM then this task is very easy. – Jeyaram Feb 17 '16 at 10:00
  • Yes, I had already done what you sad. Declare a struct variable in LKM and fills up function to the function pointer. But I don't know linux-3.16.1/mm/fileX.c how to use that struct variable declared in LKM. They don't compile together right? So the scope between them is defferent. – wayne Feb 17 '16 at 11:00
  • @wayne, try to imitate file_operations structure. http://lxr.free-electrons.com/source/include/linux/fs.h#L1600 This is part of kernel, but every char drivers(LKM) uses it to publish it's APIs. – Jeyaram Feb 17 '16 at 11:51
  • Thanks, I'm a junior in progrmming linux kernel. I will try it. – wayne Feb 17 '16 at 13:16
0

Problem in nutshell: consider this example

extern int test_module_function();

int teste_function() {
    return test_module_function();
}

When you compile this source - compiler doesn't need body of test_module_function(), declaration is enough. But when we are linking - we need definition of function. For more information please read this and this.

In your case you provided only declaration, because EXPORT_SYMBOL_GPL() just makes your function callable from modules ( provides extern declaration of function ). It doesn't copy body of function in kernel sources ( see this ). And body of function is in your module and that module ( I presume ) wasn't builtin into kernel. So linker can't find it.

Possible solution - make module builtin into kernel ( as mentioned by dragosht ).

Side note:
I agree with unwind and Ian Abbott - search for a better solution, kernel provides API. For example look at other modules.

Community
  • 1
  • 1
Roman Zaitsev
  • 1,328
  • 5
  • 20
  • 28
  • Yes, I think the worst way is to rewrite driver into part of linux kernel. But I don't know whether it's illegal or not. – wayne Feb 11 '16 at 09:24
  • @wayne I think ( can be wrong ), that for your own usage and experimentations on home PC - it's not illegal, but if we are talking about something, that will be distributed, than I'm not sure. You can consult a lawyer. – Roman Zaitsev Feb 11 '16 at 09:34
  • 1
    If it will be distributed, then legally, you need to offer the kernel source code under the terms of the GPLv2. Loadable kernel modules also technically fall under the GPL since they link to the kernel, but some people argue about that. – Ian Abbott Feb 11 '16 at 10:57