| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux内存地址管理 -> 正文阅读 |
|
[系统运维]Linux内存地址管理 |
Linux系统中的每个内存地址都是虚拟的,它们不直接指向任何物理内存地址。每当访问内存位置时,可以执行转换机制以匹配相应的物理内存,所以我们在程序中必须用虚拟地址来访问数据。 注:下面所说的内核空间和用户空间这样的术语指的都是虚拟地址空间 系统内存布局在Linux系统中,每个进程都有自己独立的虚拟地址空间。它是一种内存沙箱,存在于进程的生命周期中。在32位系统上,该地址空间大小是4GB。针对每一个进程,4GB的地址空间被分割成两个部分:
分割方式依赖于特殊的内核配置选项CONFIG_PAGE_OFFSET,这个选项定义内核虚拟地址部分在进程地址空间的起始位置。典型的进程虚拟地址空间布局如下图: 内核与每个进程共享其地址空间,原因如下:因为每个进程在给定的时刻都使用系统调用,这将涉及内核。将内核的虚拟内存地址映射到每个进程的虚拟地址空间能够避免每次进入(或者退出)内核时内存地址切换产生的开销。这就是内核地址空间被永久映射到每个进程顶部的原因—加快系统调用对内核的访问。 每个进程地址空间顶部都是内核的虚拟地址空间,这一部分每个进程都是相同的。 内存管理单元把内存组织为大小固定的单元—页面,内存页(虚拟页)指的是连续虚拟内存块,内核数据结构也使用相同的名称页面来表示内存页。帧(页面帧)指一段固定长度的连续物理内存块,操作系统在其上映射内存页。每个页面帧都有一个号码,叫做页面帧号(PFN)。 内核地址的低端和高端内存概念Linux内核具有自己的虚拟地址空间。比如32位的x86,内核的虚拟地址空间是1GB大小,分成两个部分:
低端内存内核地址空间的第一个896MB空间构成低端内存区域。在启动早期,内核永久映射这896MB的空间。该映射产生的地址为逻辑地址,这些都是虚拟地址,但是减去固定的偏移量后就可以将其转换为物理地址。因为映射是永久的,并且事先知道。大多数内核内存函数返回低端内存。事实上,为了满足不同的用途,内核内存被划分为区域,LOWMEM的第一个16MB内存保留为DMA使用。内核空间可以确定3种不同的内存区域:
这就是说,512MB的系统上,不存在以上的划分。 逻辑地址的另一个定义:线性映射到物理地址上的内核空间中的地址,可以用偏移量或者应用位掩码将其转为物理地址,使用__pa(地址)宏可以将逻辑地址(内核中的虚拟地址)转换为物理地址,使用__va(地址)可以做相反的操作。 高端内存内核地址空间顶部顶部128MB称为高端内存区域,内核用它临时映射1GB以上的物理内存,当需要访问896MB以上的物理内存时,内核会使用这128MB创建到其虚拟地址空间的临时映射,也就是将需要访问数据的物理页映射到这128MB内核虚拟地址空间来,从而实现访问所有物理页面的目标。可以把高端内存定义为逻辑地址存在的内存,但不会将其永久映射到内核地址空间。896MB以上的物理内存按需映射到HIGHMEM区域的128MB。 访问高端内存的映射由内核动态创建,访问后销毁,这使高内存访问速度变慢,64位系统上不存在高端内存这一概念。 地址转换和MMU每次访问内存位置时,由CPU完成从虚拟地址到物理地址的转换。该机制称为地址转换,这由CPU中的内存管理单元(MMU)来执行。MMU转换的都是虚拟地址,所以访问数据,必须是虚拟地址,不能是物理地址,否则访问不了数据。 对于虚拟内存,内存组织为固定大小的页,而物理内存则按帧组织,页面表(PTE)概念的引入是为了管理页面和帧之间的映射。页面分部在表间,因此每个PTE的表项对于一个页面和帧之间的映射,然后给每个进程一组页面表来描述其整个内存空间。 Linux中的四级分页模型Linux采用了一种同时适用于32位和64位系统的普通分页模型。从2.6.11版本开始,采用了四级分页模型:
虚拟地址被分为5个部分,每个页表项指向一个页框,每一部分的大小与具体的计算机体系结构有关。 MMU如何知道进程页面表?很简单,MMU不存储任何地址。但CPU有一个特殊的寄存器,称为页面表基址寄存器(PTBR)或转换基址寄存器0(TTBR0),它指向进程1级页面表(PGD)的基址。这正是 虚拟地址字段下面宏简化了页表处理:
页表处理pte_t、pmd_t、pud_t和pgd_t分别描述页表项、页中间目录项、页上级目录项和页全局目录项。 五个类型转换宏(__pte,__pmd,__pgd和__pgprot)把一个无符号整数转换成所需的类型。另外的五个类型转换宏(pte_val,pmd_val,pud_val,pgd_val和pgport_val)执行相反的转换。 如果相应的表项值位0,那么,宏pte_none、pmd_none、pud_none、和pgd_none产生的值为1,否则产生的值为0 将虚拟地址转换物理地址进程访问的都是用户空间内虚拟地址,内核访问的都是内核虚拟地址,进程用不了内核虚拟地址,同样内核用不了进程内虚拟地址。如果我们将用户空间地址传给内核,内核必须先将找到该用户空间虚拟地址对应的物理地址,再将物理地址转换成内核虚拟地址,内核才能访问数据。 代码地址:http://edsionte.com/techblog/archives/1966
整个程序的结构如下:
vaddr2paddr()的执行过程如下:
我们可以获得物理地址了,就可以使用__pa(地址)宏可以将物理地址转换为逻辑地址(内核中的虚拟地址),使用__va(地址)可以做相反的操作 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 15:41:58- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |