贵阳做网站,徐州市铜山区建设局网站,建设通网站是什么性质,百度一下你就知道官页用户程序可以在由操作系统加载时通过指定整个eflags设置#xff0c;操作系统如何设置自己的IOPL呢#xff0c;即使内核IOPL为0也得写进去eflags寄存器中才生效。可惜的是#xff0c;没有直接读写eflags寄存器的指令#xff0c;不过可以通过将栈中数据弹出到eflags寄存器中来…用户程序可以在由操作系统加载时通过指定整个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 mapmap就是映射建立的是某种对应关系像地图那样图上某个区域代表实际地理范围bit就是位bit map就是用一个bit映射到某个实际的对象。位图这种结构的操作单位就是bit所以位图其实就是一串二进制01数字对位图的操作也就是读写相应的位处理器中对内存的访问是以字节为单位不能直接操作位所以对于操作位图简单说来就是先将该位所在的字节读到内存若是想将该位置为1可以用1对该位进行或’运算若想将该位清0可以用0对该位进行’与’运算以后咱们少不了操作位图到时候再实践。
intel处理器最大支持65536个端口它允许任务通过I/O位图来开启特定端口位图中的每一bit代表相应的端口比如第0个bit表示第0个端口第65535个bit表示第65535个端口65536个端口号占用的位图大小是63356/88192字节即8KB。I/O位图中如果相应bit被置为0表示相应端口可以访问否则为1的话表示该端口禁止访问。如图 再次声明I/O位图只是在数值上CPL IOPL即当前特权级比IOPL低时才有效若当前特权级大于等于IOPL任何端口都可直接访问不受限制。