【问题标题】:linux kernel module linker warnings: "*** Warning: <function> [<module>] undefined!" - any way to get rid of them?linux 内核模块链接器警告:“*** 警告:<function> [<module>] 未定义!” - 有什么办法摆脱它们?
【发布时间】:2010-10-12 03:50:01
【问题描述】:

在编译相互依赖的 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 - 似乎没有人知道答案。当您构建内核模块时,这些链接器警告是否应该是这种方式?

【问题讨论】:

    标签: c++ linux kernel-module compiler-errors


    【解决方案1】:

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

    【讨论】:

    • 这是正确的方法。 linux 内核源代码树中的 Documentation/kbuild/modules.txt 是获取此信息的来源。
    • +1。在一个相关的步骤中,绝对确保如果您已经重建了内核(即使没有更改),之后执行一个 make 模块以保持 symvers 同步。否则你会得到这个错误。
    【解决方案2】:

    终于,我明白了。感谢 shodanex 让我走上正轨。

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

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

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

    foo 的源文件在 foo/module/ 中,bar 的源文件在 bar/module/

    fooMakefile 中的 make 命令可能看起来像

    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

    【讨论】:

    • 这是从哪个版本的 linux 开始工作的?我尝试在 2.6.12 内核构建外部模块时使用此方法,但无济于事,它只构建到 bar 模块,完全忽略 foo 模块,有什么帮助吗?
    • KBUILD_EXTMOD 是 M(和 SUBDIRS)的同义词,这就是它构建 bar 模块的原因。根据 sinojs 的回复使用 KBUILD_EXTRA_SYMBOLS。
    【解决方案3】:

    不,他们不是。无论您在树内还是树外构建代码,都不应显示此消息。我认为您应该修复您的 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过程为documented

    【讨论】:

    • 感谢您的回答。知道具体是怎么回事吗?
    • 很抱歉,但它并没有真正起作用。警告仍然存在。此外,@echo '请忽略“覆盖子目录”警告'让我感到困扰。我可以使用相同的方法来回显“请忽略 [module_name] 未定义!”警告,但显然这不是我正在寻找的方式。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      SYMBOLSDIR = '一些路径'

      制作(与上例相同)$(KERNELDIR) MODVERDIR=$(SYMBOLSDIR) 模块

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 1970-01-01
        • 2021-04-05
        • 1970-01-01
        • 2016-11-20
        相关资源
        最近更新 更多