问题描述
Linux支持运行32位应用程序,只要
Linux supports running 32-bit application, as long as
- 内核启用
CONFIG_COMPAT
- 硬件支持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之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!