ARM架构中如何读取协处理器寄存器

问题描述 投票:0回答:2

我正在尝试读取以下片上系统中的CP15协处理器

Cortex A7 - ARMv7-A

在我的片段下面

void main (void)
{
    unsigned int reg_value = 0;
    asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(reg_value) );
    printf("reg_value: %d", reg_value);
}

我不知道这是否是读取协处理器寄存器的正确方法,但它的编译已完成,没有错误。 问题是在执行过程中出现的(代码是在root中执行的):

Illegal instruction

如果我使用 gdb,我会得到以下结果:

   0x000086a0 <+16>:    str r3, [r11, #-40] ; 0x28
=> 0x000086a4 <+20>:    mrc 15, 0, r3, cr0, cr0, {0}
   0x000086a8 <+24>:    str r3, [r11, #-40] ; 0x28

为什么我无法读取协处理器寄存器?我的代码有什么问题吗?

c assembly arm
2个回答
4
投票

您似乎正在尝试使用指令访问 MIDR:主 ID 寄存器(来自 ARMARMv7 B4.1.105)

MRC p15, 0, <Rt>, c0, c0, 0    ; Read MIDR into Rt

但是,当您在 Linux 中执行应用程序时,您处于用户模式 (PL0) ARMARMv7 在 MIDR 的使用限制中指定

只能从 PL1 或更高版本访问。

因此只能在 PL1、PL2、PL3 访问。要访问它,您需要创建一个在 PL1 上运行的驱动程序,该驱动程序将读取 MIDR。然后,在您的应用程序中,打开此驱动程序以使用 IOCTL 获取数据。

您还可以尝试使用 PL0 中的 SVC 调用来访问内核模式 (PL1),但这意味着修改您的内核 SVC 处理程序。


0
投票

如果您使用的是 Linux,那么您可以从用户空间从文件系统访问每个 CPU 的寄存器值。例如:

$ cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1 
0x0000000012345678
© www.soinside.com 2019 - 2024. All rights reserved.