Eug*_*Sh. 5 c linux embedded kernel 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);
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
该模块正在rootfs上编译和安装就好了.也正在加载:
$ insmod hello.ko
[ 30.692404] Hello, world
Run Code Online (Sandbox Code Playgroud)
但是当我试图删除它时,我得到:
$ rmmod hello.ko
Segmentation fault
$modprobe -r hello.ko
Segmentation fault
$ lsmod
hello 813 0 - Live 0xbf000000 (O)
Run Code Online (Sandbox Code Playgroud)
编译内核时启用了模块卸载(常规和强制)支持.
这个问题的可能原因是什么?接受调查的方法是什么?
更新:
正如意见建议我曾尝试包括linux/kernel.h,定义MODULE,LINUX和__KERNEL__符号.添加了函数的前缀__init和__exit前缀.删除了static修饰符.删除了这些printk行.结果一样.dmesg仅显示初始问候语.令人惊讶的是,加载和卸载内核模块这样gpio_keys或crypto/ccm 正在工作.所以唯一值得怀疑的是编译模块的方式.
更新2
将内核更新为最新鲜的快照没有帮助.用不同的优化设置编译模块没有帮助.下一步,我想,我将修改BusyBox的rmmod以获得问题位置的一些指示.
我已经设法解决这个问题。使用strace我发现在read特定BusyBox文件时某处发生了段错误modules.dep.bb。BusyBox当使用“Simplified modutils”选项 ( ) 编译该文件时,将使用该文件CONFIG_MODPROBE_SMALL。通过禁用该选项、选择要安装的实用程序并重建 BusybBox,我完成了模块卸载工作。我相信问题根源接近于测试模块被编译并存储在/lib/..../modules目录之外的事实,因此busybox简化modutils只是令人困惑。