zoukankan      html  css  js  c++  java
  • __iomem解析

    以下是在学习电池驱动中遇到的知识点之_iomem

    A new I/O memory access mechanism


     

    Most reasonably current cards for the PCI bus (and others) provide one or more I/O memory regions to the bus. By accessing those regions, the

    现在绝大多数PCI总线卡(和其他人)提供一个或多个I / O总线的内存区域。通过访问这些内存区域,

     processor can communicate with the peripheral and make things happen. A look at /proc/iomem will show the I/O memory regions which have been registered on a given system.

    处理器可以与外围设备通信和做出一些反应。查看/ proc / iomem将显示I / O内存区域已被注册在一个给定的系统中的信息。如下:

    [fulinux@centos6 ~]$ vim /proc/iomem 
     /p/iomem                                                                                                                           
    00000000-00000fff : reserved
    00001000-0009f7ff : System RAM
    0009f800-0009ffff : reserved
    000a0000-000bffff : PCI Bus 0000:00
    000c0000-000dffff : PCI Bus 0000:00
      000c0000-000cdbff : Video ROM
      000cdc00-000cffff : pnp 00:0d
    000e0000-000effff : pnp 00:0d
    000f0000-000fffff : reserved
      000f0000-000fffff : System ROM
    00100000-dafcffff : System RAM
      01000000-014f4774 : Kernel code
      014f4775-01c07c6f : Kernel data
      01d4c000-02010023 : Kernel bss
      03000000-0affffff : Crash kernel
    dafd0000-dafd2fff : ACPI Non-volatile Storage
    dafd3000-dafeffff : ACPI Tables
    daff0000-daffffff : reserved
    db000000-dbffffff : RAM buffer
    dfa00000-febfffff : PCI Bus 0000:00
      dfa00000-dfbfffff : PCI Bus 0000:01
      dfc00000-dfdfffff : PCI Bus 0000:01
      e0000000-efffffff : 0000:00:02.0
      f4000000-f7ffffff : PCI MMCONFIG 0 [00-3f]
        f4000000-f7ffffff : reserved
          f4000000-f7ffffff : pnp 00:0c
      fb800000-fbbfffff : 0000:00:02.0
      fbe00000-fbefffff : PCI Bus 0000:02
        fbec0000-fbefffff : 0000:02:00.0
          fbec0000-fbefffff : atl1c
      fbff8000-fbffbfff : 0000:00:1b.0
        fbff8000-fbffbfff : ICH HD audio
      fbffc000-fbffc0ff : 0000:00:1f.3
      fbffd000-fbffd3ff : 0000:00:1d.0
        fbffd000-fbffd3ff : ehci_hcd
      fbffe000-fbffe3ff : 0000:00:1a.0
        fbffe000-fbffe3ff : ehci_hcd
      fbfff000-fbfff00f : 0000:00:16.0
    fec00000-ffffffff : reserved
      fec00000-fec00fff : IOAPIC 0
      fed00000-fed003ff : HPET 0
      fed10000-fed1dfff : pnp 00:0d
      fed20000-fed8ffff : pnp 00:0d
      fee00000-fee00fff : Local APIC
        fee00000-fee00fff : pnp 00:0d
      ffb00000-ffb7ffff : pnp 00:0d
      fff00000-ffffffff : pnp 00:0d
    100000000-21fdfffff : System RAM
    21fe00000-21fffffff : RAM buffer

    Advertisement
    介绍
    To work with an I/O memory region, a driver is supposed to map that region with a call to  ioremap(). The return value from  ioremap() is a magic cookie which can be passed to a set of accessor functions (with names
    为了处理一个I/O存储区域,设备驱动通过ioremap()函数调用来映射这片区域。ioremap()函数的返回一个a magic cookie值可以用来传输到存取函数中去(例如
     like  readb() or  writel()) to actually move data to or from the I/O memory. On some architectures (notably x86), I/O memory is truly mapped into the kernel's memory space, so those accessor functions turn into a
    名为readb()和writel()函数),用来将数据放入或取出这片区域。在一些体系架构中(尤其是x86体系架构),I/O存储区域被映射到内核存储空间中去,所以那些存取函数就
     straightforward pointer dereference. Other architectures require more complicated operations.
    明确的变为了指针,其他的体系结构需要复杂的操作。

    There have been some longstanding problems with this scheme. Drivers written for the x86 architecture have often been known to simply dereference I/O memory addresses directly, rather than using the accessor functions. That approach works on the x86, but breaks on other architectures. Other drivers, knowing that I/O memory addresses are not real pointers, store them in integer variables; that works until they encounter a system with a physical address space which doesn't fit into 32 bits. And, in any case, readb() and friends perform no type checking, and thus fail to catch errors which could be found at compile time.

    The 2.6.9 kernel will contain a series of changes designed to improve how the kernel works with I/O memory. The first of these is a new __iomem annotation used to mark pointers to I/O memory. These annotations work much like the __user markers, except that they reference a different address space. As with __user, the__iomem marker serves a documentation role in the kernel code; it is ignored by the compiler. When checking the code with sparse, however, developers will see a whole new set of warnings caused by code which mixes normal pointers with __iomem pointers, or which dereferences those pointers.

    The next step is the addition of a new set of accessor functions which explicitly require a pointer argument. These functions are:

     

        unsigned int ioread8(void __iomem *addr);
        unsigned int ioread16(void __iomem *addr);
        unsigned int ioread32(void __iomem *addr);
        void iowrite8(u8 value, void __iomem *addr);
        void iowrite16(u16 value, void __iomem *addr);
        void iowrite32(u32 value, void __iomem *addr);
    

    By default, these functions are simply wrappers around readb() and friends. The explicit pointer type for the argument will generate warnings, however, if a driver passes in an integer type.

    There are "string" versions of these operations:

     

        extern void ioread8_rep(void __iomem *port, void *buf, 
                                unsigned long count);
    

    All of the other variants are defined as well, of course.

    There is actually one other twist to these functions. Some drivers have to be able to use either I/O memory or I/O ports, depending on the architecture and the device. Some such drivers have gone to considerable lengths to try to avoid duplicating code in those two cases. With the new accessors, a driver which finds it needs to work with x86-style ports can call:

     

        void __iomem *ioport_map(unsigned long port, unsigned int count);
    

    The return value will be a cookie which allows the mapped ports to be treated as if they were I/O memory; functions like ioread8() will automatically do the right thing. For PCI devices, there is a new function:

     

        void __iomem *pci_iomap(struct pci_dev *dev, int base, 
                                unsigned long maxlen);
    

    For this function, the base can be either a port number or an I/O memory address, and the right thing will be done.

    As of 2.6.9-rc2, there are no in-tree users of the new interface. That can be expected to change soon as patches get merged and the kernel janitors get to work. For more information on the new I/O memory interface and the motivation behind it, see this explanation from Linus.

  • 相关阅读:
    HAproxy 1.5 dev14 发布
    IBM/DW 使用 Java 测试网络连通性的几种方法
    Skype 4.1 Linux 发布,支持微软帐号登录
    Dorado 7.1.20 发布,Ajax的Web开发平台
    Aspose.Slides for Java 3.0 发布
    开发版本 Wine 1.5.18 发布
    BitNami Rubystack 开始支持 Ruby 2.0
    XWiki 4.3 正式版发布
    Silverlight实例教程 Out of Browser的Debug和Notifications窗口
    Silverlight实例教程 Out of Browser与Office的互操作
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3181803.html
Copyright © 2011-2022 走看看