一个最著名的 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);

linux 在 1 MB 之下的 ISA 内存的更多相关文章

  1. Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

  2. Linux系统、版本、CPU、内存查看、硬盘空间

    查看系统版本:lsb_release -a [root@localhost /]# lsb_release -a LSB Version:    :core-4.0-amd64:core-4.0-no ...

  3. linux下使用free命令查看实际内存占用(可用内存)

    转:http://blog.is36.com/linux_free_command_for_memory/ linux下在终端环境下可以使用free命令看到系统实际使用内存的情况,一般用free -m ...

  4. Linux 下安装sql server 时 2G内存限制的最新(2019-08-15) 解决方案

    关于 sqlserver 在linux下安装时有最小内存限制的问题,网上有很多类似的说明,那些操作都是正确的,如果不成功可能 “姿势”不对. 需要注意的是:不能使用最新版本!!!  不能在线下载!!! ...

  5. 【转载】Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()

    来源:https://www.cnblogs.com/52php/p/5861372.html 下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相 ...

  6. 【Linux】浅谈段页式内存管理

    让我们来回顾一下历史,在早期的计算机中,程序是直接运行在物理内存上的.换句话说,就是程序在运行的过程中访问的都是物理地址.如果这个系统只运行一个程序,那么只要这个程序所需的内存不要超过该机器的物理内存 ...

  7. Linux下查看内核、CPU、内存及各组件版本的命令和方法

    Linux下查看内核.CPU.内存及各组件版本的命令和方法 Linux查看内核版本: uname -a                        more /etc/*release       ...

  8. c/c++ linux 进程间通信系列4,使用共享内存

    linux 进程间通信系列4,使用共享内存 1,创建共享内存,用到的函数shmget, shmat, shmdt 函数名 功能描述 shmget 创建共享内存,返回pic key shmat 第一次创 ...

  9. 【转】Linux环境进程间通信(五) 共享内存(上)

    转自:https://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以 ...

随机推荐

  1. 【JZOJ4895】【NOIP2016提高A组集训第16场11.15】三部曲

    =v= 因为外来的入侵,国王决定在某些城市加派士兵.所有城市初始士兵数量为0.当城市 被加派了k名士兵时.城市i的所有子城市需要被加派k+1名士兵.这些子城市的所有子城市需要被加派k+2名士兵.以此类 ...

  2. Date日期类,Canlendar日历类,Math类,Random随机数学类

    Date日期类,SimpleDateFormat日期格式类 Date  表示特定的时间,精确到毫秒 常用方法 getTime() setTime() before() after() compareT ...

  3. java读取properties文件总结

    一.java读取properties文件总结 在java项目中,操作properties文件是经常要做的,因为很多的配置信息都会写在properties文件中,这里主要是总结使用getResource ...

  4. TZOJ 4471: Postman FJ (二分+bfs)

    描述 FJ now is a postman of a small town in the hills. The town can be represented by a N×N matrix. Ea ...

  5. 部署zabbix3.2.7,升级到3.4、proxy部署

    一.Server安装 可以使用mysql.percona.mariadb等,本例使用mariadb.由于是事后整理,只截取部分命令. #yum install mariadb-server maria ...

  6. Java练习 SDUT-2445_小学数学

    小学数学 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 今年中秋节,大宝哥带着一盒月饼去看望小学数学老师.碰巧数学老师 ...

  7. importError: DLL load failed when import matplotlib.pyplot as plt

    importError: DLL load failed when import matplotlib.pyplot as plt 出现这种情况的原因, 大多是matplotlib的版本与python ...

  8. phpstudy易犯的错误

  9. pictures

  10. UVa 10323 【数学】

    UVa 10323 题目:计算阶乘在10000~6227020800之间的值,不在范围对应输出Under或者Over. 分析:简单题.数论.因为13!=6227020800,7!<10000&l ...