I/O端口

每个连接到I/O总线上的设备都有自己的I/O地址集,即所谓的I/O端口(I/O port)。在IBM PC体系结构中,I/O地址空间一共提供了65,5368位的I/O端口。可以把两个连续的8位端口看成一个16位端口,但是这必须是从偶数地址开始。同理,也可以把两个连续的16位端口看成一个32位端口,但是这必须是从4的整数地址开始。有四条专用的汇编语言指令可以允许CPUI/O端口进行读写:它们分别是ininsoutouts。在执行其中的一条指令时,CPU使用地址总线选择所请求的I/O端口,使用数据总线在CPU寄存器和端口之间传送数据。

I/O端口还可以被映射到物理地址空间:因此,处理器和I/O设备之间的通信就可以直接使用对内存进行操作的汇编语言指令(例如,movandor等等)。现代的硬件设备更倾向于映射I/O,因为这样处理的速度较快,并可以和DMA结合起来使用。

系统设计者的主要目的是提供对I/O编程的统一方法,但又不牺牲性能。为了达到这个目的,每个设备的I/O 端口都被组织成一组专用寄存器。CPU把要发给设备的命令写入控制寄存器(control register),并从状态寄存器(status register)中读出表示设备内部状态的值。CPU还可以通过读取输入寄存器(input register)的内容从设备取得数据,也可以通过向输出寄存器(output register)中写入字节而把数据输出到设备。

为了降低成本,通常把同一I/O端口用于不同目的。例如,某些位描述设备的状态,而其他位指定发布给设备的命令。同理,也可以把同一I/O端口用作输入寄存器或输出寄存器。

    那么如何访问I/O端口? inoutinsouts汇编语言指令都可以访问I/O端口。Linux内核中定义了以下辅助函数来简化这种访问:

·      inb( )inw( )inl( )函数

分别从I/O端口读取124个连续字节。后缀“b”、“w”、“l”分别代表一个字       节(8位)、一个字(16位)以及一个长整型(32位)。

·      inb_p( )inw_p( )inl_p( )

分别从I/O端口读取124个连续字节,然后执行一条“哑元(dummy,即空指令)”指令使CPU暂停。

·      outb( )outw( )outl( )

    分别向一个I/O端口写入124个连续字节。

·      outb_p( )outw_p( )outl_p( )

分别向一个I/O端口写入124个连续字节,然后执行一条“哑元”指令使CPU暂停。

·      insb( )insw( )insl( )

分别从I/O端口读入以124个字节为一组的连续字节序列。字节序列的长度由该函数的参数给出。

·      outsb( )outsw( )outsl( )

    分别向I/O端口写入以124个字节为一组的连续字节序列。

    虽然访问I/O端口非常简单,但是检测哪些I/O端口已经分配给I/O设备可能就不这么简单,特别是对基于ISA总线的系统来说更是如此。通常,I/O设备驱动程序为了侦探硬件设备,需要盲目地向某一I/O端口写入数据;但是,如果其他硬件设备已经使用这个端口,那么系统就会崩溃。为了防止这种情况的发生,内核必须使用iotable表来记录分配给每个硬件设备的I/O端口。任何设备驱动程序都可以使用下面三个函数:

request_region( )

把一个给定区间的I/O端口分配给一个I/O设备。

check_region( )

检查一个给定区间的I/O端口是否空闲,或者其中一些是否已经分配给某个I/O设备。

release_region( )

释放以前分配给一个I/O设备的给定区间的I/O端口。

当前分配给I/O设备的I/O地址可以从/proc/ioports文件中获得。

几乎每一种外设都是通过读写设备上的寄存器来进行操作的。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。CPU对外设IO端口物理地址的编址方式有两种:一种是I/O映射方式(I/O-mapped),另一种是内存映射方式(Memory-mapped)。具体采用哪一种则取决于CPU的体系结构。

  有些体系结构的CPU(如PowerPC、m68k等)通常只实现一个物理地址空间(RAM)。在这种情况下,外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中,而成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。这就是所谓的“内存映射方式”(Memory-mapped)。主要缺点是是存储器空间变小.

  而另外一些体系结构的CPU(如X86)则为外设专门实现了一个单独地地址空间,称为“I/O地址空间”或者“I/O端口空间”。这是一个与CPU的RAM物理地址空间不同的地址空间,所有外设的I/O端口均在这一空间中进行编址。CPU通过设立专门I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元(也即I/O端口)。这就是所谓的“I/O映射方式”(I/O-mapped)。与RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是“I/O映射方式”的一个主要缺点。

         在张凡的<微机原理与接口技术>一书中提到的I/O端口的两种编址方式:(1)I/O与存储器统一编址(如单片机);(2)单独编址(X86系统).这和上述的内存映射方式,I/O映射方式分别对应.
        我的理解是:寄存器就是I/O端口;而采用内存映射方式的I/O是存储器的一个子集,采用I/O单独映射方式的I/O是和存储器平级的存储空间.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值