前言
参考文章:无法生成设备节点
最后证实:是bootargs配置错误导致的,不过中间发现也是可以通过mdev -s间接解决的,算是学习经验吧。
misc驱动框架是linux内核驱动中最简单实用的框架了。记录一下今天调试misc驱动的问题。misc驱动主要就是注册和注销函数,还有struct miscdevice结构体的初始化赋值,如果注册成功,会在/proc/misc文件中看到新注册的主设备号是10,次设备号如果配置MISC_DYNAMIC_MINOR,那就是随机分配的。
先引入一个问题,我的根文件系统使用的mdev,在udev机制的根文件系统的我的驱动是能正常工作的。
然后,创建的misc设备在/dev目录下看不到。我通过两个地方确认了该设备确实注册成功了
/sys/class/misc目录
该目录中确实有我的文件:video1,可能有人会疑问了,这个不是V4L2驱动框架中的摄像头吗?没错,只不过,我将V4L2框架重写了o(* ̄︶ ̄*)o,还有点小骄傲,不存在的,咱很谦虚的。
root@host:/sys/class/misc# ls
apm_bios memory_bandwidth rfkill
autofs mxc_asrc ubi_ctrl
cpu_dma_latency network_latency video1
fuse network_throughput watchdog
hw_random ov9281 wsinput
loop-control pxp_device wskey
root@host:/sys/class/misc#
查看/proc/misc文件
mymisc前面的52表示次设备号。
root@host:~# cat /proc/misc
52 video1
53 ov9281
54 wskey
55 wsinput
56 ubi_ctrl
57 pxp_device
58 memory_bandwidth
59 network_throughput
60 network_latency
61 cpu_dma_latency
62 mxc_asrc
130 watchdog
237 loop-control
183 hw_random
134 apm_bios
229 fuse
235 autofs
63 rfkill
root@host:~#
然后我使用mknode /dev/mymisc c 10 52
root@host:~#mknod /dev/video1 c 10 52
root@host:~# ls /dev/video1 -ls
0 crw-rw-rw- 1 root root 10, 52 Jan 1 00:10 /dev/video1
root@host:~#
测试以后发现,这样可行,但是每次mknod显示是不行的,所以要研究mdev为什么不支持设备节点创建?到底是哪里配置出了问题。
一 dev节点的原理
dev目录下的节点不是由驱动本身生成的,是由文件系统中的工具mdev生成的;当系统启动后,加载完内核再去加载文件系统,执行文件系统中的脚本,脚本会执行mdev -s命令(即执行mdev程序,在博文《设备模型》中有说到,此处不赘述),该命令会去遍历/sys/class下的所有文件,寻找所有名为dev的文件,dev文件保存了每个驱动的主设备号、次设备号,以及驱动名。
这段文件写的太好了。重启设备,然后insmod完驱动以后,执行mdev -s命令,然后设备节点出现了。
root@host:/sys/class/misc# mdev -s
root@host:/sys/class/misc# ls /dev/video1 -ls
0 crw-rw---- 1 root root 10, 52 Jan 1 00:03 /dev/video1
root@host:/sys/class/misc#
假如将这个作为解决方案使用的话,那就在应用程序中执行如下语句:
system("/sbin/mdev -s");
NAME
system - execute a shell commandSYNOPSIS
#include <stdlib.h>int system(const char *command);
测试小代码:
#include <stdlib.h>
#include <stdio.h>
#define DEBUG_INFO(format,...) printf("line=%d:"format"\n",\
__LINE__,##__VA_ARGS__)
int main(int argc,char *argv[])
{
int ret;
char *cmd;
cmd = "/bin/ls -ls /dev/video*";
ret = system(cmd);
DEBUG_INFO("cmd = %s,ret = %d,%s",cmd,ret,ret == 0?"ok":"error");
cmd = "/sbin/mdev -s";
ret = system(cmd);
DEBUG_INFO("cmd = %s,ret = %d,%s",cmd,ret,ret == 0?"ok":"error");
cmd = "/bin/ls -ls /dev/video*";
ret = system(cmd);
DEBUG_INFO("cmd = %s,ret = %d,%s",cmd,ret,ret == 0?"ok":"error");
return 0;
}
编译:
arm-linux-gnueabihf-gcc mdevs.c -o mdevs
执行结果:这勉强算是解决的问题吧。
root@host:~# ./mdevs
line=12:cmd = /sbin/mdev -s,ret = 0,ok
0 crw-rw---- 1 root root 81, 0 Jan 1 00:00 /dev/video0
0 crw-rw---- 1 root root 10, 52 Jan 1 00:01 /dev/video1
line=15:cmd = /bin/ls -ls /dev/video*,ret = 0,ok
root@host:~#
二 挂载到NFS
我前面测试使用的是ramdisk,后来我将这个根文件系统挂载到了NFS上,这时,奇迹出现了,insmod xxx.ko后,/dev/video1出现了,经过排查后发现是bootargs的问题。原来的写法:这种写法,也能正常启动,为什么,因为mmcblk1p2分区也有一个根文件系统。
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
挂载/dev/mmcblk1p2到//mmcblk1p2目录:mount -t ext4 /dev/mmcblk1p2 /mmcblk1p2
正确的写法:
setenv bootargs 'console=ttymxc0,115200 root=/dev/ram0 rootfstype=ext2 rootwait rw'
三 假如这时还是不行
参考 无法生成设备节点 一文。可能是UEVENT_HELPER_PATH没配置。在我的内核.config文件中搜索这个宏:如下所示:
lkmao@ubuntu:~/imx/linux/linux-imx$ grep -rn UEVENT_HELPER_PATH .config
879:CONFIG_UEVENT_HELPER_PATH=""
lkmao@ubuntu:~/imx/linux/linux-imx$
虽然我的问题并非如此,但是我还是准备配置它,看看配置后的运行状态。make menuconfig ,然后搜索UEVENT_HELPER_PATH
注意配置树的层次关系
保存配置,编译内核,然后启动内核,看看系统会不会出问题。
... ...
好了系统启动了,表面上状态和配置之前一样。
小结
我以为的问题,并不是我以为的问题,这个就是知识的局限性,学海无涯苦作舟。