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. 详解< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />

    < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" /> 这是个是 ...

  2. struct和typedef struct在c语言中的用法

    在c语言中,定义一个结构体要用typedef ,例如下面的示例代码,Stack sq:中的Stack就是struct Stack的别名. 如果没有用到typedef,例如定义 struct test1 ...

  3. MySQL入门(上)

    1 课程回顾 自定义标签&编码实战 1)自定义标签步骤: 1.1 编写标签处理器类,继承SimpleTagSupport类,覆盖doTag方法 1.2 在WEB-INF目录下建立tld文件,在 ...

  4. Power BI Embedded 与 Bot Framework 结合的AI解决方案

    最近最热门的话题莫过于AI了,之前我做过一片讲 BOTFRAMEWORK和微信 相结合的帖子 如何将 Microsoft Bot Framework 链接至微信公共号 我想今天基于这个题目扩展一下,P ...

  5. 前端开发必备组件库【基于原生js、兼容主流浏览器、B/S必备】

    [持续更新中...跪求点击右上角星星,好人一生平安!] API详见github,链接如下: https://github.com/pomelott/pomelo-plug-in

  6. apache 配置多个版本的 php

    注:这里说的是windows环境下的配置 我们在配置apache+php的时候,是在apache的配置文件httpd.conf里加载php的模块并指定php.ini路径 LoadModule php5 ...

  7. java学习笔记 --- 方法

    一.方法  (1)方法:就是完成特定功能的代码块.   注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法.  (2)格式:   修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 ...

  8. redux核心思路和代码解析

    最近在公司内部培训的时候,发现很多小伙伴只是会用redux.react-redux.redux-thunk的api,对于其中的实现原理和数据真正的流向不是特别的清楚,知其然,也要知其所以然,其实red ...

  9. centos6.5用tomcat安装jenkins

    1下载jdk并安装配置环境变量 # cd /opt/app # .0_45.tar.gz # vi /etc/profile JAVA_HOME=/opt/app/jdk1..0_45 CLASSPA ...

  10. Struts2.5简单使用入门

    今天学了Struts2.5最新版的,老师在黑板上讲的很是简单,也很是容易,简单的就实现了.可是课下让我们自己弄,自己无论如何都无法运行成功,一直提示404.偶然间灵机一动,改了一下那个文件就好了.希望 ...