SoC嵌入式软件架构设计II:否MMU的CPU虚拟内存管理的设计与实现方法

大多数的程序代码是必要的时,它可以被加载到内存中运行。手术后,可直接丢弃或覆盖其他代码。我们PC然在同一时间大量的应用,能够整个线性地址空间(除了部分留给操作系统或者预留它用),能够觉得每一个应用程序都独占了整个虚拟地址空间(字长是32的CPU是4G的虚拟地址空间),但我们的物理内存仅仅是1G或者2G。即多个应用程序在同一时候竞争使用这块物理内存。其必定会导致某个时刻仅仅存在程序的某个片段在运行,也即是全部程序代码和数据分时复用物理内存空间—这就是内存管理单元(MMU)工作核心作用所在。

处理器系列的芯片(如X86、ARM7以上、MIPS)一般都会有MMU,跟操作系统一块实现虚拟内存管理,MMU也是Linux、Wince等操作系统的硬件要求。而控制器系统的芯片(面向低端控制领域,ARM1,2。MIPS M系列。80251等)一般都没有MMU,或者其仅仅有单一的线性映射机制。

本文要谈的是控制器领域SoC的内存管理单元的硬件设计。其重要的理念相同是代码和数据分时复用物理内存空间,在保障系统功能和性能的基础上最大限度地节省物理内存的目的。

相关的文章包含:SoC软件架构设计之中的一个:系统内存需求评估节省内存的软件设计技巧

一、内存管理单元(MMU)的工作机制

在阐述控制器领域的内存管理之前,还是要先介绍处理器领域的虚拟内存管理机制,前者非常大程度上是对后者核心机制精髓的借鉴。实现虚拟内存管理有几个模块是协调工作的:CPU、MMU、操作系统、物理内存,如图示(如果该芯片系列没有cache):

我们依据上图来分析一下CPU訪问内存的过程,如果寻址是0x10000008。一页大小为4K(12比特)。则虚拟地址会分成两个部分:页映射部分(20bit,0x10000)+页内偏移(12bit, 0x8)。CPU通过总线把地址信号(0x10000008)送给MMU,MMU会把该地址的页映射部分(20bit)拿到TLB中匹配。

TLB是什么东西?Translation Lookaside Buffer。网上有称为“翻译后备缓冲器”。

这个翻译都不知道它干什么。

它的作用就是页表的缓冲。我喜欢叫它为页表cache。

其结构图例如以下:

能够想象,TLB就是索引地址数组,数组的每一个元素就是一个索引结构,包括虚拟页地址和物理页地址。

其在芯片内部表现为寄存器形式。一般寄存器都是32位,实际上TLB中的页地址也是32位寄存器。仅仅只是索引比較时是比較前20bit,后12bit事实上也是实用的。比如能够设置某个bit是表示常驻的。即该索引是永远有效的,不能更换,这样的场景通常是为适合一些性能要求特别高的编解码算法而设计的。很驻内存的一般在某个时刻(如TLB填满时訪问一个新的页地址)就会发生置换。

1) 假如0x10000008的前20bit在TLB中第M个索引中命中。这时就表示该虚拟页在物理内存中已经给它分配好相应的物理内存。页表中也已经做好记录。至于虚拟地址相应的代码页是否从外存储(flash。card,硬盘)的程序中载入到内存中还须要要另外的标记,怎么标记呢?就是利用上面所讲的TLB低12位的某一bit(我们称为K)来标识,1标识代码数据已经载入到内存,0表示还没载入到内存。

假如是1,那就会用M中的物理地址作为高20bit,以页内偏移0x8作为低12bit。形成一个物理地址,送到内存去訪问。此时该次訪问就会完毕。

2) 假如K是0,那意味着代码数据尚未载入到内存。这时MMU会向中断管理模块输出信号。触发一个中断进行内核态,由操作系统负责将相应的代码页载入到内存。并改动相应页表项的K比特和TLB相应项的K比特为1.

3) 假如0x10000008的前20bit在TLB全部索引中都没有命中。则MMU也会向中断管理模块输出一个信号触发中断进入内核态。由操作系统将0x10000008右移12位(即除以4K)到页表中去取得相应的物理页值,假如物理页值非0有效,说明代码已经载入到内存了,这时将页表项的值填入到某一个空暇的TLB项中。假如物理页值为0,说明尚未给这个虚拟页分配实际的物理内存空间,这时会给它分配实际的物理内存,并写好页表的相应项(这时K是0),最后将这索引项写入TLB的当中一条。

2)和3)事实上都是在中断内核态中完毕的,为什么不一块做了呢?主要是由于一次中断不应该做太多事情。以加大中断延时。影响系统性能。当然假设有芯片将两者做成一个中断也是能够理解的。我们再来看看页表的结构。

页表当然也能够按TLB那样做成索引数组,可是这样有两个不好的地方:

1)页表是要映射所有的虚拟页面的。其维护在内存中也须要不小的空间。页大小是4K时,那映射所有就是4G/4K=1M条索引,每条索引4*2=8个字节,就是8M内存。

