24小时学通Linux内核之如何处理输入输出操作

Stella981
• 阅读 594

    Linux内核是如何将软硬件结合起来的呢?这里我们将一起探究内核与周围硬件主要是文件IO和硬件设备之间的关系,来解释这个问题。处理器与周围设备的通信依赖于一系列的电路电线,总线就是具有类似功能的电线,设备与处理器通信主要是通过地址总线,数据总线,控制总线来实现,这里在学习单片机原理的时候也提到过,这里对系统的基本结构就不多说了,觉得更新快,不好讲解,也没什么好总结的,大家看看相关书籍就行。

    了解到设备可以当做文件系统中的文件来处理,其细节都可隐藏在内核中,而对应用程序员透明,当进程对设备文件应用某一系统调用的时候,只要将这一系统调用转换成某种设备函数就足够了,其中设备驱动程序定义了这些函数,接下来看看这些设备类型。其中应用层,文件系统层,通用块设备层和设备驱动程序之间的关系如下图,这里贴出来供大家了解一下。读写块设备如下:

24小时学通Linux内核之如何处理输入输出操作

    先介绍块设备,设备驱动在驱动程序初始化时为自己注册,将这个驱动程序加入内核的驱动程序表中,并将设备号映射到数据结构block_device_operations中,数据结构block_device_operations包含了系统中启动和停止给设定块设备的函数(在include/linux/fs.h上。

struct block_operations{

    从处理器的角度来看,在适合的cidao4上定位磁头并将磁盘转到相应的块要花费相当长的时间,这种延迟迫使内核实现了系统请求队列,在Linux2.6中,每个块设备都有自己的请求队列,以便管理对该设备的IO口请求,进程只有在获得请求队列锁之后才能 更新设备的请求队列,让我们先来看看request_queue结构(这些代码都是自己敲出来的,然后分析,分析不好的请各位大神批评改正。)这些代码都可以在include/linux/blkdev.h中查看。

struct request_queue

标志名称

功能

QUEUE_FLAG_CLUSTER

将介几个段合成一个 

QUEUE_FLAG_QUEUED

使用通用标志队列

QUEUE_FLAG_STOPPED

队列被停止

QUEUE_FLAG_READFULL

读队列已经满了

QUEUE_FLAG_WRITEFULL

写队列已经满了

QUEUE_FLAG_DEAD

队列被撤销

QUEUE_FLAG_REENTER

避免重入

QUEUE_FLAG_PLUGGED

插入队列

spinlock_t *queue_lock;

    Linux内核通过在设备的_init函数中调用下列函数来初始化块设备的请求队列,这些函数中,,可以看出请求对了内部的细节和相关帮助教程,在现在的Linux2.6内核中,每个块设备控制自己的锁,并且将自旋锁作为第二个参数来传递,其中第一个参数是块设备驱动程序提供的请求函数,下面的代码在drivers/block/11_rw_blk.c中查看得到。

request_queue_t *blk_init_queue(request_fn_proc *rfn,spinlock_t *lock)

    代码实在太难,我知道的也只是皮毛,那些都需要好好体会,如若有补充的希望各路大神能够多加改正我的缺点,现在来看看设备操作,基本 的通用块设备有open,close,ioctl以及request函数,请求队列不能直接被访问,但是可以通过一组帮助例程来访问,如下:

struct request *elv_next_request(request_queue_t *q)

    这个帮助函数返回并指向下一个请求结构的指针,驱动程序可以通过查看该元素来收集所有信息,以确定它的的大小方向以及该请求相关的任何其他自定义操作,之后通过end_request()想内核报告这一信息:

void end_request(struct request *req,int uptodate)  //在请求队列中传递elev_next_request()获得的参数

    下面来介绍一下其它各种设备,与块设备不同,字符设备用来传送数据流,所有串行设备都是字符设备,与字符设备类似,网络设备的数据在物理层上串行传输,而时钟设备是基于硬件脉搏跳动的设备,其实就是时钟相关的,还有那终端设备,这里就稍微提及一下。因为这些都和输入输出相关,大家只要有个印象就行了。

小结

    结束了分析代码之旅,小结一下今天主要的内容,今天主要分享的是Linux内核是如何处理输入输出操作的,具体讨论了Linux是如何表示块设备和它的接口的,也介绍了Linux调度程序并且重点分析了请求队列,上述敲的代码,我也还有好多不懂,只能自己慢慢去体会了,希望各路大神看了之后能够稍加提醒一下,哎,反正这个寒假没啥事了,就一直和内核作伴吧,这些写的不好,以后继续努力,fighting~

特别声明:

    版权所有,转载请注明转载地址:        

http://www.cnblogs.com/lihuidashen/p/4244330.html

    我们不再是我们,我们仍然是我们......

推荐阅读

(点击标题可跳转阅读)

24小时学通Linux内核--内核探索工具类

24小时学通Linux内核之进程

24小时学通Linux内核之内存管理方式

关注公众号【技术让梦想更伟大】,获取更多Linux/C/C++/Python/FPGA等原创技术文章。后台免费获取经典电子书籍和视频资源,实时更新,原创不易,请多支持,谢谢!

24小时学通Linux内核之如何处理输入输出操作

本文分享自微信公众号 - 技术让梦想更伟大(gh_f7effb2fbc1c)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android起步
AndroidSQLite http://facebook.github.io/stethoAndroid系统架构Android大致可以分为四层架构,五块区域。1\.Linux内核层Android系统是基于Linux2.6内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动
Stella981 Stella981
3年前
Linux下PCI设备驱动程序开发
PCI是一种广泛采用的总线标准,它提供了许多优于其它总线标准(如EISA)的新特性,目前已经成为计算机系统中应用最为广泛,并且最为通用的总线标准。Linux的内核能较好地支持PCI总线,本文以Intel386体系结构为主,探讨了在Linux下开发PCI设备驱动程序的基本框架。一、PCI总线系统体系结构PCI是外围设备互连(PeripheralC
Wesley13 Wesley13
3年前
20179311《网络攻防实践》第七周作业
1.Windows操作系统的基本结构分为运行于处理器特权模式的操作系统内核,以及运行在处理器非特权模式的用户空间代码。采用宏内核模式来进行构架,这使得任意的内核模块或设备驱动程序都可能破坏其他内核模块数据,这种宏内核机制也使得Windows操作系统容易遭受以驱动方式植入内核的Rootkit的危害,为了避免这类攻击,最
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这