【问题标题】:"Segmentation fault" when `rmmod` or `modprobe -r``rmmod` 或 `modprobe -r` 时出现“分段错误”
【发布时间】:2015-06-11 12:38:53
【问题描述】:

尝试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)

内核编译时启用了模块卸载(常规和强制)支持。

此问题的可能原因是什么?调查的方法是什么?

更新:

按照我尝试过的 cmets 中的建议,包括 linux/kernel.h,定义 MODULELINUX__KERNEL__ 符号。为函数添加了__init__exit 前缀。删除了 static 修饰符。删除了 printk 行。结果一样。 dmesg 仅显示初始问候语。令人惊讶的是,内核模块的加载和卸载(例如 gpio_keyscrypto/ccm 正在工作)。所以唯一值得怀疑的是模块的编译方式..

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

【问题讨论】:

  • 代码看起来不错。删除 /var/log/messages(或 dmesg)时,您是否看到更多信息?它是否只发生在您的模块上,您可以成功加载/卸载任何系统模块吗?
  • @BlueMoon 不幸的是,我现在的 rootfs 上什至没有 /var 目录 :) 我正在从头开始构建它,我不确定应该按顺序安装哪个附加服务写消息..也许我应该从这样做开始。
  • 你能成功加载/卸载其他人,例如modprobe nfsmodprobe -r nfs吗? dmesg 说什么有用的?
  • @Blue Moon 今天晚些时候我会看看这些,现在得去上班了。我知道模块正在加载。不确定卸载。 dmesg 仅在带有busybox 的裸机系统上可用吗?无论如何,感谢您的指导。
  • 只需在命令行上运行dmesg 即可找到答案。

标签: c linux kernel embedded kernel-module


【解决方案1】:

看看这些教程:

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 */

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 2020-11-15
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多