linux-kernel - ARM Linux 在解压 head.S 中的内核时如何切换到 Thumb2 模式

标签 linux-kernel arm

我在从主线读取 4.15 版及更高版本的 Linux 内核基础时遇到问题。在 arch/arm/boot/compressed/head.S 中,我读过这样的内容。

133: #ifndef CONFIG_THUMB2_KERNEL
134:    mov r0, r0
135: #else
136:    AR_CLASS(   sub pc, pc, #3  )   @ A/R: switch to Thumb2 mode
137:    M_CLASS(    nop.w           )   @ M: already in Thumb2 mode
138:    .thumb
139: #endif

第136行表示在Thumb2中,它可以将CPU切换到Thumb-2模式,基本上是跳转到比当前PC地址低0x300偏移的地址。我还搜索了一些其他文章,其中一些使用'adr'或'xadr'切换到Thumb2模式。

我的问题是:为什么CPU可以通过这种方式切换到Thumb2模式?与使用“bx”有什么不同?

最佳答案

My question is : Why the CPU can switch to Thumb2 mode by this way? What's the different from using 'bx'?

看看代码和注释...

136:    AR_CLASS(   sub pc, pc, #3  )   @ A/R: switch to Thumb2 mode
137:    M_CLASS(    nop.w           )   @ M: already in Thumb2 mode
138:    .thumb

首先,在支持 Thumb 的 ARM 上,将 PC 设置为奇数地址会切换到拇指模式。我想你知道吗?其次,ARM PC 始终领先当前执行的指令 8 个字节。因此 sub pc, pc, #3 就像在 thumb2 模式下转到下一条指令。

但是如果CPU已经处于thumb2模式(像cortex-M一样从启动开始)怎么办? BX 在只有拇指模式的 CPU 上没有意义。 AR_CLASS 宏对于 Cortex-M CPU 没有定义。 M_CLASS对于 Cortex-A CPU 来说什么都没有定义。

我见过代码(我相信是在 U-Boot 中),其中包含旨在在两种模式下执行的指令。在thumb模式下,操作码是无操作,而在ARM模式下则执行分支。具体操作码在模式下含义不同,但二进制数相同。

为什么始终是一个很难回答的问题。也许 ARM sub 操作码在 Thumb2 中是无害的。此外,一些较旧的 CPU 可能不支持 BX

关于linux-kernel - ARM Linux 在解压 head.S 中的内核时如何切换到 Thumb2 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48722659/

相关文章:

linux - 当 kmalloc 已经返回指向内存位置的指针时,为什么需要 container_of?

linux - 如何在 linux 内核空间中读取环形缓冲区?

linux - linux 中的 Probe() 方法是否需要重入?

c - 如果在 Linux 内核中执行 make C=1 或 make C=2,检查器工具如何执行?

c - 使用 C 在 ARM Cortex M 系列上获取程序计数器值

c - 操作系统导致的 irq 延迟是多少?

c++ - 所选处理器不支持 Thumb 模式 `swp r3,sl,[fp]'

c - 为什么 sk_buff 在 h union 中有一个 ip 头指针(ipiphdr),在 nh union 中有一个常规 ip 头指针(iphdr)?

linux - 为 ARM 交叉编译 util-linux,libtool/ld 没有从 LDFLAGS 路径获取库

c - 如何在 ARM 上使用 kgdb?