2)假如按TLB那种结构。那匹配索引的过程就是一个for循环匹配电路,效率非常低,要知道我们做这个都是在中断态完毕的。

所以一般的页表都是设计成一维数组。即以整个线性虚拟地址空间按页为单位依次作为数组的下标。即页表的第一个字(4字节)就映射虚拟地址空间的最低4K。第二个字映射虚拟地址最低的第二个4K,以此类推,页表的第N个字就映射虚拟地址空间的第N个4K空间。即(N-1)*4K~4KN的地址空间。这样页表的大小就是1M*4=4M字节,并且匹配索引的时候仅仅是一个偏移计算,很快。

承前启后,在引出第二部分之前先明白两个概念:

1. Bank表示代码分块的意思,类似于上面提到的页的概念。

2.不同代码分时复用内存:不同代码即意味着不同的虚拟地址相应的代码,(程序链接后的地址都是虚拟地址),内存即物理内存。即一定大小的不同虚拟地址的代码在不同的时刻都跑在同一块一定大小的物理内存空间上。每一块不同的代码块即是不同的代码Bank。

二、控制器领域SoC内存管理单元的硬件设计

这里专指没有内存管理单元的SoC设计,一般为了减少成本,在性能足够时。假设16位或者24位字长CPU可以解决这个问题,一般都不会去选32位字长的CPU,除非是计算性能考虑,或者32位CPU的license更廉价(一般非常少见)。仅仅要可以达到高效地进行内存管理,实现物理内存分时复用的目的,那都可以称为是成功或者有效的。在介绍真正的内存管理单元硬件设计之前,我们先简介一种利用工具链来实现内存分时复用的机制。然后再结合MMU和这个工具链实现的分块处理方法去设计我们新的内存管理单元,包含其硬件工作机制和软件设计和关键机制。

因为下面内容涉及到在审专利,经过考虑,临时将下面内容隐藏,适当时候再公开。抱歉。

×××××××

后记补充

在集成没有MMU的CPU时,SoC要实现内存管理,须要另外设计一个内存管理模块。实现MMU的核心功能,即代码分页(块)映射的功能。并且须要简化设计以达到最高的效率,同一时候代码分块须要直接地体如今链接脚本上。为了追求效率,编译链接后的可运行性文件还会被离线解析组织成一个更简化的运行文件。把不须要的段都删除,并将分块代码按逻辑顺序放好。以便于操作系统在必要时更快地载入。

当然。操作系统的代码内存管理也须要配合内存管理硬件电路,并可以解析又一次打包后的运行程序文件。因此内存管理的实现是须要架构师从软件和硬件上全面考虑。尽可能地在实现核心功能的基础上简化电路和设计,涉及的模块包含:硬件机制设计、物理内存分配、代码分块原则、linker脚本定义、打包运行文件、操作系统定制等等。兴许阐述的架构设计将会包含以上内容。

请关注SoC嵌入式软件架构设计(控制器SoC固件架构)系列博文:

SoC嵌入式软件架构设计之中的一个:系统内存需求评估

SoC嵌入式软件架构设计之二:没有MMU的CPU实现虚拟内存管理的设计方法

SoC嵌入式软件架构设计之三:代码分块(Bank)设计原则

SoC嵌入式软件架构设计之四:内存空间规划分配

SoC嵌入式软件架构设计之五:可运行程序的重构

嵌入式:节省内存的软件设计技巧

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-11-11 08:48:53

SoC嵌入式软件架构设计II:否MMU的CPU虚拟内存管理的设计与实现方法的相关文章

SoC嵌入式软件架构设计之四 :内存空间规划分配

本文继续阐述基于低端控制器CPU的SoC固件架构设计.第一节 SoC嵌入式软件架构设计之一:系统内存需求评估 讲述了系统内存需求的评估.这一节讲述内存空间的具体规划分配.CPU有两种体系结构:哈佛结构和冯诺依曼结构.哈佛结构是一种将程序指令存储和数据存储分开的存储器结构,如80251,代码空间与数据空间完全分开,独立编址:冯诺依曼结构是一种将程序指令存储器和数据存储器合并在一起的存储器结构,如MIPS,ARM等,其代码和数据空间是统一编址.这里就以冯诺依曼体系结构为例. 一.嵌入式系统软件分层

SoC嵌入式软件架构设计之三:代码分块(Bank)设计原则

上一节讲述了在没有MMU的CPU(如80251.MIPS M控制器系列.ARM cortex m系列)上实现虚拟内存管理的集成硬件设计方法,新设计的内存管理管理单元要实现虚拟内存管理还需要操作系统.代码分块(Bank)的支持,详见SoC嵌入式软件架构设计之二:没有MMU的CPU实现虚拟内存管理的设计方法.这里要阐述Bank设计的一些原则. Bank设计是为了实现不同时刻运行的Bank(代码块)运行在同一块内存上,所以在运行之前操作系统需要将已存在内存的代码/数据进行缓存处理,并加载将要运行的Ba

