我在armv8(aarch64)中编写了一个简单的内核。MMU配置: 48 VA位(T1SZ = 64-48 = 16) 4K页面大小所有物理RAM平面映射到内核虚拟内存(在TTBR1_EL1上)(MMU在TTBR0_EL1 = 0时处于 Activity 状态,因此我仅使用0xffff 中的地址,所有地址均映射到物理内存中)我正在将一个新的地址空间(从1 ESR_EL1=0x96000044FAR_EL1=0xffff010000000000检查其他寄存器,我有:TTBR1_EL1=0x82000000TTBR1_EL1[2]=0x0000000082003003因此,基于《 ARMv8的ARM体系结构引用手册》(ARMv8-A配置文件): ESR(异常综合症寄存器)转换为:D7-1933 sq。上的异常类= 100101(数据异常中止,异常级别不变); WnR = 1(故障指令为写操作); DFSC = 0b000100(在D7-1958页上的翻译错误在0级上); FAR_EL1是故障地址;它指示使用了TTBR1_EL1(因为高位全为1)。 VA的前9位为0b000000010,表示表中使用了条目2; 该表中的条目2指示物理地址0x82003000处的下一个表(低位0b11)。 因此,转换将在0级失败,而在0级则不会。我的问题是:我做错什么了吗?我是否缺少一些可能导致翻译错误的信息?而且,更一般而言,如何调试翻译错误? 更新:在启用MMU之前写表时,一切都会正常。每当我在启用MMU之后(通过平面映射表区域)向表写入数据时,映射就永远不会起作用。我不知道为什么会这样。我还尝试了手动写入选定的表(以消除我的mmapping函数的任何副作用):相同的结果(当在MMU开启之前完成写入时,它会起作用;在失败之后,它会发生)。我尝试执行tlbi和dsb sy指令,然后执行isb,但没有效果。此时只有一个CPU在运行,因此缓存应该不是问题-编写指令和MMU可以访问相同的缓存(但我将在下一步进行测试)。 最佳答案 我忽略了单个内核中的缓存问题。问题在于,在打开MMU之后,CPU和工作台行走单元的内存 View 不同。 《 ARMv8 Cortex-A编程指南》指出,在修改表之后,必须清理/使缓存无效以达到统一点(单个内核的相同 View )。有两种可能性可以解释这种现象(我还不完全了解缓存的工作原理): 第一种可能性: MMU在其内部步行缓存中没有所需的地址。在这种情况下,当更新常规数据并将其提供给其他内核的L1时,dsb指令仅等待所有内核具有同步状态(由于一致性网络):其他内核将知道必须更新该行,并且当他们尝试访问它时,它会更新为L2或从以前的内核的L1迁移到其L1。对于MMU(没有一致性参与),这不会发生,因此它仍然看到L2中的旧值。但是,如果是这种情况,则应该在打开MMU之前发生同样的事情(因为缓存是在之前激活的),除非在激活MMU之前将所有内存视为L1不可缓存(这是可能的,我是我必须再次检查)。解决该问题的最小方法可能是更改表页面的缓存策略,但是仍然需要维护缓存以从MMU中清除可能的旧值。 第二种可能性:在所有经过测试的情况下,MMU在其内部步移缓存中已经具有故障地址,该地址与数据L1或L2不相干。在这种情况下,只有显式的无效对象才能从MMU缓存中弹出旧行。在打开MMU之前,缓存不包含任何内容,并且永远不会获得旧值(0),而只会获得新值。我仍然认为这种情况不太可能,因为我测试了很多情况,有时还会预先映射的内存(例如,级别1表中的条目0)与新映射的内存(例如,同一级别1表中的条目128)之间的偏移量大于缓存行大小(在这种情况下为1024字节,大于任何缓存行大小)。 因此,我仍然不确定到底是什么引起了该问题,但是清除/使所有更新的地址无效是可行的。关于arm - 如何调试aarch64翻译错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45764483/ 10-10 22:38