首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

中间的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页表项。

38310

通过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开始遍历多级页表

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

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

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

    3.2K20

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

    根据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.4K20

    Linux内存管理之MMU的过程

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

    2.3K42

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

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

    10.5K1110

    韦东山: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源文件,示例代码如下: ?

    7K40

    探秘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.4K51

    韦东山: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.1K31

    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

    2.8K41

    【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 , 表示有多少个 " 进程 " 共享 " 用户虚拟地址空间 " , 即 线程组 的 进程

    49710

    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分配到各种段当中,这时候是没有真正分配物理地址的。

    2.9K30

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

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

    3.5K42

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

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

    1.5K20

    深入理解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节中描述的硬件页表的属性是相互对应的,其含义与硬件页表属性含义一致。

    3.7K11

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

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

    1.9K22

    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.7K90

    【Linux内核大揭秘】程序地址空间

    地址空间的组成 地址空间分为逻辑地址和物理地址两种: 逻辑地址:是程序在代码中使用的地址,不直接对应物理内存。每个进程都有独立的逻辑地址空间。 物理地址:是真正存储在内存中的位置。...这个内核数据结构叫做mm_struct,在PCB中有一个指针指向虚拟地址空间,PCB控制着这个虚拟地址空间,然后mm_struct通过映射,映射到真实的物理内存上。...页表 什么是页表: 页表是操作系统内核用来管理虚拟地址和物理地址之间映射的一个数据结构。它的核心作用是支持虚拟内存,使得每个进程可以在自己的独立虚拟地址空间中运行,增强了内存隔离和安全性。...首先父进程创建子进程会以自己为模版创建一个PCB,内核会为子进程创建一个新的mm_struct,mm_struct的大部分字段和和父进程共享,页表也会被创建,所以这里物理地址指向的是同一块空间。...在Linux中如何查看各个分段的信息 readelf -S 文件名 总结 通过本篇文章,我们了解了 Linux 程序地址空间的基本结构和分布,包括代码段、数据段、堆、栈以及内核空间的划分。

    12210

    Linux C程序真的不能访问NULL指针吗?

    本文表达的宗旨: 任何虚拟地址,只要有合法的页表映射,就能访问! ---- 提到C语言编程,我想几乎所有人都遭遇过NULL指针。我们的代码中总是在不断的判断指针是否为NULL: if (p1 !...---- 在现代操作系统中,程序访问的地址都是虚拟地址,硬件MMU结合操作系统创建的页表会在进程私有虚拟地址和全局物理地址之间做映射,当程序访问一个虚拟地址的时候,该映射会将这次访问转换成到物理地址的访问...所以, segfault的本质是程序访问的虚拟内存地址无法合理映射到物理地址的一种错误通知。 引发segfault的地址成为非法地址。...下面该写内核模块了,为了简化操作,这里采用Guru模式的stap脚本来进行编程: // mapNULL.stp%{#include linux/mm.h>#include linux/sched.h...很显然,used内存是calloc返回的,这种内存是被malloc内存管理结构锁管理的,第一行的16字节就是这种管理机构,如果我们破坏掉它,那么在最后的free处就会出错。

    3.4K10

    深入理解虚拟 物理地址转换,页表--基于ARMV8

    页表转换寄存器描述符 1.1,页表/页目录结构 基于前言中的内核配置,内核采用39位虚拟地址,因此可寻址范围为2^39 = 512G,采用(linux 默认为五级页表,另外还有PUD,P4D,由于本文只配置三级...; 当bit[1:0] = {1,0|0,0}时,该表项为无效项; 转换表描述符中lower attributes中存储相关属性信息,mmu在查找到相应的表项时,首先会查询属性信息,确认地址的相关属性(...2.3 用户/内核PGD表基地址 基于之前的分析可知,用户虚拟地址和内核虚拟地址转换为物理地址的时候使用不同的页表基地址寄存器(TTBRx),因此他们的转换是基于不同的全局页目录表PGD。...其中内核全局页目录表PGD存储在init_mm.pgd中,我们知道内核是常驻内存的,因此内核的PGD表只有一份,他不会因为进程的切换而改变,所有内核地址访问都依赖这一个PGD表;用户全局页目录表PGD存储在进程描述符...页表的查询,因此在进程切换时,TTBR0中的值(task_struct.mm.pgd)是要同时改变的,这也与linux中每一个进程都独占整个虚拟(此为512G)地址空间相对应; 三、转换流程 据此可以画出如下转换框图

    63800
    领券