SoC嵌入式软件架构设计之四:内存空间规划分配

本文继续阐述基于低端控制器CPU的SoC固件架构设计.第一节 SoC嵌入式软件架构设计之一:系统内存需求评估 讲述了系统内存需求的评估.这一节讲述内存空间的具体规划分配.CPU有两种体系结构:哈佛结构和冯诺依曼结构.哈佛结构是一种将程序指令存储和数据存储分开的存储器结构,如80251,代码空间与数据空间完全分开,独立编址:冯诺依曼结构是一种将程序指令存储器和数据存储器合并在一起的存储器结构,如MIPS,ARM等,其代码和数据空间是统一编址.这里就以冯诺依曼体系结构为例. 一.嵌入式系统软件分层

SoC嵌入式软件架构设计之七:嵌入式文件系统设计

嵌入式的系统区(system disk,SD)包括操作系统.驱动.中间件.应用和字库.UI资源等文件,本文讲述SD区的文件系统设计.文件系统最主要的目标是为了实现单个文件的定位和读写.因为一般代码都是不可自修改的,即量产之后不会有写操作,嵌入式系统的SD文件系统就是为了能够简单.高效地定位某个文件和读取文件中的数据.设计原则和要点有以下几方面: 1. 逻辑连续存储单个文件,以扇区对齐. SD区的单个代码和资源文件一般都不大,所以不必要像fat32文件系统那样用fat表把文件簇串起来,直接逻辑连续

SoC嵌入式软件架构设计之六:API设计方法

在嵌入式系统中,驱动都是以API的方式提供给应用进行调用.这里介绍嵌入式系统的API设计和管理方法. 驱动在系统中会按模块进行分类,例如按键驱动.LCD驱动.文件系统.card驱动.I2C驱动等等:每个模块又有多个接口,例如LCD驱动有光标定位.画点.画直线等,而文件系统有fread.fwrite.fseek.fopen等接口.以下举例将以文件系统的fopen为例,工具链为mips. 一.API设计方法 1. 驱动接口声明:extern FILE * fopen(const char * pat

SoC嵌入式软件架构设计之五:可执行程序的重构

低端控制器对执行效率要求很高,成本敏感,因而SoC内置SRAM是紧缺资源.代码分块管理就是为了充分利用内存,提高内存的复用效率而提出的一种设计方法.代码分块管理不仅涉及到硬件,同样对操作系统和应用.驱动的设计都有要求,这些模块共同努力以使执行效率达到最高. 本节讲述代码分块(Bank)管理思想下可执行文件的重构,即对程序编译后的可执行文件进行重新组织.打包,以在加载阶段获得最高的执行效率,减少内存占用.要使执行效率高,意味着可执行文件的格式尽可能简单,解析执行文件的流程简单,相应地,解析过程代码

SoC嵌入式软件架构设计之二:虚拟内存管理原理、MMU硬件设计及代码分块管理

程序的大部分代码都可以在必要的时候才加载到内存去执行,运行完后可以被直接丢弃或者被其他代码覆盖.我们PC上同时跑着很多的应用程序,每个应用程序使用的虚拟地址空间几乎可以整个线性地址空间(除了部分留给操作系统或者预留它用),可以认为每个应用程序都独占了整个虚拟地址空间(字长是32的CPU是4G的虚拟地址空间),但我们的物理内存只是1G或者2G.即多个应用程序在同时竞争使用这块物理内存,其必然会导致某个时刻只存在程序的某个片段在执行,也即是所有程序代码和数据分时复用物理内存空间—这就是内存管理单元(

SoC嵌入式软件架构设计之一:系统内存需求评估

内存是SoC(System on Chip,片上系统)集成设计的重要模块,是SoC中成本比重较大的部分.内存管理的软硬件设计是SoC软件架构设计的重要一环,架构设计师必须要在成本和效率中取得平衡,做到在节省内存的同时保证整个系统的性能.系统内存需求评估是对嵌入式软件架构师的最基本要求,同时也是其最重要的技能之一.一般在SoC项目立项的时候,架构师就要完成系统内存需求评估. 下面以一个多媒体电子解决方案中的SoC设计为原型,说明大致的评估流程: 1. 根据产品规格,对各个应用场景进行功能和性能分解

SoC嵌入式软件架构设计之五 :可执行程序的重构

低端控制器对执行效率要求很高,成本敏感,因而SoC内置SRAM是紧缺资源.代码分块管理就是为了充分利用内存,提高内存的复用效率而提出的一种设计方法.代码分块管理不仅涉及到硬件,同样对操作系统和应用.驱动的设计都有要求,这些模块共同努力以使执行效率达到最高. 本节讲述代码分块(Bank)管理思想下可执行文件的重构,即对程序编译后的可执行文件进行重新组织.打包,以在加载阶段获得最高的执行效率,减少内存占用.要使执行效率高,意味着可执行文件的格式尽可能简单,解析执行文件的流程简单,相应地,解析过程代码