"分段错误"什么时候`rmmod`或`modprobe -r`

时间:2015-06-11 12:38:53

标签: c linux kernel embedded kernel-module

尝试使用LDD3中最简单的内核模块,而无需对使用BusyBox v1.23.0的Beagle Bone板的自定义内核v4.1.0-rc6进行任何修改。该模块的代码如下:

#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

模块正在rootfs上编译和安装就好了。它也在加载:

$ 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,定义了MODULELINUX__KERNEL__符号。在函数中添加了__init__exit前缀。删除了static修饰符。删除了printk行。结果一样。 dmesg仅显示初始问候语。令人惊讶的是,gpio_keyscrypto/ccm 等内核模块的加载和卸载工作正在。所以唯一值得怀疑的是编译模块的方式..

更新2
将内核更新到最新的快照并没有帮助。使用不同的优化设置编译模块没有帮助。下一步,我想,我将修改BusyBox的rmmod以显示问题位置的一些指示..

2 个答案:

答案 0 :(得分:0)

看看这些教程:

http://www.tldp.org/HOWTO/Module-HOWTO/x839.html http://www.tldp.org/LDP/lkmpg/2.4/html/x281.htm

尝试添加:

#define MODULE
#define LINUX
#define __KERNEL__

#include <linux/kernel.h>      /* Needed for KERN_ALERT */

答案 1 :(得分:0)

我设法解决了这个问题。使用strace我发现当read BusyBox特定modules.dep.bb文件时,会发生段错误。使用“Simplified modutils”选项(BusyBox)编译时,CONFIG_MODPROBE_SMALL使用此文件。通过禁用该选项,选择要安装的工具并重建BusybBox我已经让模块卸载工作。我认为问题根就在于测试模块被编译并存储在/lib/..../modules目录之外的事实,因此busybox与简化的modutils混淆了。