更新 SCTLR_EL1 寄存器在 QEMU 上的裸机 ARMv8 程序中不起作用

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

我正在为我的项目学习armv8汇编程序。我编写了一个简单的程序,尝试修改 SCTLR_EL1 寄存器的值。不幸的是这个代码不起作用。我正在启用 I-cache,但我唯一看到的是 SCTLR_EL1 中的 0x0。

.section .text
.global _start

_start:
    mov x0, xzr                 // Initialize x0 to zero
    // Set SCTLR_EL1 and confirm the modification
    mrs x0, SCTLR_EL1            // Read SCTLR_EL1 into x0
    orr x0, x0, #(1 << 12)       // Enable I-Cache
    msr SCTLR_EL1, x0            // Write back to SCTLR_EL1

    mrs x0, SCTLR_EL1            // Read the modified SCTLR_EL1 into x0
    // Store the value in a known memory location for debugging
    ldr x1, =sctlr_el1_val
    str x0, [x1]

    b loop

loop:
    b loop

.data
.align 8
sctlr_el1_val: .quad 0x0100        // Memory location to store the SCTLR_EL1 value

内存映射

MEMORY
{
    rom  : ORIGIN = 0x00010000, LENGTH = 32K
}

SECTIONS
{
   .text : { *(.text*) } > rom
}

QEMU使用命令如下:

qemu-system-aarch64 -M virt -cpu cortex-a57 -m 512M -nographic -machine secure=on \
-S -s -kernel path_to_your_binary.elf -d in_asm,cpu

我在控制台中看到的输出是:

PSTATE=000003cd ---- EL3h
 PC=0000000000000200 X00=0000000000000000 X01=0000000000000000
X02=0000000000000000 X03=0000000000000000 X04=0000000000000000
X05=0000000000000000 X06=0000000000000000 X07=0000000000000000
X08=0000000000000000 X09=0000000000000000 X10=0000000000000000
X11=0000000000000000 X12=0000000000000000 X13=0000000000000000
X14=0000000000000000 X15=0000000000000000 X16=0000000000000000
X17=0000000000000000 X18=0000000000000000 X19=0000000000000000
X20=0000000000000000 X21=0000000000000000 X22=0000000000000000
X23=0000000000000000 X24=0000000000000000 X25=0000000000000000
X26=0000000000000000 X27=0000000000000000 X28=0000000000000000
X29=0000000000000000 X30=0000000000000000  SP=0000000000000000
PSTATE=000003cd ---- EL3h

GDB没有显示任何东西:

(gdb) x/x 0x0100
0x100:  0x00000000
(gdb) x/x $SCTLR_EL1
Value can't be converted to integer.
(gdb) p/x $SCTLR_EL1
$1 = void
(gdb) display  $SCTLR_EL1
1: $SCTLR_EL1 = void
(gdb)  p/x $CurrentEL
$2 = void

如何修改CurrentEL和SCTLR_EL1?我如何使用 GDB 查看这些寄存器值? 有人可以帮忙吗?谢谢。

assembly arm64 armv8 cortex-a
1个回答
0
投票

您看到的 QEMU 输出是由异常引起的。正如 @Jester 提到的,这是因为您正在启用

-machine secure=on
。此选项启用 ARM TrustZone 扩展。使用更高的程序入口点地址。
0x40000000
处的入口点应该可以工作。

写信给

isb
后,您也忘记了
SCTLR_EL1
指令。当您回写后直接读取
SCTLR_EL1
而没有
isb
指令时,
SCTLR_EL1
中的内容是旧的(
msr SCTLR_EL1, x0
之前的内容)。

.section .text
.func _start,_start
.type _start,%function
.global _start

_start:
    mov x0, xzr                 /* Initialize x0 to zero */
    mrs x0, SCTLR_EL1           /* Read SCTLR_EL1 into x0 */
    orr x0, x0, #(1 << 12)      /* Enable I-Cache */
    msr SCTLR_EL1, x0           /* Write back to SCTLR_EL1 */
    isb                         /* Instruction Synchronization barrier */

loop:
    b loop

.size _start, . - _start
.endfunc

要使用 GDB 显示寄存器值,您可以使用命令

info registers
info all-registers
。这些还应包括
SCTLR
寄存器。

CurrentEL
可以从 GDB 输出中的当前程序状态寄存器 (
cpsr
) 中提取。

要更改/切换到较低的异常级别,您可以在其他站点上找到足够的示例。

© www.soinside.com 2019 - 2024. All rights reserved.