linux物理地址和虚拟地.pdf_第1页
linux物理地址和虚拟地.pdf_第2页
linux物理地址和虚拟地.pdf_第3页
linux物理地址和虚拟地.pdf_第4页
linux物理地址和虚拟地.pdf_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

linuxlinuxlinuxlinux 中的物理地址和虚拟地址中的物理地址和虚拟地址 在支持 MMU 的 32位处理器平台上 Linux 系统中的物理存储空间和虚拟存储空间的地址范围分别都是从 0 x00000000到 0 xFFFFFFFF 共 4GB 但物理存储空间与虚拟存储空间布局完全不同 Linux 运行在虚 拟存储空间 并负责把系统中实际存在的远小于 4GB 的物理内存根据不同需求映射到整个 4GB 的虚拟存 储空间中 物理存储空间布局物理存储空间布局物理存储空间布局物理存储空间布局 Linux 的物理存储空间布局与处理器相关 详细情况可以从处理器用户手册的存储空间分布表 memory map 相关章节中查到 我们这里只列出嵌入式处理器平台 Linux 物理内存空间的一般布局 如图 18 4所 示 500 this width 500 图 18 4 Linux 物理内存空间一般布局示意图 说明 1 最大 node号 n 不能大于 MAX NUMNODES 1 2 MAX NUMNODES 表示系统支持的最多 node数 在 ARM 系统中 Sharp芯片最多支持 16个 nodes 其他芯片最多支持 4 个 nodes 3 numnodes 是当前系统中实际的内存 node数 4 在不支持 CONFIG DISCONTIGMEM 选项的系统中 只有一个内存 node 5 最大 bank 号 m 不能大于 NR BANKS 1 6 NR BANKS 表示系统中支持的最大内存 bank数 一般等于处理器的 RAM 片选数 在 ARM 系统中 Sharp芯片最多支持 16个 banks 其他芯片最多支持 8 个 banks 7 mem init 函数会将所有节点的页帧位码表所占空间 孔洞页描述符空间及空闲内存页都释放掉 虚拟存储空间布局虚拟存储空间布局虚拟存储空间布局虚拟存储空间布局 在支持 MMU 的系统中 当系统做完硬件初始化后就使能 MMU 功能 这样整个系统就运行在虚拟存储空 间中 实现虚拟存储空间到物理存储空间映射功能的是处理器的 MMU 而虚拟存储空间与 5 路存储空间 的映射关系则是由 Linux 内核来管理的 32位系统中物理存储空间占 4GB 空间 虚拟存储空间同样占 4GB 空间 Linux 把物理空间中实际存在的远远小于 4GB 的内存空间映射到整个 4GB 虚拟存储空间中除映射 I O 空间之外的全部空间 所以虚拟内存空间远远大于物理内存空间 这就说同一块物理内存可能映射到多 处虚拟内存地址空间上 这正是 Linux 内存管理职责所在 图 18 5列出了 Linux 内核中虚拟内存空间的一 般布局 其实 I O 空间也在其中 通常占用高端内存空间 在此未标出 500 this width 500 图 18 5 Linux 系统虚拟内存空间一般布局示意图 说明 1 线性地址空间 是指 Linux系统中从 0 x00000000到 0 xFFFFFFFF 整个 4GB 虚拟存储空间 2 内核空间 内核空间表示运行在处理器最高级别的超级用户模式 supervisor mode 下的代码或数据 内核空间占用从 0 xC0000000到 0 xFFFFFFFF 的 1GB 线性地址空间 内核线性地址空间由所有进程共享 但只有运行在内核态的进程才能访问 用户进程可以通过系统调用切换到内核态访问内核空间 进程运行 在内核态时所产生的地址都属于内核空间 3 用户空间 用户空间占用从 0 x00000000到 0 xBFFFFFFF 共 3GB 的线性地址空间 每个进程都有一个 独立的 3GB 用户空间 所以用户空间由每个进程独有 但是内核线程没有用户空间 因为它不产生用户空 间地址 另外子进程共享 继承 父进程的用户空间只是使用与父进程相同的用户线性地址到物理内存地 址的映射关系 而不是共享父进程用户空间 运行在用户态和内核态的进程都可以访问用户空间 4 内核逻辑地址空间 是指从 PAGE OFFSET 到 high memory 之间的线性地址空间 是系统物理内存 映射区 它映射了全部或部分 如果系统包含高端内存 物理内存 内核逻辑地址空间与图 18 4中的系统 RAM 内存物理地址空间是一一对应的 包括内存孔洞也是一一对应的 内核逻辑地址空间中的地址与 RAM 内存物理地址空间中对应的地址只差一个固定偏移量 如果 RAM 内存物理地址空间从 0 x00000000 地址编址 那么这个偏移量就是 PAGE OFFSET 5 低端内存 内核逻辑地址空间所映射物理内存就是低端内存 低端内存在 Linux 线性地址空间中始终有 永久的一一对应的内核逻辑地址 系统初始化过程中将低端内存永久映射到了内核逻辑地址空间 为低端 内存建立了虚拟映射页表 低端内存内物理内存的物理地址与线性地址之间的转换可以通过 pa x 和 va x 两个宏来进行 pa x 将内核逻辑地址空间的地址 x 转换成对应的物理地址 相当于 virt to phys unsignedlong x va x 则相反 把低端物理内存空间的地址转换成对应的内核逻辑地 址 相当于 void phys to virt unsigned long x 6 高端内存 低端内存地址之上的物理内存是高端内存 高端内存在 Linux 线性地址空间中没有没有固定 的一一对应的内核逻辑地址 系统初始化过程中不会为这些内存建立映射页表将其固定映射到 Linux 线性 地址空间 而是需要使用高端内存的时候才为分配的高端物理内存建立映射页表 使其能够被内核使用 否则不能被使用 高端内存的物理地址于现行地址之间的转换不能使用上面的 pa x 和 va x 宏 7 高端内存概念的由来 如上所述 Linux将 4GB 的线性地址空间划分成两部分 从 0 x00000000到 0 xBFFFFFFF 共 3GB 空间作为用户空间由用户进程独占 这部分线性地址空间并没有固定映射到物理内 存空间上 从 0 xC0000000到 0 xFFFFFFFF 的第 4GB 线性地址空间作为内核空间 在嵌入式系统中 这 部分线性地址空间除了映射物理内存空间之外还要映射处理器内部外设寄存器空间等 I O 空间 0 xC0000000 high memory 之间的内核逻辑地址空间专用来固定映射系统中的物理内存 也就是说 0 xC0000000 high memory 之间空间大小与系统的物理内存空间大小是相同的 当然在配置了 CONFIG DISCONTIGMEMD 选项的非连续内存系统中 内核逻辑地址空间和物理内存空间一样可能存在 内存孔洞 如果系统中的物理内存容量远小于 1GB 那么内核现行地址空间中内核逻辑地址空间之上的 high memory 0 xFFFFFFFF 之间还有足够的空间来固定映射一些 I O 空间 可是 如果系统中的物理内 存容量 包括内存孔洞 大于 1GB 那么就没有足够的内核线性地址空间来固定映射系统全部物理内存以 及一些 I O 空间了 为了解决这个问题 在 x86处理器平台设置了一个经验值 896MB 就是说 如果系 统中的物理内存 包括内存孔洞 大于 896MB 那么将前 896MB 物理内存固定映射到内核逻辑地址空间 0 xC0000000 0 xC0000000 896MB high memory 上 而 896MB 之后的物理内存则不建立到内核线 性地址空间的固定映射 这部分内存就叫高端物理内存 此时内核线性地址空间 high memory 0 xFFFFFFFF 之间的 128MB 空间就称为高端内存线性地址空间 用来映射高端物理内存和 I O 空间 896MB 是 x86 处理器平台的经验值 留了 128MB 线性地址空间来映射高端内存以及 I O 地址空 间 我们在嵌入式系统中可以根据具体情况修改这个阈值 比如 MIPS 中将这个值设置为 0 x20000000B 512MB 那么只有当系统中的物理内存空间容量大于 0 x20000000B时 内核才需要配置 CONFIG HIGHMEM 选项 使能内核对高端内存的分配和映射功能 什么情况需要划分出高端物理内存以 及高端物理内存阈值的设置原则见上面的内存页区 zone 概念说明 8 高端线性地址空间 从 high memory到 0 xFFFFFFFF 之间的线性地址空间属于高端线性地址空间 其 中VMALLOC START VMALLOC END之间线性地址被vmalloc 函数用来分配物理上不连续但线性地址 空间连续的高端物理内存 或者被 vmap 函数用来映射高端或低端物理内存 或者由 ioremap 函数来重 新映射 I O 物理空间 PKMAP BASE 开始的 LAST PKMAP 一般等于 1024 页线性地址空间被 kmap 函数用来永久映射高端物理内存 FIXADDR START 开始的 KM TYPE NR NR CPUS 页线性地址空间 被 kmap atomic 函数用来临时映射高端物理内存 其他未用高端线性地址空间可以用来在系统初始化期 间永久映射 I O 地址空间 Linux 2 6 10内核中的ARM处理器平台部分没有对高端内存的支持 图18 6和图 18 7分别列出了SA1100 和 IXP4XX 处理器平台的 Linux 线性地址空间布局 在嵌入式系统中如何访问在嵌入式系统中如何访问 I OI O 资源呢 资源呢 几乎每一种外设都是通过读写设备上的寄存器来进行的 通常包括控制寄存器 状态寄存器和数据寄存器 三大类 外设的寄存器通常被连续地编址 根据 CPU 体系结构的不同 CPU 对 IO 端口的编址方式有两种 1 I O 映射方式 I O mapped 典型地 如 X86 处理器为外设专门实现了一个单独的地址空间 称为 I O 地址空间 或者 I O 端口空 间 CPU 通过专门的 I O 指令 如 X86 的 IN 和 OUT 指令 来访问这一空间中的地址单元 2 内存映射方式 Memory mapped RISC 指令系统的 CPU 如 ARM PowerPC 等 通常只实现一个物理地址空间 外设 I O 端口成为内存的 一部分 此时 CPU 可以象访问一个内存单元那样访问外设 I O 端口 而不需要设立专门的外设 I O 指令 但是 这两者在硬件实现上的差异对于软件来说是完全透明的 驱动程序开发人员可以将内存映射方 式的 I O 端口和外设内存统一看作是 I O 内存 资源 一般来说 在系统运行时 外设的 I O 内存资源的物理地址是已知的 由硬件的设计决定 但是 CPU 通常并没有为这些已知的外设 I O 内存资源的物理地址预定义虚拟地址范围 驱动程序并不能直接通过物 理地址访问 I O 内存资源 而必须将它们映射到核心虚地址空间内 通过页表 然后才能根据映射所得 到的核心虚地址范围 通过访内指令访问这些 I O 内存资源 Linux 在 io h 头文件中声明了函数 ioremap 用来将 I O 内存资源的物理地址映射到核心虚地址空间 3GB 4GB 中 原型如下 void ioremap unsigned long phys addr unsigned long size unsigned long flags iounmap 函数用于取消 ioremap 所做的映射 原型如下 void iounmap void addr 这两个函数都是实现在 mm ioremap c 文件中 在将 I O内存资源的物理地址映射成核心虚地址后 理论上讲我们就可以象读写 RAM 那样直接读写 I O 内存资源了 为了保证驱动程序的跨平台的可移植性 我们应该使用 Linux 中特定的函数来访问 I O 内存 资源 而不应该通过指向核心虚地址的指针来访问 如在 x86 平台上 读写 I O 的函数如下所示 define readb addr volatile unsigned char io virt addr define readw addr volatile unsigned short io virt addr define readl addr volatile unsigned int io virt addr define writeb b addr volatile unsigned char io virt addr b define writew b addr volatile unsigned short io virt addr b define writel b addr v

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论