Linux 内核模块链接器警告:“*** 警告:” [<模块>] 未定义!” - 有什么方法可以摆脱它们吗?

发布于 2024-07-14 22:04:45 字数 424 浏览 7 评论 0原文

在编译相互依赖的 Linux 内核模块时,链接器会给出未定义的符号警告,例如

 Building modules, stage 2.
 MODPOST
*** Warning: "function_name1" [module_name] undefined!
*** Warning: "function_name2" [module_name] undefined!
*** Warning: "function_name3" [module_name] undefined!

使用 insmod 或 modprobe 将模块插入内核后,未解析的符号将立即解析。 有什么办法可以消除链接器警告吗?

我已经阅读了 3 个关于这个问题的 Google SERP - 似乎没有人知道答案。 当您构建内核模块时,这些链接器警告应该是这样的吗?

While compiling Linux kernel modules that depend on each other, linker gives undefined symbol warnings like

 Building modules, stage 2.
 MODPOST
*** Warning: "function_name1" [module_name] undefined!
*** Warning: "function_name2" [module_name] undefined!
*** Warning: "function_name3" [module_name] undefined!

The unresolved symbols are resolved as soon as module is inserted into kernel using insmod or modprobe. Is there any way to get rid of the linker warning, though?

I have read through 3 Google SERP's on this issue - it seems nobody knows the answer. Are these linker warnings supposed to be this way when you build a kernel module?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

傲鸠 2024-07-21 22:04:45

使用 KBUILD_EXTRA_SYMBOLS 如下:
KBUILD_EXTRA_SYMBOLS='你的模块路径'/Module.symvers

Use KBUILD_EXTRA_SYMBOLS as below:
KBUILD_EXTRA_SYMBOLS='your module path'/Module.symvers

极致的悲 2024-07-21 22:04:45

最后我得到了它。 感谢 Shodanex 让我走上了正确的道路。

更新:将此修复应用于旧版本内核的构建时要非常小心,因为旧版本的 Makefile.modpost 文件中存在错误当您指定 KBUILD_EXTMOD 选项时,内核版本会导致您的构建行为不当并构建错误的目标。

您必须在 KBUILD_EXTMOD make 参数中指定您所依赖的模块的源路径。

假设您有一个模块 foo,它依赖于模块 bar 中的符号。

foo 的源文件位于 foo/module/ 中,bar 的源文件位于 bar/module/

Makefile 中的 make 命令 for foo 可能看起来像

make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE -C $LINUX_DIR \
    M=`pwd`/module \
    modules

(确切的行可能在您的项目中有所不同)。

将其更改为

make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE -C $LINUX_DIR \
    M=`pwd`/module \
    KBUILD_EXTMOD=`pwd`/../bar/module \
    modules

(我们添加了 KBUILD_EXTMOD=pwd/../bar/module \ 行,其中 pwd/../bar/module 是内核源代码的路径我们所依赖的模块。

人们期望 KBUILD_EXTRA_SYMBOLS 参数以这种方式工作,但它是 KBUILD_EXTMOD

Finally, I got it. Thanks to shodanex for putting me on the right track.

Update: Be very careful when applying this fix to builds for older versions of kernel, as there is a bug in Makefile.modpost file in older versions of the kernel which makes your build misbehave and build wrong targets when you specify KBUILD_EXTMOD option.

You have to specify the paths to the source of the modules you depend on in KBUILD_EXTMOD make parameter.

Say, you have a module foo that depends on symbols from module bar.

Source files for foo are in foo/module/ and source files for bar are in bar/module/

The make command in Makefile for foo probably looks like

make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE -C $LINUX_DIR \
    M=`pwd`/module \
    modules

(the exact line may differ in your project).

Change it to

make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE -C $LINUX_DIR \
    M=`pwd`/module \
    KBUILD_EXTMOD=`pwd`/../bar/module \
    modules

(we added the KBUILD_EXTMOD=pwd/../bar/module \ line, where pwd/../bar/module is a path to sources of kernel module we depend on.

One would expect KBUILD_EXTRA_SYMBOLS parameter to work this way, however it's KBUILD_EXTMOD.

つ低調成傷 2024-07-21 22:04:45

不,他们不是。 无论您在树内还是树外构建代码,都不应显示此消息。我认为您应该修复您的 Makefile。 这是一个 makefile 示例。 不完美,但曾经可以工作(直到 2.6.26,此后就没有尝试过):

ifneq ($(KERNELRELEASE),)
# We were called by kbuild

obj-m += mymodule.o 
mymodule-objs := mymodule_usb.o a.o b.o c.o

else  # We were called from command line

KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

default:
    @echo '    Building FOO drivers for 2.6 kernel.'
    @echo '    PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

install:
    ./do_install.sh *.ko

endif  # End kbuild check

clean:
    rm -f -r *.o *.ko .*cmd .tmp* core *.i

有关进一步的文档,您可以检查内核树,kbuild 过程是 记录

No they are not. Wheter you build your code in-tree or out of tree, this message should not be displayed.I think you should fix your Makefile. Here is an example makefile. Not perfect, but used to work (until 2.6.26, did not try it since) :

ifneq ($(KERNELRELEASE),)
# We were called by kbuild

obj-m += mymodule.o 
mymodule-objs := mymodule_usb.o a.o b.o c.o

else  # We were called from command line

KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

default:
    @echo '    Building FOO drivers for 2.6 kernel.'
    @echo '    PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

install:
    ./do_install.sh *.ko

endif  # End kbuild check

clean:
    rm -f -r *.o *.ko .*cmd .tmp* core *.i

For further documentation, you can check the kernel tree, the kbuild process is documented

毁梦 2024-07-21 22:04:45

与上述使用 KBUILD_EXTMOD 的技术相关,以及它在哪个内核版本下工作的问题:

  • andycjw 表明它在 2.6.12 中对他不起作用
  • 它在 2.6.15 中对我不起作用(破坏了我的模块构建)
  • 查看内核提交,我发现 Makefile.modpost 的许多更改似乎与 2.6.26 和 2.6.28 相关,因此我预计其中之一是限制。

Related to the above technique of using KBUILD_EXTMOD, and the question of which kernel versions it works under:

  • andycjw indicated it didn't work for him in 2.6.12
  • It didn't work for me in 2.6.15 (broke my module build)
  • Looking through the kernel commits, I see a number of changes to Makefile.modpost that seem related in 2.6.26 and 2.6.28, so I expect one of those is the limit.
月棠 2024-07-21 22:04:45

我的需要是为你的树量身定制的。
在我们的源代码中,我们创建了一个 SYMBOLSDIR,它是所有模块的路径

SYMBOLSDIR = 'some path'

make (与上面的示例相同) $(KERNELDIR) MODVERDIR=$(SYMBOLSDIR) 模块

My need to be tailored to your tree.
In our source we created a SYMBOLSDIR that is a path to all the modules

SYMBOLSDIR = 'some path'

make (same as above example) $(KERNELDIR) MODVERDIR=$(SYMBOLSDIR) modules

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文