0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式ARM与MMU神秘的内部世界!一目了然

Q4MP_gh_c472c21 来源: 聂磊 作者:电子发烧友 2019-03-01 15:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

ARM MMU页表框架

先上一张arm mmu的页表结构的通用框图(以下的论述都由该图来逐渐展开):

以上是arm的页表框图的典型结构,即是二级页表结构。

其中第一级页表(L1)是由虚拟地址的高12bit(bits[31:20])组成,所以第一级页表有4096个item,每个item占4个字节,所以一级页表的大小为16KB,而在第一级页表中的每个entry的最低2bit可以用来区分具体是什么种类的页表项,2bit可以区分4种页表项,具体每种页表项的结构如下:

简而言之L1页表的页表项主要有两大类:

  • 第一大类是指向第二级页表(L2页表)的基地址;

  • 第二类直接指向1MB的物理内存。

在L1页表中每个表项可以覆盖1MB的内存,由于有4096K个选项(item),所以总计可以覆盖4096K*1MB=4GB的内存空间。

具体对应到Linux,由于Linux的软件架构是支持3级页表结构,而arm架构实际只有2级的页表结构,所以linux代码中的中间级页表的实现是空的。在linux代码中,第一级的页表的页目录表项用pgd表示,中间级的页表的页目录表项用pud表示(arm架构其实不需要),第三级的页表的页目录表项用pmd表示(由于中间pud是空的,所以pgd=pmd),另外目前arm体系的移动设备中RAM的page大小一般都是4KB/page,所以L1页表中的页表项都是指向fine page table的。

但在linux内核启动的初始化阶段,临时建立页表(initial page tables)以供linux内核初始化提供执行环境,这时L1的页表项使用的就是第二种页表项(section enty),他直接映射的是1M的内存空间。具体的可以参考arch/arm/kernel/head.S中的__create_page_tables函数,限于篇幅,这里就不展开说了。

针对这种section page translation,mmu硬件执行虚拟地址转物理地址的过程如下:

以上在初始化过程使用的临时页表(initial page tables),在内核启动的后期会被覆盖掉,即在paging_init--->map_lowmem函数中会重新建立页表,该函数为物理内存从0地址到低端内存(lowmem_limit)建立一个一一映射的映射表。所谓的一一映射就是物理地址和虚拟地址就差一个固定的偏移量,该偏移量一般就是0xc0000000(呵呵,为什么是0xc0000000?)。

说到这里引入一个重要的概念,就是与低端内存相对的高端内存,什么是高端内存?为什么需要高端内存?为了解析这个问题,我们假设我们使用的物理内存有2GB大小,另外由于我们内核空间的地址范围是从3G-4G的空间,并且前面也说到了,linux内核的低端内存空间都是一一映射的,如果不引入高端内存这个概念,全部都使用一一映射的方式,那内核只能访问到1GB的物理内存,但实际上,我们是需要内核在内核空间能够访问所有的4GB的内存大小的,那怎么做到呢?

方法就是我们不让3G-4G的空间都使用一一映射,而是将物理地址的[0x00,fix_addr](fix_addr<1GB)映射到内核空间虚拟地址[0x00+3G,fix_addr+3G],然后将[fix_addr+3G,4G]这段空间保留下来用于动态映射,这样我们可以通过这段虚拟地址来访问从fix_addr到4GB的物理内存空间。怎么做到的呢?

譬如我们想要访问物理地址[fix_addr,4GB]这段区间中的任何一段,我就用宝贵的内核虚拟地址[fix_addr+3G,4G]的一段去映射他,建立好mmu硬件使用的页表,访问完后,将映射清除,将内核的这段虚拟地址释放,以供下次访问其他的物理内存使用。这样就可以达到访问所有4GB的物理内存的目的

那么内核代码是如何建立映射表的呢?

我们着重从arch/arm/mm/mmu.c中的create_mapping函数来分析。在分析之前我们先看下arm mmu硬件是如何在二级页表结构中,实现虚拟地址转物理地址的。

先贴出原代码(arch/arm/mm/mmu.c),该函数的功能描述如下:

