__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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM