Linux中I/O设备分为两类:块设备和字符设备。两种设备本身没有严格限制,但是,基于不同的功能进行了分类。

(1) 字符设备:提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字节/字符来读写数据。举例来说,调制解调器是典型的字符设备。

(2) 块设备:应用程序可以随机访问设备数据,程序可自行确定读取数据的位置。硬盘是典型的块设备,应用程序可以寻址磁盘上的任何位置,并由此读取数据。此外,数据的读写只能以块(通常是512B)的倍数进行。与字符设备不同,块设备并不支持基于字符的寻址。

两种设备本身并没用严格的区分,主要是字符设备和块设备驱动程序提供的访问接口(file I/O API)是不一样的。本文主要就数据接口、访问接口和设备注册方法对两种设备进行比较。

1、数据结构

1.1字符设备数据结构

struct file; 

        struct inode;

file定义于 <linux/fs.h>, 是设备驱动中第二个最重要的数据结构. 文件结构代表一个打开的文件. 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的关闭. 在文件的所有实例都关闭后, 内核释放这个数据结构。

inode 结构由内核在内部用来表示文件.inode 结构包含大量关于文件的信息其中dev_t i_rdev成员包含实际的设备编号.struct cdev *i_cdev中struct cdev 是内核的内部结构, 代表字符设备。

1.2块设备数据结构

struct gendisk (定义于 <linux/genhd.h>) 是单独一个磁盘驱动器的内核表示. 事实上, 内核还使用 gendisk 来表示分区。

2、设备访问接口

2.1字符设备访问接口

struct file_operations 其中file_operation 结构中的每个成员必须指向驱动中的函数, 这些函数实现一个特别的操作, 或者对于不支持的操作留置为 NULL. 当指定为 NULL 指针时内核的确切的行为是每个函数不同的,该结构中主要函数如下:

ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp);

        ssize_t write(struct file *filp, const char __user *buff, size_t count, loff_t *offp);

filp 是文件指针, count 是请求的传输数据大小. buff 参数指向持有被写入数据的缓存, 或者放入新数据的空缓存. 最后, offp 是一个指针指向一个"long offset type"对象, 它指出用户正在存取的文件位置. 返回值是一个"signed size type"。

2.2块设备访问接口

字符设备通过 file_ 操作结构使它们的操作对系统可用. 一个类似的结构用在块设备上; 它是 struct block_device_operations, 定义在 <linux/fs.h>,其主要操作方法如下:

int (*open)(struct inode *inode, struct file *filp); 

        int (*release)(struct inode *inode, struct file *filp);

就像它们的字符驱动对等体一样工作的函数; 无论何时设备被打开和关闭都调用它们. 一个字符驱动可能通过启动设备或者锁住门(为可移出的介质)来响应一个 open 调用. 如果你将介质锁入设备, 你当然应当在 release 方法中解锁。

int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);

实现 ioctl 系统调用的方法. 但是, 块层首先解释大量的标准请求; 因此大部分的块驱动 ioctl 方法相当短。

3、设备注册

3.1字符设备注册

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

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

        void unregister_chrdev_region(dev_t first, unsigned int count);

允许驱动分配和释放设备编号的范围的函数. register_chrdev_region 应当用在事先知道需要的主编号时; 对于动态分配, 使用 alloc_chrdev_region 代替.

3.2块设备注册

int register_blkdev(unsigned int major, const char *name); 

        int unregister_blkdev(unsigned int major, const char *name);

register_blkdev 注册一个块驱动到内核, 并且, 可选地, 获得一个主编号. 一个驱动可被注销, 使用 unregister_blkdev。

Linux字符设备与块设备的区别与比较的更多相关文章

  1. Linux系统中/dev/mtd与/dev/mtdblock的区别,即MTD字符设备和块设备的区别

    转:http://www.crifan.com/linux_system_in__dev__mtd_and__dev__mtdblock_distinction_character_devices_a ...

  2. 【APUE】一个fork的面试题及字符设备、块设备的区别

    具体内容见:http://coolshell.cn/articles/7965.html 字符设备.块设备主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,而块设备则不然, ...

  3. linux驱动开发之块设备学习笔记

    我的博客主要用来存放我的学习笔记,如有侵权,请与我练习,我会立刻删除.学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.h ...

  4. Linux中什么是块设备 及 lsblk命令的使用

    Linux中I/O设备分为两类:字符设备和块设备.两种设备本身没有严格限制,但是,基于不同的功能进行了分类.(1)字符设备:提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取.相反,此类设备支 ...

  5. Linux平台下:块设备、裸设备、ASMlib、Udev相关关系

    对磁盘设备(裸分区)的访问方式分为两种:1.字符方式访问(裸设备):2.块方式访问 Solaris平台 : 在Solaris平台下,系统同时提供对磁盘设备的字符.块方式访问.每个磁盘有两个设备文件名: ...

  6. 【转】Linux设备驱动--块设备(一)之概念和框架

    原文地址:Linux设备驱动--块设备(一)之概念和框架 基本概念   块设备(blockdevice) --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时 ...

  7. 驱动开发--【字符设备、块设备简介】【sky原创】

    驱动开发   字符设备,块设备,网络设备   字符设备 以字节流的方式访问, 不能随机访问 有例外,显卡.EEPROM可以随机访问   EEPROM可以擦写1亿次,是一种字符设备,可以随机访问 读写是 ...

  8. 字符设备 Vs. 块设备 Character Device Vs. Block Device

    字符设备是指驱动发送/接受单个字符(例如字节)的设备. 块设备是指驱动发送/接受整块数据(例如512个字节为一个块)的设备. 常见的字符设备:串口,并口,声卡. 常见的块设备:硬盘(最小读取单位为扇区 ...

  9. Linux 下模拟制作块设备并挂载

    Linux 下模拟制作块设备并挂载 作者:Grey 原文地址: 博客园:Linux 下模拟制作块设备并挂载 CSDN:Linux 下模拟制作块设备并挂载 环境 CentOS-7 下载地址:下载 Cen ...

随机推荐

  1. Java集合ArrayList源码解读

    最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见.  :) 内部原理 ArrayList 的3个字段 priva ...

  2. TypeScript设计模式之解释器

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...

  3. mac下常用软件整理

    1.非常好用的压缩管理软件(免费版):RAR Extrator Free  解压的中文不会产生乱码: 2.记笔记用的:有道笔记.Evernote 3.SVN管理软件:ConerStone 4.非常给力 ...

  4. struct和typedef struct在c++中的用法

    #include<iostream> using namespace std; struct test{ int a; }test; //定义了结构体类型test,声明变量时候直接test ...

  5. SSH相关小应用

    1.隐藏值:<s:hidden name="bbsTopic.id" value="%{bbsTopic.id}"></s:hidden> ...

  6. (转)开源分布式搜索平台ELK(Elasticsearch+Logstash+Kibana)入门学习资源索引

    Github, Soundcloud, FogCreek, Stackoverflow, Foursquare,等公司通过elasticsearch提供搜索或大规模日志分析可视化等服务.博主近4个月搜 ...

  7. JIRA6.36-7.23数据迁移文档

    JIRA6.3.6-JIRA7.2.3数据迁移文档 安装JIRA7.2.3 安装包位于服务器/opt/SOFTWARE_PACKAGE目录下 建立JIRA安装的目录数据目录 cd /opt mkdir ...

  8. 运用google-protobuf的IM消息应用开发(前端篇)

    前言: 公司原本使用了第三方提供的IM消息系统,随着业务发展需要,三方的服务有限,并且出现问题也很难处理和排查,所以这次新版本迭代,我们的server同事呕心沥血做了一个新的IM消息系统,我们也因此配 ...

  9. Android之利用正则表达式校验邮箱、手机号、密码、身份证号码等

    概述 现在Android应用在注册的时候基本会校验邮箱.手机号.密码.身份证号码其中一项或多项,特此收集了相关的正则表达式给大家分享.除了正则表达式,文章末尾提供Demo中有惊喜哦! 具体验证的图片效 ...

  10. Hexo + Github Pages 搭建个人博客

    之前一直想搭建自己的博客,由于自己的懒惰拖到现在.好了,废话不多说!直接上干货! 安装Node.js 安装Git Github Pages配置 安装Hexo及主题设置 进阶篇-高级定制 其它实用功能 ...