How does the Linux kernel get info about the processors and the cores?

linux, linux-kernel

Solution

Short answer

Kernel uses special CPU instruction `cpuid` and saves results in internal structure - `cpuinfo_x86` for x86

Long answer

Kernel source is your best friend. Start from entry point - file `/proc/cpuinfo`. As any proc file it has to be cretaed somewhere in kernel and declared with some file_operations. This is done at fs/proc/cpuinfo.c. Interesting piece is `seq_open` that uses reference to some `cpuinfo_op`. This ops are declared in arch/x86/kernel/cpu/proc.c where we see some `show_cpuinfo` function. This function is in the same file on line 57.

Here you can see

 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");

Structure `c` declared on the first line as `struct cpuinfo_x86`. This structure is declared in arch/x86/include/asm/processor.h. And if you search for references on that structure you will find function `cpu_detect` and that function calls function `cpuid` which is finally resolved to `native_cpuid` that looks like this:

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 }

And here you see assembler instruction `cpuid`. And this little thing does real work.

Problem

Assume we have a blank computer without any OS and we are installing a Linux. Where in the kernel is the code that identifies the processors and the cores and get information about/from them? This info eventually shows up in places like /proc/cpuinfo but how does the kernel get it in the first place?!

Original source