0

I am developing several kernel modules for linux, below are my module structure:

inc\
    shman.h
shman\
    extern.c
    extern.h
    module.c
    module.h
    ...
server\
    module.c
    module.h

I declared extern functions in extern.h that will be used by server module, define and export them in extern.c through EXPORT_SYMBOL:

===extern.h===
long shman_open(char *name, int flags, int mode);
long shman_write(long fd, void *data, long size, long offset);
long shman_read(long fd, void *data, long size, long offset);
long block_write(long fd, void *data, long size, long offset);
void *block_read(long fd, long offset, long *len);
void *block_first(void *cursor);
void *block_next(void *blk);
void *block_data(void *blk);
typedef int (*Compare)(void *src, void *dst);
void *block_search(long fd, Compare cmpfunc, void *dst);

===extern.c===
/*
 * Function definition, ignored...
*/

/*
 * Export functions
*/
EXPORT_SYMBOL(shman_open);
EXPORT_SYMBOL(shman_write);
EXPORT_SYMBOL(shman_read);
EXPORT_SYMBOL(block_write);
EXPORT_SYMBOL(block_read);
EXPORT_SYMBOL(block_first);
EXPORT_SYMBOL(block_next);
EXPORT_SYMBOL(block_data);
EXPORT_SYMBOL(block_search);
EXPORT_SYMBOL(cursor_free);

I also declared extern function in shman.h as below, which will be included by server module:

extern long shman_open(char *name, int flags, int mode);
extern long shman_write(long fd, void *data, long size, long offset);
extern long shman_read(long fd, void *data, long size, long offset);
extern long block_write(long fd, void *data, long size, long offset);
extern void *block_read(long fd, long offset, long *len);
extern void *block_first(void *cursor);
extern void *block_next(void *blk);
extern void *block_data(void *blk);
typedef int (*Compare)(void *src, void *dst);
extern void *block_search(long fd, Compare cmpfunc, void *dst);
extern void cursor_free(void *data);

I include "shman.h" in server\module.c, and use those extern functions in kernel module server.

It works fine in WSL(Ubuntu 20.04, kernel version is 4.19.128-microsoft-standard), but when I compile on normal Ubuntu distribution(20.04, kernel version is 5.4.100-generic), I got following compile error:

ERROR: "block_search" [/root/l4a/build/kernel/server/l4aserver.ko] undefined!
ERROR: "shman_open" [/root/l4a/build/kernel/server/l4aserver.ko] undefined!
ERROR: "block_first" [/root/l4a/build/kernel/server/l4aserver.ko] undefined!
ERROR: "block_data" [/root/l4a/build/kernel/server/l4aserver.ko] undefined!
ERROR: "cursor_free" [/root/l4a/build/kernel/server/l4aserver.ko] undefined!
make[4]: *** [scripts/Makefile.modpost:94: __modpost] Error 1
make[3]: *** [Makefile:1675: modules] Error 2
make[2]: *** [kernel/server/CMakeFiles/l4aserver.dir/build.make:65: kernel/server/l4aserver.ko] Error 2
make[1]: *** [CMakeFiles/Makefile2:348: kernel/server/CMakeFiles/l4aserver.dir/all] Error 2
make: *** [Makefile:95: all] Error 2

Kbuild for shman module:

obj-m := shman.o
shman-objs :=  extern.o factory.o handler.o module.o test.o file.o nl_handler.o nl_net.o
EXTRA_CFLAGS=-I/root/l4a/src/kernel/common/../inc -I/root/l4a/src/kernel/netlink -I/root/l4a/src/kernel/shman

Kbuild for server module:

obj-m := l4aserver.o
l4aserver-objs := server.o server.o file.o crypto.o hash.o machine.o
EXTRA_CFLAGS=-I/root/l4a/src/kernel/common/../inc
Jarvis Bao
  • 21
  • 4
  • `l4aserver-objs` is missing `extern.o`, no? – Andrejs Cainikovs Apr 11 '22 at 09:40
  • should I add extern.o into l4aserver-objs list? – Jarvis Bao Apr 11 '22 at 09:42
  • Yes, and come back with the results. If build succeeds, I'll move the comment into the answer. – Andrejs Cainikovs Apr 11 '22 at 11:01
  • The build succeeds, but it will raise runtime error, when I insmod server module: `exports duplicate symbol block_data (owned by shman)` – Jarvis Bao Apr 11 '22 at 11:26
  • Original solution works fine in kernel version `4.19.128-microsoft-standard`, so I think it's related with kernel version issue. – Jarvis Bao Apr 11 '22 at 11:27
  • I moved EXPORT_SYMBOL statements to module.c in shman module, both build and insmod works normal, but the kernel module does not work as expected, because the extern functions declared in server will have different namespace againest the one in shman. – Jarvis Bao Apr 11 '22 at 11:38
  • Does this answer your question? [How to call exported kernel module functions from another module?](https://stackoverflow.com/questions/12311867/how-to-call-exported-kernel-module-functions-from-another-module) – Tsyvarev Apr 11 '22 at 13:06
  • Also, just to be clear: are you building in WSL *and* loading the module there, and building in normal Ubuntu installation *and* loading the module there? I.e., no cross-machine topics involved? – Andrejs Cainikovs Apr 11 '22 at 17:58

1 Answers1

0

Alternatively resolved as below: copy Module.symvers under shman build directory to server build directory.

Jarvis Bao
  • 21
  • 4