之前把Linux Kernel移植好,就把驱动程序加载进去
结果发现:
/ # ls
bin first_drv.ko linuxrc root tmp
dev firstdrvtest mnt sbin usr
etc lib proc sys
/ # insmod first_drv.ko
first_drv: loading out-of-tree module taints kernel.
/ # lsmod
lsmod: can't open '/proc/modules': No such file or directory
/ # random: crng init done
/ # insmod first_drv.ko
insmod: can't insert 'first_drv.ko': File exists
/ #
好坑,insmod提示 loading out-of-tree module taints kernel.
而且lsmod也提示 can't open '/proc/modules': No such file or directory...
纠结了半天,发现Kernel打印出来的log有一句:
cann't run '/etc/init.d/rcS':Permission denied.
原来是rcS没有得到运行,加上执行权限即可:
sudo chmod u+x /work/nfs/root/etc/init.d/rcS
这样,重启开发板,进行文件系统后,
insmod虽然还会提示:loading out-of-tree module taints kernel.
但是lsmod是会看到刚刚安装好的驱动的了。
loading out-of-tree module taints kernel.
这个好像是因为内核在编译的时候选择支持内核签名机制,据说在3.7版本后面就支持
模块签名了。这是为了Kernel安全加上的。
其中,内核配置项:
CONFIG_MODULE_SIG=y
表示开启了签名机制。
CONFIG_MODULE_SIG_FORCE=y
则模块必须有正确的签名才能正常使用。
CONFIG_MODULE_SIG_ALL=y
内核在编译的时候,会主动去给模块签名。
我在Kernel的menuconfig看了下,我的
CONFIG_MODULE_SIG是=n的啊。奇怪。
不管了,提示taints kernel就提示吧,反正能把驱动加载上去就行。
估计CONFIG_MODULE_SIG=y的话就不能正常把驱动加载上去吧。
需要给驱动签名.
然后,insmod和lsmod都没问题了,现在试试rmmod卸载驱动.
需要在lib目录下建一个空文件夹加能使用rmmod.
mkdir -p /lib/module/4.8.17
但是rmmod时还会出现一个问题:
Unable to handle kernel paging request at virtual address fffffffc
pgd = c3b40000
在卸载驱动时出这个错,估计是内存访问错误了。
后来经大佬提醒,在驱动卸载时,device_destroy函数的第一个参数是struct class *类型.
之前我程序的参数传入错误,传了个struct class_device *类型的参数进行.
这个还是新内核导致的差异啊。
总的来说,加载和卸载驱动,都需要:
init函数: 1. devno注册 2. class注册 3. device申请
exit函数: 1. device销毁 2. class释放 3. devno释放