Linux arm64 如何在 AArch32 和 AArch64 之间切换 [英] How Linux arm64 switch between AArch32 and AArch64

查看:110
本文介绍了Linux arm64 如何在 AArch32 和 AArch64 之间切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Linux 支持运行 32 位应用程序,只要

Linux supports running 32-bit application, as long as

  1. 内核启用CONFIG_COMPAT
  2. 硬件支持 AArch32

我假设 32 位应用程序必须在 arm AArch32 执行状态下运行,并且环境是否有 32 位应用程序和 64 位应用程序.

I assume that 32-bit application must run in arm AArch32 execution state and if the environment has 32-bit application and 64-bit application.

32位应用进程->arm状态为AArch32

32-bit application process -> arm state is AArch32

64 位应用进程和内核 -> arm 状态为 AArch64

64-bit application process and kernel -> arm state is AArch64

正确吗?

如果是这样,
Linux 如何处理 AArch32 和 AArch64 切换?
内核是否知道正在运行的进程是 32 位还是 64 位?

If so,
how does the Linux handle the AArch32 and AArch64 switch?
Does the kernel know the running process is 32-bit or 64-bit?

推荐答案

链接 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 发表在 0andriy (内核开发人员) 由 Martin Weidmann 解释了在 AArch32 用户空间进程和 AArch64 linux 内核之间切换一>.32->64 模式切换是在异常情况下完成的;并且 64->32 切换在异常返回时完成.

The link 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 posted in comments by 0andriy (kernel developer) has explanation of switching between AArch32 user-space process and AArch64 linux kernel by Martin Weidmann. The 32->64 mode switch is done at exceptions; and 64->32 switch is done at exception return.

如果您当前正在运行其中一个 32 位应用程序并且出现异常(例如 IRQ、系统调用中的 SVC、页面错误中止等),您将进入 64 位操作系统.所以 AArch32 --> AArch64 过渡.当操作系统执行异常返回到应用程序时,这是一个 AArch64-->AArch32 转换....AArch32 状态中的任何异常类型都可能导致执行状态更改为 AArch64.... 对于异常返回,反之亦然.AArch64 中的异常返回可能会导致执行状态更改为 AArch32.
对于异常和异常返回,只有当 EL 也发生变化时,才会发生执行状态的变化.即从 EL0 到 EL1 的异常可能会导致执行状态发生变化.但是从 EL1 到 EL1 的异常不能.

If you are currently running one of the 32-bit apps and you take an exception (e.g. IRQ, SVC from a system call, abort from a page fault,....) you enter the 64-bit OS. So a AArch32 --> AArch64 transition. When the OS performs an exception return back into the app, that's an AArch64-->AArch32 transition. ... Any exception type in AArch32 state could potentially lead to Execution state changing to AArch64. ... For exceptions returns the reverse is true. An exception return in AArch64 might cause execution state to change to AArch32.
For both exceptions and exception returns, a change of Execution state can only occur if there is also a change in EL. That is an exception from EL0 to EL1 could lead to a change in Execution state. But an exception from EL1 to EL1 could not.

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 线程有更多细节.或者在 https://medium.com/@om 中有更简单的解释.nara/aarch64-exception-levels-60d3a74280e6 在在 AArch32 和 AArch64 之间移动"

The 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 thread has some more details. Or there is much simpler explanation in https://medium.com/@om.nara/aarch64-exception-levels-60d3a74280e6 in "Moving between AArch32 and AArch64"

在发生异常时,如果异常级别发生变化,则执行状态可以:保持不变,或从 AArch32 更改为 AArch64.

On taking an exception, if the Exception level changes, the Execution state can: Remain unchanged, OR Change from AArch32 to AArch64.

从异常返回时,如果异常级别发生变化,则执行状态可以:保持不变,或从 AArch64 更改为 AArch32.

On returning from an exception, if the Exception level changes, the Execution state can: Remain unchanged, OR Change from AArch64 to AArch32.

同样在 https://events.static.linuxfound.org/images/stories/pdf/lcna_co2012_marinas.pdf 演示文稿(幻灯片 5)或在 https://developer.arm.com/architectures/learn-the-architecture/exception-model/execution-and-security-states 或在 https://www.realworldtech.com/arm64/2/:

Same in https://events.static.linuxfound.org/images/stories/pdf/lcna_co2012_marinas.pdf presentation (slide 5) or in https://developer.arm.com/architectures/learn-the-architecture/exception-model/execution-and-security-states or in https://www.realworldtech.com/arm64/2/:

AArch64 异常模型

AArch64 Exception Model

  • 特权级别:EL3 – 最高,EL0 – 最低
  • 通过异常过渡到更高级别

  • Privilege levels: EL3 – highest, EL0 – lowest
  • Transition to higher levels via exceptions

寄存器宽度不能在较低级别中更高

Register width cannot be higher in lower levels

  • 例如没有 64 位 EL0 和 32 位 EL1
  • AArch32/AArch64 无法互通

现在回答您的问题:

Linux 如何处理 AArch32 和 AArch64 切换?

how does the Linux handle the AArch32 and AArch64 switch?

通过使用具有不同 PSTATE 值的 EL0/EL1 开关的异常处理(和返回)硬件功能.

By using hardware capability of exception handling (and return) with EL0/EL1 switch with different PSTATE values.

内核是否知道正在运行的进程是 32 位还是 64 位?

Does the kernel know the running process is 32-bit or 64-bit?

是的,在 64 位内核(兼容系统调用)上检查 32 位进程(任务")的内核:arch/arm64/kernel/syscall.c

Yes, there is the check in kernel for 32-bit processes ("tasks") on 64-bit kernels (compat syscalls): 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.harch/arm64/include/asm/thread_info.h as

Test is defined in include/asm/compat.h and arch/arm64/include/asm/thread_info.h as

#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 位精灵加载设置,并带有几个个性宏:

TIF_32BIT is set by in fs/compat_binfmt_elf.c on 32-bit elf loading with several personality macro:

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);

这篇关于Linux arm64 如何在 AArch32 和 AArch64 之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