首页
学习
活动
专区
圈层
工具
发布

【内存管理】页表映射基础知识

中间的8个bit位叫做L2索引,在Linux内核中叫做PT,页表。最低的12位叫做页索引。 在ARM处理器中,TTBRx寄存器存放着页表基地址,我们这里的一级页表有4096个页表项。...二级页表通常是动态分配的,可以通过虚拟地址的中间8bit位L2索引访问二级页表,在L2索引中存放着最终物理地址的高20bit位,然后和虚拟地址的低12bit位就组成了最终的物理地址。...以上就是虚拟地址转换为物理地址的过程。 MMU访问页表是硬件实现的,但页表的创建和填充需要Linux内核来填充。通常,一级页表和二级页表存放在主存储器中。...是匿名页,即是vma->vm_ops为空,即vm_operations函数指针为空 我们知道在进程的task_struct结构中包含了一个mm_struct结构的指针,mm_struct用来描述一个进程的虚拟地址空间...因此ARM在移植到Linux时只能参考x86版本的Linux内核的实现。 X86的PGD是从bit22 ~ bit31,总共10bit位,1024页表项。

1.2K10

通过fork来剖析Linux内核的内存管理和进程管理(上)

实际上,除了0号进程,其他的所有进程无论是内核线程还是普通的用户进程和线程都是fork出来的,而创建进程是内核所做的事情,要么在内核空间直接创建出所谓的内核线程,要么是通过fork,clone这样的系统调用陷入内核空间来创建..._el1,当进行va->pa的转换的时候,mmu会判断地址是属于用户空间地址还是内核空间,如果是用户空间就使用ttbr0_el1作为base来进行页表walk,当地址属于内核空间地址就使用ttbr1_el1...内核将mm->pgd的虚拟地址转化为物理地址之后设置到了ttbr0_el1,将为进程分配的ASID设置到了ttbr1_el1(其实ttbr0_el1和ttbr1_el1都有ASID域,究竟设置到那个寄存器由...2)访问内核空间虚拟地址 访问内核空间虚拟地址,也会首先从tlb中查找对应的表项,找不到就会从ttbr1_el1开始遍历各级页表,然后最终将叶子表项(即是最后一级页表表项)填充到tlb中,并返回物理地址...没有找到就要接受系统惩罚,需要遍历多级页表项然后获得所需要的表项从表项中获得物理地址,这个过程呢需要根据是用户空间虚拟地址还是内核空间虚拟地址,从ttbr0_el1或 ttbr1_el1开始遍历多级页表

