【发布时间】:2014-01-29 20:31:09
【问题描述】:
假设我们有一台没有任何操作系统的空白计算机,并且我们正在安装 Linux。内核中的哪里是识别处理器和内核并获取有关/从它们的信息的代码? 这些信息最终会出现在 /proc/cpuinfo 之类的地方,但是内核首先是如何获得它的呢?!
【问题讨论】:
标签: linux linux-kernel
假设我们有一台没有任何操作系统的空白计算机,并且我们正在安装 Linux。内核中的哪里是识别处理器和内核并获取有关/从它们的信息的代码? 这些信息最终会出现在 /proc/cpuinfo 之类的地方,但是内核首先是如何获得它的呢?!
【问题讨论】:
标签: linux linux-kernel
简答
内核使用特殊的 CPU 指令 cpuid 并将结果保存在内部结构中 - cpuinfo_x86 for x86
长答案
内核源是你最好的朋友。
从入口点开始 - 文件 /proc/cpuinfo。
与任何 proc 文件一样,它必须在内核中的某个位置创建并使用一些 file_operations 声明。这是在fs/proc/cpuinfo.c 完成的。有趣的部分是seq_open,它引用了一些cpuinfo_op。此操作在arch/x86/kernel/cpu/proc.c 中声明,我们在其中看到一些show_cpuinfo 函数。这个函数在line 57 的同一个文件中。
在这里你可以看到
64 seq_printf(m, "processor\t: %u\n"
65 "vendor_id\t: %s\n"
66 "cpu family\t: %d\n"
67 "model\t\t: %u\n"
68 "model name\t: %s\n",
69 cpu,
70 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
71 c->x86,
72 c->x86_model,
73 c->x86_model_id[0] ? c->x86_model_id : "unknown");
结构c 在第一行声明为struct cpuinfo_x86。这个结构在arch/x86/include/asm/processor.h 中声明。如果您搜索该结构的引用,您会发现函数cpu_detect,该函数调用函数cpuid,最终解析为native_cpuid,如下所示:
189 static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
190 unsigned int *ecx, unsigned int *edx)
191 {
192 /* ecx is often an input as well as an output. */
193 asm volatile("cpuid"
194 : "=a" (*eax),
195 "=b" (*ebx),
196 "=c" (*ecx),
197 "=d" (*edx)
198 : "" (*eax), "2" (*ecx)
199 : "memory");
200 }
在这里你可以看到汇编指令cpuid。这个小东西确实有效。
【讨论】:
此信息来自 BIOS + 硬件 DB。例如,您可以通过 dmidecode 直接获取信息(如果您需要更多信息 - 尝试检查 dmidecode 源代码)
sudo dmidecode -t processor
【讨论】: