用户程序可以在由操作系统加载时通过指定整个eflags设置,操作系统如何设置自己的IOPL呢,即使内核IOPL为0也得写进去eflags寄存器中才生效。可惜的是,没有直接读写eflags寄存器的指令,不过可以通过将栈中数据弹出到eflags寄存器中来实现修改。可以先用pushf指令将eflags整体压入栈,然后在栈中修改相应位,再用popf指令弹出到eflags寄存器中。另外一个可利用栈的指令是iretd,用iretd指令从中断返回时,会将栈中相应位置的数据当成eflags的内容弹出到eflags寄存器中。所以可以改变IOPL的指令只有popf和iretd指令,依然是只有在0特权下才能执行。如果在其它特权级下执行此指令,处理器也不会引发异常,只是没任何反应。

接下来看看IO位图是怎么回事。

假如,数值上CPL <= IOPL,程序既可以执行IO特权指令,又可以操作所有的IO端口。倘若数值上CPL > IOPL,程序也不是完全无法进行任何IO操作,有点奇怪是不,似乎和咱们的逻辑不符,其实这样是有道理的。

之前说过,IOPL是所有IO端口的开关,不过,这个开关还留有余地,如果将开关打开,便可以访问全部65536个端口,如果开关被关上,即数值上CPL > IOPL,则可以通过IO位图来设置部分端口的访问权限。也就是说,先在整体上关闭,再从局部上打开。这有点像设置防火墙的规则,先默认为全部禁止访问,想放行哪些端口再单独打开。

处理器为什么允许这么做呢?原因是为了提速。

如果所有IO端口访问都要经过内核的话,由低特权级转向高特权级时是需要保存任务上下文环境的,这个过程也是要消耗处理器时间,随着端口访问多起来,时间成本还是很可观的。这一典型的应用就是硬件的驱动程序,它位于特权级1。

什么是驱动程序?

驱动程序就是通过in、out等IO指令直接访问硬件的程序,它为上层程序提供对硬件的控制访问,相当于硬件的代理,程序员通过它就免去了学习硬件控制的相关知识,简化了程序设计。

所以说,驱动程序肯定是要直接控制IO端口的,尽管它可以像linux那样位于0特权级,但它位于1特权级时,依然可以直接操作硬件端口。

即使是在3特权级下,也要考虑某些需要快速反应的场合,比如某个应用程序需要快速的以硬件交互,所以处理器允许通过I/O位图来为3特权级程序打开某些端口的控制。这些规则同样适用于2特权级,也就是说在任意特权级下,处理器都可以通过I/O位图为相应特权级的程序开启特定的端口。

欲知I/O位图是怎么回事,咱们先把位图的概念明确。

位图就是bit map,map就是映射,建立的是某种对应关系,像地图那样,图上某个区域代表实际地理范围,bit就是位,bit map就是用一个bit映射到某个实际的对象。位图这种结构的操作单位就是bit,所以位图其实就是一串二进制01数字,对位图的操作也就是读写相应的位,处理器中对内存的访问是以字节为单位,不能直接操作位,所以对于操作位图,简单说来就是先将该位所在的字节读到内存,若是想将该位置为1,可以用1对该位进行或’运算,若想将该位清0,可以用0对该位进行’与’运算,以后咱们少不了操作位图,到时候再实践。

intel处理器最大支持65536个端口,它允许任务通过I/O位图来开启特定端口,位图中的每一bit代表相应的端口,比如第0个bit表示第0个端口,第65535个bit表示第65535个端口,65536个端口号占用的位图大小是63356/8=8192字节,即8KB。I/O位图中如果相应bit被置为0,表示相应端口可以访问,否则为1的话,表示该端口禁止访问。如图

再次声明,I/O位图只是在数值上CPL > IOPL,即当前特权级比IOPL低时才有效,若当前特权级大于等于IOPL,任何端口都可直接访问不受限制。

