Linux 字符设备记录

来源:互联网 发布:2016淘宝销售前十名 编辑:程序博客网 时间:2024/05/28 05:14

字符设备的定义特性

字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。

常见的字符设备:字符终端(/dev/console),串口(/dev/ttyS0以及类似设备)等,字符设备可以通过文件系统节点来访问,这些设备文件和普通文件之间的唯一差别在于普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道,但是有例外(帧抓取器)。

 

知识点简要记录

1、对字符设备的访问是通过文件系统内的设备名称进行的。

2、通过ls -l显示设备类型,第一列的首字母为c,而块设备是b。

crw--w----  1 root root      4,   0 2013-03-23 01:14 tty0

brw-rw----  1 root disk      8,   1 2013-03-23 01:14 sda1

3、一个主设备号对应一个驱动程序,可以通过次设备号获得一个指向内核设备的直接指针。

4、dev_t类型包括主设备号和次设备号,是一个32位的数,其中12位表示主设备号,而其余20位用来表示次设备号;获得主设备号和次设备好的方法:MAJOR(dev_t dev),MINOR(dev_t dev);如果要将主次设备号转换成dev_t类型:MKDEV(int major,int minor)。

5、分配和释放设备编号

int register_chrdev_region(dev_t first,unsigned int count,char *name);

first是要分配的设备编号范围的起始值,count是所申请的连续设备编号的个数,name是和该编号范围关联的设备名称。成功返回0,失败返回一个负的错误编码。

int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);

dev是用于输出的参数,firstminor是所申请的连续设备编号的个数,通常是0,count是连续申请的个数,name是和该编号范围关联的设备名称。

void unregister_chrdev_region(dev_t first,unsigned int count);

以上这个函数是释放设备编号的。

6、动态分配的主设备号不能保证始终一致,所以无法预先创建设备节点。

7、查看当前字符设备以及主设备号:cat /proc/device

Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
 10 misc
 13 input
 14 sound
 21 sg
 29 fb

8、file_operations结构

file_operations结构是将设备编号和驱动程序操作连接在一起的结构。

struct module *owner;指向“拥有”该结构模块的指针,一般初始化为THIS_MODULE;

loff_t (*llseek)(struct file *,loff_t,int);修改文件的当前读写位置;

ssize_t (*read)(struct file *,char __user *,size_t,loff_t *);返回非负值表示成功读取的字节数

ssize_t (*aio_read)(struct kiocb *,char __user *,size_t,loff_t);异步读取,不能保证读取能完成

ssize_t (*write)(struct file *,constc char __user *,size_t,loff_t *);返回非负值表示成功写入的字节数

ssize_t (*aio_write)(struct kiocb *,const char __user *,size_t,loff_t);异步写入

int (*ioctl)(struct inode *,struct file *,unsigned int,unsigned long);提供一种执行设备特定命令的方法

int (*mmap)(struct file *,struct vm_area_struct *);用于请求将设备内存映射到进程地址空间

int (*open)(struct inode *,struct file *);对设备文件执行的第一个操作,如果为NULL,将永远打开成功

int (*release)(struct inode *,struct file *);当file结构被释放时,将调用这个操作

其他成员参考include/linux/fs.h

9、file结构

file结构和用户空间的FILE没有任何关联,后者在C库中定义,不会出现在内核中;前者是一个内核结构,不会出现在用户程序中;

loff_t f_fpos;一个64位的数,表示文件当前的位置,read/write会更新这一个值,用户可以读取,不用直接修改这个值

unsigned int f_flags;文件标志,如O_RDONLY、O_WRONLY、O_RDWR、O_NONBLOCK、O_SYNC

其他成员参考include/linux/fs.h

10、inode结构

dev_t i_rdev;对表示设备文件的inode结构,该字段包含了真正的设备编号

struct cdev *i_cdev;表示字符设备的内核的内部结构;

从inode中获得主次设备号:

unsigned int iminor(struct inode *inode);

unsinged int imajor(struct inode *inode);

11、分配字符设备

获得字符设备:struct cdev *my_cdev = cdev_alloc();my_cdev->ops = &my_ops;

初始化分配到的字符设备:cdev_init(struct *cdev,struct file_operation *fops);

增加到内核:int cdev_add(struct cdev *dev,dev_t num,unsinged int count);

移除字符设备:void cdev_del(struct cdev *dev);

 

 

 

原创粉丝点击