在 x86 平台中使用 -mcmodel=kernel 标志
use of -mcmodel=kernel flag in x86 platform
我正在尝试交叉编译为 x86 架构构建的设备驱动程序以用于 arm 平台。它编译没有任何错误,但我不认为所有功能都可用。所以我检查了 makefile 并找到了这个特定部分。
ifeq ($(ARCH),x86_64)
EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone
这似乎是唯一依赖于体系结构的部分。在 google 上一段时间后,我发现 -mcmodel=kernel 用于内核代码模型,-mno-red-zone 用于避免在内存中使用红色区域,它们都是用于 x86_64。但我不清楚,将 cmodel 设置为内核有什么影响?
(对 arm 问题的任何见解也非常感谢。)
The x86 Options section of the GCC manual 说:
-mcmodel=kernel
Generate code for the kernel code model. The kernel runs in the negative 2 GB of the address space.
(即上部 2GiB,地址如 0xfffffffff0001234
)
在内核代码模型中,静态符号地址不适合 32 位 zero-extended 常量(不同于默认的小代码模型,其中 mov eax, imm32
(5 字节)是最有效的方式将符号地址放入寄存器)。
但是它们 适合 sign-extended 32 位常量,这与 large
代码模型不同。所以 mov rax, sign_extended_imm32
(7 个字节)可以工作,并且大小相同但可能比 lea rax, [rel symbol]
.
效率稍高
但更重要的是 mov eax, [table + rdi*4]
有效,因为 disp32 位移是 sign-extended 到 64 位。 -mcmodel=kernel
告诉 gcc 它可以做到这一点但 mov eax, table
.
RIP-relative 寻址也可以从任何代码地址到达任何符号(具有 rel32 +-2GiB 偏移量),因此 -fPIC
或 -fPIE
也将使您的代码工作,在在有用的情况下不利用 32 位绝对寻址的小代价。 (例如索引静态数组)。
如果没有 -mcmodel=kernel
(like these), you probably have a gcc that makes PIE executables by default(在最近的发行版中很常见),那么它就避免了绝对寻址。
我正在尝试交叉编译为 x86 架构构建的设备驱动程序以用于 arm 平台。它编译没有任何错误,但我不认为所有功能都可用。所以我检查了 makefile 并找到了这个特定部分。
ifeq ($(ARCH),x86_64)
EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone
这似乎是唯一依赖于体系结构的部分。在 google 上一段时间后,我发现 -mcmodel=kernel 用于内核代码模型,-mno-red-zone 用于避免在内存中使用红色区域,它们都是用于 x86_64。但我不清楚,将 cmodel 设置为内核有什么影响?
(对 arm 问题的任何见解也非常感谢。)
The x86 Options section of the GCC manual 说:
-mcmodel=kernel
Generate code for the kernel code model. The kernel runs in the negative 2 GB of the address space.
(即上部 2GiB,地址如 0xfffffffff0001234
)
在内核代码模型中,静态符号地址不适合 32 位 zero-extended 常量(不同于默认的小代码模型,其中 mov eax, imm32
(5 字节)是最有效的方式将符号地址放入寄存器)。
但是它们 适合 sign-extended 32 位常量,这与 large
代码模型不同。所以 mov rax, sign_extended_imm32
(7 个字节)可以工作,并且大小相同但可能比 lea rax, [rel symbol]
.
但更重要的是 mov eax, [table + rdi*4]
有效,因为 disp32 位移是 sign-extended 到 64 位。 -mcmodel=kernel
告诉 gcc 它可以做到这一点但 mov eax, table
.
RIP-relative 寻址也可以从任何代码地址到达任何符号(具有 rel32 +-2GiB 偏移量),因此 -fPIC
或 -fPIE
也将使您的代码工作,在在有用的情况下不利用 32 位绝对寻址的小代价。 (例如索引静态数组)。
如果没有 -mcmodel=kernel
(like these), you probably have a gcc that makes PIE executables by default(在最近的发行版中很常见),那么它就避免了绝对寻址。