1

在制作页表之后,我已经在 ARMv8 上运行了虚拟内存。奇怪的是,我的大部分翻译都在工作(身份映射),除了位于物理地址零的 Flash。我使用一个编辑页表的函数,所以有些工作有些不工作对我来说很奇怪。具体来说,我只映射了几个范围:

Flash       [0x00000000, len = 0x08000000]
UART        [0x09000000, len = 0x1000    ]
RAM         [0x40000000, len = 0x0fe00000]
Secure RAM  [0x4fe00000, len = 0x00200000]

再说一次,除了 Flash ,它们都可以工作。我的映射功能也适用于非身份映射。Flash 系列有点奇怪。

我有一个异常处理程序用于剖析问题。我在捕获Data Abort异常时发现了两个有趣的案例。根据访问的内存类型,我遇到了两种 Data Abort 子类型:

    - [1] Flash address range (e.g. 0x00000000)
            - ESR.ISS = 0x10 (ISS.DFSC = 0x10)
                - Synchronous External abort, not on translation table walk 

    - [2] An expected unmapped address (e.g. 0x50000000)
            - ESR.ISS = 0x06 (ISS.DFSC = 0x06)
                - Synchronous External abort, on translation table walk, level 2

当尝试处理访问地址的异常时,我不希望出现在表中,我得到一个 [2] (第 2 级错误,因为映射了一些附近的地址)。

当我尝试处理访问 Flash 的异常时,我确实希望在表中出现 [1](不在表中)。

所以,我对这两种情况代表什么感到困惑。[1] 和 [2] 有什么区别?它们似乎代表着同样的东西。[1] 是否以某种方式代表了翻译在尝试之前失败的情况?如果是这种情况,我希望处理已定义的 0 级故障。对于我不希望出现在表中但收到另一个地址的地址,我期待“不在表中”错误。

4

1 回答 1

0

事实证明,我看到的问题是由于 Flash 被映射为仅安全设备,因此只有安全访问才能通过 MMU(即表条目上的 NSTable=0 和块条目上的 NS=0) .

在意识到这一点之后,在@artlessnoise 的帮助下,在评论中关于“外部中止”的问题,我得出了数据中止的两种子类型之间的以下区别:

"Not on translation table walk"

并不意味着,正如我正在阅读的那样,“发生异常是因为在'转换表遍历'上找不到请求的内存地址”。但更确切地说,它意味着异常发生在“不在翻译表上行走”时(即在操作之前或之后)。在这种情况下,Flash PA 映射到表中,但我的访问是非安全的,因此设备没有响应(MMU 没有将它们路由到设备)。这种缺乏响应导致外部中止。因此,ARM 可能更简洁地将此异常定义为,例如:

"Not on translation table walk" -> "Not as a result of translation table walk"

另一个亚型:

"On translation table walk, level 2"

是一个人应该期望在page fault. 换句话说,试图读取在转换表中没有 VA->PA 映射的内存。观察到的水平反映了 MMU 在停止前走多远。


请注意,我删除了定义的“同步外部中止”部分。两者都被视为外部中止,因为在尝试读取内存或直接从 MMU 读取内存时,两者都是由于 CPU 外部的操作而引发的。

于 2019-09-23T15:23:34.160 回答