x86架构——常用的IO端口

来源:互联网 发布:java replace first 编辑:程序博客网 时间:2024/06/05 17:25

IO就是Input/Output,顾名思义就是CPU与外设之间的访问。

x86架构中有两种类型的IO,一种是Memory-mapped IO,另一种是Port-mapped IO。

关于这两种IO的介绍,可以参考wiki。

也可以參考http://bochs.sourceforge.net/techspec/PORTS.LST,裏面有比較全面的IO端口介紹。

对于MMIO,其实就是给定一个定制,这个地址可以对应到实际的物理内存,也可以是外设。这种方式使用的地址跟一般的内存访问地址无异,访问方式也一致。它不是这里讨论的重点。

这里需要讨论的是PMIO(一般说道IO端口就是指这种访问方式需要使用的地址)。

要进行PMIO,下面简称IO了,需要使用特定的CPU指令,简单来说就是两条,in和out。(当然这个也跟使用的汇编有关,有的还有inb,inw等按字节区分的)


如何使用IO端口

前面已经讲了,就是使用汇编指令,这里以Intel汇编指令为介绍对象,所以就是in和out指令。

关于这两条指令的使用方式,可以参考 asm基础——汇编指令之in/out指令

因为比较简单,所以也没有特别可以说的。


常用的IO端口

下面简单介绍一些常用的IO端口。

在http://www.os2site.com/sw/info/memory/ports.txt上也有介绍,可以参考。


0x80

这个是比较原始而常见的调试端口。

一般就是往里面丢一个字节,计算机启动的不同阶段丢不同的值,以确定当前的状态。

通常从80口丢出来的数据会反映到某个显示设备上,比如LED灯上,比如像下图这种的:


当计算机在某个阶段如果出现了异常时,就可以根据这个值来判断当前运行到哪个阶段才导致的异常。

大概是这样的,实际上我遇到过到80口的输出并没有到实际的设备上去了,一般都转到了串口或者BMC上,并没有实际的设备可以查看。


0x3F8

这个是最常用的串口输出IO口。

其它的串口输出口还有0x2F8等。

不过这只是串口需要用到的基地址,这之后的几个IO地址也是给串口用的,下面的宏就是在0x3F8(或者0x2F8等)基地址之上的偏移说明:

//---------------------------------------------// UART Register Offsets//---------------------------------------------#define BAUD_LOW_OFFSET         0x00#define BAUD_HIGH_OFFSET        0x01#define IER_OFFSET              0x01#define LCR_SHADOW_OFFSET       0x01#define FCR_SHADOW_OFFSET       0x02#define IR_CONTROL_OFFSET       0x02#define FCR_OFFSET              0x02#define EIR_OFFSET              0x02#define BSR_OFFSET              0x03#define LCR_OFFSET              0x03#define MCR_OFFSET              0x04#define LSR_OFFSET              0x05#define MSR_OFFSET              0x06
不同的偏移地址有不同的作用,比如配置波特率等、查看串口状态等。


0x2E/0x2F

这只成对出现的IO端口。

它用于Super IO模块的配置。另外的0x4E/0x4F也可以给Super IO用。

与前面提到的串口用IO口不同,Super IO只占据两个IO地址,但是它内部还是有很多不同用途的寄存器的,要访问那些寄存器,就需要使用0x2E/0x2F这样的IO端口。

这样的端口也被称为Index/Data端口。

比如我们要访问Super IO内不能偏移是0x30的寄存器,那么需要将0x30写到0x2E这个IO端口中,然后再读或者写0x2F端口来得到或者改写Super IO内存0x30寄存器的值。

这样的使用手法在x80的IO端口中是很常见的,算是为了节约IO地址空间吧。


0x70/0x71

也是成对出现的Index/Data形式的IO端口。

它是用来访问CMOS的。

另外还有一对访问Extend CMOS的,是0x72/0x73。

对于CMOS的访问,大致是下面这样:

/**  Reads 8-bits of CMOS data.  Reads the 8-bits of CMOS data at the location specified by Index.  The 8-bit read value is returned.  @param  Index  The CMOS location to read.  @return The value read.**/UINT8EFIAPICmosRead8 (  IN      UINTN                     Index  ){  IoWrite8 (0x70, (UINT8) Index);  return IoRead8 (0x71);}/**  Writes 8-bits of CMOS data.  Writes 8-bits of CMOS data to the location specified by Index  with the value specified by Value and returns Value.  @param  Index  The CMOS location to write.  @param  Value  The value to write to CMOS.  @return The value written to CMOS.**/UINT8EFIAPICmosWrite8 (  IN      UINTN                     Index,  IN      UINT8                     Value  ){  IoWrite8 (0x70, (UINT8) Index);  IoWrite8 (0x71, Value);  return Value;}

to be continued...


原创粉丝点击