gpt4 book ai didi

cpu-registers - 从 GNU/Linux shell 使用 devmem 读取 Armv8-A 寄存器

转载 作者:行者123 更新时间:2023-12-03 19:18:10 27 4
gpt4 key购买 nike

我想读取一些 Cortex-A53 寄存器的值,比如

  • D_AA64ISAR0_EL1 (AArch64)
  • ID_ISAR5 (Aarch32)
  • ID_ISAR5_EL1 (Aarch64)

  • 不幸的是,我缺乏一点嵌入式/组装经验。文件显示

    To access the ID_AA64ISAR0_EL1:MRS , ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into XtID_AA64ISAR0_EL1[31:0] can be accessed through the internal memory-mapped interfaceand the external debug interface, offset 0xD30.


    我决定在我的目标上使用 devmem2(因为 busybox 不包括 devmem 小程序)。以下程序是否正确读取寄存器?
    devmem2 0xD30
    我不确定的部分是使用“偏移量”作为直接物理地址。如果是实际地址,为什么要调用“偏移”而不是“地址”。如果是偏移量,基地址是什么?我 99% 确定这不是正确的程序,但我怎么知道要添加偏移量的基地址?我搜索了 Armv8 技术引用手册和 A53 MPCore 文档均无济于事。详细解释寄存器内容,但似乎假设您使用标签 ID_AA64ISAR0_EL1 从 ASM 读取它们。
    更新:
    我找到了这个:

    Configuration Base Address Register, EL1The CBAR_EL1 characteristics are:Purpose Holds the physical base address of the memory-mapped GIC CPUinterface registers.


    但这只是重复了我的问题,如何读取其他寄存器?
    更新 2:
    第一次更新似乎只与 GIC 相关,而与我试图读取的配置寄存器无关(我误解了我认为的信息)。
    对于手头的具体问题(检查加密扩展可用性),可以简单地 cat/proc/cpuinfo 并查找 aes/sha 等。
    更新 3:
    我现在正在调查 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0176c/ar01s04s01.html ,以及特定于 SoC 的基地址,因此可以在 SoC 的引用手册中找到。
    更新 4:
    感谢出色的答案,我似乎能够通过我的内核模块读取数据:
    [ 4943.461948] ID_AA64ISA_EL1 : 0x11120
    [ 4943.465775] ID_ISAR5_EL1 : 0x11121
    附:这非常有见地,再次感谢您!
    更新 5:
    根据要求的源代码:
    /******************************************************************************
    *
    * Copyright (C) 2011 Intel Corporation. All rights reserved.
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; version 2 of the License.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
    * the GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program; if not, write to the Free Software
    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    *
    *****************************************************************************/

    #include <linux/module.h>
    #include <linux/types.h>

    /*****************************************************************************/

    // read system register value ID_AA64ISAR0_EL1 (s3_0_c0_c6_0).
    static inline uint64_t system_read_ID_AA64ISAR0_EL1(void)
    {
    uint64_t val;
    asm volatile("mrs %0, ID_AA64ISAR0_EL1" : "=r" (val));
    return val;
    }

    // read system register value ID_ISAR5_EL1 (s3_0_c0_c2_5).
    static inline uint64_t system_read_ID_ISAR5_EL1(void)
    {
    uint64_t val;
    asm volatile("mrs %0, s3_0_c0_c2_5" : "=r" (val));
    return val;
    }

    /*****************************************************************************/

    int init_module(void)
    {
    printk("ramdump Hello World!\n");
    printk("ID_AA64ISAR0_EL1 : 0x%llX\n", system_read_ID_AA64ISAR0_EL1());
    printk("ID_ISAR5_EL1 : 0x%llX\n", system_read_ID_ISAR5_EL1());
    return 0;
    }

    void cleanup_module(void)
    {
    printk("ramdump Goodbye Cruel World!\n");
    }

    MODULE_LICENSE("GPL");

    最佳答案

    免责声明:我不是 Aarch64 专家,但我目前正在学习架构并阅读了一些内容。

    您无法阅读 ID_AA64ISAR0_EL1 , ID_ISAR5_EL1也不是 ID_ISAR5来自运行在 EL0 的用户模式应用程序: _EL1后缀意味着比至少运行 EL1为了被允许读取这两个寄存器是必需的。

    阅读 arm 文档 here 中的伪代码可能会对您有所帮助。和 here .
    ID_ISAR5 的情况下例如,伪代码非常明确:

    if PSTATE.EL == EL0 then
    UNDEFINED;
    elsif PSTATE.EL == EL1 then
    if EL2Enabled() && !ELUsingAArch32(EL2) && HSTR_EL2.T0 == '1' then
    AArch64.AArch32SystemAccessTrap(EL2, 0x03);
    elsif EL2Enabled() && ELUsingAArch32(EL2) && HSTR.T0 == '1' then
    AArch32.TakeHypTrapException(0x03);
    elsif EL2Enabled() && !ELUsingAArch32(EL2) && HCR_EL2.TID3 == '1' then
    AArch64.AArch32SystemAccessTrap(EL2, 0x03);
    elsif EL2Enabled() && ELUsingAArch32(EL2) && HCR.TID3 == '1' then
    AArch32.TakeHypTrapException(0x03);
    else
    return ID_ISAR5;
    elsif PSTATE.EL == EL2 then
    return ID_ISAR5;
    elsif PSTATE.EL == EL3 then
    return ID_ISAR5;

    读取这些寄存器的一种简单方法是编写一个可从用户模式应用程序调用的微型可加载内核模块:因为 Linux 内核运行在 EL1。 ,它完全能够读取这三个寄存器。

    参见示例 this这篇文章很好地介绍了 Linux 可加载内核模块。

    这很可能是在 EL0 上运行的应用程序。无法访问只能从 EL1 访问的内存映射寄存器,因为这显然会破坏保护方案。

    在 Aarch64 状态下读取这些寄存器所需的 C 代码片段将是(使用 gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu 测试):
    #include <stdint.h>

    // read system register value ID_AA64ISAR0_EL1 (s3_0_c0_c6_0).
    static inline uint64_t system_read_ID_AA64ISAR0_EL1(void)
    {
    uint64_t val;
    asm volatile("mrs %0, s3_0_c0_c6_0" : "=r" (val));
    return val;
    }

    // read system register value ID_ISAR5_EL1 (s3_0_c0_c2_5).
    static inline uint64_t system_read_ID_ISAR5_EL1(void)
    {
    uint64_t val;
    asm volatile("mrs %0, s3_0_c0_c2_5" : "=r" (val));
    return val;
    }

    更新 #1 :
    GCC 工具链不理解所有 arm 系统寄存器名称,但如果指定 coproc、opc1、CRn、CRm 和 opc2 字段的哪些确切值与此寄存器相关联,则可以正确编码系统寄存器访问指令。

    ID_AA64ISAR0_EL1 的情况下, Arm® Architecture Registers Armv8, for Armv8-A architecture profile 中指定的值文件 are :
    coproc=0b11 , opc1=0b000 , CRn=0b0000 , CRm=0b0110 , opc2=0b000
    系统寄存器别名将是 s[coproc]_[opc1]_c[CRn]_c[CRm]_[opc2] ,即 s3_0_c0_c6_0ID_AA64ISAR0_EL1 的情况下.

    关于cpu-registers - 从 GNU/Linux shell 使用 devmem 读取 Armv8-A 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60071590/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com