====================================================================
本文用于汇总整理Intel80386的I/O系统相关知识,
参考文献:
- 《INTEL 80386 programmer's reference manual 1986》
本文是系列文章《Intel80386知识总结》的一部分。
===================================================================
1. I/O寻址模式
i386支持两种I/O寻址模式:
- 使用单独的I/O地址空间,单独的I/O指令
- 使用I/O内存映射,使用通用操作数操作指令
1.1 使用单独的I/O地址空间
单独的I/O地址空间被称为I/O端口,共计64K个8位端口,可以合并为32K个16位端口或16K个32位端口使用。这些端口可以供最多16个外部设备使用。访问I/O端口的方式有两种:
- 使用DX(16位)中的值:8-bit ports numbered 0 through 65535;16-bit ports numbered 0, 2, 4, . . . , 65532, 65534;32-bit ports numbered 0, 4, 8, . . . , 65528, 65532
- 使用1byte常量:256 8-bit ports numbered 0 through 255;128 16-bit ports numbered 0, 2, 4, . . . , 252, 254;64 32-bit ports numbered 0, 4, 8, . . . , 248, 252.
i386可以一次性向指定的I/O端口发送32位/16位/8位的数据,要求32位数据对齐4的倍数地址,16位数据对齐2的倍数地址,8位数据可以放在任意地址。
1.2 使用I/O内存地址映射
I/O设备也可以直接放在内存地址空间中,如下图所示:
2. I/O保护机制
在实模式中没有任何I/O保护机制,所有任务都可以执行I/O指令,I/O指令可以访问任意I/O端口。在保护模式下,提供两个I/O保护机制:
- EFLAGS寄存器中的IO Privilege Level(IOPL)字段
- TSS中的I/O Permission Bit Map
2.1 EFLAGS寄存器中的IOPL字段
IOPL长度2位,只有当CPL不大于IOPL时,下列指令才能访问I/O(这些指令被称为I/O敏感指令):
- IN ── Input
- INS ── Input String
- OUT ── Output
- OUTS ── Output String
- CLI ── Clear Interrupt-Enable Flag
- STI ── Set Interrupt-Enable
2.2 TSS中的I/O Permission Bit Map
I/O Permission Bit Map由TSS中的I/O map base字段确定,I/O map base字段长度16位,给出I/O Permission Bit Map在TSS段内偏移。如下图所示:
I/O Permission Bit Map在IOPL检查失败的情况下使用,例如要访问I/O端口41,如果IOPL检查失败,则查看I/O map base+5 bit offset 1处的比特位是否为1,若为1,则可以访问,否则不可访问产生异常。I/O Permission Bit Map不必包括所有的I/O端口权限信息,例如,TSS LINIT = I/O map base+31,则只有前256个I/O端口在I/O Permission Bit Map中有显示权限定义,大于255的I/O端口都隐式的被声明为0。如果I/O map base大于等于TSS的LIMIT,则当前任务TSS没有I/O Permission Bit Map。