前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开启MMU瞬间出现的问题以及解决方案

开启MMU瞬间出现的问题以及解决方案

作者头像
刘盼
发布2022-05-23 12:18:20
4310
发布2022-05-23 12:18:20
举报
文章被收录于专栏:人人都是极客

作者简介:baron (csdn:代码改变世界ctw),九年手机安全/SOC底层安全开发经验。擅长trustzone/tee安全产品的设计和开发。

在 MMU 未开启阶段,PC 操作的都是物理地址执行程序,这样看起来一切正常,没啥问题。例如:

取指(到物理地址 0x4000 处取指)、译码、执行 取指(物理地址 0x4004 处取指)、译码、执行 取指(物理地址 0x4008 处取指)、译码、执行 取指(物理地址 0x400C 处取指)、译码、执行

但是假如程序在执行的过程中,你突然打开了 MMU,那么会发生什么呢?

比如在前面的示例中,程序本来执行在 0X4000、0x4004 处,而 0x4004 正好是 enable_mmu 指令,那么接下来 PC 将取值 0x4008 处地址的指令,由于此时 MMU 已经被打开,那么 0x4008 会被当作虚拟地址,经过MMU翻译......

经过 MMU,那么就可能出现两种问题:

  1. 虚拟地址 0x4008 所对应的页表没有建立,此时会产生 prefetch abort;
  2. 虚拟地址 0x4008 所对应的页表已经建立了(例如指向物理 0xXXXX 处),那么此时 CPU 本应该访问的物理地址由 0x4008,被突然变成了物理地址 0xXXXX。

那么上面的程序执行就变成了如下逻辑:

取指(到到物理地址 0x4000 处取指)、译码、执行 取指(物理地址 0x4004 处取指)、译码、执行  -- 这条指令是开启 MMU 取指(到虚拟地址 0x4008 处取指,经 MMU 单元后,要么是 invalid;要么是 0xXXXX)、译码、执行 ......

为了解决上述描述的问题,你有什么想法吗?

先自己想下......

下面给出了两种解决方案:

  • 第一种方案:在开启 MMU 之前,先对正在执行的这一小块代码建立个页表(一一映射),那么此时的逻辑就变成了:

取指(到到物理地址 0x4000 处取指)、译码、执行 取指(物理地址 0x4004 处取指)、译码、执行  -- 这条指令是开启MMU 取指(到虚拟地址 0x4008 处取指,因为是一一映射,所以经 MMU 单元后,物理地址依然是是 0x4008)、译码、执行 ......

  • 第二种方案:在开启 MMU 之前,我确实建立个页表(不是一一映射),此时的逻辑如下:

取指(到到物理地址 0x4000 处取指)、译码、执行 取指(物理地址 0x4004 处取指)、译码、执行  -- 这条指令是开启MMU 取指,到虚拟地址 0x4008 处取指,经 MMU 单元时在页表是找不到 0x4008 这个虚拟地址的(因为没做 map),所以会产生 prefetch abort 异常、而在异常代码 ERET 返回时,正好返回到 0xXXXX 地址处,该地址是虚拟地址,正好 map 到 0x4008 物理地址,程序得到继续执行,译码、执行 ......

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 人人都是极客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档