查缺补漏----程序查询,中断,DMA方式(结合设备驱动程序)

本篇主要讲设备驱动程序和中断处理程序的关系,以及具体中断处理流程。主要针对下面这道题:

​​

1.中断方式实现sys_write

用户层软件包括库函数,系统调用以及Spooling系统。

对于库函数和系统调用,以执行printf函数为例,梳理一下流程:

 1.

执行printf函数,其对应的库函数中封装的系统调用命令就是write命令,操作系统实际是调用write命令,完成printf操作。

注:库函数中可能封装一个或多个不同的系统调用命令。

答案:A

2.

write函数展开成一段包含“int 0x80的核心代码”,进入内核态执行。int 0x80就是一条陷入指令,将系统由用户态转为内核态。本质是通过中断实现的(包括了中断响应以及中断服务的过程)

如下图所示,在int 0x80之前,系统处于用户态,用户态主要完成的工作就是传递参数。int 0x80之后,转为内核态。

例题:

答案:C

I,IV(从用户态到内核态)是在中断响应阶段由中断隐指令完成的,也就是由硬件完成,II,III是由操作系统完成的。

答案B

3.sys_write有3种不同的实现方式,也就是我们所学的三种中断方式程序查询,中断,DMA方式。

1.轮询方式

I/O设备(包括设备控制器)将自己的状态放到状态寄存器中

OS阶段性地查询状态寄存器中的特定状态,以决定下一步动作。如:未“就绪”时,则一直“等待。

因为系统调用write处于内核态,系统首先会将用户缓冲区的内容复制到内核缓冲区,保证数据的一致性和安全性(原因下面会讲)。因为没有发生过进程切换,只是从用户态转为内核态,所以这一步直接访问内存即可。

接着系统会不断轮询,直到显示器状态为就绪,就输出一个字符,接着继续轮询。

如何判断就绪,就是读取状态寄存器(通过读取状态寄存器可以获取外设或I/O控制器的状态信息),判断特定的位, 就绪为1,未就绪为0,如果未就绪就一直读状态寄存器,这就是等待。

注:I/O控制器中,CPU能够访问的各类寄存器称为I/O端口,CPU通过I/O端口发命令,读写数据。中间涉及设备驱动程序,设备驱动程序负责具体实现系统对设备发出的操作指令,驱动 I/O设备工作的驱动程序。上面的轮询以及字符串的输出都是设备驱动程序所做的。

总结下来,当用户态下输入printf时,系统会调用系统调用命令,从用户态转到内核态,sys_write通过使用设备驱动程序具体实现数据输出。

所以轮询方式下,CPU与外设是串行工作的。

2.中断方式

这个图在真题中有考过:

由于程序P被阻塞,CPU调度其他进程Q执行,CPU执行Q程序的同时,外设也在并行工作。

当外设准备好时,便向CPU发中断请求,CPU响应后(图中黑色划线部分),中止现行程序的执行,转入“中断服务程序”,进行输入/出操作,以实现主机和外设接口之间的数据传送,并启动外设工作。“中断服务程序”执行完后,返回原被中止的程序断点处继续执行。此时,外设和CPU并行工作。

采用中断方式的具体流程:

第一步和轮询方式相同,系统会通过访存的方式,将printf输入的字符串从用户缓冲区复制到内核缓冲区,接着会进行开中断(在系统调用进入内核态的时候,进行了关中断,所以此时有对应的开中断)。

可以看到,向数据端口输出一个字符后,并不会向程序查询方式那样通过while轮询。中断方式下,仅仅是把第一个字符放入数据寄存器中,然后就不管了,至于这个字符何时打印出来,以及剩余的字符如何打印出来,就不是系统调用函数的任务了。而是中断服务程序的任务,当显示器完成了一个字符的输出之后,外设向CPU发出中断请求,调出相应的中断服务程序。

中断处理程序如下:

所以除了第一个字符是系统调用程序输出的,其他字符都是用中断服务程序输出的。

总结一下:

中断方式下完成数据输出是由两部分完成的,一个是系统调用,一个是中断服务程序。

例如上面的例子的数据输出,就是通过sys_write和中断服务程序共同完成的。

sys_write是如何调出来的?系统调用
中断服务程序是如何调出来的?外设完成任务,像CPU发出中断请求

完整捋一下:

① 执行printf("Hello,world")时,用户进程A执行write,触发系统调用,进入内核态。
② 把第一个字符“H”送到显示器的设备控制器。控制器命令显示器输出这个字符,与此同时,进程A被阻塞,调度另一个进程B执行。

③ 当“H”输出之后,控制器发出一个中断给CPU(此时CPU在执行程序B),并跳转到相应的中断处理程序,在中断处理程序中,进行后续的字符输出。

CPU是在执行B程序时,转入中断处理程序的,也就是在B的运行环境中,执行完成剩余字符的输出。A的任务由别的进程完成。 

注意事项:

① 设备驱动程序在哪里出现?

进程A通过系统调用进入内核态,内核态下,系统会调用驱动程序完成相关工作。进程A阻塞,CPU切换到进程B执行,直到外设完成工作,发出中断请求,CPU在进程B中转入中断处理程序,完成后续字符的输出,数据输出完成后,中断返回。

② 设备驱动程序和中断处理程序全部在同一个进程中运行的吗?

设备驱动程序一定有一部分是在发起系统调用的进程A当中执行的(例如将字符串复制到内核缓冲区,以及输出第1个字符),而中断处理程序则一定不是在进程A中执行,取决于CPU响应中断时正在执行哪个进程。

所以,执行设备驱动程序是在中断处理程序之前的。

答案:B

③ 如果buffer不复制到内核缓冲区,直接使用用户缓冲区会发生什么问题?

如图所示,A,B进程有各自的用户空间,并且都会映射到同一片内核空间。

进程A执行printf操作,进程A的页表中就有字符串buf的内容,发生进程切换之后,页表中的内容会变成B的内容。

中断服务程序运行时,是在进程B的资源平台上,进程B的页表与进程A的页表是不同的,而用户缓冲区buf是进程A中的地址,它不能用进程B的页表页表来进行地址映射。而内核缓冲区中的数据,无论是进程A还是进程B,它们的内核地址空间中的内容都是相同的,因此能顺利的访问。

中断服务程序与设备驱动程序的关系:

区分不同中断的只有终端中断处理程序,其他中断过程是一样的。1,2,3,5,6被称为中断总控程序。中断总控程序会调用具体的设备驱动程序完成具体的中断处理过程。

 

所以,如果题目当中同时出现了中断服务程序和设备驱动程序,那么这里的中断服务程序应理解为中断总控程序。如果题目当中只有中断服务程序,那么一般情况下,此时中断服务程序应该理解1,2,3,4,5,6整个过程。

机组中讲的中断服务程序,包括了设备驱动程序处理的过程。而在操作系统中,则是将设备驱动程序,即由设备驱动程序负责具体实现系统对设备发出的操作指令。

3.DMA方式

执行printf函数,系统调用命令如下:

例题:

A

B

2.中断方式实现sys_read

用上面学的中断处理过程,捋一下scanf操作的中断流程。对于printf,是通过write系统调用完成数据输出。对于scanf,是通过read系统调用完成数据输入。

用户进程A执行了scanf函数,然后进入系统调用,然后到标准接口read函数,然后再到驱动程序foo_read函数,这些都是普通的函数调用,都是在进程A的资源平台上运行的。接下来,在foo_read函数中,在使用outb指令启动了这次I/O操作后,进程A就会被阻塞起来。然后进行进程切
换,调度另一个进程B去运行。当B在运行时,如果I/O操作完成(也就是我们按下键盘,进行数据输入),就会发生一次中断,把进程B打断,并跳转到中断处理程序foo_interruptible去执行,然后在这里唤醒进程A。

对于sys_read函数执行结果:

scanf输入的字符串,会被放到内核缓冲区,如果内核缓冲区为空,那么进程就会阻塞等待。如果内核缓冲区不空,就会从内核缓冲区取字符,并放到用户缓冲区中。

 

中断过程如下,当我们按下键盘,当前运行的进程被中断,CPU会转入中断处理程序,将设备控制器中的数据(键盘输入的数据)读 出,送到内核缓冲区。

从设备控制器中读出数据,将取出的数据送到内核缓冲区这两个与硬件直接交互的操作肯定都是由设备驱动程序完成的。

设备控制器---->内核缓冲区---->用户缓冲区

所以,将取出字符送入内核缓冲区是由设备驱动程序完成的,而内核缓存区的数据如何送到用户缓冲区:假如是p进程发起scanf命令,那么就由p进程完成。

例题:

1.

答案:C

2.

(1)② ⑥ ④ ③ ① (选中P执行,它会将内核缓冲区的内容读到用户缓冲区,取完数据后,才会从系统调用返回 )⑤ 

(2) ② ①

(3)③ (当驱动程序和中断处理程序同时出现,要将这里的中断处理程序看作中断总控程序,所以不是④)

(4)阻塞态,CPU处于内核态(从用户态到内核态是中断响应阶段完成的,即用中断隐指令完成的,也就是用硬件完成的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值