Chinaunix首页 | 论坛 | 博客
  • 博客访问: 126443
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 599
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-29 17:40
个人简介

Just for fun ! 不要迷茫...

文章分类

全部博文(28)

文章存档

2014年(25)

2013年(3)

分类: LINUX

2014-04-23 10:42:46


  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/cdev.h>
  5. #include <linux/init.h>

  6. static struct cdev chr_dev;       //cdev是设备在内核中的内部结构
  7. static dev_t ndev;               //设备编号

  8. static int chr_open(struct inode *nd, struct file *filp)
  9. {
  10.     int major = MAJOR(nd -> i_rdev);              //表示设备的inode的字段中的i_rdev保存了真正的设备编号
  11.     int minor = MINOR(nd -> i_rdev);
  12.     printk("chr_open, major = %d , minor = %d\n.", major, minor);
  13.     return 0;
  14. }

  15. static ssize_t chr_read(struct file *f, char __user *u, size_t sz, loff_t *off)
  16. {
  17.     printk("In the chr_read() function!\n");

  18.     return 0;
  19. }

  20. struct file_operations chr_ops =
  21. {
  22.     .owner = THIS_MODULE,         //避免模块的操作正在被使用时卸载该模块
  23.     .open = chr_open,
  24.     .read = chr_read,
  25. };

  26. static int demo_init(void)
  27. {
  28.     int ret;
  29.     cdev_init(&chr_dev, &chr_ops);                //字符设备cdev初始化,建立cdev和file_operations之间的连接
  30.     ret = alloc_chrdev_region(&ndev, 0 , 1 ,"chr_dev");  //第一个参数类型是dev_t *是输出参数动态分配的设备编号,最后为设备名

  31.     if (ret < 0)
  32.         return ret;

  33.     printk("demo_init(): major = %d ,minot = %d\n", MAJOR(ndev), MINOR(ndev));        //两个宏分别获得设备的主次编号
  34.     ret = cdev_add(&chr_dev, ndev, 1);                                              //将设备添加到系统中,需要失败检查
  35.     if (ret < 0)
  36.         return ret;

  37.     return 0;
  38. }

  39. static void demo_exit(void)
  40. {
  41.     printk("Removing chr_dev module...\n");
  42.     cdev_del(&chr_dev);                                                           //移除字符设备
  43.     unregister_chrdev_region(ndev, 1);                                   //释放设备编号
  44. }

  45. module_init(demo_init);
  46. module_exit(demo_exit);

  47. MODULE_LICENSE("GPL");


点击(此处)折叠或打开

  1. ifneq ($(KERNELRELEASE),)
  2.     obj-m := demo_chr_dev.o
  3. else
  4. KERNELDIR ?= /lib/modules/$(shell uname -r)/build
  5. PWD := $(shell pwd)

  6. default:
  7.     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  8. endif


  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>

  4. #define CHR_DEV_NAME "/dev/chr_dev"

  5. int main()
  6. {
  7.     int ret;
  8.     char buf[32];
  9.     int fd = open(CHR_DEV_NAME, O_RDONLY | O_NDELAY);
  10.     if (fd < 0)
  11.         {
  12.             printf("open file faild!\n");
  13.             return -1;
  14.         }

  15.     read(fd ,buf, 32);
  16.     close(fd);

  17.     return 0;
  18. }
#insmod demo_chr_dev.ko
   demo_init(): major = 248, minor = 0
#mknod  /dev/chr_dev  c  248  0        //动态分配设备号无法预先创建设备节点
#./main


阅读(2235) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~