Chinaunix首页 | 论坛 | 博客
  • 博客访问: 142816
  • 博文数量: 19
  • 博客积分: 1746
  • 博客等级: 上尉
  • 技术积分: 443
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-22 22:54
文章分类
文章存档

2011年(3)

2010年(16)

分类: LINUX

2010-03-07 17:24:16

------------------------------------------------
#个人浅见,如有问题敬请谅解!
#kernel version: 2.6.26
#Author: andy wang
-------------------------------------------------
  下面是自己写的一个测试程序, 加载模块后将会在/dev目录下动态创建名为”test”的字符设备文件,并在class目录下生成相关文件.
首先在虚拟机上执行:
[root@FLYING ~]# ps -aux | grep "udev"
root       452  0.0  0.2   2244   608 ?        S
root      2531  0.0  0.2   3980   632 pts/0    R+   00:53   0:00 grep udev
确定udev进程存在, udev会动态创建设备文件.
在加载模块后,我们需要看以下的内容:
[root@FLYING ~]# ls -l /dev/test
crw------- 1 root root 100, 0 2020-03-30 00:56 /dev/test  ///dev目录下动态生成test字符设备文件
 
[root@FLYING andy]# pwd
/sys/class/andy           //class目录下生成andy目录
[root@FLYING andy]# tree
.
|-- classfile       
`-- test
    |-- dev
    |-- devfile
    |-- power
    |   `-- wakeup
    |-- subsystem -> ../../andy
    `-- uevent
3 directories, 5 files
 
文件: class.rar
大小: 1KB
下载: 下载
 
 
下面看看代码,我们是怎么实现的:
 1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12
 13
 14 #define MAJOR_NUM       100
 15 static struct class *test_class;
 16 static struct device *test_device;
 17
 18
 19 int char_dev_open(struct inode *inode, struct file *file)
 20 {
 21         printk(KERN_INFO "test open char dev\n");
 22         return 0;
 23 }
 24
 25 ssize_t char_dev_read (struct file *file, char __user *buf,
 26                         size_t count, loff_t *ppos)
 27 {
 28         printk(KERN_INFO "test read char dev\n");
 29         return 0;
 30 }
 31
 32 static struct file_operations testopt = {
 33         .owner = THIS_MODULE,
 34         .open = char_dev_open,
 35         .read = char_dev_read,
 36 };
 37
 38 static ssize_t classfile_sysfs_show(struct class *class, char *buf)
 39 {
 40         printk(KERN_INFO "class file show \n");
 41         return 0;
 42 }
 43
 44 static ssize_t devfile_sysfs_show(struct device *dev, struct device_attribute *attr,
 45                         char *buf)
 46 {
 47         printk(KERN_INFO "dev file show \n");
 48         return 0;
 49 }
 50
 51 static CLASS_ATTR(classfile, S_IRUGO, classfile_sysfs_show, NULL);
 52 static DEVICE_ATTR(devfile, S_IRUGO, devfile_sysfs_show,NULL);
 53
 54 static int __init class_test_init(void)
 55 {
 56         int err;
 57
 58         err = register_chrdev(MAJOR_NUM ,"test" ,&testopt);
 59         if(err)
 60                 goto error;
 61
 62         test_class = class_create(THIS_MODULE, "andy");
 63         if(IS_ERR(test_class)){
 64                 err = PTR_ERR(test_class);
 65                 goto class_error;
 66         }
 67
 68         test_device = device_create(test_class, NULL ,MKDEV(MAJOR_NUM ,0) ,"test");
 69         if(IS_ERR(test_device)){
 70                 err = PTR_ERR(test_device);
 71                 goto device_error;
 72         }
 73
 74         err = class_create_file(test_class , &class_attr_classfile);
 75         if(err)
 76                 goto error;
 77         err = device_create_file(test_device ,&dev_attr_devfile);
 78         if(err)
 79                 goto error;
 80         return 0;
 81
 82 device_error:
 83         class_destroy(test_class);
 84 class_error:
 85         unregister_chrdev(MAJOR_NUM ,"test");
 86 error:
 87         return err;
 88 }
 89
 90 void __exit class_test_exit(void)
 91 {
 92         unregister_chrdev(MAJOR_NUM ,"test");
 93         class_remove_file(test_class, &class_attr_classfile);
 94         device_remove_file(test_device,&dev_attr_devfile);
 95         device_destroy(test_class,MKDEV(MAJOR_NUM ,0));
 96         class_destroy(test_class);
 97         return;
 98 }
 99
100
101 module_init(class_test_init);
102 module_exit(class_test_exit);
103 MODULE_LICENSE("GPL");
104 MODULE_DESCRIPTION("andy wang for sys class device test");
 
#
# Makefile for the class device test.
#
 
obj-m           += class_test.o
KERNAL_PATH = /usr/src/linux-2.6.26
 
default:
        make -C $(KERNAL_PATH) M=$(PWD) modules
clean:
        rm *.o *.ko *.mod.c *.order *.symvers
 
 
58, 注册一个字符设备”test”
62,创建一个名字为andy的类class ,此时在/sys/class目录下就生成了andy目录.
68创建一个名字为“test”的类文件 ,此时就会在andy目录下生成test目录了.
74,创建一个类属性文件, 也就是在andy目录下创建一个名为”classfile”的类属性文件.
77, 创建一个设备属性文件 ,也就是在test目录下建立一个名为”devfile”的设备属性文件.
 
那么/dev/test设备文件是如何动态生成的呢?
先看看流程:
device_create()->device_register()->device_add()->kobject_uevent()
最关键的函数就是kobject_uevent() , 这个函数将action_string=add,devpath=/class/andy
,subsystem=class等环境变量信息发给用户层的udev, 然后udev会找到devpath目录下的dev文件(存放着设备号)然后在/dev目录下动态创建设备文件所以我们上面要看看udev进程是否存在了
 
 
阅读(2407) | 评论(0) | 转发(4) |
给主人留下些什么吧!~~