文章目录
- ARMv8/v9 EL 等级获取
- EL 等级获取函数实现
- EL 等级获取测试
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, 测试结果如下: