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?!