insmod *.ko
之后,部分驱动需要执行 mknod
才能正常工作,区别如下
现象
针对驱动实现不同,使用不同,主要在于是否需要手动创建设备文件
mknod /dev/panel0 c 22 0
insmod /lib/modules/ `uname -r` /panel.ko
设备管理
在 Linux
中有手动和自动两种设备管理,一种是 mknod
,在 insmod
后 /dev
下必须有对应的设备文件,需要 mknod
来创建;另外一种在驱动中自动创建
利用 udev(mdev)
来实现设备文件的自动创建,首先应保证支持 udev(mdev)
,由 busybox
配置。
在驱动用加入对 mdev
的支持主要做的就是:在驱动初始化的代码里调用 class_create(...)
为该设备创建一个 class
,再为每个设备调用 device_create(...)
创建对应的设备。
内核中定义的 struct class
结构体,顾名思义,一个 struct class
结构体类型变量对应一个类,内核同时提供了 class_create(…)
函数,可以用它来创建一个类,这个类存放于 sysfs
下面,一旦创建好了这个类,再调用 device_create(…)
函数来在 /dev
目录下创建相应的设备节点。
这样,加载模块的时候,用户空间中的 mdev
会自动响应 device_create()
函数,去 /sysfs
下寻找对应的类从而创建设备节点。
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
static int major = 250;
static int minor=0;
static dev_t devno;
static struct class *cls;
static struct device *test_device;
static int hello_open (struct inode *inode, struct file *filep)
{
printk("hello_open \n");
return 0;
}
static struct file_operations hello_ops=
{
.open = hello_open,
};
static int hello_init(void)
{
int ret;
printk("hello_init \n");
devno = MKDEV(major,minor);
ret = register_chrdev(major,"hello",&hello_ops);
cls = class_create(THIS_MODULE, "myclass");
if(IS_ERR(cls))
{
unregister_chrdev(major,"hello");
return -EBUSY;
}
test_device = device_create(cls,NULL,devno,NULL,"hello");//mknod /dev/hello
if(IS_ERR(test_device))
{
class_destroy(cls);
unregister_chrdev(major,"hello");
return -EBUSY;
}
return 0;
}
static void hello_exit(void)
{
device_destroy(cls,devno);
class_destroy(cls);
unregister_chrdev(major,"hello");
printk("hello_exit \n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
下面可以看几个 class 几个名字的对应关系:
不同内核版本区别
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
# define CLASS_DEV_CREATE(class, devt, device, id) device_create(class, devt, device, NULL, "hello%d", id)
# define CLASS_DEV_DESTROY(class, devt) device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
# define CLASS_DEV_CREATE(class, devt, device, id) device_create(class, devt, device, NULL, "hello%d", id)
# define CLASS_DEV_DESTROY(class, devt) device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
# define CLASS_DEV_CREATE(class, devt, device, id) class_device_create(class, devt, device, NULL, "hello%d", id)
# define CLASS_DEV_DESTROY(class, devt) class_device_destroy(class, devt)
#else
# define CLASS_DEV_CREATE(class, devt, device, id) device_create_drvdata(class, devt, device, "hello%d", id)
# define CLASS_DEV_DESTROY(classs, devt) device_destroy(class, devt)
#endif
mdev
echo "mdev..."
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
mdev.conf
如下
null 0:0 666
zero 0:0 666
urandom 0:0 444
kmem 0:9 000
mem 0:9 640
port 0:9 640
console 0:5 600
ptmx 0:5 660
pty[a-z]. 0:0 660
tty[a-z]. 0:0 660
tty[0-9][0-9] 0:0 660
ttyS[0-9] 0:20 640
sd[a-z][0-9]* 0:6 660 * /etc/hotplug/usb/automount.sh $MDEV $ACTION
fd[0-9]* 0:11 660
hd[a-z]* 0:6 660