一个 PCI 设备实现直至 6 个 I/O 地址区. 每个区由要么内存要么 I/O 区组成. 大部分 设备实现它们的 I/O 寄存器在内存区中, 因为通常它是一个完善的方法(如同在" I/O 端

口和 I/O 内存"一节中解释的, 在第 9 章). 但是, 不像正常的内存, I/O 寄存器不应当 被 CPU 缓存, 因为每次存取都可能有边际效果. 作为内存区来实现 I/O 寄存器的 PCI 设备, 通过设置一个在它的配置寄存器的"内存可预取"位来标志出这个不同.[43] 如果这个 内存区被标识为可预取的, CPU 可缓存它的内容并且对它做所有类型的优化. 非可预取的 内存存取, 另一方面, 不能被优化因为每次存取可能有边际效果, 就象 I/O 端口. 映射 它们的寄存器到一个内存地址范围的外设声明这个范围是非可预取的, 而象在 PCI 板的 视频内存的一些是可预取的. 在本节, 我们使用词语"区"来指代一个通用的 I/O 地址空 间, 这个空间要么是内存映射的, 要么是端口映射的.

一个接口板报告它的区的大小和当前位置, 使用配置寄存器- 6 个 32 位寄存器, 在图 12-2 中显示的, 它们的符号名是 PCI_ADDRESS_0 到 PCI_BASE_ADDRESS_5. 因为 PCI 定 义的 I/O 空间是 32-位空间, 使用同样的配置接口给内存和 I/O 是有意义的. 如果设备 使用 64-位地址总线, 它可以在 64-位内存空间声明各个区, 使用 2 个连续的

PCI_BASE_ADDRESS 寄存器给每个区, 低位在前. 对一个设备可能提供 32-位 和 64-位区.

内核中, PCI 设备的 I/O 区已被集成到通用的资源管理中. 由于这个原因, 你不必存取 配置变量来知道你的设备映射到内存或者 I/O 空间什么地方. 首选的用来获得区信息的 接口包括下列函数:

unsigned long pci_resource_start(struct pci_dev *dev, int bar);

这个函数返回第一个地址(内存地址或者 I/O 端口号), 和 6 个 PCI I/O 区中的 一个相关联的. 这个区通过整数 bar (the base address register), 范围从 0-5 (包含).

unsigned long pci_resource_end(struct pci_dev *dev, int bar);

这个函数返回最后一个地址, I/O 区号 bar 的一部分. 注意这是最后一个可用地 址, 不是这个区后的第一个地址.

unsigned long pci_resource_flags(struct pci_dev *dev, int bar); 这个函数返回和这个资源相关联的标识.

资源标识用来定义单个资源的一些特性. 对于和 PCI I/O 区相关联的 PCI 资源, 这个信 息从基地址寄存器中抽取出来, 但是可来自其他地方, 对于没有和 PCI 设备关联的资源.

所有的资源标志都定义在 <linux/ioport.h>; 最重要的是: IORESOURCE_IO

IORESOURCE_MEM

如果被关联的 I/O 区存在, 一个并且只有一个这样的标志被设置.

IORESOURCE_PREFETCH IORESOURCE_READONLY

这些标志告诉是否一个内存区是可预取的并且/或者写保护的. 后一个标志对 PCI 资源从不设置.

通过使用
pci_resource_ 函数, 一个设备驱动可完全忽略底层的 PCI 寄存器, 因为系统 已经使用它们来构造资源信息.

Linux 内核存取 I/O 和内存空间的更多相关文章

  1. 十天学Linux内核之第三天---内存管理方式

    原文:十天学Linux内核之第三天---内存管理方式 昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今 ...

  2. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  3. 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...

  4. [置顶] linux内核启动2-setup_arch中的内存初始化(目前分析高端内存)

    上一篇微博留下了这几个函数,现在我们来分析它们         sanity_check_meminfo();         arm_memblock_init(&meminfo, mdes ...

  5. Linux内核源码分析 day01——内存寻址

    前言 Linux内核源码分析 Antz系统编写已经开始了内核部分了,在编写时同时也参考学习一点Linux内核知识. 自制Antz操作系统 一个自制的操作系统,Antz .半图形化半命令式系统,同时嵌入 ...

  6. Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...

  7. Linux 内核存取配置空间

    在驱动已探测到设备后, 它常常需要读或写 3 个地址空间: 内存, 端口, 和配置. 特别 地, 存取配置空间对驱动是至关重要的, 因为这是唯一的找到设备被映射到内存和 I/O 空间的位置的方法. 因 ...

  8. 《Linux内核设计与实现》内存管理札记

    1.页 芯作为物理页存储器管理的基本单元,MMU(内存管理单元)中的页表,从虚拟内存的角度来看,页就是最小单位. 内核用struct page结构来标识系统中的每个物理页.它的定义例如以下: flag ...

  9. 发布Ubuntu/Linux系统cache,增加可用内存空间

    桌面Ubuntu总内存4G,但free只有内存有100M 重视top命令检查看到真正的能力free内存.以下是真正的内存使用情况的看法有一个命令. watch -n 1 cat /proc/memin ...

随机推荐

  1. Person Re-identification 系列论文笔记(八):SPReID

    Human Semantic Parsing for Person Re-identification Kalayeh M M, Basaran E, Gokmen M, et al. Human S ...

  2. 全球首个百万IOPS云盘即将商业化 阿里云推出超高性能云盘ESSD

    近日,在经过近半年的上线公测后,阿里云全球首个跨入IOPS百万时代的云盘——ESSD即将迎来商业化,单盘IOPS高达100万,这是阿里云迄今为止性能最强的企业级块存储服务. 搭配ECS云服务器使用, ...

  3. bzoj1221 软件开发

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  4. Codeforces 414B

    题目链接 附上代码: #include<cstdio> #include<cstring> #include<bits/stdc++.h> #define mod ...

  5. 猜年龄v2.0

    ''' 用户登录,只有三次机会 给定年龄,用户可以猜三次年龄 年龄猜对,让用户选择两次奖励,输入无效字符,让其选择要不要礼物 用户选择两次奖励后可以退出,选择第一次后提示还有一次 ''' #基本信息定 ...

  6. APP上线前,如何做运营推广工作?

    http://www.cocoachina.com/market/20150723/12731.html 一 竞品分析 1.选择竞品,做好定位(选择两个产品最好,最多三个). 如何获取竞品? A 百度 ...

  7. python 类与类之间的关系. 特殊成员

    一.类与类之间的关系 1.依赖关系 在方法的参数位置把另一个类的对象作为参数进行传递 class Person: def play(self, tools): # 通过参数的传递把另一个类的对象传递进 ...

  8. 2018-7-5-dotnet-设计规范-·-抽象定义

    title author date CreateTime categories dotnet 设计规范 · 抽象定义 lindexi 2018-07-05 15:48:20 +0800 2018-2- ...

  9. 当better-scroll遇见了react擦出的火花

    关于better-scroll这个插件前面已经介绍过两次了 从原生js使用到结合服务端发送数据使用都有过介绍 今天给大家分享一下这款插件在react中遇见的坑  总之我真是对这款插件又爱又恨 每次各种 ...

  10. 洛谷P1510 精卫填海

    //01背包 求背包内物品价值超过某一定值时的最小体积 #include<bits/stdc++.h> using namespace std; ; ; int n,v_tot,w_tot ...