一步步编写操作系统 60 cpu的IO特权级2 什么是驱动程序相关推荐

  1. 一步步编写操作系统 59 cpu的IO特权级1

    在保护模式下,处理器中的"阶级"不仅体现在数据和代码的访问,还体现在指令中. 一方面将指令分级的原因是,有些指令的执行对计算机有着严重的影响,它们只有在0特权级下被执行,因此被称为 ...

  2. 一步步编写操作系统 25 cpu的保护模式

    在保护模式下,我们将见到很多在实模式下没有的新概念,很多都是cpu硬件原生提供,并且要求的东西,也就是说按照cpu的设计,必须有这些东西cpu才能运行.咱们只要了解它们是什么并且怎么用就行了,不用深入 ...

  3. 一步步编写操作系统 15 CPU与外设通信——IO接口,下

    既然都说到IO接口了,不知道各位有没有疑问,cpu是怎样访问到IO接口呢?肯定得有个链路吧?什么?有隐约听到有同学开玩笑说:cpu用无线访问其它设备.哈哈,不知道各位听说过没有,无线的终端是有线.无论 ...

  4. 一步步编写操作系统 14 CPU与外设通信——IO接口 上

    介绍显卡之前,必须得和大家交待清楚,那么多的外部设备,cpu是如何与他们交流. 大家都学过微机接口技术吧?没学过也没关系,反正我也只是笼统地说说^_^,保证大家一定能看得懂. 按理说,如果硬件种类较少 ...

  5. 一步步编写操作系统 30 cpu的分支预测简介

    人在道路的分岔口时要预测哪条路能够到达目的地,面对众多选择时,计算机也一样要抉择,毕竟计算机的运行方式是以人的思路来设计的,计算机中的抉择其实就是人在抉择. cpu中的指令是在流水线上执行.分支预测, ...

  6. 一步步编写操作系统 29 cpu缓存简介

    缓存是20世纪最大的发明,其原理用一些存取速度较快的存储设备做为数据缓冲区,避免频繁访问速度较慢的低速存储设备,归根结底的原因是,低速存储设备是整个系统的瓶颈,缓存用来缓解"瓶颈设备&quo ...

  7. 一步步编写操作系统 31 cpu的分支预测 下

    让我们说说预测的算法吧. 对于无条件跳转,没啥可犹豫的,直接跳过去就是了.所谓的预测是针对有条件跳转来说的,因为不知道条件成不成立.最简单的统计是根据上一次跳转的结果来预测本次,如果上一次跳转啦,这一 ...

  8. 一步步编写操作系统 28 cpu乱序执行

    乱序执行(乱序执行译作异步执行更贴切),是指在cpu中运行的指令并不按照代码中的顺序执行,而是按照一定的策略打乱顺序执行,也许后面的指令先执行,当然,得保证指令之间不具备相关性. 举个简单的例子,比如 ...

  9. 一步步编写操作系统 10 cpu的实模式

    cpu的实模式 由于mbr在实模式下工作--什么?什么是实模式?这时候有同学打断了我.我心想,这下好办了--哈哈,没有啦,开个玩笑而已.我们这里所说的实模式其实就是8086 cpu的工作环境.工作方式 ...

最新文章

  1. DOM manipulation
  2. AndroidStudio创建jinLibs文件夹
  3. 前端学习(2165):vuecli3配置文件的修改和查看
  4. 小程序 | 微信小程序from报名表单提交至数据库(含js提交函数)
  5. ICCV2021 | 最新ICCV2021论文抢先看,附全部下载链接!ICCV2021下载
  6. python队列中替换某元素_如何打印队列中的元素(Python)
  7. java isdebugenabled_在log4j中,在记录之前检查isDebugEnabled是否可以提高性能?
  8. refprop物性库_Refprop9.1_Refprop(制冷剂物性查询软件)下载 v9.1免费版 附教程 - 121下载站...
  9. 网吧计费管理系统(武汉理工大学大一下实验(C语言版源码))
  10. SQLite在指定列后面插入字段_如何用SQL语句添加和修改字段?
  11. Pranava Pra 使用教程
  12. pmon下nandflash相关操作
  13. 如何修改Nintendo Switch Dock以获得更好的便携性
  14. 最窄770px最宽1024px的经典布局研究
  15. 全球范围内12个典型区域提取(total runoff)
  16. CSS预处理之less,sass
  17. java 面向对象经典例题——教师,学生,家长。教师布置作业给学生和家长。
  18. CyberLink PowerDVD 9 简体中文版+注册码下载
  19. SOA成功案例—中远集运全球EDI平台建设
  20. C语言编写一下棋程序,C语言编写的与电脑下棋程序代码

热门文章

  1. [Poi2011]Tree Rotations线段树合并
  2. mysql: 模糊查询 feild like keyword or feild like keyword , concat(feild1,feild2,feild3) like keyword...
  3. CSS实现不固定宽度和高度的自动居中
  4. @jsonignore的作用
  5. 数据结构四——散列表(上)
  6. 1115. Counting Nodes in a BST (30) 数据结构
  7. pat 1085 Perfect Sequence (25) 二分查找
  8. Java学习笔记5-2——多线程
  9. python计算数组元素的和_python中数组的运算
  10. linux下tar包安装sudo命令,ubuntu12.04LTS安装gv-412-Linux-x86.tar.gz方法