[英]Linux - Can I run arm64 binaries on aarch64 architecture?
[英]How Linux arm64 switch between AArch32 and AArch64
Linux 支持运行 32 位应用程序,只要
CONFIG_COMPAT
我假设 32 位应用程序必须在 arm AArch32 执行状态下运行,并且环境是否有 32 位应用程序和 64 位应用程序。
32位应用进程->arm状态为AArch32
64 位应用进程和内核 -> arm 状态为 AArch64
这是正确的吗?
如果是这样的话,
Linux 如何处理 AArch32 和 AArch64 开关?
内核是否知道正在运行的进程是 32 位还是 64 位?
链接https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/6706/in-aarch32-state-what-is-the-mechanism-to-switch-to- aarch64软件式在发表的评论0andriy (内核开发)具有通过AArch32用户空间进程和AArch64 Linux内核之间的切换说明马丁·魏德曼。 32->64 模式切换是在异常情况下完成的; 并且 64->32 切换在异常返回时完成。
如果您当前正在运行其中一个 32 位应用程序并且出现异常(例如 IRQ、系统调用中的 SVC、页面错误中止等),您将进入 64 位操作系统。 所以 AArch32 --> AArch64 过渡。 当操作系统执行异常返回到应用程序时,这是一个 AArch64-->AArch32 转换。 ... AArch32 状态中的任何异常类型都可能导致执行状态更改为 AArch64。 ... 对于异常返回,反之亦然。 AArch64 中的异常返回可能会导致执行状态更改为 AArch32。
对于异常和异常返回,只有当 EL 也发生变化时,才会发生执行状态的变化。 即从 EL0 到 EL1 的异常可能导致执行状态的更改。 但是从 EL1 到 EL1 的异常不能。
https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/6706/in-aarch32-state-what-is-the-mechanism-to-switch-to-aarch64 -in-software线程有更多细节。 或者在“在 AArch32 和 AArch64 之间移动”中的https://medium.com/@om.nara/aarch64-exception-levels-60d3a74280e6中有更简单的解释
在发生异常时,如果异常级别发生变化,则执行状态可以:保持不变,或从 AArch32 更改为 AArch64。
从异常返回时,如果异常级别发生变化,执行状态可以:保持不变,或从 AArch64 更改为 AArch32。
在https://events.static.linuxfound.org/images/stories/pdf/lcna_co2012_marinas.pdf演示文稿(幻灯片 5)或https://developer.arm.com/architectures/learn-the-architecture/exception- 中相同模型/执行和安全状态或在https://www.realworldtech.com/arm64/2/ 中:
AArch64 异常模型
- 特权级别:EL3 – 最高,EL0 – 最低
通过异常过渡到更高级别
寄存器宽度在较低级别不能更高
- 例如,没有 64 位 EL0 和 32 位 EL1
- 通过异常在 AArch32 和 AArch64 之间转换
- AArch32/AArch64 无法互通
现在回答您的问题:
Linux 如何处理 AArch32 和 AArch64 开关?
通过使用具有不同 PSTATE 值的 EL0/EL1 开关的异常处理(和返回)硬件功能。
内核是否知道正在运行的进程是 32 位还是 64 位?
是的,在 64 位内核(兼容系统调用)上检查 32 位进程(“任务”)的内核: arch/arm64/kernel/syscall.c
static long do_ni_syscall(struct pt_regs *regs, int scno)
{
#ifdef CONFIG_COMPAT
long ret;
if (is_compat_task()) {
ret = compat_arm_syscall(regs, scno);
if (ret != -ENOSYS)
return ret;
}
#endif
return sys_ni_syscall();
}
测试在include/asm/compat.h和arch/arm64/include/asm/thread_info.h 中定义为
#define TIF_32BIT 22 /* 32bit process */
static inline int is_compat_task(void)
{
return test_thread_flag(TIF_32BIT);
}
TIF_32BIT 由 fs/compat_binfmt_elf.c 中的 32 位 elf 加载设置,带有几个个性宏:
https://elixir.bootlin.com/linux/v4.19.107/source/arch/arm64/include/asm/elf.h#L208
/*
* Unlike the native SET_PERSONALITY macro, the compat version maintains
* READ_IMPLIES_EXEC across an execve() since this is the behaviour on
* arch/arm/.
*/
#define COMPAT_SET_PERSONALITY(ex) \
({ \
set_thread_flag(TIF_32BIT); \
})
https://elixir.bootlin.com/linux/v4.19.107/source/fs/compat_binfmt_elf.c#L104
#define SET_PERSONALITY COMPAT_SET_PERSONALITY
https://elixir.bootlin.com/linux/v4.19.107/source/fs/binfmt_elf.c#L690
#define SET_PERSONALITY2(ex, state) \
SET_PERSONALITY(ex)
static int load_elf_binary(struct linux_binprm *bprm)
SET_PERSONALITY2(loc->elf_ex, &arch_state);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.