前文《Intel处理器Family、Model、Stepping等的学习》只是简单讲了CPU的标识等内容(仅针对Intel,本文也是),但其读取方法未涉及。本文就此未完事宜来了解读取的方法:使用CPUID指令来完成。
Intel的IA32架构软件开发手册卷2(Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2)中有专门章节讲CPUID。CPUID指令涉及到的内容较多,一一讲述不现实——文后附带地址有全面的介绍,可以前往学习。权威的说明请参考手册。本着实用的学习目的,本文根据常见的功能做说明,另外文中示例代码直接使用coreboot开源项目。
CPUID指令根据传递给EAX 寄存器的值,将对应的信息返回给 EAX、EBX、ECX 及 EDX 寄存器。从Intel手册上看,早期有的CPU是不支持CPUID指令的,但现在的处理器应该都支持了。通过EFLAGS寄存器可以知晓。该寄存器bit 21(ID)标志表示了处理器对CPUID指令的支持。
coreboot中,使用cpuid函数进行CPUID指令的操作,传入参数实际上即是手册中出现的eax的值。代码如下:
1 | /* |
1、EAX=0,返回vendor id 执行CPUID后,返回值寄存器依次为EBX、EDX、ECX,其中EBX为“Genu”,EDX为“ineI”,ECX为“ntel”。手册解释如下:
1 | EBX <- 756e6547h (* "Genu", with G in the low eight bits of BL *) |
这些寄存器组合起来,就是“GenuineIntel”。
实现示例:coreboot项目src/arch/x86/cpu.c文件cpu_initialize函数。
下面根据wiki整理的已经知的CPU ID字符串:
1 | "AMDisbetter!" – early engineering samples of AMD K5 processor |
下面是虚拟机的CPU ID字符串:
1 | "KVMKVMKVM" – KVM |
2、EAX=0x01,返回Model、Family、Stepping信息
执行CPUID后,返回的EAX寄存器包含Model、Family、Stepping信息。各个字段解释如下图所示:
实现示例:coreboot项目src/arch/x86/cpu.c文件cpu_initialize函数。
3、EAX=80000002h、80000003h、80000004h:返回处理器brand字符串
比如Atom的一款CPU的brand信息为:“Intel(R) Atom(TM) CPU E3815 @ 1.46GHz.”。
实现示例: coreboot项目src/cpu/x86/mp_init.c文件init_bsp函数。
4、EAX=80000008h:返回虚拟地址和物理地址大小
物理地址的大小在EAX的bit[7:0]
返回,虚拟地址的大小在EAX的bit[15:8]
。
实现示例: coreboot项目src/soc/intel/fsp_baytrail/ramstage.c文件fill_in_pattrs函数。
参考:
coreboot项目主页:http://www.coreboot.org/
Intel 64 and IA-32 Architectures Software Developer’s Manual手册下载地址:
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
CPUID的wiki:https://en.wikipedia.org/wiki/CPUID
CPUID指令:http://hengch.blog.163.com/blog/static/1078006720091414224566/
李迟 2016.2.22 周一 元宵节夜