精华内容
下载资源
问答
  • 2021-11-05 10:14:12


       研究地址关系转换表,其实它有个更加专业的名字——页表。它描述了虚拟地址到物理地址的转换关系,也可以说是虚拟页到物理页的映射关系,所以称为页表。
       为了增加灵活性和节约物理内存空间(因为页表是放在物理内存中的),所以页表中并不存放虚拟地址和物理地址的对应关系,只存放物理页面的地址,MMU 以虚拟地址为索引去查表返回物理页面地址,而且页表是分级的,总体分为三个部分:一个顶级页目录,多个中级页目录,最后才是页表,逻辑结构图如下.
       在这里插入图片描述
       从上面可以看出,一个虚拟地址被分成从左至右四个位段。第一个位段索引顶级页目录中一个项,该项指向一个中级页目录,然后用第二个位段去索引中级页目录中的一个项,该项指向一个页表,再用第三个位段去索引页表中的项,该项指向一个物理页地址,最后用第四个位段作该物理页内的偏移去访问物理内存。这就是 MMU 的工作流程。

    概述

    虚拟地址/物理地址

    如果处理器没有MMU,CPU内部执行单元产生的内存地址信号将直接通过地址总线发送到芯片引脚,被内存芯片接收,这就是物理地址(physical address),简称PA。英文physical代表物理的接触,所以PA就是与内存芯片physically connected的总线上的信号。
       如果MMU存在且启用,CPU执行单元产生的地址信号在发送到内存芯片之前将被MMU截获,这个地址信号称为虚拟地址(virtual address),简称VA,MMU会负责把VA翻译成另一个地址,然后发到内存芯片地址引脚上,即VA映射成PA,如下图:

    在这里插入图片描述
      所以物理地址①是通过CPU对外地址总线②传给Memory Chip③使用的地址;而虚拟地址④是CPU内部执行单元⑤产生的,发送给MMU⑥的地址。硬件上MMU⑥一般封装于CPU芯片⑦内部,所以虚拟地址④一般只存在于CPU⑦内部,到了CPU外部地址总线引脚上②的信号就是MMU转换过的物理地址①。
      软件上MMU对用户程序不可见,在启用MMU的平台上(没有MMU不必说,只有物理地址,不存在虚拟地址),用户C程序中变量和函数背后的数据/指令地址等都是虚拟地址,这些虚拟内存地址从CPU执行单元⑤发出后,都会首先被MMU拦截并转换成物理地址,然后再发送给内存。也就是说用户程序运行*pA =100;"这条赋值语句时,假设debugger显示指针pA的值为0x30004000(虚拟地址),但此时通过硬件工具(如逻辑分析仪)侦测到的CPU与外存芯片间总线信号很可能是另外一个值,如0x8000(物理地址)。当然对一般程序员来说,只要上述语句运行后debugger显示0x30004000位置处的内存值为100就行了,根本无需关心pA的物理地址是多少。但进行OS移植或驱动开发的系统程序员不同,他们必须清楚软件如何在幕后辅助硬件MMU完成地址转换。


    页/页帧/页表/页表项(PTE)

    ..这几个页概念也噎倒了不少人,这里澄清下。MMU是负责把虚拟地址映射为物理地址,但凡"映射"都要解决两个问题:映射的最小单位(粒度)和映射的规则。
      MMU中VA到PA映射的最小单位称为页(Page),映射的最低粒度是单个虚拟页到物理页,页大小通常是4K,即一次最少要把4K大小的VA页块整体映射到4K的PA页块(从0开始4K对齐划分页块),页内偏移不变,如VA的一页0x30004000~0x30004fff被映射到PA的一页 0x00008000~0x00008fff,当CPU执行单元访问虚拟地址0x30004008,实际访问的物理地址是0x00008008(0x30004008和0x00008008分别位于虚实两套地址空间,互不相干,不存在重叠和冲突)。以页为最小单位,就是不能把VA中某一页划分成几小块分别映射到不同PA,也不能把VA中属于不同页的碎块映射到PA某一页的不同部分,必须页对页整体映射。
      页帧(Page Frame)是指物理内存中的一页内存,MMU虚实地址映射就是寻找物理页帧的过程,对这个概念了解就可以了。
       MMU软件配置的核心是页表(Page Table),它描述MMU的映射规则,即虚拟内存哪(几)个页映射到物理内存哪(几)个页帧。页表由一条条代表映射规则的记录组成,每一条称为一个页表条目(Page Table Entry,即PTE),整个页表保存在片外内存,MMU通过查找页表确定一个VA应该映射到什么PA,以及是否有权限映射。
       但如果MMU每次地址转换都到位于外部内存的页表上查找PTE,转换速度就会大大降低,于是出现了

    TLB

    .. TLB (Translation Lookaside Buffers)即转换快表,又简称快表,可以理解为MMU内部专用的存放页表的cache,保存着最近使用的PTE乃至全部页表。MMU接收到虚拟地址后,首先在TLB中查找,如果找到该VA对应的PTE就直接转换,找不到再去外存页表查找,并置换进TLB。TLB属于片上SRAM,访问速度快,通过TLB缓存PTE可以节省MMU访问外存页表的时间,从而加速虚实地址转换。TLB和CPU cache的工作原理一样,只是TLB专用于为MMU缓存页表。

    **MMU的内存保护功能

    .. 既然所有发往内存的地址信号都要经过MMU处理,那让它只单单做地址转换,岂不是浪费了这个特意安插的转换层?显然它有能力对虚地址访问做更多的限定(就像路由器转发网络包的同时还能过滤各种非法访问),比如内存保护。可以在PTE条目中预留出几个比特,用于设置访问权限的属性,如禁止访问、可读、可写和可执行等。设好后,CPU访问一个VA时,MMU找到页表中对应PTE,把指令的权限需求与该PTE中的限定条件做比对,若符合要求就把VA转换成PA,否则不允许访问,并产生异常。

    多级页表

    直接看下面这张图吧,以64位的虚拟地址为例,其中CR3是CPU的一个寄存器,从图中也可以看出来用来存放顶级页目录项。所以MMU开启之后,首先就是读取CR3寄存器的内容
    在这里插入图片描述
      至于为啥要采取这种多级页表的形式:你想想,如果一个虚拟地址对应一个物理地址,我们把这种映射关系直接用一个映射表存起来,这是很占内存的,而且查询速度也很慢
      什么?为什么更耗内存?这样吧,你存(11111112;11111113;11111114)和(111111/(2;3;4))哪种存法,更省空间?动动你聪明的小脑袋

    **操作系统和MMU

    实际上MMU是为满足操作系统越来越复杂的内存管理而产生的。OS和MMU的关系简单说:
      a.系统初始化代码会在内存中生成页表,然后把页表地址设置给MMU对应寄存器,使MMU知道页表在物理内存中的什么位置,以便在需要时进行查找。之后通过专用指令启动MMU,以此为分界,之后程序中所有内存地址都变成虚地址,MMU硬件开始自动完成查表和虚实地址转换。
       bos初始化后期,创建第一个用户进程,这个过程中也需要创建页表,把其地址赋给进程结构体中某指针成员变量。即每个进程都要有独立的页表。

    MMU映射失败的几种情况

    ..1.访问了受内核保护的页面,或者访问了只读的页面(比如c语言中存储字符串字面量和const变量的段),此时内核会抛出段错误
      2.页面和页框没有产生映射关系,但是数据页已经被其他进程加载到内存中了,此时只需要建立页面和页框的映射关系,称为次级缺页中断
      3.页面和页框没有产生映射关系,数据页也没有被加载到内存中(在磁盘上),此时需要发生磁盘io从磁盘中加载页到内存中,还需要建立页面和页框的映射关系,称为严重缺页中断。
    除了第一点,第二第三都会以内核降低自身运行速度来修复,也就是老师说的,通过中断形成页表映射,然后再重新执行引起中断的命令(此时数据页已经在内存中并且建立映射关系了)。

    总结

    ..所以说,虚拟地址到物理地址的转换,最核心的是什么?是页表,无论中间转多少个弯(那些页目录项啥的),最终都会指向页表,而页表中存放着物理页地址
      这里扩展一点,所以说,进程空间的隔离是怎么做到呢?我们知道每个进程享有互不干扰的4GB的虚拟空间,按我们上面说的,可以推测到,不同进程最终经过MMU地址转换,会指向不同的页表,从而完成了地址的隔离

    鸣谢单位
    硬件篇之MMU_ipmux的博客-CSDN博客_mmu

    更多相关内容
  • Zynq MMU 缓存控制 控制 Zynq Cortex A9 MMU/缓存的指南 (还展示了如何在 Xilinx SDK 中创建自定义软件库) 这是一份应用笔记,适用于希望通过 Xilinx Zynq SoC 器件控制 Cortex A9 器件上的缓存/MMU 的用户。 此...
  • k210-linux-nommu简介这是一个面向初学者的教程,主要介绍如何编译内核以在k210上运行NOMMU linux。 并且,本教程将展示如何交叉编译tcc,以便您可以执行C k210-linux-nommu。简介这是面向初学者的教程,主要介绍...
  • TZB-MMU2S-固件 MMU2S 3轴TMC2130步进控制器 最新稳定的预编译HEX文件,请参考RELEASES页面。 请查看有关操作全新TZB-MMU2S安装的所有方面的内容。 注意事项 您不必重置为出厂设置,所有相同的EEPROM数据结构都用作...
  • 一、MMU的产生 许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以容纳当时的程序。...
  • MMU存储器系统的结构允许对存储器系统的精细控制,而MMU主要由ARM中协处理器Coprocessor15 (CP15)控制。  协处理器主要控制:片内的MMU、指令和数据缓存(IDC)、写缓冲(Write Buffer)。  MMU大部分的控制...
  • 来宾内核是配置有User-Mode-Linux(UML)和no-MMU的经过修改Linux。 最好的方式是使用经过改进的用户模式Linux(UML),该模式更快,更安全,但通用性却大大降低。 尝试这种单线 docker run --rm -it kollerr/...
  • MMU-板载-Android 带有解析后端的MMU Board Simple android论坛应用程序的Android版本
  • MMU,全称Memory Manage Unit, 中文名——存储器管理单元。 许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以...
  • MMU与CACHE详解

    2017-02-20 17:32:27
    本文介绍了MMU的概念及相关原理,并引出了MMU与CACHE的区别和对比,深入剖析了二者的不同点。适合那些对MMU于CACHE不太了解的同学
  • ARM-MMU中文手册

    2020-04-17 11:29:17
    ARM-MMU中文手册,主要介绍 本文描述基于存储器管理单元的系统结构, 包含以下内容: · 关于存储器管理单元的结构 · 存储器访问的顺序 · 转换过程 · 访问权限 · 域 · 异常 · CP15 寄存器
  • Func_Verif_MMU_Code_Source 具有数据缓存和指令缓存的多处理器的MMU(内存管理单元)功能验证此存储库是我在法国公司实习期间编写的所有代码源。 由于版权,请勿复制。 该存储库只是为了展示我在寻找工作期间在我...
  • 由现场可编程门阵列(FPGA)和...提出了一种基于存储管理单元(MMU)的软硬件任务间通信方法,通过引入一种基于MMU思想的虚拟地址映射机制,在硬件中实现了描述MMU进行虚拟地址映射行为的模块,使硬件任务同软件任务一
  • ./mmu < config> 或者,在Windows上,您可以使用以下命令进行编译: mkdir bin javac -d bin src\mmu\*.java 并运行: java -cp bin mmu.Main <config> 配置 配置文件是具有以下格式的文本文件: physical-...
  • 一、S3C2440存储控制器  如果大家写过S3C2440的ARM裸机程序都应该知道通常SDRAM的起始地址是0X30000000,但是大家有没有想过为什么呢?下面我将给大家做一个简要的介绍。  查S3C2440的手册可知S3C2440可寻址1G的...
  • 基于FPGA的MMU IP软核设计及实现.pdf
  • MMU学习笔记

    2018-09-30 22:21:39
    个人在学习arm Linux嵌入式开发的时候写的笔记 包括对bank的理解 对段地址和大小页的理解 协处理器的理解 TLB的理解
  • ARM关闭MMU相关资源

    2018-06-03 13:22:46
    1. 关闭MMU的 汇编源码 链接器脚本 Makefile 文件 2. 汇编语言参考手册 : arm汇编手册(中文版).chm 3. ARM 架构参考手册 : ARM Architecture Reference Manual.pdf 4. 开发板芯片手册 : S3C6410X.pdf 5.ARM11 的 ...
  • ARM920T的MMU与Cache

    2020-08-14 05:58:17
    Cache是高性能CPU解决总线访问速度瓶颈的方法,然而它的使用却是需要权衡的,因为缓存本身的动作,如块拷贝和替换等,也是很消耗CPU时间的。
  • RISCV MMU 概述

    千次阅读 2022-03-20 14:47:04
    本文只描述其中的一个知识点 Paging and MMU。 本文以全志 D1 为例,包含了平头哥出品的一颗 Riscv64 的 CPU IP-Core,代号 C906。具体手册可以参考 C906 用户手册。 2. X86_64 同样是 64bit cpu,x86_64 支持 48bit...

    1. 背景简介

    Linux 内存管理包含很多内容,主要知识点可以参考 Linux Mem。本文只描述其中的一个知识点 Paging and MMU

    本文以全志 D1 为例,包含了平头哥出品的一颗 Riscv64 的 CPU IP-Core,代号 C906。具体手册可以参考 C906 用户手册

    2. X86_64

    同样是 64bit cpu,x86_64 支持 48bit 和 57bit 两种线性地址模式,分别对应 4level 和 5level mmu 映射:

    线性地址mmu 层级Linux user address spaceLinux kernel address space
    Sv48 (48bit)4level: pgd→pud→pmd→pte→page(4k)0x00000000 00000000 - 0x00007FFF FFFFFFFF0xFFFF8000 00000000 - 0xFFFFFFFF FFFFFFFF
    Sv57 (57bit)5level: pgd→p4d→pud→pmd→pte→page(4k)0x00000000 00000000 - 0x00FFFFFF FFFFFFFF0xFF000000 00000000 - 0xFFFFFFFF FFFFFFFF

    X86_64 使用 CR3 寄存器来保存 MMU 映射表的根地址。

    更详细信息可以参考 分页寻址(Paging)机制详解内核地址空间布局详解

    3. C906

    Sv39/Sv48/Sv57/Sv64 这几种模式 riscv64 都支持。因为 C906 设计的应用场景不需要那么多的内存资源,目前 C906 只支持 Sv39 模式,对应 3level mmu 映射。

    线性地址mmu 层级Linux user address spaceLinux kernel address space
    Sv39 (39bit)3level: pgd→pmd→pte→page(4k)0x00000000 00000000 - 0x0000003F FFFFFFFF0xFFFFFFC0 00000000 - 0xFFFFFFFF FFFFFFFF

    和 x86 CR3 类似,riscv 使用 SATP 寄存器来保存 MMU 映射表的根地址。具体的映射关系如下:
    在这里插入图片描述

    3.1 SATP 寄存器

    SATP 寄存器的具体格式如下图所示:
    在这里插入图片描述

    具体字段的解析如下:

    • Mode - MMU 地址翻译模式
    ValueNameDescription
    0BareNo translation or protection
    1-7-Reserved
    8Sv39Page-based 39-bit virtual addressing
    9Sv48Page-based 48-bit virtual addressing
    10Sv57Reserved for page-based 57-bit virtual addressing
    11Sv64Reserved for page-based 64-bit virtual addressing
    12-15-Reserved

    当 Mode 为 0 时,MMU 关闭。C906 只支持 MMU 关闭和 Sv39 两种模式。

    • ASID – 当前 ASID。表示当前程序的 ASID 号。
    • PPN – 硬件回填根 PPN。第一级硬件回填使用的 PPN (Phsical Page Number)。

    3.2 页表表项

    pgd/p4d/pud/pmd/pte 每级页表中包含的表项大小都是 8 bytes,每个 4k page 内存只能容纳 512 个页表项,所以每级页表的寻址范围为 9bit。

    c906 具体的页表表项格式如下所示:
    在这里插入图片描述
    具体字段的解析如下:

    • PPN – 页表物理地址。PPN[i] 分别代表三级页表转换时所对应的 PPN 值。

    • RSW – Reserved for Software。用于预留给软件做自定义页表功能的位。default 为 2’b0。

    • D – Dirty
      D 位为 1 时,表明该页是否被改写。
      1’b0: 当前页未被写/不可写;
      1’b1: 当前页已经被写/可写。
      此位在 C906 的硬件实现与 W 属性类似。当 D 位为 0 时,对此页面进行写操作会触发 Page Fault (store)
      异常,通过在异常服务程序中配置 D 位来维护该页面是否已经被改写/可写的定义。该位复位为 0。

    • A – Accessed
      A 位为 1 时,表明该页被访问过。为 0 时表示没被访问过,对该页表的访问会触发 Page Fault (对应访问
      类型) 异常且将该域置为 1。该位复位为 0。

    • G – Global
      全局页面标识,当前页可供多个进程共享,该位复位为 0。
      1’b0: 非共享页面,进程号 ASID 私有;
      1’b1: 共享页面。

    • U – User
      用户模式可访问,该位复位为 0。
      1’b0: 用户模式不可访问,当用户模式访问,出 page fault 异常;
      1’b1: 用户模式可访问。

    • X :可执行;W :可写;R :可读。

    XRW 权限说明

    XWRMeaning
    000Pointer to next level of page table
    001Read-only page
    010Reserved for future use
    011Read-write page
    100Execute-only page
    101Read-execute page
    110Reserved for future page
    111Read-write-execute page

    违反 XWR 权限时将会触发 Page Fault 异常。

    • V – Valid
      表明物理页在内存中是否分配好,访问一个 V 为 0 的页面,将触发 Page Fault 异常。该位复位为 0。
      1’b0: 当前页没有分配好;
      1’b1: 当前页已分配好。

    C906 扩展页面属性如下

    • SO– Strong order
      用于表示内存对访问顺序的要求:
      1’b0: no strong order(Normal-memory);
      1’b1: strong order(Device)。
      默认是 no strong order。

    • C – Cacheable
      1’b0: Non-cacheable;
      1’b1: Cacheable。
      默认是 Non-cacheable。

    • B – Buff er
      1’b0: Non-bufferable ;
      1’b1: Bufferable 。
      默认是 Non-bufferable 。

    • Sec (T – Trustable)
      用于表征页面属于可信世界或者非可信世界,该位仅在配有 TEE 扩展时有意义,C906 中该位未定义。
      1’b0: Non-trustable;
      1’b1: Trustable;
      默认是 Trustable。

    3.3 Huge Page

    x86 的页表表项中使用了一个 PS 位来标识当前是不是 huge page,如果设置了这个 bit,那么 pud 能直接寻址 1G 的大页,pmd 能直接寻址 2M 的大页。
    在这里插入图片描述
    c906 的表项中并没有 PS 这个 bit,它是用 XRW 3 个 bit 的组合来标识当前是不是最后一级页表的。

    • 如果 XRW = 000,则是中间一级页表
    • 如果 XRW != 000,则是最后一级页表。pgd 为 1G 大页,pmd 为 2M 大页。

    3.4 ASID

    ASID (Adress Space ID) 的主要目的是给 mmu 缓存到 tlb 时打标签用的,如果页表表项中设置了 G – Global 则是全局的不受 ASID 的约束。

    在 Linux 中每个用户进程拥有自己的地址空间,拥有一套独立的 mmu 映射关系。所以在进程切换时 mmu 映射也需要切换。

    ASID 作用主要有两个:

    • 减少 tlb 的全局刷新。
    • 在不刷新的情况下做权限隔离。

    ASID 的详细原理可以参考:内核页表隔离 (KPTI) 详解

    4. Linux 对 mmu 的常用操作

    linux 在以下场景下会对mmu 进行操作,这里就不详细展开:

    scenedescription
    fork()简单复制 mmu 映射关系
    execv()重新创建用户态 vma 映射
    mmap()创建一段新的 vma 映射
    task_switch切换不同地址空间的 mmu 映射
    page_fault()根据 vma 映射创建实际的 mmu 映射
    mprotect()更改 vma 和 mmu 的内存属性
    system call在开启 KPTI 的情况下,会发生 mmu 切换
    mem reclaim在回收文件内存以后,销毁对应 mmu 映射

    参考文档

    1.C906 用户手册
    2.分页寻址(Paging)机制详解
    3.内核地址空间布局详解
    4.commit:RISC-V: Paging and MMU
    5.内核页表隔离 (KPTI) 详解

    展开全文
  • MPU与MMU

    2022-01-24 17:33:44
    如果处理器启用了MMU,CPU执行单元发出的内存地址将被 MMU 截获,从CPU到MMU 的地址称为虚拟地址,而MMU 将这个地址翻译成另一个地址,发到CPU芯片的外部地址引脚上,也就是将VA映射成了PA 了。 如果是32位处理器,...

    MPU

    MPU 有以下能力可以增加系统的健壮性

    • 可以阻止用户去破坏操作系统需要使用的数据
    • 可以防止一个任务去非法访问其他任务的数据,将任务完全隔离开
    • 可以把关键数据区设为只读,从而不被破坏
    • 检测其他意外访问,比如,堆栈溢出,数组越界等。

    原理

    通常MPU功能这个是由操作系统提供的服务。在嵌入式调试的时候,我们经常会遇到 hardfault,这个时候一般情况可能是某个指针指到未知的地方,然后对该地址进行修改赋值,会触发 hardfault。MPU的功能其实和这个功能基本类似。

    比如,RTOS中的一些特殊的变量,用户线程是不被允许访问和修改的,这个时候如果你启用了 MPU,并且保护了这些变量,那用户即使知道这里的实际的物理地址,也是不被允许访问和修改的。

    MPU 本质上就是为了保护某一段地址区域不被非授权状态的程序进行访问。

    MMU

    我们知道应用程序不能随意访问内存的,如果让应用程序直接访问内存,计算机内存中所有的内容将被暴露出来,这是很危险的。所以出现了MMU,MMU是内存管理单元,应用程序访问的是虚拟内存,虚拟内存能够通过MMU的转换,变成物理内存。

    内存管理的好处:

    • 为编程提供方便统一的内存空间抽象,在应用开发而言,好似都完全拥有各自独立的用户内存空间的访问权限,这样隐藏了底层实现细节,提供了统一可移植用户抽象。
    • 以最小的开销换取性能最大化,利用MMU管理内存肯定不如直接对内存进行访问效率高,为什么需要用这样的机制进行内存管理,是因为并发进程每个进程都拥有完整且相互独立的内存空间。那么实际上内存是昂贵的,即使内存成本远比从前便宜,但是应用进程对内存的寻求仍然无法在实际硬件中,设计足够大的内存实现直接访问,即使能满足,CPU利用地址总线直接寻址空间也是有限的。

    从操作系统角度来看,虚拟内存的基本抽象由操作系统实现完成:

    • 处理器内存空间不必与真实的所连接的物理内存空间一致。
    • 当应用程序请求访问内存时,操作系统将虚拟内存地址翻译成物理内存地址,然后完成访问。

    虚拟内存系统会将虚拟内存,划分为固定大小的块(又叫做最小粒度,一般有4KB、16KB、64KB等大小,其中4KB最流行),这个块我们称作为虚拟页(Virtual Page简称VP),同理将物理内存划分为物理页(Physical Page简称PP),也叫页帧(Page Frame)

    每个虚拟页的首地址,会被维护在一个表内,这个表叫做查询表或页表(Page Table,简称PT),页表内的每一个条目,被称为页表项(Page Table Entry,简称PTE)

    这个页表可能有多级,一般来说,级数越多,能覆盖的虚拟地址范围就越大。在多级页表当中,除最后一级页表之外的所有页表,它的页表项存放的不一定是物理页,也可能是下一级页表的地址。
    在这里插入图片描述

    在这个基础上,虚拟系统会产生一个虚拟地址,由虚页号+页偏移组成。 虚页号存放的一般是页表项的偏移地址(也可能是多级页表的组合),通过对页表的不断查询,最后找到对应的物理页(的首地址),然后加上虚拟地址的页偏移,就能顺利计算出真实的物理地址。
    在这里插入图片描述

    虚拟存储器(Virtual Memory)

    虚拟存储存的基本思想是:

    程序、数据、堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。

    与虚拟地址空间 和 虚拟地址相对应的则是物理地址空间 和 物理地址,多数时候系统所具备的物理地址空间只是虚拟地址空间的一个子集。

    这时举一个最简单的例子直观的说明这两者,对于一台内存为256MB 的32Bit x86 主机来说,它的虚拟地址空间范围是0x0 ~ 0xFFFF FFFF (4G),而物理地址空间范围是0x0000 0000 ~ 0x0FFF FFFF ( 256MB )。

    在没有使用虚拟地址的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储被读写。而使用了虚拟存储的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到内存管理单元— MMU。MMU由一个或一组芯片组成,一般存在于协处理器中,其功能是把虚拟地址映射为物理地址。

    在这里插入图片描述

    1. CPU 看到的是 Virtual Adress (程序中的逻辑地址)
    2. Caches 和 MMU 使用的是 MVA (实际的虚拟地址 MVA = (pid << 25) | VA)
    3. 实际物理设备使用的是 Physical Address (物理地址)

    MMU的工作过程

    大多数使用虚拟存储器的系统都使用一种称为分页(paging)。

    虚拟地址空间划分为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页框(frame)。页和页框的大小必须相同。

    接下来配全图片,以一个例子说明页与页框之间在MMU 的调度下是如何进行映射的:

    在这里插入图片描述

    在这个例子中,我们有一个可以生成16位地址的机器,它的虚拟地址范围从0x0000 ~ 0xFFFF(64k),而这台机器只有32K 的物理地址,因此它可以运行64K 的程序,但该程序不能一次性调入内存运行。

    这台机器必须有一个达到可以存放64K 程序 的外部存储器(例如磁盘或Flash) 以保证程序片段在需要时可以被调用。

    这个例子中,页的大小为64K ,页框大小与页相同(这点必须保证的,内存和外围存储器之间传输总是以页为单位),对 应64K 的虚拟地址和32K 的物理存储器,它们分别包含了16 个页 和 8 个页框。

    执行下面这些指令:

    MOVE REG,0 // 将 0 号地址的值传递进寄存器 REG

    虚拟地址 0 将被送往MMU,MMU看到该虚拟地址落在页0 范围内(页0 范围是0 到 4095),从上图我们可以看出页0 所对应的(映射)的页框为 2(页框2的地址范围是8192 到 12287)。

    因此,MMU 将该虚拟地址转化为物理地址 8192, 并把地址8192送到地址总结上。

    内存对MMU 的映射一无所知,它只看到一个对地址8192的读请求并执行它,MMU 从而将8192 到 12287换虚拟地址解析为对应的物理地址 0 到 4096 。

    MOVE REG , 20500 //被转换为----> MOVE REG, 12308

    因为虚拟地址20500 在虚页5(虚拟地址范围是20480 到 24575)距开头20个字节处,虚页5映射到页框3(页框3的地址范围是12288 到 16383),于是被映射到物理地址12288 + 20 = 12308。

    MOV REG , 32780

    虚拟地址32780 落在页 8 的范围内,从上图我们看出,页8并没有被 有效的进行映射(该页被打上X),这时又会发生什么呢?

    MMU 注意到这个页没有被映射,于是通知CPU 发生一个缺页故障(page fault),这种情况下,操作系统必须处理这个页故障,它必须从8个物理页框中找到一个很少被使用的页框,并把该页框的内容写入外围存储器(这个动作被称为page copy),随后把需要引用的页(本例 是页8)映射到刚才被释放的页框中(这个动作被称为修改映射关系),然后重新执行产生故障的指令(MOV REG, 32780).

    假定操作系统,决定释放页框1, 以使以后任何对虚拟地址4K 到 8K 的访问都引起故障而使操作系统做出适当的动作。

    其次它把虚页8 对应的页框号由X 变为1, 因此得新执行MOV REG, 32780,MMU 将32780 映射为 4180。

    我们已经知道,大多数使用虚拟存储器的系统都使用一种称为分页(paging)的技术,就象我们刚才所举的例子,虚拟地址空间被分为大小相同的一组页,每个页有一个用来标示它的页号(这个页号一般是它在该组中的索引,这点和C/C++中的数组相似)。

    在上面的例子中04K的页号为0,48K的页号为1,8~12K的页号为2,以此类推。

    而虚拟地址(注意:是一个确定的地址,不是一个空间)被MMU分为2个部分,第一部分是页号索引(page Index),第二部分则是相对该页首地址的偏移量(offset).

    我们还是以刚才那个16位机器结合下图进行一个实例说明,该实例中,虚拟地址8196被送进MMU,MMU把它映射成物理地址。16位的CPU总共能产生的地址范围是0~64K,按每页4K的大小计算,该空间必须被分成16个页。而我们的虚拟地址第一部分所能够表达的范围也必须等于16(这样才能索引到该页组中的每一个页),也就是说这个部分至少需要4个bit。
    在这里插入图片描述

    该地址的页号索引为0010(二进制码),即索引的页为页2,第二部分为000000000100(二进制),偏移量为4。

    页2中的页框号为6(页2映射在页框6,见上图),我们看到页框6的物理地址是24~28K。于是MMU计算出虚拟地址8196应该被映射成物理地址24580(页框首地址+偏移量=24576+4=24580)。

    同样的,若我们对虚拟地址1026进行读取,1026的二进制码为0000010000000010,page index=“0000”=0,offset=010000000010=1026。

    页号为0,该页映射的页框号为2,页框2的物理地址范围是8192~12287,故MMU将虚拟地址1026映射为物理地址9218(页框首地址+偏移量=8192+1026=9218)。

    虚拟内存管理

    现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Mangement Unit,内存管理单元)提供支持。

    首先引入两个概念,虚拟地址和物理地址。

    如果处理器没有MMU,或者有MMU 但没有启用,CPU执行单元发出的内存地址将直接传到芯片引脚上,被物理内存芯片接收,这称为物理地址。
    如果处理器启用了MMU,CPU执行单元发出的内存地址将被 MMU 截获,从CPU到MMU 的地址称为虚拟地址,而MMU 将这个地址翻译成另一个地址,发到CPU芯片的外部地址引脚上,也就是将VA映射成了PA 了。
    如果是32位处理器, 则内存地址总线是32位的,与CPU 执行单元相连,而经过MMU转换后的外地址总线则不一定是32位。

    也就是说,虚拟地址空间与物理地址空间是独立的,32位处理器的虚拟地址空间是4GB,而物理地址空间既可以大于也可以小于4G。

    MMU 将 VA映射到PA是以页(page)为单位的,32位处理器的页尺寸通常是4KB。

    例如:
    MMU 可以通过一个映射项将VA 的一页0xB7001000 - 0xB7001FFFF映射到PA 的一页0x2000 ~ 0x2FFF。

    如果CPU 执行单元要访问虚拟地址0xB7001008,则实际访问到的物理地址是0x2008。

    物理内存中的页称为物理页帧(page frame),虚拟内存的哪个页面映射到物理内存的哪个页帧是通过页表(Page Table)来描述的,页表保存在物理内存中,MMU 会查找页表来确定一个VA 应该映射到什么PA.

    操作系统和 MMU 是这样配合的:操作系统在初始化或分配、释放内存时会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU 页表在物理内存中的什么位置。

    设置好之后,CPU 每次执行访问内存的指令都会自动引发MMU 做查表和地址转换操作,地址转换操作由硬件自动完成,不需要用指令控制MMU 去做。

    我们在程序中使用的变量和函数都有各自的地址,程序被编译后,这些地址就成了指令中的地址,指令中的地址被 CPU解释执行,就成了CPU的执行单元发出的内存地址,所以在启用MMU 的情况下,程序中使用的地址都是虚拟地址,都会引发MMU 做查表和地址转主换操作。

    那为什么要设计这么复杂的内存管理机制呢? 多了一层VA 到 PA 的转换到底换来什么好处?

    MMU 除了做地址转换之外,还提供内存保护机制,各种体系结构都有用户模式(User Mode)和特权模式(Privileged Mode)之分,操作系统可以在页表中设置每个内存页面的访问权限

    • 有些页面不允许访问,

    • 有些页面只有在CPU 处于特权模式时才允许访问,

    • 有些页面在用户模工和特权模式都可以访问,访问权限又分为可读、可写 和可执行三种。

    这样设定好之后,当CPU 要访问一个VA 时,MMU都会检查CPU 当前处于用户模式还是特权模式,访问内存的目的是读数据、写数据、还是取指令,如果和操作系统设定的页面权限相符,就允许访问,把它转换成PA ;如果不允许访问,就产生一个异常(Exception)。

    异常处理过程和中断类似,不同的是中断由外部设备产生而异常由CPU 内部产生,中断产生的原因和CPU 当前执行的指令无关,而异常的产生就是由于CPU 当前执行的指令出了问题,例如,访问内存的指令被 MMU 检查出权限错误,除法指令的除数为0 都会产生异常。

    用户空间和内核空间

    通常操作系统把虚拟地址划分为用户空间和内核空间,例如 X86平台的Linux 系统虚拟地址空间是0x00000000 - 0xFFFFFFFF,前3GB(0x00000000 - 0xBFFFFFFF)是用户空间,后1GB(0xC0000000 - 0xFFFFFFFF)是内核空间。

    用户程序加载到用户空间,在用户模式下执行,不能访问内核中的数据,也不能跳转到内核代码中执行。

    这样可以保护内核,如果一个进程访问了非法地址,顶多这一个进程崩溃,而不会影响到内核和整个系统的稳定性。

    CPU 在产生中断和异常时不仅会跳转到中断或异常服务程序,还会自动切换模式,从用户模式切换到特权模式,因此从中断或异常服务程序可以跳转到内核代码中执行。

    事实上,整 个内核就是由各种中断和异常处理程序组成的。

    总结下:
    在正常情况下 ,处理器在用户模式执行用户程序,在中断或异常情况下处理器切换到特权模式执行内核程序,处理完中断或异常之后再返回用户模式继续执行用户程序。

    段错误

    段错误是这样产生的:用户程序要访问一个VA, 经MMU 检查无权访问,MMU 产生一个异常,CPU 从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序。内核把这个异常解释为段错误,把相发异常的进程终止掉。

    文摘主要摘录自Linux内核 MMU的工作原理

    展开全文
  • MMU原理.pdf

    2019-09-27 14:36:49
    包含以下内容: · 关于存储器管理单元的结构;存储器访问的顺序; 转换过程; 访问权限; 域; 异常; CP15 寄存器。
  • 内存管理单元MMU

    2022-03-28 20:58:23
    掌握如何通过设置MMU来控制虚拟地址到物理地址的转化 了解MMU的内存访问权限机制 了解TLB、Cache、Writebuffer的原理,使用时的注意事项 在计算机开始阶段实际应用程序功能简单,程序文件较小,可以全部装在机器...
    • 了解物理地址和虚拟地址的关系
    • 掌握如何通过设置MMU来控制虚拟地址到物理地址的转化
    • 了解MMU的内存访问权限机制
    • 了解TLB、Cache、Writebuffer的原理,使用时的注意事项

    在计算机开始阶段实际应用程序功能简单,程序文件较小,可以全部装在机器的内存中。随着技术的不断推进逐渐出现如下三个问题:

    1. 程序逻辑越来越复杂,程序文件不断扩充,对应的需要实际物理内存大小也在增加,甚至很多时候一个程序都无法全部装载到内存当中。
    2. 多道系统由很多程序需要同时执行,各个程序之间的在执行过程中数据空间是不能够重叠在一起的,权限管理和禁止访问等需求功能出现。
    3. 程序越来越繁多,手动规划地址或者自动脚本编译完成空间针对程序的分配无法实现。

    计算机最初的理论模型就是一条无限长的纸袋,实际工程开发过程中告诉芯片电子特性不可能做到无限大,成本与其它配套供电也决定内存不可能做到无限大。这种情况下就需要从设计层面解决无线的需求和有限实际之间的矛盾,基于硬件的MMU虚拟内存和实际内存映射管理单元边应用而生。程序实际执行的时间和空间局部性告诉我们,我们短期之内并不需要将整个程序文件加载到内存当中。因此,我们可以通过复杂的调度算法实现同时将多个短时间内需要支撑的程序中各自某个范围段加载到硬件SDRAM中,然后对不同程序分时复用CPU资源。因此,我们实际运行的程序文件地址空间范围就可以扩充到总线宽度,对于32为CPU,虚拟内存空间范围为0 ~ 0xFFFFFFFF。拿实际s3c2440芯片为例,实际的物理空间大小事64M,0x3000_0000 ~ 0x3400_0000范围。MMU工作任务就是按照某种计算规则,完成物理地址空间、物理地址到虚拟空间、虚拟地址的映射任务。

    1. 内存管理单元介绍

    内存管理单元(Memory management unit)简称MMU,其在芯片设计中的物理位置是CPU<==>MMU<==>Memory controler<==>SDRAM(other controler)。它负责虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。现代软件多用户多进程通过MMU是的各个用户进程能够拥有自己独立的地址空间,这种映射机制使得所有的应用程序“看起来”都拥有一样的地址空间,而内存访问权限的检查可以保护每个进程所用的内存不会被其他进程破坏(多个程序不同物理地址可能映射到相同的物理地址)。

    ARM上的地址转换过程涉及3个概念,虚拟地址(VA,Virtual address),变换后的虚拟地址(MVA,Modified vritual address)和物理地址(PA,physical address)。没有启动MMU情况下,CPU核、cache、MMU、外设等素有设备看到的都是物理地址,地址空间规划按照芯片memory map章节中给定的样子划分。启动MMU后,CPU和对外发出虚拟地址VA;VA在CPU内部通过协处理器转换成MVA共cache和MMU使用,在这里又被转换为PA;最后使用PA读写实际的设备:

    1. CPU核看到的、用到的只是虚拟地址VA,至于VA如何最终落到物理地址PA上,CPU和是不需要例会的。
    2. cache和MMU看不到VA地址,它利用MVA地址转换为PA。
    3. 设计设备看不到VA、MVA,读写它们时使用的是物理地址PA。

    CPU协处理指令完成VA和MVA地址的映射,中间具体通过C13寄存器来完成。计算规则对于VA<32M空间,需要使用进程PCI转换MVA地址。利用PID生成MVA的目的是为了减少进程切换时的代价,不适用MVA而直接使用VA的话,当两个进程所用的虚拟地址有重叠时,在切换进程时需重建页表、使无效cache等来避免地址重叠,这样将会有很大的代价。使用MVA后,进程切换审视很多,假设进程IP为1和2的两个进程编译结果VA地址是0~(32M-1),通过计算规则计算以后实际的MVA地址变成了0x0200_0000 ~ 0x03ff_ffff和0x0400_0000 ~ 0x05ff_ffff,这样就没有不要重新建立页表了。后面我们讨论中没有特别强调的情况下,地址默认是指MVA地址。

    if( VA < 32M ) then
        MVA = VA | (PID << 25)
    else 
        MVA = VA

    2 地址转换算法

    虚拟地址和物理地址之间进行转换算法一般可以通过一个公式或者某种表格完成这种地址关系的映射,这种映射算法肯定是按照某个段给定的一种划分关系,否则反而会占用大量不要的内存空间。映射过程表格成为页表(page table),页表由一个个条目(entry)组成;每个条目存储了一段地址对应的物理地址以及其映射访问权限,或者下一级页表的地址(多级页表)。在S3C2440中最多用到两级页表:以段(section,1MB)方式进行转换时使用以及页表,以页(page)的方式进行转换时使用过的两级页表。页的大小有3种,大页(64K)、小页(4KB)、极小页(1KB)。条目保存的描述符(descriptor)根据这些不同的映射规则自然后端描述符、大页描述符、小页描述符和极小页描述符,他们保存端、大页、小页或者极小页的起始物理地址;粗页表描述符、细页表描述符用来保存二级页表的物理地址。ARM中地址转换过程大概如下:

    1. 根据给定的虚拟地址找到一级页表中的条目;
    2. 如果侧跳木事段描述符,则返回物理地址,转换结束;
    3. 否则如果是二级页表描述符,继续利用虚拟地址在此二级页表中找到下一个条目;
    4. 如果第二个条目式也描述符,则返回物理地址,转换结束;
    5. 其他情况出错。

     图中TTB代表以及页表的地址,将它写入到协处理器CP15的寄存器C2(称为页表地址寄存器)即可,以及页表的地址必须是16K对应的(位【14:0】为0)。

     对于一级页表,32位CPU的虚拟地址空间达到4GB,每个描述符对应1M的虚拟地址,要么存储它对应的1MB物理空间的起始地址。要么存储下一级页表的基地址。使用MVA[31:20]来索引一级页表,得到一个描述符,每个描述符占据4字节,具体格式:

     具体描述符各个字段含义进行如下分析,最低两位bit给定一级页表的类型,通过这个类型划分不同的映射方式,2bit产生4中映射情况:

    1. 0b00:无效
    2. 0b01:粗页表(coarse page table)

    位[31:10]称为粗页表基地址(coarse page table base address),此描述符低10位填充0后就是一个二级页表的物理地址。此二级页表汉256个条目(所以大小为1KB),称为粗页表。其中每个条目表示4KB的物理地址空间,所以一个粗页表表示1MB的物理地址空间。

    2.3. 0b10:段(section)

    位[31:20]称为段及地址(section base),此描述符低20位填充0后就是一块1MB的物理地址空间起始地址。MVA[19:0]来表示1MB空间中寻址。随意,描述符的位[31:20]和MVA[19:0]就构成了这个虚拟地址MVA对应的物理地址。以段的方式进行映射时,虚拟地址MVA到物理地址PA的转换过程如下:

            (1)页表基地址寄存器位[31:14]和MVA[31:20]组成一个低两位为0的32位地址,MMU利用这个地址找到段描述符,对应的这个条目共包含4096个,每个条目是我们真正的具体划分的描述。

            (2)取出段描述符[31:20],它和MVA[19:0]组成一个32位的物理地址,这个地址就是MVA对应的PA。

     2.4. 0b11:细页表(fine page table)

    位[31:12]称为细页表基地址,此描述符的第12位填充0后就是一个二级页表的物理地址。此二级页表含有1024个条目(所以大小4KB),称为系页表(Fine page table)。其中每个条目大小为1KB的物理地址空间,所以一个细页表表示1MB的U物理空间。以大页(64KB)、小页(4KB)或者极小页(1KB)进行地址映射时,需要永达两级页表。二级页表有粗页表、细页表两种,联众页表的描述符如下:

     根据二级页表描述的低两位分为如下4种情况:

    1. 0b00:无效。
    2. 0x01:大页描述符
    3. 0x10:小页描述符
    4. 0x11:极小页描述符

    3. 二级页表

    3.1 0x01大页描述符

    位[31:16]为大页表的基地址,此描述符的低16位填充0后就是一个快64KB的物理地址空间的其实地址。粗页表中每个条目只能表示4GB的物理空间,如果大页描述符保存在粗页表中,则连续16个条目都保存想听一个大页描述符。类似的细页表中的每个条目只能表示1KB物理空间,如果大页描述符保存在细页表中,则连续64个条目都保存同一个大页描述符。

     粗页表中的大页描述符具体地址转换过程:

    1. 页表基地址寄存器位[31:14]和MVA[31:20]组成一个低两位为0的32位地址,MMU利用这个地址找到主页表描述符。
    2. 取出粗页表描述符的位[31:10],即粗页基地址,它和MVA[19:12]组成一个低两位为0的物理地址,基于此地址找到大页描述符。
    3. 去除大页描述符[31:16],即大页基地址,它和MVA[15:0]组成一个32位的物理地址,这个地址就是MVA对应的PA地址。

    上面步骤2和3中,用于主页表中索引的MVA[19:12]和用于大业内寻址的MVA[15:0]有重合的位[15:12]。当位[15:12]从0b0000变化到0b1111时,步骤2返回的大页描述符相同。所以,粗页表中连续16个条目保存一个相同的大页描述符。大页描述符保存在细页表中时,地址转换过程与上面类似。

    4. 内存的访问权限检查

    内存的访问权限检查是MMU的主要功能之一,简单的说,它就是决定一块内存是否允许读、是否允许写。这个有CP15寄存器C3域访问控制、描述符域、CP15寄存器C1的R/S/A位、描述符的AP位等联合作用。

    CP15寄存器C1中的A位表示是否对地址进行检查对齐。所谓对齐检查就是,访问字时是否为4字节对齐,访问半字时(2字节)时地址是否2字节对齐,如果地址不对齐则产生“Aligment fault”异常。无论MMU是否被开启,都可以进行对齐检查。CPU读取指令时不进行对齐检查,以字节为单位访问时不进行对齐检查。对齐检查在MMU的权限检查、地址映射前进行。

    内存访问权限包括以下两点:

    1. “域”决定是否对某块内存进行权限检查
    2. “AP”决定如何对某块内存进行权限检查

    5. TLB的作用

    从虚拟地址到物理地址的转换过程可知,使用以及页表进行地址转换时,每次读/写数据需要访问两次内存,第一次访问获取一级页表的物理地址,第二次才是真正的读/写数据。使用两级页表时,每次数据读/写都需要访问3次内存,访问两次页表(一级页表和二级页表)才能获得物理地址,第三次才是真正的读/写数据。这样的转换过程大大降低了CPU的性能,有没有办法改进呢?程序执行过程中,所用到的指令、数据的地址往往集中在一个很小的范围内,其中地址、数据经常多次使用,这称为程序访问的局部性。由此,通过使用一个高速、容量相对较小的存储器来存储近期用到的页表条目(段/大页/小页/极小页描述符),以避免每次地址转换时都到主存中查找,这样可以大幅的性能。这个存储器用来帮助快速的进行地址转换,成为“转译查找缓存”(Translation lookaside buffers,TLB)。

    当CPU发出一个虚拟地址,MMU首先访问TLB。如果TLB中含有能够转换这个虚拟地址的描述符,则直接利用此描述符进行地址转换和权限检查;否则MMU访问页表找到描述符后再进行地址转换和权限检查,并将这个描述符填入TLB中(如果TLB已满,则利用round-robin算法查找到一个条目,然后覆盖它),下次再使用这个虚拟地址时就可以直接使用TLB中的描述符了。

    使用TLB需要保证TLB中的内容与页表一致,在启动MMU之前、在页表中的内容发生变化后,尤其需要注意这点。S3C2440可以使无效整个TLB,或者通过某个虚拟地址使无效TLB中的某个条目。一般的做法是:在启动MMU之前使无效整个TLB,改变页表时,使无效所涉及的虚拟地址对应的TLB中的条目。

    展开全文
  • MMU篇】初见MMU和TLB

    2022-04-27 16:05:36
    为了能够使得操作系统同时运行多个任务,现代CPU都设计了MMU(内存管理单元),其作用是管理虚拟地址和物理地址的映射关系。应用层的虚拟地址看起来连续,实际映射的时候,物理地址很大可能是碎片化的。 虚拟地址:...
  • MMU解读

    2020-12-21 14:02:02
    转:...当我们执行一个程序时,会把这个进程的mmu页表地址放到该寄存器中,跳转找到mmu页表执行。TLB是MMU内部的缓存,页表是每个进程都有的一段保存虚拟地址到物理地址对应映射关系的数组,此...
  • 一、S3C2440存储控制器  如果大家写过S3C2440的ARM裸机程序都应该知道通常SDRAM的起始地址是0X30000000,但是大家有没有想过为什么呢?下面我将给大家做一个简要的介绍。  查S3C2440的手册可知S3C2440可寻址1G的...
  • arm的内存管理单元手册,适合想要了解arm内存管理单元详细信息的同学
  • MMU

    2020-08-22 16:57:22
    MMU中文名是内存管理单元, 关MMU关掉MMU,因为u-boot软件是硬件实地址访问。 根本没有用到内存地址映射 因为MMU是;把虚拟地址转化为物理地址得作用,而目的是设置控制寄存器,而控制寄存器本来就是实地址(物理地址...
  • MMU和TLB详解

    千次阅读 2022-04-14 10:49:49
    MMU和TLB MMU 虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。 比如对一个16MB的程序和一个内存只有4MB...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,469
精华内容 17,787
关键字:

MMU