Device File Creation
创建字符设备设备文件
在上一个小节中,我们知道了如何分配主副设备号,但是到此为止,只是创建主副设备号。并未在 /dev
目录下创建设备文件。
设备文件
设备文件可以实现用户空间应用与硬件的通讯。它们并不是普通文件,只是从编程视角来看是一个文件,可以读,可以写,可以 mmap
等。当访问这类文件时,内核识别这样的 I/O 请求,并将请求给到设备驱动。
执行下面的命令可以查看 /dev
目录中的设备:
ls -l /dev
这一命令会列出设备类型,设备权限,主副设备号。
创建设备文件
可以使用两种方式创建设备文件:
- 手动
- 自动
手动创建设备文件
可以使用 mknod
手动创建设备文件:
mknod -m <permissions> <name> <device type> <major> <minor>
其中:
- name,
/dev
下的设备文件名 - device type,设备类型,选择
c
或b
为字符设备或块设备 - major,对应的驱动主号
- minor,对应的驱动副号
- permissions,设置新设备的权限
例:
sudo mknod -m 666 /dev/mydevice c 246 0
如果不希望给定权限,可以在创建文件成功后,使用 chmod
命令修改设备文件权限。
使用如下命令删除节点:
sudo rm -f /dev/mydevice
优点
使用手动创建设备文件的方法的优点是:
- 任何人可以使用这个方法创建设备文件
- 可以在加载驱动之间就创建设备文件
自动创建设备文件
可以使用 udev
方法自动创建设备文件,udev
可以在 /dev
目录下动态创建/移除设备文件,步骤如下:
- 内核源码中包含头文件
linux/device.h
与linux/kdev_t.h
- 创建结构体类
- 使用结构体类创建设备
创建 class
这将为设备驱动创建 class
结构,这将会在 /sys/class/
下创建对应的结构。
struct class *class_create(struct module *owner, const char *name);
- owner,指向拥有这个
class
结构体的模块 - name,指向
class
的名字串
创建设备
下面的函数可以用来创建字符设备文件,这将会在 sysfs
中创建设备,并注册指定 class
。
struct device *device_create(struct *class, struct device *parent, dev_t dev, void *drvdata, const char *fmt, ...);
- class,设备要注册的
class
- parent,这个设备的父设备结构体指针
- dev,字符设备绑定的
dev
- drvdata,添加数据,用作回调
- fmt,设备名
- ...,变量参数
编程
手动
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#define DRV_NAME "mydrv"
dev_t dev = 0;
static int __init dev_init(void)
{
if ((alloc_chrdev_region(&dev, 0, 1, DRV_NAME)) < 0) {
printk(KERN_ERR "alloc major number failed\n");
return -1;
}
printk(KERN_INFO "kernel module create successfully\n");
return 0;
}
static void __exit dev_exit(void)
{
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "kernel module removed successfully\n");
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xdd");
MODULE_DESCRIPTION("A device driver");
MODULE_VERSION("1.0");
$ cat /proc/devices | grep mydrv
239 mydrv
$ sudo mknod -m 666 /dev/mydevice c 239 0
$ ls -l /dev | grep "mydevice"
crw-rw-rw- 1 root root 239, 0 Feb 19 21:09 mydevice
$ sudo rm /dev/mydevice
自动
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/device.h>
#define DRV_NAME "mydrv"
#define DEV_CLASS "mydrvclass"
#define DEV_NAME "mydev"
dev_t dev = 0;
static struct class *dev_class;
static int __init dev_init(void)
{
if ((alloc_chrdev_region(&dev, 0, 1, DRV_NAME)) < 0) {
printk(KERN_INFO "alloc device number failed\n");
return -1;
}
printk(KERN_INFO "Major: %d Minor: %d \n", MAJOR(dev), MINOR(dev));
dev_class = class_create(THIS_MODULE, DEV_CLASS);
if (IS_ERR(dev_class)) {
printk(KERN_INFO "create class failed\n");
goto f_class;
}
if (IS_ERR(device_create(dev_class, NULL, dev, NULL, DEV_NAME))) {
printk(KERN_INFO "create device failed\n");
goto f_device;
}
printk(KERN_INFO "device create success\n");
return 0;
f_device:
class_destory(dev_class);
f_class:
unregister_chrdev_region(dev, 1);
return -1;
}
static void __exit dev_exit(void)
{
device_destroy(dev_class, dev);
class_destroy(dev_class);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "device removed success\n");
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xdd");
MODULE_DESCRIPTION("A device driver");
MODULE_VERSION("1.0");
$ ls -l /dev/mydev
crw------- 1 root root 239, 0 Feb 19 21:14 /dev/mydev
标签:文件创建,创建,dev,device,include,class,设备
From: https://www.cnblogs.com/arvin-blog/p/18028127