【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
Linux设备文件系统的起源-3, linux内核2.6引入的sysfs
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
static int major = 111;
static struct class *led_class;
static struct device *led_class_device;
static struct file_operations hi3516cv500_led_fops = {
.owner = THIS_MODULE,
};
int __init led_drv_init(void)
{
register_chrdev(major, "led_drv", &hi3516cv500_led_fops);
led_class = class_create(THIS_MODULE, "led class"); // 创建类
led_class_device = device_create(led_class, NULL, MKDEV(major, 0), NULL, "led"); // 创建类设备
return 0;
}
void __exit led_drv_exit(void)
{
unregister_chrdev(major, "led_drv");
device_destroy(led_class, led_class_device); // 删除类设备
class_destroy(led_class); // 删除类.
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_AUTHOR("yangbkGit");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A driver model.");
MODULE_ALIAS("model");
结果:
-
cat /proc/devices
Character devices:
111 led_drv -
ls -l /dev
crw------- 1 root root 111, 0 Feb 13 08:28 led
原因: udev
udev 是 Linux2.6 内核推出的一个功能,它替代了原来的 devfs,成为了当前 Linux 默认的设备管理工具。udev 以守护进程的形式运行,通过侦听内核发出来的 uevent 来管理 /dev目录下的设备文件。不像之前的设备管理工具,udev 在用户空间 (user space) 运行,而不在内核空间 (kernel space) 运行。
在Linux中, 所有的设备在 Linux 里都是以设备文件的形式存在。在早期的 Linux 版本中,/dev目录包含了所有可能出现的设备的设备文件。很难想象 Linux 用户如何在这些大量的设备文件中找到匹配条件的设备文件。现在 udev 只为那些连接到 Linux 操作系统的设备产生设备文件。并且 udev 能通过定义一个 udev 规则 (rule) 来产生匹配设备属性的设备文件,这些设备属性可以是内核设备名称、总线路径、厂商名称、型号、序列号或者磁盘大小等等。
udev需要内核sysfs和tmpfs的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间,
sysfs是 Linux 2.6 内核里的一个虚拟文件系统 (/sys)。它把设备和驱动的信息从内核的设备模块导出到用户空间 (userspace)。从该文件系统中,Linux 用户可以获取很多设备的属性。
好处:
- 动态管理: 当设备添加/删除时, udev的守护进程会侦听到来自内核的uevent, 以此来添加或删除/dev下面的设备文件, 所以udev只为已经连接的设备产生设备文件, 而不会在/dev下产生大量虚无的设备文件;
- 自定义命名规则: 通过Linux默认的规则文件, udev在/dev/里为所有的设备定义了内核设备名称, 如: /dev/sda、/dev/hda、/dev/fd等等. 由于udev是在用户空间(user space)中运行, Linux用户可以通过自定义的规则文件灵活地产生标识性强的设备文件名. 比如: /dev/boot_disk、/dev/root_disk、/dev/color_printer等等.
- 设定设备的权限和所有者/组: udev可以按一定的条件来设置设备文件的权限和设备文件的所有者/组. 在不同的udev版本中, 实现的方法不同.
你可能会遇到的问题:
问题1: class_device_create()函数没找到
error: implicit declaration of function 'class_device_create' [-Werror=implicit-function-declaration]
class_device_create(led_class, NULL, MKDEV(major, 0), NULL, "led");
答:
如上问题是Linux内核版本不同的原因!
早期的版本,使用的是class_device_create(),但是在2.6.29以后,使用的函数则变成了device_create(), 两个函数的参数完全一致, 不需要进行任何改动.
问题2: class_device_unregister()函数没找到
error: implicit declaration of function 'class_device_unregister' [-Werror=implicit-function-declaration]
class_device_unregister(led_class_device);
答:
如上问题是Linux内核版本不同的原因!
早期的版本,使用的是class_device_unregister(),但是在2.6.29以后,使用的函数则变成了device_destroy().
问题3: struct class_device *的incompatible pointer type
error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
led_class_device = device_create(led_class, NULL, MKDEV(major, 0), NULL, "led");
如果你出现了问题1和问题2, 那么问题3应该也是你遇到的, 那就是类型不兼容.
如上问题是Linux内核版本不同的原因!之前的struct class_device *已经改成了struct device *.