Create the page directory entries and any necessary page tables for the mapping specified by `md'. We are able to cope here with varying sizes and address offsets, and we take full advantage of sections and supersections.

line737-line742:参数合法性检查,该函数不为用户空间的虚拟地址建立映射表(记得多问自己一个为什么?)

line744-line750:如果是iomemory,则映射的虚拟地址范围应属于高端内存区间,由于我们这里是常规的memory,即type为MT_MEMORY,所以不会进入该分支。

line775: 获得该虚拟地址addr属于第一级页表(L1)的哪个表项,详细跟踪pgd_offset_k函数(定义在:arch/arm/include/asm/pgtable.h),你会发现,我们内核的L1页目录表的基地址位于0xc0004000,而我们的内核代码则是放置在0xc0008000开始的位置。而从0xc0004000到0xc0008000区间大小是16KB,刚好就是L1页表的大小(见文章开头的描述)。

在这里需要注意一个概念:内核的页目录表项和进程的页目录表项,内核的页目录表项是对系统所有进程都是公共的;而进程的页目录表项则是跟特定进程相关的,每个应用进程都有自己的页目录表项,但各个进程对应的内核空间的页目录表相都是一样的。正是由于每个进程都有自己的页目录表相,所以才能做到每个进程都可以独立拥有属于自己的[0,3GB]的内存空间。

line778pgd_addr_end()确保[addr,next]地址不会跨越一个L1表项所能映射的最大内存空间2MB(为什么是2MB而不是1MB呢?这个是linux的一个处理技巧,以后再详细展开说)。

line780alloc_init_pud()函数为定位到的L1页目录表项pgd所指向的二级页表(L2)建立映射表。

line784 pdg++下移L1页目录表项pgd,映射下一个2MB空间的虚拟地址到对应的2MB的物理空间。

在这里解析下,为什么L1页目录表项pgd能够映射2MB的虚地地址空间。

在本文的第一个图中,他是arm典型的mmu映射框架图,但并不是linux的,linux映射框架图在它的基础做了些调整和优化。

linux所做的调整描述如下(以下摘自linux内核:arch/arm/include/asm/pgtable-2level.h中提供的注释说明):

/** Hardware-wise, we have a two level page table structure, where the first* level has 4096 entries, and the second level has 256 entries. Each entry* is one 32-bit word. Most of the bits in the second level entry are used* by hardware, and there aren't any "accessed" and "dirty" bits.** Linux on the other hand has a three level page table structure, which can* be wrapped to fit a two level page table structure easily - using the PGD* and PTE only. However, Linux also expects one "PTE" table per page, and* at least a "dirty" bit.** Therefore, we tweak the implementation slightly - we tell Linux that we* have 2048 entries in the first level, each of which is 8 bytes (iow, two* hardware pointers to the second level.) The second level contains two* hardware PTE tables arranged contiguously, preceded by Linux versions* which contain the state information Linux needs. We, therefore, end up* with 512 entries in the "PTE" level.** This leads to the page tables having the following layout:*

重要调整说明如下:

L1页表从4096个item变为2048个item,但每个item的大小从原来的4字节变为8个字节。

一个page中,放置2个L2页表,每个还是256项,每项是4个字节,所以总计是256*2*4=2KB,放置在page页的下半部,而上部分放置对应的linux内存管理系统使用的页表,mmu硬件是不会去使用它的。所以刚好 占满一个page页的大小(4KB),这样就不浪费空间了。

有了上面基础,下面再详细的分析以上的line780的函数alloc_init_pud,该函数会最终调用到alloc_init_pte函数:

line598early_pte_alloc函数判断对应的pmd所指向的L2页表是否存在,如果不存在就分配L2页表,如果存在就返回L2页表所在page页的虚地址。

line572 判断pmd所指向的L2页表是否存在,不存在则通过early_alloc 函数分配PTE_HWTABLE_OFF(512*4=2KB)+PTE_HWTABLE_SIZE(512*4=2KB)总计4KB的一个物理页来存储2个linuxpet 页表+2个hwpte页表。

line574返回这个物理页所在虚拟地址,

回到alloc_init_pte函数的line599。

line183pte_index用来确定该虚拟地址在L2页表中的偏移量。即虚拟地址的bit[12~21]共计9个bit,刚好用于寻址两个L2页表(总计512项)。

回到alloc_init_pte函数,其中line605行,是设置L2页表中addr所定位到的页表项(即pte),主要工作就是填充对应物理页的物理地址,以供mmu硬件来实现地址的翻译。

line604~line607循环填充完两个hwpte页表,完成一个2M物理内存的映射表的建立。

line608 将最终调用如下函数:static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,pmdval_t prot)

在执行这个函数之前,2个L2页表已经建立,该函数的作用就是设置L1页表的对应表项,使其指向刚建立的2个L2页表(hwpte0,hwpte1),正如前面所说,由于linux的L1页表项是8个字节大小,所以:

  • line133 将头4个字节指向hwpte0页表,

  • line135 将后4个字节指向hwpte1页表,至此L1---〉L2页表的关联已经建立。

  • line137 是刷新TLB缓冲,使系统的cpu都可以看见该映射的变化

至此已完成struct map_desc *md结构体所指定的虚拟地址到物理地址的映射关系的建立,以供硬件mmu来自动实现虚拟到物理地址的翻译。

以上过程,有选择的将某些细节给省略了,限于篇幅,另外如果明白了这个过程,很细节的可以自己去看相关的代码。譬如上面的set_pte_ext函数,会调用的汇编函数来实现pte表项的设置。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    135

    文章

    9588

    浏览量

    393572
  • 嵌入式
    +关注

    关注

    5209

    文章

    20645

    浏览量

    336924
  • MMU
    MMU
    +关注

    关注

    0

    文章

    92

    浏览量

    19289

原文标题:带你走进嵌入式ARM与MMU神秘的内部世界

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入式AI开发必看:杜绝幻觉,才是工业级IDE的核心底气

    ,问题定位一目了然,无需在代码中逐行排查。而组件级复用机制确保校验标准可继承,避免重复校验工作,进步提升开发效率。 三、核心价值:让AI代码直接落地工业产线 PPEC Workbench 的全流程校验
    发表于 03-18 13:49

    国民技术发布N32Cube芯片配置与初始化代码生成工具

    1月30日,国民技术(NSING)正式发布N32Cube——芯片配置与初始化代码生成工具,让时钟、引脚与外设的配置一目了然、轻松上手!
    的头像 发表于 02-02 15:26 870次阅读
    国民技术发布N32Cube芯片配置与初始化代码生成工具

    什么是嵌入式应用开发?

    包括ARM7、ARM9、ARM11、PowerPC、MIPS等。这些处理器和编程语言的选择取决于具体的硬件条件和开发需求‌。 综上所述,嵌入式应用开发是
    发表于 01-12 16:13

    arm嵌入式主板优缺点

    嵌入式主板是嵌入在设备里面做控制、数据处理使用的CPU板 ,常见的有两类,即基于X86的嵌入式主板和基于RISC的ARM 嵌入式主板。今天我
    发表于 01-08 07:08

    分享嵌入式开发学习路线

    如果你想要学习嵌入式开发,我建议按照这个学习路线准备: 1. 基础铺垫期(1-2个月) 理解嵌入式系统的“硬件基础”和“编程入门”,能看懂简单电路,写出基础C语言代码。这阶段的学习对学历没有
    发表于 12-04 11:01

    ARM嵌入式这样学

    的内核就是ARM内核,它的主频高很多,普通的都有几百M。CPU缓存大,分有很多级的流水处理线,这样大大提高了CPU利用率。这种IC的资源足以让嵌入式操作系统正常跑起来,WINCE, LINUX
    发表于 12-04 07:48

    IAR邀您相约2025上海国际嵌入式会议

    在德国纽伦堡成功举办二十余届的 embedded world 嵌入式世界展览与会议,已连续在中国落地数年。作为专注于嵌入式系统行业的盛会,上海国际嵌入式展已成为引领全球
    的头像 发表于 10-17 10:37 922次阅读

    物联网平台让智慧工地管控系统搭建一目了然

    整合智能硬件、无线通信与大数据分析技术,构建“实时感知、智能分析、联动控制”的智慧管理体系,让工地管理从“凭经验、靠人力”转向“数据驱动、智能决策”,为建筑行业破解管理痛点、降本增效提供关键支撑。 、物联网
    的头像 发表于 08-27 15:47 811次阅读

    揭秘淘宝 API,让天猫店铺流量来源一目了然

    ​ 在当今竞争激烈的电商环境中,天猫店铺的运营者最关心的问题之就是:流量从哪里来?了解流量来源不仅能优化营销策略,还能提升转化率。淘宝开放平台提供的 API 接口,正是解锁这秘密的钥匙。本文将
    的头像 发表于 08-12 14:48 1017次阅读
    揭秘淘宝 API,让天猫店铺流量来源<b class='flag-5'>一目了然</b>

    飞凌嵌入式RK3576多模态大模型图像理解助手,让嵌入式设备“看懂”世界

    (LLM)+视觉语言模型(VLM)多模态架构,推出多模态大模型图像理解助手,为嵌入式设备打造 “智能视觉中枢”,让终端设备能够真正 “看懂” 复杂的世界
    的头像 发表于 07-25 11:09 1810次阅读
    飞凌<b class='flag-5'>嵌入式</b>RK3576多模态大模型图像理解助手,让<b class='flag-5'>嵌入式</b>设备“看懂”<b class='flag-5'>世界</b>

    超越想象的小身板!这款2.8寸触摸串口屏,让嵌入式交互卷出新高度

    ×320高清炫彩屏:262K鲜活色彩+全视角显示,告别“侧视即瞎”的尴尬,信息一目了然。流畅触控黑科技:I²C触摸接口响应如飞,指尖滑动如丝般顺滑,告别卡顿误触。
    的头像 发表于 07-08 18:30 1000次阅读
    超越想象的小身板!这款2.8寸触摸串口屏,让<b class='flag-5'>嵌入式</b>交互卷出新高度

    运行在嵌入式系统上的emApps

    在当今快节奏的嵌入式系统世界中,灵活性和适应性是嵌入式系统实现的关键。SEGGER推出了其最新创新:Embedded apps(emApps)应用,类似于手机上的应用程序,可以运行在嵌入式
    的头像 发表于 06-18 09:53 1053次阅读
    运行在<b class='flag-5'>嵌入式</b>系统上的emApps

    嵌入式开发,如何选择适合的系统?

    嵌入式ARM开发中,面对多种操作系统的选择,如何做出最适合项目的决策?本文将为您梳理常见系统的特性,帮助您快速了解它们的优缺点,以便更好地选择适合的系统。引言在嵌入式ARM开发中,选
    的头像 发表于 05-20 11:32 1295次阅读
    <b class='flag-5'>嵌入式</b>开发,如何选择适合的系统?

    嵌入式开发入门指南:从零开始学习嵌入式

    随着物联网、智能硬件的发展,嵌入式开发成为热门技能之。以下将为初学者提供份详细的嵌入式开发入门指南,涵盖学习路径、必备工具、推荐资源等内容。 1.
    发表于 05-15 09:29

    精密配电采集器 让列头柜的数据一目了然

    ​  安科瑞刘鸿鹏 摘要  随着企业信息化、智能化水平不断提高,尤其是数据中心、新能源和制造领域对电能质量、供电连续性提出了更高要求,传统的交流配电系统已难以满足部分应用场景下的需求。直流配电因其效率高、损耗低、架构简洁而逐渐成为重要选择。本文基于安科瑞AMC16Z系列直流电能计量装置,探讨直流电能表在企业精密配电系统中的应用价值、实施方式及带来的管理优化。 1. 引言 现代企业在推进数字化建设过程中,对供配电系统提出
    的头像 发表于 04-28 15:26 900次阅读
    精密配电采集器 让列头柜的数据<b class='flag-5'>一目了然</b>!