一个 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. node 写的简单爬虫(三)

    异步爬取数据 先引入 var async = require('async'); 然后同样上代码 var topicUrls = [];//存所有地址 http.get(url,function(re ...

  2. Python2 生成器 简介

    1. A generator: provide a kind of function that can return an intermediate result ("the next va ...

  3. element-ui select 二级联动

    在使用select 选择框时,2个select 怎么关联在一起(第一个值发生变化,第二个select值随第一个变化而不同)  两个输入框代码 <el-form :inline="tru ...

  4. DFS-生日蛋糕

    生日蛋糕 一道深搜题,看了这两个博客才懂的. http://blog.csdn.net/blesslzh0108/article/details/53486168 http://blog.csdn.n ...

  5. 18.libgdx制作预览图,背景移动循环,改变地图颜色

    经过构思,游戏将分为两部分, 1,预览图,只负责展示世界形势 2,根据预览图生成的战役项 现在要记录的是我制作预览图的部分 1.预览图只有实际地图的1/4,首先生成地图(建议不要缩放以前地图,由于误差 ...

  6. dva与create-react-app的结合使用

    dva与我们的create-react-app创建的两款脚手架是我们写react项目的两款优秀框架,之前一种使用create-react-app这款脚手架进行开发.然后这个框架美中不足的是redux方 ...

  7. java代码简单实现队列

    1. 基于链表简单实现 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; / ...

  8. 2019-2-3-VisualStudio-扩展开发-添加输出窗口

    title author date CreateTime categories VisualStudio 扩展开发 添加输出窗口 lindexi 2019-02-03 11:41:40 +0800 2 ...

  9. @bzoj - 4356@ Ceoi2014 Wall

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给出一个N*M的网格图,有一些方格里面存在城市,其中首都位于网格 ...

  10. Laravel Class config does not exist in

    修改了Laravel里面的.env文件之后报这个错误,找半天,找到罪魁祸首了,错误信息: Fatal error: Uncaught ReflectionException: Class config ...