14.5 保护模式I/O

翻译自《Intel®64和IA-32架构软件开发者指南》卷一。


当处理器运行在保护模式,以下保护机制控制对I/O端口的访问:

    ·  通过I/O寻址空间访问I/O端口时,两种保护设施会控制访问:

        — EFLAGS寄存器中的I/O特权级(IOPL)位域

        — 任务状态段(TSS)中的I/O允许位图

    ·  在访问内存映射的I/O端口时,一般的分段和分页基址还有MTRR(在支持它们的处理器上)会影响对I/O端口的访问。对内存的保护的完整的讨论,请见《Intel®64和IA-32架构软件开发者指南》卷3A的第5章《保护》和第11章《内存缓存控制》。

以下章节描述用I/O指令访问I/O寻址空间中的I/O端口时可用的保护机制。

14.5.1  I/O特权级

在使用I/O保护机制的系统中,EFLAGS寄存器中的IOPL位域通过限制特定指令的使用来控制对I/O寻址空间的访问。这种保护机制允许操作系统或其他系统软件来设置执行I/O所需的特权级。在典型的保护环模型中,对I/O寻址空间的访问被限制在特权级0和1。这里,内核和设备驱动允许执行I/O,而更次特权级的设备驱动和应用程序则被拒绝访问I/O寻址空间。应用程序必须用系统调用来执行I/O。

以下指令只能在当前执行的程序或任务的当前特权级(CPL)小于等于IOPL时执行:IN、INS、OUT、OUTS、CLI(中断允许标志清0)和STI(中断允许标志设1)。可称这些指令为I/O敏感的指令,因为它们对IOPL敏感。更次特权级的程序或任务的任何使用I/O敏感指令的意图都将导致一般保护异常(#GP)。因为每个任务都有其自己的EFLAGS的值,每个任务可拥有不同的IOPL。

TSS中的I/O允许位图可用来改变IOPL对I/O敏感指令的影响,允许更次特权级的程序或任务访问某些I/O端口(请见章节14.5.2《I/O允许位图》)。

程序或任务只能通过POPF或IRET指令来改变其IOPL,但这样的改变是需要特权的。任何不运行在特权级0的程序都不能修改其IOPL。更次特权级的程序修改IOPL的意图不会导致异常;只是IOPL会保持不变。

除了CLI和STI指令,POPF指令也可能用来改变IF标志位的状态;但是这样的POPF指令也是I/O敏感的。只有CPL小于等于当前IOPL的程序可以用POPF来改变IF标志位。更次特权级的程序修改IF标志位的意图不会导致异常;只是IF标志位会保持不变。

14.5.2  I/O允许位图

I/O允许位图是允许更次特权级的程序或任务或者运行在虚拟8086模式中的任务对I/O端口进行有限访问的设施。I/O允许位图位于当前程序或任务的TSS中(见图14-2)。I/O允许位图的首地址由TSS的I/O允许位图基础地址位域给出。TSS中I/O允许位图的大小和位置是可变的。

14.5 保护模式I/O_第1张图片

图14-2、I/O允许位图

因为每个任务都有其自己的TSS,每个任务有其自己的I/O允许位图。对每个I/O端口的访问可以根据每个任务单独考虑。

如果保护模式中CPL小于等于当前IOPL,处理器允许所有I/O操作。如果CPL大于IOPL或者处理器处于虚拟8086模式,处理器检查I/O允许位图来检查对特定I/O端口的访问是否可被允许。位图中的每一位对应一个I/O端口字节地址。例如,I/O寻址空间中地址为29h的I/O端口的控制位是I/O允许位图第6字节的位1。在允许I/O访问前,处理器会测试所有寻址到的I/O端口的控制位。例如对于一个双字(doubleword)访问,处理器会测试对应4个8位端口地址的4个控制位。如果任一被测试的位被设1,会产生一般保护异常(#GP)。如果所有被测试的位都被清0,则允许I/O操作。

因为I/O端口地址不必要对齐到字(word)或双字(doubleword)边界,对于每次I/O端口访问,处理器会从I/O允许位图读取两个字节。为了防止访问最高的I/O端口地址时产生异常,一个额外的字节必须紧跟在I/O允许位图之后并包含在TSS中。这个字节的所有位都必须为1(0FFh),并且必须不超过TSS的段界限。

I/O允许位图不需要包含所有I/O地址。I/O允许位图不包含的I/O地址会被视同I/O允许位图中的全设1的字节而被禁止访问。例如,如果TSS的段界限是位图基础地址后10字节,从而I/O允许位图有11字节且映射前80个I/O端口,访问I/O寻址空间中地址高于80的I/O端口会产生异常。

如果I/O允许位图的基础地址大于等于TSS的段界限,则认为没有I/O允许位图,在CPL大于当前IOPL时所有I/O指令都会产生异常。

你可能感兴趣的:(操作系统)