如何解决无法使用 ttbr0_el1 寄存器读取分页表..(arm64)
在设备驱动程序中,我想读取 ttbr0_el1 寄存器(EL1 的转换表基址寄存器)指向的第一个数据,如下所示。但是引用指针会导致陷阱(数据访问中止)。怎么了?
static inline uint64_t system_read_TTBR0_EL1(void)
{
uint64_t val;
asm volatile("mrs %0,ttbr0_el1" : "=r" (val));
return val;
}
static inline uint64_t system_read_TTBR1_EL1(void)
{
uint64_t val;
asm volatile("mrs %0,ttbr1_el1" : "=r" (val));
return val;
}
ttbr0_el1 = system_read_TTBR0_EL1();
ttbr1_el1 = system_read_TTBR1_EL1();
printk("ttbr0 = %llx\n",ttbr0_el1);
printk("ttbr1 = %llx\n",ttbr1_el1);
printk("*ttbr1 = %llx\n",*(uint64_t *)ttbr1_el1);
printk("*ttbr0 = %llx\n",*(uint64_t *)ttbr0_el1);
输出
[100450.356279] ttbr0 = 27f0000042dd7001
[100450.356595] ttbr1 = 27f00000414ab001
[100450.357015] Unable to handle kernel paging request at virtual address 27f00000414ab001
[100450.357564] Mem abort info:
[100450.357803] ESR = 0x96000004
[100450.358116] EC = 0x25: DABT (current EL),IL = 32 bits
[100450.358535] SET = 0,FnV = 0
[100450.359256] EA = 0,S1PTW = 0
[100450.359537] Data abort info:
[100450.359785] ISV = 0,ISS = 0x00000004
[100450.360101] CM = 0,WnR = 0
[100450.360449] [27f00000414ab001] address between user and kernel address ranges
[100450.360986] Internal error: Oops: 96000004 [#22] SMP
解决方法
首先,您需要屏蔽一些东西:
但还有更多的东西,甚至。来自the manual:
Translation table base address: • Bits A[47:x] of the stage 1 translation table base address bits are in register bits[47:x]. • Bits A[(x-1):0] of the stage 1 translation table base address are zero. Address bit x is the minimum address bit required to align the translation table to the size of the table. The smallest permitted value of x is 6. The AArch64 Virtual Memory System Architecture chapter describes how x is calculated based on the value of TCR_EL1.T0SZ,the translation stage,and the translation granule size. -------- Note ------------ A translation table is required to be aligned to the size of the table. If a table contains fewer than eight entries,it must be aligned on a 64 byte address boundary. -------------------------- If the value of TCR_EL1.IPS is not 0b110,then: • Register bits[(x-1):1] are RES0. • If the implementation supports 52-bit PAs and IPAs,then bits A[51:48] of the stage 1 translation table base address are 0b0000. If FEAT_LPA is implemented and the value of TCR_EL1.IPS is 0b110,then: • Bits A[51:48] of the stage 1 translation table base address bits are in register bits[5:2]. • Register bit[1] is RES0.
描述继续解释无效值的允许影响,但如果我们假设仅有效使用 TTBR 寄存器,那么这就是提取有效物理基地址的方式:
static inline uint64_t ttbr0_base_address(void)
{
uint64_t val;
asm volatile("mrs %0,ttbr0_el1" : "=r" (val));
return (val & 0xffffffffffc0) | ((val & 0x3c) << 46);
}
static inline uint64_t ttbr1_base_address(void)
{
uint64_t val;
asm volatile("mrs %0,ttbr1_el1" : "=r" (val));
return (val & 0xffffffffffc0) | ((val & 0x3c) << 46);
}
但是如果您正常运行 Linux,那么您就不太可能按原样取消引用该地址。您需要获得该物理地址的虚拟映射。假设在 DRAM 中的标准环境中,phys_to_virt()
应该可以工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。