Linux: modpost无法构建任何内容

10

我在我的机器上无法构建任何内核模块。每当我构建一个模块时,modpost总是说没有模块:

MODPOST 0 modules

为了解决问题,我编写了一个测试模块(hello.c):
#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */

static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
return 0;
}

static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye Mr.\n");
}

module_init(hello_start);
module_exit(hello_end);

这是该模块的Makefile文件:
obj-m = hello.o
KVERSION = $(shell uname -r)
all:
        make -C /lib/modules/$(KVERSION)/build M=$(shell pwd) modules
clean:
        make -C /lib/modules/$(KVERSION)/build M=$(shell pwd) clean

在我的电脑上构建时,我得到了以下输出:

make -C /lib/modules/2.6.32-27-generic/build M=/home/waffleman/tmp/mod-test modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-27-generic'
  CC [M]  /home/waffleman/tmp/mod-test/hello.o
  Building modules, stage 2.
  MODPOST 0 modules
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-27-generic'

当我在另一台机器上制作模块时,它是成功的:

make -C /lib/modules/2.6.24-27-generic/build M=/home/somedude/tmp/mod-test modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-27-generic'
  CC [M]  /home/somedude/tmp/mod-test/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/somedude/tmp/mod-test/hello.mod.o
  LD [M]  /home/somedude/tmp/mod-test/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-27-generic'

我查找了与modpost相关的文档,但是发现很少。有人知道modpost如何决定要构建什么吗?我可能错过了某些环境吗?

顺便说一下,这是我正在运行的内容:

uname -a
Linux waffleman-desktop 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux

编辑

这里是使用V=1进行编译的make命令:

make -C /lib/modules/2.6.32-27-generic/build M=/home/waffleman/tmp/mod-test modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-27-generic'
test -e include/linux/autoconf.h -a -e include/config/auto.conf || (        \
    echo;                               \
    echo "  ERROR: Kernel configuration is invalid.";       \
    echo "         include/linux/autoconf.h or include/config/auto.conf are missing.";  \
    echo "         Run 'make oldconfig && make prepare' on kernel src to fix it.";  \
    echo;                               \
    /bin/false)
