在使用`rmmod`或`modprobe -r`时出现“分段错误”

5
尝试在自定义构建的内核v4.1.0-rc6上,使用BusyBox v1.23.0为Beagle Bone板编写的最简单的内核模块,不对LDD3中的代码进行任何修改。该模块的代码如下:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
    printk(KERN_ALERT "Hello, world\n");
    return 0;
}
static void hello_exit(void)
{
    printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);

Makefile是一个文件:
ARCH := arm
CROSS_COMPILE := arm-cortex_a8-linux-gnueabi-
obj-m := hello.o
all:
        make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) modules
clean:
        make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) clean

该模块在根文件系统上编译和安装都很顺利,而且已经加载:
$ insmod hello.ko 
[   30.692404] Hello, world

但是当我尝试删除它时,出现了以下错误:
$ rmmod hello.ko 
Segmentation fault
$modprobe -r hello.ko 
Segmentation fault
$ lsmod
hello 813 0 - Live 0xbf000000 (O)

内核编译时启用了模块卸载(常规和强制)支持。这个问题可能的原因是什么?如何进行调查?
更新:根据评论中的建议,我尝试包含linux/kernel.h,定义MODULE、LINUX和__KERNEL__符号。给函数添加__init和__exit前缀。移除static修饰符。移除printk行。结果仍然相同。dmesg只显示初始问候语。加载和卸载内核模块,例如gpio_keys或crypto/ccm,出奇地可行。所以唯一剩下的怀疑就是模块编译的方式...
更新2:将内核更新到最新快照没有帮助。使用不同的优化设置编译模块也没有帮助。我想下一步将修改BusyBox的rmmod,以便有一些指示问题位置的迹象...

代码看起来没问题。当你移除它时,在 /var/log/messages(或 dmesg)中是否还有更多信息?这只发生在你的模块上吗?你能成功地加载/卸载任何系统模块吗? - P.P
@Blue Moon 我今天晚些时候会看一下这些,现在得去上班了。我知道模块正在加载,但不确定如何卸载。在只有Busybox的基本系统中是否可用 dmesg 呢?无论如何,感谢你的指引。 - Eugene Sh.
我会回到我的实验室。谢谢。 - Eugene Sh.
为了好玩,添加 #include <linux/kernel.h> - Les
@BlueMoon 请查看更新。这真的很奇怪。 - Eugene Sh.
显示剩余3条评论
2个回答

0

0

我已经成功解决了这个问题。使用strace,我发现当read BusyBox 特定的 modules.dep.bb 文件时,段错误发生在某个地方。当使用“简化modutils”选项(CONFIG_MODPROBE_SMALL)编译BusyBox时,该文件被BusyBox使用。通过禁用该选项,选择要安装的工具并重新构建BusybBox,我已经使模块卸载正常工作。我相信问题的根源在于测试模块被编译并存储在/lib/..../modules目录之外,因此使用简化的modutilsbusybox只是感到困惑。


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