【ARMv8/v9 系统寄存器 6 -- EL 异常等级判定寄存器 CurrentEL 使用详细将介绍】

ARMv8/v9 EL 等级获取

下面这个宏定义是用于ARMv8/v9架构下,通过汇编语言检查当前执行在哪个异常级别(Exception Level,EL)并据此跳转到不同的标签。

异常级别是ARM架构中定义的用于隔离和保护系统资源的机制,不同的级别有不同的权限,一般来说:

  • EL0是用户模式,
  • EL1是操作系统内核模式,
  • EL2是虚拟机监控器模式,
  • EL3是安全监控模式。

下面代码是UEFI中实现如何判断当前EL等级的代码如下:

#define  EL1_OR_EL2_OR_EL3(SAFE_XREG) \
        mrs    SAFE_XREG, CurrentEL ;\  // 从"CurrentEL"系统寄存器中读取当前的异常级别到SAFE_XREG寄存器
        cmp    SAFE_XREG, #0x8      ;\  // 比较当前的异常级别是否为EL2 (0x8)
        b.gt   3f                   ;\  // 如果当前异常级别大于EL2,跳转到标签3
        b.eq   2f                   ;\  // 如果当前异常级别等于EL2,跳转到标签2
        cbnz   SAFE_XREG, 1f        ;\  // 如果当前异常级别不为0(即不是EL0),跳转到标签1
        b      .                    ;\  // 如果没有进入任何异常级别,就停在当前位置(这种情况应该不会发生,这里的跳转是一个死循环)
                                       // 我们不应该到达这里

这段宏定义使用了几个汇编指令:

  • mrs:将系统寄存器的值移动到一个通用寄存器中。
  • cmp:比较两个值。
  • b.gt:如果比较的结果是大于,则跳转。
  • b.eq:如果比较的结果是等于,则跳转。
  • cbnz:如果寄存器的值不为零,则跳转。
  • b:无条件跳转。

使用这个宏可以根据当前的异常级别执行不同的代码路径。例如,如果当前是EL1、EL2或EL3,它可以执行一些特定于这些级别的安全检查或配置。下面以

EL 等级获取函数实现

如下是我自己实现的获取当前 EL等级的汇编代码和C代码:

  • 异常等级判断汇编代码:
.macro EL1_OR_EL2_OR_EL3 label
    mrs    \label, CurrentEL
    cmp    \label, #0x8
    b.gt   3f
    b.eq   2f
    cbnz   \label, 1f
    b      .
.endm
  • 获取当前异常等级汇编代码:
func get_arm_eln
   EL1_OR_EL2_OR_EL3 x1
1: mov x0, #1
   ret
2: mov x0, #2
   ret
3: mov x0, #3
   ret
endfunc get_arm_eln

EL 等级获取测试

int get_eln(void *data)
{
        uint32_t el = get_current_el();

        log_info("current el is:%d\n", el);

        return 0;
}

由于当前我的代码是运行在EL3等级上的,所以理论上应该打印出当前异常等级为3, 测试结果如下:
在这里插入图片描述

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-16 03:00:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-16 03:00:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-16 03:00:05       82 阅读
  4. Python语言-面向对象

    2024-05-16 03:00:05       91 阅读

热门阅读

  1. 自媒体探索

    2024-05-16 03:00:05       28 阅读
  2. Helm安装集群整理

    2024-05-16 03:00:05       30 阅读
  3. golang encoding/json 使用基础

    2024-05-16 03:00:05       27 阅读
  4. RocketMQ:broker配置说明

    2024-05-16 03:00:05       27 阅读
  5. Kruskal算法刷题笔记

    2024-05-16 03:00:05       31 阅读
  6. Conda常用命令

    2024-05-16 03:00:05       35 阅读
  7. Redis如何实现持久化

    2024-05-16 03:00:05       33 阅读
  8. 【Go语言入门学习笔记】Part1.梦开始的地方

    2024-05-16 03:00:05       32 阅读
  9. day 27 第七章 回溯算法part03

    2024-05-16 03:00:05       35 阅读