Linux虚拟地址空间和物理地址空间怎么映射的?
在之前的文章中《CPU是如何访问内存的?》,我们知道了CPU是如何访问内存的,本篇文章我们来讲下虚拟地址空间和物理地址空间的映射。 通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。下面以X86为例。 物理地址空间布局
Linux系统在初始化时,会根据实际的物理内存的大小,为每个物理页面创建一个page对象,所有的page对象构成一个mem_map数组。 进一步,针对不同的用途,Linux内核将所有的物理页面划分到3类内存管理区中,如图,分别为:
linux虚拟地址内核空间分布 在kernel image下面有16M的内核空间用于DMA操作。位于内核空间高端的128M地址主要由3部分组成,分别为vmalloc area,持久化内核映射区,临时内核映射区。 由于ZONE_NORMAL和内核线性空间存在直接映射关系,所以内核会将频繁使用的数据如kernel代码、GDT、IDT、PGD、mem_map数组等放在ZONE_NORMAL里。而将用户数据、页表(PT)等不常用数据放在ZONE_ HIGHMEM里,只在要访问这些数据时才建立映射关系(kmap())。比如,当内核要访问I/O设备存储空间时,就使用ioremap()将位于物理地址高端的mmio区内存映射到内核空间的vmalloc area中,在使用完之后便断开映射关系。 linux虚拟地址用户空间分布 用户进程的代码区一般从虚拟地址空间的0x08048000开始,这是为了便于检查空指针。代码区之上便是数据区,未初始化数据区,堆区,栈区,以及参数、全局环境变量。 linux虚拟地址与物理地址映射的关系 Linux将4G的线性地址空间分为2部分,0~3G为user space,3G~4G为kernel space。 由于开启了分页机制,内核想要访问物理地址空间的话,必须先建立映射关系,然后通过虚拟地址来访问。为了能够访问所有的物理地址空间,就要将全部物理地址空间映射到1G的内核线性空间中,这显然不可能。于是,内核将0~896M的物理地址空间一对一映射到自己的线性地址空间中,这样它便可以随时访问ZONE_DMA和ZONE_NORMAL里的物理页面;此时内核剩下的128M线性地址空间不足以完全映射所有的ZONE_HIGHMEM,Linux采取了动态映射的方法,即按需的将ZONE_HIGHMEM里的物理页面映射到kernel space的最后128M线性地址空间里,使用完之后释放映射关系,以供其它物理页面映射。虽然这样存在效率的问题,但是内核毕竟可以正常的访问所有的物理地址空间了。 【编辑推荐】
点赞 0 (编辑:辽源站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- CPU通俗演义及代码级性能优化实例分析
- 10款Windows实用软件推荐,满满的干货,建议大家低调收藏!
- windows-server-2012-r2 – 我是否需要在每个虚拟机中安装防
- 从Linux终端查看笔记本电池状态和等级的5个方法
- “系统管理大
- windows-server-2008 – 如何从IIS 7提供未知文件类型
- windows-server-2008 – 在Active Directory中禁用密码复杂
- active-directory – 将2012 R2域控制器添加到2008 R2功能级
- 快速查看win10 build版本号的最简单的办法
- 这波操作不错——你真的会高效的在GitHub搜索开源项目吗?