加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux系统对IO端口和IO内存的管理

发布时间:2016-10-22 05:51:22 所属栏目:Linux 来源:网络整理
导读:一、I/O端口 端口(port)是接口电路中能被CPU直接访问的寄存器的地址。几乎每一种外设都是通过读写设备上的寄存器来进行的。CPU通过这些地址即端口向接口电路

下面具体看一下ioport_map和ioport_umap的源码:

void __iomem *ioport_map(unsigned long port, unsigned int nr)  
{  
    if (port > PIO_MASK)  
        return NULL;  
    return (void __iomem *) (unsigned long) (port + PIO_OFFSET);  
}  
      
void ioport_unmap(void __iomem *addr)  
{  
    /* Nothing to do */  
}

ioport_map仅仅是将port加上PIO_OFFSET(64k),而ioport_unmap则什么都不做。这样portio的64k空间就被映射到虚拟地址的64k~128k之间,而ioremap返回的虚拟地址则肯定在3G之上。ioport_map函数的目的是试图提供与ioremap一致的虚拟地址空间。分析ioport_map()的源代码可发现,所谓的映射到内存空间行为实际上是给开发人员制造的一个“假象”,并没有映射到内核虚拟地址,仅仅是为了让工程师可使用统一的I/O内存访问接口ioread8/iowrite8(......)访问I/O端口。

最后来看一下ioread8的源码,其实现也就是对虚拟地址进行了判断,以区分IO端口和IO内存,然后分别使用inb/outb和readb/writeb来读写。

unsigned int fastcall ioread8(void __iomem *addr)  
{  
    IO_COND(addr, return inb(port), return readb(addr));  
}  
      
#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)  
#define IO_COND(addr, is_pio, is_mmio) do {  
    unsigned long port = (unsigned long __force)addr; 
        if (port < PIO_RESERVED) {  
            VERIFY_PIO(port);  
            port &= PIO_MASK;   
            is_pio;   
        } else {   
            is_mmio;   
        }   
} while (0)  
      
展开:  
unsigned int fastcall ioread8(void __iomem *addr)  
{  
    unsigned long port = (unsigned long __force)addr;  
    if( port < 0x40000UL ) {  
        BUG_ON( (port & ~PIO_MASK) != PIO_OFFSET );  
        port &= PIO_MASK;  
        return inb(port);  
    }else{  
        return readb(addr);  
    }  
}

七、总结

外设IO寄存器地址独立编址的CPU,这时应该称外设IO寄存器为IO端口,访问IO寄存器可通过ioport_map将其映射到虚拟地址空间,但实际上这是给开发人员制造的一个“假象”,并没有映射到内核虚拟地址,仅仅是为了可以使用和IO内存一样的接口访问IO寄存器;也可以直接使用in/out指令访问IO寄存器。

例如:Intel x86平台普通使用了名为内存映射(MMIO)的技术,该技术是PCI规范的一部分,IO设备端口被映射到内存空间,映射后,CPU访问IO端口就如同访 问内存一样。

外设IO寄存器地址统一编址的CPU,这时应该称外设IO寄存器为IO内存,访问IO寄存器可通过ioremap将其映射到虚拟地址空间,然后再使用read/write接口访问。

作者:csdn博客 ce123

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读