linux内核获取cpu,Linux内核中CPU信息获取方法

Linux内核中CPU信息获取方法

本文介绍了Linux Kernel中X86架构下CPU信息获取方法。

1.     EFLAGS寄存器

The ID flag (bit 21) in the EFLAGS register indicates support for the CPUID instruction. If a software procedure can set and clear this flag, the processor executing the procedure supports the CPUID instruction.

在Linux Kernel代码中,通过以下函数来判断CPU是否支持CPUID指令:

static inline int flag_is_changeable_p(u32 flag)

{

u1, f2;

1: asm("pushfl\n\t"

2:     "pushfl\n\t"

3:     "popl %0\n\t"

4:     "movl %0,%1\n\t"

5:     "xorl %2,%0\n\t"

6:     "pushl %0\n\t"

7:     "popfl\n\t"

8:     "pushfl\n\t"

9:     "popl %0\n\t"

10:          "popfl\n\t"

11:          : "=&r" (f1), "=&r" (f2)

12:          : "ir" (flag));

return ((f1^f2) & flag) != 0;

}

#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */

/* Probe for the CPUID instruction */

static int __cpuinit have_cpuid_p(void)

{

return flag_is_changeable_p(X86_EFLAGS_ID);

}

第1行代码保存目前的EFLAGS寄存器内容到堆栈中,以便使用第10行代码恢复EFLAGS寄存器内容到本函数执行前的状态;第2-4行代码将目前的EFLAGS寄存器内容保存到输出变量f2中;第5行代码将EFLAGS寄存器ID位与1进行异或操作,达到使ID位进行翻转,其他位不变的目的;第6-9行代码将变换后的EFLAGS寄存器内容保存到输出变量f1中;第11行代码中,”=”表示输出,”r”表示输出变量可以存储在General Purpose Registers(GRP)。”&”表示指令在完成使用输入变量前,可以编辑输出变量。第12行代码中,”i”表示输入变量可以是立即数常量;

当确定CPU支持CPUID指令后,就可以利用CPUID指令来获取CPU信息了。

2.     CPUID指令

CPUID returns processor identification and feature information in the EAX, EBX, ECX, and EDX registers. The instruction’s output is dependent on the contents of the EAX register upon execution (in some cases, ECX as well).

27052082_1.jpg

When CPUID executes with EAX set to 1, version information is returned in EAX (see Figure 3-6).

27052082_2.jpg

The Extended Family ID needs to be examined only when the Family ID is 0FH. The Extended Model ID needs to be examined only when the Family ID is 06H or 0FH. When CPUID executes with EAX set to 1, additional information is returned to the EBX register:

CLFLUSH instruction cache line size (second byte of EBX) — this number indicates the size of the cache line flushed with CLFLUSH instruction in 8-byte increments.

When CPUID executes with EAX set to 1, feature information is returned in EDX.

Bit 10 CLFSH in EDX: CLFLUSH Instruction. CLFLUSH Instruction is supported.

在Linux Kernel代码中,通过以下函数将上述信息存储到boot_cpu_data变量中:

void __init cpu_detect(struct cpuinfo_x86 *c)

{

/* Get vendor name */

cpuid(0x00000000, (unsigned int *)&c->cpuid_level,

(unsigned int *)&c->x86_vendor_id[0],

(unsigned int *)&c->x86_vendor_id[8],

(unsigned int *)&c->x86_vendor_id[4]);

if (c->cpuid_level >= 0x00000001) {

u32 junk, tfms, cap0, misc;

cpuid(0x00000001, &tfms, &misc, &junk, &cap0);

c->x86 = (tfms >> 8) & 15;

c->x86_model = (tfms >> 4) & 15;

if (c->x86 == 0xf)

c->x86 += (tfms >> 20) & 0xff;

if (c->x86 >= 0x6)

c->x86_model += ((tfms >> 16) & 0xF) << 4;

if (cap0 & (1<<19)) {

c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;

c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值