Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23091
  • 博文数量: 8
  • 博客积分: 20
  • 博客等级: 民兵
  • 技术积分: 149
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-01 11:02
个人简介

no no no

文章分类

全部博文(8)

文章存档

2013年(8)

我的朋友

分类: LINUX

2013-06-16 17:16:14

1. 设备号
主,次:
crw-rw----   1 root tty       7, 134 2013-06-16 09:45 vcsa6
crw-------   1 root root     10,  63 2013-06-16 09:45 vga_arbiter
crw-rw-rw-   1 root root      1,   5 2013-06-16 09:45 zero
其中,主设备号标识设备对应的驱动程序,次设备内核使用直接指向设备本身。
内核中,用dev_t保存设备号。以下宏用来在dev_t和主次设备号之间转换。
MAJOR(dev_t dev); MINOR(dev_t dev);MKDEV(int major, int minor);

分配:
可用动态或静态两种方法来分配设备号,对应方法为:

点击(此处)折叠或打开

  1. if (scull_major) {
  2. dev = MKDEV(scull_major, scull_minor);
  3. result = register_chrdev_region(dev, scull_nr_devs, "scull");
  4. } else {
  5. result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
  6. scull_major = MAJOR(dev);
  7. }

  8. if (result < 0) {
  9. printk(KERN_WARNING "scull: can't get major %dn", scull_major);
  10. return result;
  11. }




2. 设备相关的数据结构
struct file_operations:指定了一些操作,如open, read, write。应该如下初始化:

点击(此处)折叠或打开

  1. struct file_operations scull_fops = {
  2.  .owner = THIS_MODULE,
  3.  .llseek = scull_llseek,
  4.  .read = scull_read,
  5.  .write = scull_write,
  6.  .ioctl = scull_ioctl,
  7.  .open = scull_open,
  8.  .release = scull_release,
  9. };



struct file:内核结构,与用户空间的FILE不同,它为每个打开的文件创建一个,简称flip。

struct inode:此结构表示真正的文件,以下两字段重要:dev_t i_rdev; 指出对应设备文件的设备号;  struct cdev *i_cdev;若inode指向字符设备,则这指针指向struct cdev。可用宏从inode结构中取得主次设备号。

3. 字符设备的注册
注册就是获取一个struct cdev结构,有以下两种方法:

独立获取cdev结构应该这样:

点击(此处)折叠或打开

  1. struct cdev *my_cdev = cdev_alloc();
  2. my_cdev->ops = &my_fops;

否则如果在自己的结构体中嵌入cdev时应该这样:

点击(此处)折叠或打开

  1. static void scull_setup_cdev(struct scull_dev *dev, int index)
  2. {
  3.  int err, devno = MKDEV(scull_major, scull_minor + index);

  4.  cdev_init(&dev->cdev, &scull_fops);
  5.  dev->cdev.owner = THIS_MODULE;
  6.  dev->cdev.ops = &scull_fops;
  7.  err = cdev_add (&dev->cdev, devno, 1);


4. 驱动简单实现:
open:

点击(此处)折叠或打开

  1. int (*open)(struct inode *inode, struct file *filp)
输入为inode,可从中取得cdev指针,进而用container_of宏取得自定结构体,最终将自定结构体传递给filp的private_data结构。如有需要,处理自带结构中的内存。

release:做适当的清理。

read: write:
就是从自带结构中相关数据与用户空间数据读写。
注意的是,内核中不可直接引用用户空间的指针。因为可能页被换出,会导致出错。必须用copy_to_user, copy_from_user宏来完成数据传送。这两个宏是cpu级别的汇编代码实现的。
用这两个宏时如果用户空间的内存被换出,那么此进程会睡眠。所以必须保证任何访问用户空间的函数必须可重入

阅读(514) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:ldd ch4

给主人留下些什么吧!~~