我正在 QEMU 上编写一个裸机 ARMv8 程序,但是当我启用 MMU 时,它无法继续执行任何指令。
QEMU 选项是“-machine virt -cpu cortex-a57 -smp 1 -m 1G -nographic -serial mon:stdio -kernel a.bin”
这是我的代码https://github.com/zhulangpi/NBOS/blob/mmu/arch/start.S
我尝试将 0x4000 0000~0x7fbf ffff(DRAM) 映射到 0xffff 0000 0000 0000~0xffff 0000 3fbf ffff(总 1020MB)。
我使用 GDB 通过连接 QEMU 来调试二进制映像,当我启用 MMU 时,如果我执行下一条指令,它会显示:
(gdb) x/x 0x400800c8
0x400800c8: 0xd28014b4
(gdb) si
0x00000000400800c8 in ?? ()
=> 0x00000000400800c8: Cannot access memory at address 0x400800c8
0x400800c8 是 PA,对应的 VA(链接描述文件中的地址)是 0xffff 0000 0008 00c8。
我可以通过 GDB 中的虚拟地址正确访问内存,如下所示,
(gdb) x/x 0xffff0000000800c8
0xffff0000000800c8 <_start+200>: 0xd28014b4
我如下配置MMU,
adrp x0, pg_tbl_start //defined in linker script
msr ttbr1_el1, x0
ldr x0, =(TCR_VALUE) //(TCR_T0SZ | TCR_T1SZ | TCR_TG0_4K | TCR_TG1_4K)
msr tcr_el1, x0
ldr x0, =(MAIR_VALUE) //(0<<(8*1))|(0x44<<(8*0))
msr mair_el1, x0
//Initialize VBAR_EL1
ldr x0, =vector_table_el1
msr vbar_el1, x0
/* configure init kernel task stack */
ldr x0, =__init_stack_top //defined in linker script
mov sp, x0 //sp_el1
mrs x0, s3_1_c15_c2_1
orr x0, x0, #(0x1<<6) //cpuectlr.smpen = 1
msr s3_1_c15_c2_1, x0
mrs x0, sctlr_el1
orr x0, x0, #1 // M bit, mmu
msr sctlr_el1, x0 //enable the MMU
我希望正确访问内存和设备。或者有人可以向我展示如何在 qemu virt 机器中启用 mmu 的代码。