免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 662 | 回复: 0
打印 上一主题 下一主题

PCI驱动程序之与硬件通信 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-21 19:18 |只看该作者 |倒序浏览

                每种外设都通过读写寄存器进行控制。大部分外设都有几个寄存器,不管是在内存地址空间还是在I/O地址空间,这些寄存器的访问地址都是连续的。x86的处
理器为I/O端口的读和写提供了独立的线路,并且使用特殊的CPU指令访问端口。但即使这样,也不是所有的设备都会把寄存器映射到I/O端口中。ISA设
备普遍使用I/O端口,而大多数PCI设备则把寄存器映射到某个内存地址区段。
    I/O端口是驱动程序与许多设备之间的通信方式,Linux的内核为我们提供了I/O端口分配的操作接口,但对PCI设备来讲,它的配置地址空间已经为其指定了I/O端口范围,不需要额外的分配操作。Linux内核
提供了如下一些访问I/O端口的内联函数:
    unsigned inb(unsigned port);
    void outb(unsigned char byte, unsigned port);
    unsigned inw(unsigned port);
    void outw(unsigned short word, unsigned port);
    unsigned inl(unsigned port);
    void outl(unsigned longword, unsigned port);
    下面我们重点来看一下2.6内核引入的ioport_map函数:
    void *ioport_map( unsigned long port, unsigned int count );
    通过这个函数,可以把port开始的count个连续端口重映射为一段“内存空间”。然后就可以在其返回的地址上象访问I/O内存一样访问这几个I/O端口。当不需要这种映射时,需要调用下面的函数来撤消:
    void iport_unmap(void *addr);
    浏览2.6内核的源代码,我们不难发现,这种所谓的映射其实是“假”的。下面是这两个函数的实现,及一些相关数据:
    #define PIO_OFFSET  0x10000UL
    #define PIO_MASK    0x0ffffUL
    #define PIO_RESERVED    0x40000UL
    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 */
    }
   
它只是简单地把I/O端口号加上PIO_OFFSET(64K),作为一个“假”的内存地址返回,而unmap则什么也不做。之所以这样做,是基于这样一
个事实:真正的I/O内存地址经过映射成为虚拟地址后,由于是在内核空间,其值肯定大于3G。而port+PIO_OFFSET不会大于128K。所以,
内核不会把这两种地址搞混。可以分别进行处理,下面看看ioread8函数的实现:
    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
    void *ioremap(unsigned long phys_addr, unsigned long size);
    它把一个总线内存地址映射到CPU空间。
    关于这些接口的实际使用,可参考前一篇。
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/67414/showart_1657719.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP