ARM技术论坛
直播中

韩刚龙

7年用户 1015经验值
私信 关注
[经验]

在ARMv8中aarch64与aarch32是怎样进行切换的

ARMv8中,aarch64和aarch32是通过异常进行切换的。而A32和T32是通过bx指令进行切换的。如下图:


以下A64和A32混合编程,是在EL3为aarch64, EL2为aarch32条件下进行编程。在EL3,设置EL2的架构为aarch32,设置好返回地址,通过ERET指令,切换到EL2。

对于A64代码,使用aarch64编译工具链进行编译。


对于A32代码,使用arm编译工具链。


因为A32和A64所使用的编译器不是同一个,因此要分开进行编译,对于A64的代码,使用aarch64进行编译,,对于A32的代码,使用arm进行编译,最后使用aarch64的链接器,将生成的文件,链接成A64的elf程序,供fastmodel使用。如下图所示:


但是对于aarch64链接器,只能将A64的.o文件,链接到一起,不能链接A32的.o文件,因此这里要用到一个小技巧,将A32代码生成A32的可执行程序,然后使用arm工具链中的objcopy工具,将可执行程序转换为bin文件,然后aarch64链接器,将该bin文件和A64的.o文件进行链接。如下图所示:


demo代码目录:


◾a32.S: A32汇编代码
◾test32.lds: A32的链接脚本
◾boot-a64.S: A64汇编代码
◾test.lds: A64的链接脚本
◾Makefile: make脚本
◾load_file_ns: non-secure地址划分文件
◾load_file_s: secure地址划分文件
◾VAL_VAL_AEMv8A.cfg: fastmodel的配置文件,一个core,EL3为aarch64

一、boot-a64.S
fastmodel最开始执行程序,是在EL3,在EL3,设置scr_el3寄存器,设置EL2运行模式是non-secure,aarch32。


设置elr_el3,以及spsr_el3寄存器:

◾elf_el3寄存器保存,切换到EL2时取指令的地址
◾spsr_el3寄存器保存,切换到EL2后pstate的值。

对于spsr_el3,要设置正确,此时要参考AArch32的cpsr寄存器值进行设置。

第4bit要设置为1,第5bit设置为0,1都可。3-0bit,要设置为A32的特权模式。


二、test.lds

A64的链接脚本。

将A32代码生成的bin文件,直接插入到a32_begin开始的memory区域中。这里,要使用INPUT,指定a32.bin的位置。


三、a32.S

A32的代码,包括两部分,一部分是A32指令,另一部分是thumb指令。

对于A32指令,使用.code 32 或者 .arm 声明。


使用bx指令从A32切换到T32状态,跳转地址的最低位要为1。

对于T32指令,使用 .code 16 或者 .thumb 声明。



使用bx指令从T32状态,切换到A32状态,跳转地址的最低为要为0。

四、test32.lds

A32程序的链接脚本。



五、makefile

对于A64的程序,要使用aarch64-none-elf工具链,对于A32的程序,要使用arm-none-eabi工具链。

◾gcc:编译工具
◾ld: 链接工具
◾objdump: 反汇编工具
◾objcopy: 文件转换工具



执行 make;make run 命令

最后生成all.tarmac,就是A64和A32汇编程序的程序执行流的执行结果。

最开始是EL3,执行ERET后,切换到EL2,但是EL2是aarch32,因此切换到A32,执行A32程序。



在A32状态,执行bx指令,并且跳转地址最低位为1,切换到thumb状态。


在T32状态,执行bx指令,并且跳转指令最低为是0,切换到A32状态。


六、结论

EL2的A64和A32状态,由EL3决定,也就是SCR_EL3.RW寄存器决定。
EL1的A64和A32状态,由EL2决定,也就是HCR_EL3.RW寄存器决定。
EL0的A64和A32状态,由EL1决定,也就是CPSR.M[4] 位决定。
以上的demo是从EL3的A64切换到EL2的A32,其他EL的切换,道理是一样的。设置相关寄存器,设置spsr,设置elr。

更多回帖

发帖
×
20
完善资料,
赚取积分