2.4K33
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Linux内核如何私闯进程地址空间并修改进程内存

    我们知道,在原始野人社会,是没有家庭的观念的,所有的资源都是部落内共享的,所有的野人都可以以任意的方式在任意时间和任何其他野人交互。类似Dos这样的操作系统就是这样的,内存地址空间并没有隔离。...在操作系统中,家庭类似于虚拟地址空间,而房子就是页表。 邻居不能闯入你的房子,但特权管理机构只要理由充分,就可以进入普通人家的房子,touch这家人的东西。...---- 仔细看上面那个内核模块的 get_pte 函数,这个函数要想写对,你必须对你想蹂躏的进程所在的机器的MMU有一定的了解,比如是32位系统还是64位系统,是3级页表还是4级页表或者5级?...有啊,别忘了一切皆文件,恰好在proc文件系统中,就有这么一个文件: /proc/$pid/pagemap 读取这个文件,得到的就是进程虚拟地址的页表项,下图截自内核Doc:Documentation/...---- 虚拟地址空间是每进程的,而物理地址空间则是所有进程共享的。换句话说,物理地址是全局的。

    3.6K20

    Linux操作系统:再谈虚拟地址空间

    在Linux系统中,将源代码转换为可执行程序通常需要四个主要步骤: 预处理:处理源代码中的宏定义、头文件包含等 编译:将预处理后的代码转换为汇编代码 汇编:将汇编代码转换为机器码(目标文件...这是我们已经梳理清楚的一条完整的线路。 那么,假如我们要加载一个文件到物理地址上,他的加载过程与虚拟地址空间有什么关联呢? 我想提出两个疑问: 1、mm_struct,是由谁初始化的?...而我们CPU在执行程序的时候,都用的是什么地址呢? 答案是虚拟地址,为什么可以使用虚拟地址来运行程序呢? :页表 页表的映射关系怎么来的呢? :把可执行加载到内存时,每个语句就放在他的物理地址上。...四、动态库的加载 在Linux内核中,每个进程的虚拟地址空间都由一个关键的数据结构mm_struct来管理。...动态库的加载过程完美体现了Linux内存管理的精妙设计,过程是一样的,由磁盘加载到内存中,虚拟地址与物理地址形成页表。

    24810

    手动玩转虚拟地址到物理地址转化

    根据TTBR(0/1)寄存器获取到页表的基地址 页表基地址+PGD_Index获取PGD表中的一项,此项就是PMD表的基地址 根据PDM基地址+PMD_Index获取PMD中的一项,此项就是PTE表的基地址...根据PTE基地址+PTE_Index获取直接页表的基地址 根据直接页表的地址+offset就可以获取真正的物理地址 转化之前先确认的是此地址是属于用户空间还是内核空间。...用户地址:页表的基地址是mm_struct→pgd 内核空间: 页表的基地址是init_mm→pgd 很明显我们需要转化的地址是属于内核空间的,则首先需要确认init_mm→pgd的值,它来了 init_mm...present的意思是页是否是有效的,无效代表虚拟到物理地址之间的转化无效,当访问虚拟地址的时候就会page fault protection :权限之类的,是否读写执行权限之类的。...如果你访问一段虚拟地址,页表中是无法执行的权限,但是你想执行这段代码就会出错 reference: 引用之类的 cache: cache是否有效。

    2.7K20

    深入理解Linux内核进程上下文切换

    实际上linux内核中,进程上下文包括进程的虚拟地址空间和硬件上下文。...,而这个地址空间是假的,是linux内核通过数据结构来描述出来的,从而使得每一个进程都感觉到自己拥有整个内存的假象,cpu访问的指令和数据最终会落实到实际的物理地址,对用进程而言通过缺页异常来分配和建立页表映射...pgd中保存的是进程的页全局目录的虚拟地址(本文会涉及到页表相关的一些概念,在此不是重点,不清楚的可以查阅相关资料,后期有机会会讲解进程页表),记住保存的是虚拟地址,那么pgd的值是何时被设置的呢?...181行,最终将进程的pgd虚拟地址转化为物理地址存放在ttbr0_el1中,这是用户空间的页表基址寄存器,当访问用户空间地址的时候mmu会通过这个寄存器来做遍历页表获得物理地址(ttbr1_el1是内核空间的页表基址寄存器...),每次用户虚拟地址访问的时候(内核空间共享不考虑),由于页表基地址寄存器内存放的是当前执行进程的页全局目录的物理地址,所以访问自己的一套页表,拿到的是属于自己的物理地址(实际上,进程是访问虚拟地址空间的指令数据的时候不断发生缺页异常

    11.7K1110

    韦东山:Linux驱动程序基石之mmap

    解析如下: ① 每个APP在内核中都有一个task_struct结构体,它用来描述一个进程; ② 每个APP都要占据内存,在task_struct中用mm_struct来管理进程占用的内存; 内存在虚拟地址...、物理地址,mm_struct中用mmap来描述虚拟地址,用pgd来描述对应的物理地址。...每一个APP的虚拟地址可能相同,物理地址不相同,这些对应关系保存在pgd中。...二级页表地址旺射的最小单位有4K、1K,Linux使用4K。 一级页表项里的内容,决定了它是指向一块物理内存,还是指问二级页表,如下图: ?...3.3, 驱动程序要做的事 驱动程序要做的事情有3点: ① 确定物理地址 ② 确定属性:是否使用cache、buffer ③ 建立映射关系 参考Linux源文件,示例代码如下: ?

    7.5K40

    Linux内存管理之MMU的过程

    「那么CPU是如何通过MMU和Cache来访问内存的呢?」 ? 可以看出虚拟地址和物理地址的转换关键是过程Table Walk Unit。...虚拟地址转换为物理地址的本质 我们知道内核中的寻址空间大小是由CONFIG_ARM64_VA_BITS控制的,这里以48位为例,ARMv8中,Kernel Space的页表基地址存放在TTBR1_EL1...有了宏观概念,下面我们以内核态寻址过程为例看下是如何把虚拟地址转换为物理地址的。...不管是页表还是要访问的数据都是以页为单位存放在主存中的,因此每次访问内存时都要先获得基址,再通过索引(或偏移)在页内访问数据,因此可以将线性地址看作是若干个索引的集合。...下面我们动手操作一下,通过代码来深度理解下虚拟地址是如何转化为物理地址的。

    2.7K43

    探秘malloc是如何申请内存的

    当我们尝试第一次读或者写的时候,就会经过如下步骤的: CPU将此虚拟地址,送到MMU上去 MMU会做虚拟到物理地址的转化 MMU在操作时发现,此虚拟地址还没有建立物理地址关系,则发生exception...当我们尝试写这个虚拟地址的时候,就会发生上面一系列操作,我通过修改内核的代码,当在申请此虚拟地址的时候会发生panic,然后抓到dump。...can_reuse_spf_vma(vma, addr)) //如果不存在vma,则通过地址找到vma,vma在mm_struct的红黑树中,只需要找此地址属于start...return 0; } 此函数主要是确认下当前错误是来自内核还是应用层 当调用__do_page_fault处理完毕后,就会对结果做进一步处理 如果用户空间,则后发信号的方式告知的。...虚拟地址到物理地址转化文档(手动玩转虚拟地址到物理地址转化) 虚拟地址:0x00000076143BC000 mm_struct→pgd = rd(0xFFFFFFE2E5D8B000) = 0xE5D80003

    2.9K51

    Linux操作系统之进程(五):初识地址空间

    在Linux地址下,这种地址叫做虚拟地址 我们在⽤C/C++语言所看到的地址,全部都是虚拟地址!...所谓的进程虚拟地址空间本质上是一个内核数据结构对象 mm_struct。...... }; 在 Linux 内核中,每个进程的虚拟地址空间都是由一个 mm_struct 结构来描述和管理的,它就像是大富翁的账本,详细记录着每个私生子(进程)“以为自己拥有的所有钱”的分布和使用情况...注意,这个是数值上的调整,但实际还是没有分配哦!只有当你真正用到了,才会真的申请,就跟期末的你一样,不到期末不学习啊 页表与写时拷贝 加载进程时,除了PCB,虚拟地址、物理地址也会被加载。...实际上,页表并不只是简单的虚拟地址与物理地址的映射,他还有很多小标记位来记录很多重要的指标: 在 32 位系统中,每个页表项(PTE)是一个 32 位(4 字节) 的数据。

    29010

    韦东山:Linux驱动程序基石之mmap

    映射关系保存在页表中: 解析如下: ① 每个APP在内核中都有一个task_struct结构体,它用来描述一个进程; ② 每个APP都要占据内存,在task_struct中用mm_struct来管理进程占用的内存...; 内存在虚拟地址、物理地址,mm_struct中用mmap来描述虚拟地址,用pgd来描述对应的物理地址。...vm_area_struct中的vm_start、vm_end是虚拟地址。 ④ vm_area_struct中虚拟地址如何映射到物理地址去?...每一个APP的虚拟地址可能相同,物理地址不相同,这些对应关系保存在pgd中。...3.3, 驱动程序要做的事 驱动程序要做的事情有3点: ① 确定物理地址 ② 确定属性:是否使用cache、buffer ③ 建立映射关系 参考Linux源文件,示例代码如下: 还有一个更简单的函数:

    4.7K31

    【Linux系统】进程地址空间

    在C/C++中,输出的地址是虚拟地址(virtual address),不是物理地址(physical address)。虚拟地址是进程视角的地址,由OS统一管理,每个进程都有自己的虚拟地址空间。...父子进程可能有相同的虚拟地址,但页表映射到不同的物理地址,因此变量值独立。 在上面代码中,gval的虚拟地址相同,但物理地址不同:子进程的gval存储在另一个物理位置,导致值变化。...1. mm_struct 的核心地位 作用:mm_struct 是描述整个进程用户空间虚拟地址空间的核心结构体,定义在 include/linux/mm_types.h 中 。...可以说,mm_struct 结构是对整个用户空间的完整描述。在Linux内核中,每个进程都会拥有自己独立的mm_struct结构体实例,这个结构体包含了该进程所有内存管理相关的信息。...虚拟内存区域(VMA):vm_area_struct vm_area_struct(简称 VMA)是 Linux 内核中描述进程虚拟地址空间中连续内存区域的核心数据结构。

    23311

    Linux用户态进程的内存管理

    下面闲话少说,开始本篇的内容——进程的内存消耗和泄漏 进程的虚拟地址空间VMA(Virtual Memory Area) 在linux操作系统中,每个进程都通过一个task_struct的结构体描叙,每个进程的地址空间都通过一个...上图中,task_struct中的mm_struct就代表进程的整个内存资源,mm_struct中的pgd为页表,mmap指针指向的vm_area_struct链表的每一个节点就代表进程的一个虚拟地址空间...但由于Lazy机制,这100M其实并没有获得,这100M全部映射到一个物理地址相同的零页,且在页表中记录的权限为只读的。...,在缺页中断的处理程序中读出虚拟地址和原因,去VMA中查,发现是用户程序在写malloc的合法区域且有写权限,Linux内核就真正的申请内存,页表中对应一页的权限也修改为R+W。...一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS 推荐阅读: CPU是如何访问内存的? 物理地址和虚拟地址的分布 Linux内核内存管理算法Buddy和Slab

    3.2K41

    【Linux 内核 内存管理】虚拟地址空间布局架构 ③ ( 内存描述符 mm_struct 结构体成员分析 | mmap | mm_rb | task_size | pgd | mm_users )

    文章目录 一、mm_struct 结构体成员分析 1、mmap 成员 2、mm_rb 成员 3、get_unmapped_area 函数指针 4、task_size 成员 5、pgd 成员 6、mm_users...成员 7、mm_count 成员 一、mm_struct 结构体成员分析 ---- mm_struct 结构体 在 Linux 源码 linux-4.12\include\linux\mm_types.h...#359 位置 ; 参考 【Linux 内核 内存管理】虚拟地址空间布局架构 ② ( 用户虚拟地址空间组成 | 内存描述符 mm_struct 结构体源码 ) 博客 ; 下面开始分析 mm_struct..." 大小 ; unsigned long task_size; /* size of task vm space */ 5、pgd 成员 pgd_t * pgd , 该指针指向 " 内存页 " 全局目录..., 第一级的页表 ; pgd_t * pgd; 6、mm_users 成员 atomic_t mm_users , 表示有多少个 " 进程 " 共享 " 用户虚拟地址空间 " , 即 线程组 的 进程

    69610

    Linux用户态进程的内存管理

    下面闲话少说,开始本篇的内容——进程的内存消耗和泄漏 进程的虚拟地址空间VMA(Virtual Memory Area) 在linux操作系统中,每个进程都通过一个task_struct的结构体描叙,每个进程的地址空间都通过一个...上图中,task_struct中的mm_struct就代表进程的整个内存资源,mm_struct中的pgd为页表,mmap指针指向的vm_area_struct链表的每一个节点就代表进程的一个虚拟地址空间...但由于Lazy机制,这100M其实并没有获得,这100M全部映射到一个物理地址相同的零页,且在页表中记录的权限为只读的。...,在缺页中断的处理程序中读出虚拟地址和原因,去VMA中查,发现是用户程序在写malloc的合法区域且有写权限,Linux内核就真正的申请内存,页表中对应一页的权限也修改为R+W。...malloc分配的原理 malloc的过程其实就是把VMA分配到各种段当中,这时候是没有真正分配物理地址的。

    3.4K30

    Linux分页机制之分页机制的实现详解--Linux内存管理(八)

    因此,在虚拟地址转化物理物理地址的过程中,每访问一级页表就会访问一次内存。 3.1.2 页表项 页表项从四种页表项的数据结构可以看出,每个页表项其实就是一个无符号长整型数据。...每个页表项分两大类信息:页框基地址和页的属性信息。在x86-32体系结构中,每个页表项的结构图如下: ? 这个图是一个通用模型,其中页表项的前20位是物理页的基地址。...不管是那一级的页表,它的功能就是建立虚拟地址和物理地址之间的映射关系,一个页和一个页框之间的映射关系体现在页表项中。...不管是页表还是要访问的数据都是以页为单 位存放在主存中的,因此每次访问内存时都要先获得基址,再通过索引(或偏移)在页内访问数据,因此可以将线性地址看作是若干个索引的集合。...通过如下几个函数,不断向下索引,就可以从进程的页表中搜索特定地址对应的页面对象 宏函数 说明 pgd_offset 根据当前虚拟地址和当前进程的mm_struct获取pgd项 pud_offset 参数为指向页全局目录项的指针

    4K42

    【Linux】虚拟地址空间 --- 虚拟地址、空间布局、内存描述符、写时拷贝、页表…

    (多提一句,static修饰的全局变量会由原来的外部链接属性改为内部链接属性) 9.内核空间: 非常抱歉,我当前的这个水平无法给您讲解透彻内核空间的知识,下面的知识内容是我从腾讯云开发社区找到的内容,...虚拟地址空间的本质就是内核的一种数据结构,叫做mm_struct结构体,这个结构体是描述虚拟地址空间的最核心的结构。 4.mm_struct内部结构(详谈OS画的大饼) 1....因为虚拟地址是包含所有的地址的,也就是4GB的空间,虽然是虚拟的,但是进程可以使用呀,所以如果进程在虚拟地址中访问了某个本不该属于当前进程的地址,接下来在通过页表映射到物理地址的这个阶段中,页表就会拦截进程非法访问地址的请求...mm_struct里面,mm_struct中无论是区域的起始和结束地址,还是区域里面程序对应的代码和数据,都被操作系统填充好了,至于栈和堆空间的开辟,在CPU读取mm_struct的代码段的时候,也就是在进程运行期间由操作系统分配相应的空间就好了...还是选择32位虚拟地址空间编址,一个是4GB一个是16GB,但也没啥用,因为都是虚拟的,仅仅只是空间范围而已。

    1.9K20

    深入理解Linux内核页表映射分页机制原理

    可见页表所需要的空间是很大的,所以页表都存储在物理内存中。即MMU通将虚拟地址转换为物理地址,需要访问物理内存中对应的页表。...pgd_offset_k(addr) 根据入参虚拟地址address和init_mm,找到address在页全局目录中相应表项的线性地址。仅用于内核页表。...页表映射过程是MMU通过TTBRx和虚拟地址VA[31:20]索引到PGD一级页表,再由PGD一级页表和虚拟地址VA[19:12]索引到PTE页映射表,在由PTE页映射表和虚拟地址VA[11:0]索引到物理地址...二级页表中的属性没有“dirty”位。 而Linux有一个三层的页表结构,可以很容易地将其包装成适合两层的页表结构—只使用PGD和PTE。...3.2节中描述的硬件页表的属性是相互对应的,其含义与硬件页表属性含义一致。

    4.7K11

    Linux内核页表管理-那些鲜为人知的秘密

    ,而页表管理是在虚拟内存管理中尤为重要,本文主要以回答几个页表管理中关键性问题来解析Linux内核页表管理,看一看页表管理中那些鲜为人知的秘密。...页表存放在物理内存中,打开mmu之后,如果需要修改页表,需要将页表所在的物理地址映射到虚拟地址才能访问页表(如内核初始化后会将物理内存线性映射,这样通过物理地址和虚拟地址的偏移就可以获得页表物理地址对应的虚拟地址...页表项中存放是虚是实? 页表基地址寄存器和各级页表项中存放的都是物理地址,而不是虚拟地址。 5. 开启mmu后地址转换过程?...虚拟地址转换物理地址的过程:打开mmu后,cpu访问的都是虚拟地址,当cpu访问一个虚拟地址的时候,会通过cpu内部的mmu来查询物理地址,mmu首先通过虚拟地址在tlb中查找,如果找到相应表项,直接获得物理地址...,可以将各级页表放到物理内存的任何地方,无论是硬件遍历还是内核遍历,比一级页表更复杂,但是为了节省内存,内核选择多级页表结构。

    2.5K22

    Linux内存管理--基本概念

    • 内存节点node 内存节点node是计算机系统中对物理内存的一种描述方法,一个总线主设备访问位于同一个节点中的任意内存单元所花的代价相同,而访问任意两个不同节点中的内存单元所花的代价不同...Linux内核中使用数据结构pg_data_t来表示内存节点node。如常用的ARM架构为UMA架构。...如基于IA32体系结构的个人计算机系统中,由于历史原因使得ISA设备只能使用最低16MB来进行DMA传输。又如,由于Linux内核采用 • 物理页框page 2....每个pte_t指向一个物理页的地址,并且所有的地址都是页对齐的。因此在32位地址中有PAGE_SHIFT(12)位是空闲的,它可以为PTE的状态位。...• pgd_offset 根据当前虚拟地址和当前进程的mm_struct获取pgd项的宏定义如下: • pmd_offset 根据通过pgd_offset

    1.9K90
    领券