zoukankan      html  css  js  c++  java
  • linux 在 1 MB 之下的 ISA 内存

    一个最著名的 I/O 内存区是在个人计算机上的 ISA 范围. 这是在 640 KB(0xA0000)和 1 MB(0x100000)之间的内存范围. 因此, 它正好出现于常规内存 RAM 中间. 这个位置可能 看起来有点奇怪; 它是一个在 1980 年代早期所作的决定的产物, 当时 640 KB 内存看来 多于任何人可能用到的大小.

    这个内存方法属于非直接映射的内存类别. [36]你可以读/写几个字节在这个内存范围, 如 同前面解释的使用 short 模块, 就是, 通过在加载时设置 use_mem.

    尽管 ISA I/O 内存只在 x86-类 计算机中存在, 我们认为值得用几句话和一个例子驱动.

    我们不会谈论 PCI 在本章, 因为它是最干净的一类 I/O 内存: 一旦你知道内存地址, 你 可简单地重映射和存取它. PCI I/O 内存的"问题"是它不能为本章提供一个能工作的例子, 因为我们不能事先知道你的 PCI 内存映射到的物理地址, 或者是否它是安全的来存取任 一这些范围. 我们选择来描述 ISA 内存范围, 因为它不但少干净并且更适合运行例子代 码.

    为演示存取 ISA 内存, 我们还使用另一个 silly 小模块( 例子源码的一部分). 实际上, 这个称为 silly, 作为 Simple Tool for Unloading and Printing ISA Data 的缩写, 或者如此的东东.

    模块补充了 short 的功能, 通过存取整个 384-KB 内存空间和通过显示所有的不同 I/O 功能. 它特有 4 个设备节点来进行同样的任务, 使用不同的数据传输函数. silly 设备 作为一个 I/O 内存上的窗口, 以类似 /dev/mem 的方式. 你可以读和写数据, 并且 lseek 到一个任意 I/O 内存地址.

    因为 silly 提供了对 ISA 内存的存取, 它必须开始于从映射物理 ISA 地址到内核虚拟 地址. 在 Linux 内核的早期, 一个人可以简单地安排一个指针给一个感兴趣的 ISA 地址, 接着直接对它解引用. 在现代世界, 但是, 我们必须首先使用虚拟内存系统和重映射内存 范围. 这个映射使用 ioremap 完成, 如同前面为 short 解释的:

    #define ISA_BASE 0xA0000

    #define ISA_MAX 0x100000 /* for general memory access */

    /* this line appears in silly_init */

    io_base = ioremap(ISA_BASE, ISA_MAX - ISA_BASE);

    ioremap 返回一个指针值, 它能被用来使用 ioread8 和其他函数, 在"存取 I/O 内存"一 节中解释.

    让我们回顾我们的例子模块来看看这些函数如何被使用. /dev/sillyb, 特有次编号 0, 存取 I/O 内存使用 ioread8 和 iowrite8. 下列代码显示了读的实现, 它使地址范围 0xA0000-0xFFFF 作为一个虚拟文件在范围 0-0x5FFF. 读函数构造为一个 switch 语句在 不同存取模式上; 这是 sillyb 例子:

    case M_8:

    while (count) {

    *ptr = ioread8(add); add++;

    count--;

    ptr++;

    }

    break;

    实际上, 这不是完全正确. 内存范围是很小和很频繁的使用, 以至于内核在启动时建立页 表来存取这些地址. 但是, 这个用来存取它们的虚拟地址不是同一个物理地址, 并且因此 无论如何需要 ioremap.

    下 2 个设备是 /dev/sillyw (次编号 1) 和 /dev/silly1 (次编号 2). 它们表现象

    /dev/sillyb, 除了它们使用 16-位 和 32-位 函数. 这是 sillyl 的写实现, 又一次部 分 switch:

    case M_32:

    while (count >= 4) { iowrite8(*(u32 *)ptr, add); add += 4;

    count -= 4;

    ptr += 4;

    }

    break;

    最后的设备是 /dev/sillycp (次编号 3), 它使用 memcpy_*io 函数来进行同样的任务. 这是它的读实现的核心:

    case M_memcpy: memcpy_fromio(ptr, add, count); break;

    因为 ioremap 用来提供对 ISA 内存区的存取, silly 必须调用 iounmap 当模块卸载时: iounmap(io_base);

  • 相关阅读:
    解决云服务器ECS,windows server 2012不能安装SQL Server 2012,不能安装.NET Fromework 3.5
    html5中checkbox的选中状态的设置与获取
    sql server 韩文查询匹配失败
    管理nuget程序包中搜索不到任何程序包
    ftp下出现“当前的安全设置不允许从该位置下载文件”提示
    windows server 2012 下IIS8.5关于“ 配置错误 不能在此路径中使用此配置节”的解决办法
    服务器升级后访问网站资源返回404
    centos7yum的更新与优化
    linux(centos7)命令提示符优化
    检查vmware虚拟软件服务是否开启?
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11142263.html
Copyright © 2011-2022 走看看