mkdir -p /home/waffleman/tmp/mod-test/.tmp_versions ; rm -f /home/waffleman/tmp/mod-test/.tmp_versions/*
make -f scripts/Makefile.build obj=/home/waffleman/tmp/mod-test
  gcc -Wp,-MD,/home/waffleman/tmp/mod-test/.hello.o.d  -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.4.3/include  -Iinclude  -I/usr/src/linux-headers-2.6.32-27-generic/arch/x86/include -include include/linux/autoconf.h -Iubuntu/include  -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i586 -mtune=generic -maccumulate-outgoing-args -Wa,-mtune=generic32 -ffreestanding -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Wframe-larger-than=1024 -fno-omit-frame-pointer -fno-optimize-sibling-calls -pg -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fno-dwarf2-cfi-asm -fconserve-stack  -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hello)"  -D"KBUILD_MODNAME=KBUILD_STR(hello)"  -c -o /home/waffleman/tmp/mod-test/.tmp_hello.o /home/waffleman/tmp/mod-test/hello.c
  set -e ; perl /usr/src/linux-headers-2.6.32-27-generic/scripts/recordmcount.pl "i386" "32" "objdump" "objcopy" "gcc" "ld" "nm" "" "" "1" "/home/waffleman/tmp/mod-test/hello.o";
(cat /dev/null;   echo kernel//home/waffleman/tmp/mod-test/hello.ko;) > /home/waffleman/tmp/mod-test/modules.order
make -f /usr/src/linux-headers-2.6.32-27-generic/scripts/Makefile.modpost
  scripts/mod/modpost -m -a -i /usr/src/linux-headers-2.6.32-27-generic/Module.symvers -I /home/waffleman/tmp/mod-test/Module.symvers  -o /home/waffleman/tmp/mod-test/Module.symvers -S -w  -s
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-27-generic'
waffleman@waffleman-desktop:~/tmp/mod-test$ cat /home/waffleman/tmp/mod-test/modules.order
kernel//home/waffleman/tmp/mod-test/hello.ko

7
尝试使用“make V=1”命令进行编译,可能会出现编译错误。 - ismail
这提供了更多的输出。包括 /linux/autoconf.h 和 /config/auto.conf 两者都存在。 - waffleman
13个回答

7

我整天都粘在电脑上,与这个确切的问题作斗争……最后像楼主一样神秘地消失了。

至少我可以从我的经验中提供这个微不足道的细节:我得到了与楼主相同的输出(对于make V=1),并且将打印语句放入$ {kernel_directory} /scripts/makefile.build中显示,在包括我的makefile之后,obj-m没有被奇怪地设置,即使它明显是如上所述键入的。

我对“obj-m + = hello.o”和周围的行进行了一堆愚弄。最终它神奇地起作用了……虽然最终看起来与以前完全相同。也许我从在线教程中复制了那些行,并且其中包含某种无效/不正确的字符?

对于任何遇到此问题的人,请验证是否实际上将obj-m设置为hello.o
如果它神秘地没有,删除该行,甚至整个Makefile,然后重新输入它。

我知道这帮助不大;我希望我能够重现发生了什么!


遇到了同样的问题...这是由于Makefile的复制,如果有人遇到了这个问题,请编辑您的Makefile,不要复制和粘贴它。 - vinay hunachyal
谢谢,我也尝试了重新编写这行代码,而不是粘贴它,对我来说有效。 - Jefferson

2

在另一个帖子中,我发现当我复制粘贴makefile内容时,make后面的-C使用了错误的"-"符号,我不得不重新输入。恰好对于上面的obj-m += ...行也是如此。您需要重新输入该字符才能使其有效。希望任何遵循hello world模块教程的人都能找到这个问题。


我认为这是问题的真正解决方案。错误的“-”字符! - Xerusial
是的,这是一种非常棘手的问题...曾经浪费了数小时来弄清楚一个同事在从Slack复制shell命令时如何获得相当定向的Unicode引号... - Chris Stratton

1
我遇到了同样的问题,原因是通过 GREP_OPTIONS 环境变量更改了默认的 grep 选项。我没有深入研究,但模块构建过程中的某些内容不喜欢我的替代 grep 输出(包括文件名和行号)。移除 GREP_OPTIONS 环境变量可以解决问题。

1
这是因为当你从PDF或其他教程网站复制makefile内容并直接使用时,会出现一些问题。在Linux环境下进行复制粘贴时,内容可能会显示不正常,即存在一些特殊字符问题。如果你在Linux环境下重新输入内容并执行make操作,就可以解决这个问题。

1

我猜你是从PDF或HTML文档中复制了Makefile的内容。使用的连字符有些奇怪。尝试替换Makefile中的连字符,它会像魔法一样正常工作。


欢迎来到Stack Overflow。那是一个有趣的论题,但我不确定它是否在这里得到证明。至少,当我将问题中显示的makefile复制到Mac(Mac OS X 10.7.5; Firefox 15.0.1)上并分析数据时,所有字符都是常规ASCII码。这并不是说它不会发生;“智能引号”确实会带来麻烦。我只是没有看到在这个问题中做出这种假设的依据。(此外,如果连字符不是连字符,编译器会抱怨找不到以非连字符开头的文件名;我认为这不是问题的原因)。 - Jonathan Leffler
我只是分享了发生在我身上的事情。我将一个 PDF 文件中 Makefile 的内容复制到了我在 Ubuntu-11.10 中通过 vim 打开的 Makefile 中。然而,复制的连字符却成为了无效字符。 - saai63

0

我曾经遇到过同样的问题。最终,我重建了内核,重新编写了Makefile文件。最终它成功了。

我猜主要原因是在make ARCH=arm...之后的下一行中有M=$(PWD)模块。


0

这个错误神奇地消失了。如果有人知道可能是什么原因引起的,下次再出现类似情况时我想知道。


很可能您的发行版进行了自动更新,因为我的机器已经过去一周了,但是没有出现任何神奇的解决方法。 :/ - dimitarvp
我也遇到了同样的问题。我从http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html复制了Makefile。一开始它没有起作用。然后我使用了之前编写的Makefile。奇怪的是,当我再次使用它时,它就可以工作了!我不知道为什么它能工作。 - louxiu

0
在出现问题的机器上,您的 .config 文件是否禁用了模块支持?
尝试执行 "make menuconfig" 命令,确保模块支持已启用。

0

我只能猜测你的内核构建环境出了问题,因为它通过了理论检查(开发者的外观)和实际测试:

make -C /lib/modules/2.6.36-rc8-32-desktop/build M=/dev/shm modules
make[1]: Entering directory `/usr/src/linux-2.6.36-rc8-32-obj/x86_64/desktop'
make -C ../../../linux-2.6.36-rc8-32 O=/usr/src/linux-2.6.36-rc8-32-obj/x86_64/desktop/. modules
  CC [M]  /dev/shm/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /dev/shm/hello.mod.o
  LD [M]  /dev/shm/hello.ko
make[1]: Leaving directory `/usr/src/linux-2.6.36-rc8-32-obj/x86_64/desktop'

0

我通过将

来解决了这个问题。
obj-m += <module name>.o

在一个名为Kbuild的单独文件中。请参阅Linux/documentation/kbuild/modules.txt,了解为什么这可能有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接