Linux arm64如何在AArch32和AArch64之间切换

问题描述 投票:1回答:1

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

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

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

32位应用程序过程->手臂状态为AArch32

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

正确吗?

如果是这样,Linux如何处理AArch32和AArch64开关?内核知道运行的进程是32位还是64位吗?

linux linux-kernel arm embedded-linux
1个回答
0
投票

[如果您当前正在运行32位应用程序之一,并且遇到异常(例如IRQ,系统调用中的SVC,由于页面错误而中止...。),请输入64位OS。所以是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线程有更多详细信息。或者在https://medium.com/@om.nara/aarch64-exception-levels-60d3a74280e6中的“在AArch32和AArch64之间移动”中有更简单的解释]

在发生异常时,如果异常级别更改,则执行状态可以:保持不变,或从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-model/execution-and-security-stateshttps://www.realworldtech.com/arm64/2/中相同:

AArch64异常模型

特权级别:EL3-最高,EL0-最低

  • 通过异常过渡到更高级别
  • 寄存器宽度不能在较低的级别中更大

  • 例如没有带有32位EL1的64位EL0
    通过异常在AArch32和AArch64之间进行转换
  • 无法与AArch32 / AArch64互通
    现在回答您的问题:
  • Linux如何处理AArch32和AArch64开关?

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

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

    是,在64位内核(compat syscalls)上有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.harch/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);
    
  • © www.soinside.com 2019 - 2024. All rights reserved.