__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
介绍
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
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
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.
__iomem解析的更多相关文章
- Linux 字符设备驱动—— ioremap() 函数解析
一. ioremap() 函数基础概念 几乎每一种外设都是通过读写设备上的相关寄存器来进行的,通常包括控制寄存器.状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址.根据CPU体系结构的不同, ...
- linux device tree源代码解析--转
//Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...
- linux device tree源代码解析【转】
转自:http://blog.csdn.net/Tommy_wxie/article/details/42806457 //Basedon Linux v3.14 source code Linux设 ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- Html Agility Pack 解析Html
Hello 好久不见 哈哈,今天给大家分享一个解析Html的类库 Html Agility Pack.这个适用于想获取某网页里面的部分内容.今天就拿我的Csdn的博客列表来举例. 打开页面 用Fir ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
随机推荐
- Servlet的学习之Session(2)
在上一篇中我们学习了Session对象默认在一个会话过程中,由服务器创建,能保存在这个会话过程中用户访问多个web资源时产生的需要保存的数据,并在访问服务器中其他web资源时可以将这些数据从Sessi ...
- asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装)
原文 asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装) 检测Office是否安装以及获取安装 路径 及安装版本 代码如下 复制代码 #region 检测Office是否 ...
- 简单的ajax获取json
一个DBhelper类,用来操作数据库 using System; using System.Collections.Generic; using System.Linq; using System. ...
- 使用Material Design 创建App翻译系列----材料主题的使用(Using Material Theme)
上一篇是使用Material Design 创建App翻译系列--開始学习篇,进入正题: 新的材料主题提供了下面内容: 1. 提供了同意设置颜色板的系统部件组件. 2. 为这些系统组件提供了触摸反馈动 ...
- Swift - 浮点数转换成整数(四舍五入与直接截断)
1,直接截去小数部分转换成整数 使用强制转换会将浮点部分去除,把整数部分转换为整数. 1 var i = Int(23.50) //23 2,四舍五入转换成整数 lroundf是一个全局函数,作用是将 ...
- 用VC制作应用程序启动画面
摘 要:本文提供了四种启动画面制作方法. 使用启动画面一是可以减少等待程序加载过程中的枯燥感(尤其是一些大型程序):二是 可以用来显示软件名称和版权等提示信息.怎样使用VC++制作应用程序的启动画面呢 ...
- Lucene.Net 2.3.1开发介绍 —— 三、索引(五)
原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(五) 话接上篇,继续来说权重对排序的影响.从上面的4个测试,只能说是有个直观的理解了.“哦,是!调整权重是能影响排序了,但是好像没办法来 ...
- 仿ios版微信应用源代码
仿微信基本功能. 基于XMPPserver的即时通信以及交友client. ----第一期代码的功能例如以下---- 1.新用户注冊 2.登陆并连接XMPPserver 握手 保持 ...
- HealthKit开发教程Swift版:起步
原文:HealthKit Tutorial with Swift: Getting Started 作者:Ernesto García 译者:Mr_cyz ) HealthKit是iOS 8中的新的A ...
- HTML事件
Media 事件