本文介绍了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位应用程序->臂状态为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-insoftware 0andriy (内核开发人员)通过马丁·魏德曼解释了如何在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.

https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/6706/in-aarch32状态什么机制可以切换到软件中的aarch64 线程具有更多详细信息.或 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"

从异常返回时,如果异常级别更改,则执行状态可以:保持不变,或从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/:

  • 特权级别: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互通

现在提出您的问题:

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

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

是的,在64位内核(compat syscalls)上有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.h 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位elf加载中通过几个个性宏设置:

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之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-23 07:11