在x86平台上使用-mcmodel = kernel标志 [英] use of -mcmodel=kernel flag in x86 platform

查看:636
本文介绍了在x86平台上使用-mcmodel = kernel标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图交叉编译为x86架构构建的设备驱动程序,以武装平台.它已编译,没有任何错误,但我认为所有功能均不可用.因此,我检查了makefile并找到了该特定部分.

I am trying to cross compile a device driver built for x86 architecture to arm platform. It got compiled without any errors, but I dont think whole features are available. So I checked the makefile and found this particular part.

ifeq ($(ARCH),x86_64)
    EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone

这是唯一看起来依赖于体系结构的部分.在Google上待了一段时间后,我发现-mcmodel = kernel用于内核代码模型,而-mno-red-zone是为了避免在内存中使用红色区域,并且它们都用于x86_64.但是我不清楚,将cmodel设置为内核会产生什么影响?

This is the only part that depends on architecture it seems. After some time on google, I found that -mcmodel=kernel is for kernel code model and -mno-red-zone is to avoid using red zone in memory and both them were for x86_64. But its not clear to me, what impact does it make setting cmodel to kernel?

(对手臂问题的任何见解也将不胜感激.)

(Any insight into the problem with arm is also greatly appreciated.)

推荐答案

GCC手册的 x86选项部分说:

-mcmodel=kernel

为内核代码模型生成代码. 内核在负2 GB的地址空间中运行.

Generate code for the kernel code model. The kernel runs in the negative 2 GB of the address space.

(即高2GiB,类似0xfffffffff0001234的地址)

(i.e. the upper 2GiB, addresses like 0xfffffffff0001234)

在内核代码模型中,静态符号地址不适合32位零扩展常量(与默认的小代码模型不同,在默认小代码模型中,mov eax, imm32(5个字节)是在其中放置符号地址的最有效方法)一个寄存器).

In the kernel code model, static symbol addresses don't fit in 32-bit zero-extended constants (unlike the default small code model where mov eax, imm32 (5 bytes) is the most efficient way to put a symbol address in a register).

但是它们 do 符合符号扩展的32位常量,例如,不同于large代码模型.因此,mov rax, sign_extended_imm32(7个字节)有效,并且大小相同,但可能比lea rax, [rel symbol]效率更高.

But they do fit in sign-extended 32-bit constants, unlike the large code model for example. So mov rax, sign_extended_imm32 (7 bytes) works, and is the same size but maybe slightly more efficient than lea rax, [rel symbol].

但更重要的是mov eax, [table + rdi*4]可以工作,因为disp32位移被符号扩展为64位. -mcmodel=kernel告诉gcc可以执行此操作,但mov eax, table 不能.

But more importantly mov eax, [table + rdi*4] works, because disp32 displacements are sign-extended to 64 bits. -mcmodel=kernel tells gcc it can do this but not mov eax, table.

相对于RIP的寻址也可以到达任何代码地址中的任何符号(具有rel32 + -2GiB偏移),因此-fPIC-fPIE也会使您的代码正常工作,而付出的代价很小,就是不利用以下代码:在有用的情况下使用32位绝对寻址. (例如,索引静态数组).

RIP-relative addressing can also reach any symbol from any code address (with a rel32 +-2GiB offset), so -fPIC or -fPIE will also make your code work, at the minor expense of not taking advantage of 32-bit absolute addressing in cases where it's useful. (e.g. indexing static arrays).

如果没有-mcmodel=kernel(像这样),您不会收到链接错误,您可能有一个通过PIE可执行文件的gcc默认值(在最近的发行版中很常见),因此避免了绝对寻址.

If you didn't get link errors without -mcmodel=kernel (like these), you probably have a gcc that makes PIE executables by default (common on recent distros), so it avoids absolute addressing.

这篇关于在x86平台上使用-mcmodel = kernel标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