在Linux中使用C / C ++获取机器序列号和CPU ID

如何在Linux系统中获得机器序列号和CPU ID?

示例代码非常感谢。

Solutions Collecting From Web of "在Linux中使用C / C ++获取机器序列号和CPU ID"

以下是Linux内核似乎使用的内容:

static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ asm volatile("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (*eax), "2" (*ecx)); } 

哪一个然后可以使用如:

 #include <stdio.h> int main(int argc, char **argv) { unsigned eax, ebx, ecx, edx; eax = 1; /* processor info and feature bits */ native_cpuid(&eax, &ebx, &ecx, &edx); printf("stepping %d\n", eax & 0xF); printf("model %d\n", (eax >> 4) & 0xF); printf("family %d\n", (eax >> 8) & 0xF); printf("processor type %d\n", (eax >> 12) & 0x3); printf("extended model %d\n", (eax >> 16) & 0xF); printf("extended family %d\n", (eax >> 20) & 0xFF); /* EDIT */ eax = 3; /* processor serial number */ native_cpuid(&eax, &ebx, &ecx, &edx); /** see the CPUID Wikipedia article on which models return the serial number in which registers. The example here is for Pentium III */ printf("serial number 0x%08x%08x\n", edx, ecx); } 

在这篇维基百科文章中 ,如何使用CPUID指令是一个很好的参考。

编辑维基百科文章说,序列号是与奔腾III一起引入的,但由于隐私问题,在后来的模型中不再执行。 在Linux系统上,您可以通过执行以下操作来检查是否存在此功能(PSN位):

 grep -i --color psn /proc/cpuinfo 

如果这不显示任何内容,则说明您的系统不支持处理器序列号。

在GCC中有一个cpuinfo.h包含。 这是安全的,使用它。

示例(我有GCC 4.7+,并感到高兴使用“自动”在这里):

 #include <cpuid.h> #include <iostream> #include <map> #include <string> using namespace std; struct CPUVendorID { unsigned int ebx; unsigned int edx; unsigned int ecx; string toString() const { return string(reinterpret_cast<const char *>(this), 12); } }; int main() { unsigned int level = 0; unsigned int eax = 0; unsigned int ebx; unsigned int ecx; unsigned int edx; __get_cpuid(level, &eax, &ebx, &ecx, &edx); CPUVendorID vendorID { .ebx = ebx, .edx = edx, .ecx = ecx }; map<string, string> vendorIdToName; vendorIdToName["GenuineIntel"] = "Intel"; vendorIdToName["AuthenticAMD"] = "AMD"; vendorIdToName["CyrixInstead"] = "Cyrix"; vendorIdToName["CentaurHauls"] = "Centaur"; vendorIdToName["SiS SiS SiS "] = "SiS"; vendorIdToName["NexGenDriven"] = "NexGen"; vendorIdToName["GenuineTMx86"] = "Transmeta"; vendorIdToName["RiseRiseRise"] = "Rise"; vendorIdToName["UMC UMC UMC "] = "UMC"; vendorIdToName["Geode by NSC"] = "National Semiconductor"; string vendorIDString = vendorID.toString(); auto it = vendorIdToName.find(vendorIDString); string vendorName = (it == vendorIdToName.end()) ? "Unknown" : it->second; cout << "Max instruction ID: " << eax << endl; cout << "Vendor ID: " << vendorIDString << endl; cout << "Vendor name: " << vendorName << endl; } 

输出:

 $ make g++ --std=c++11 main.cc -o cpuid $ ./cpuid Max instruction ID: 6 Vendor ID: GenuineIntel Vendor name: Intel 

有关您可以从/proc/cpuinfo提取的处理器的信息。

要得到序列号,你应该看看dmidecode 。 我现在没有看,但是dmidecode能够显示你的序列号,所以我会从那里开始。

 #include <stdio.h> void getPSN(char *PSN) { int varEAX, varEBX, varECX, varEDX; char str[9]; //%eax=1 gives most significant 32 bits in eax __asm__ __volatile__ ("cpuid" : "=a" (varEAX), "=b" (varEBX), "=c" (varECX), "=d" (varEDX) : "a" (1)); sprintf(str, "%08X", varEAX); //ie XXXX-XXXX-xxxx-xxxx-xxxx-xxxx sprintf(PSN, "%C%C%C%C-%C%C%C%C", str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]); //%eax=3 gives least significant 64 bits in edx and ecx [if PN is enabled] __asm__ __volatile__ ("cpuid" : "=a" (varEAX), "=b" (varEBX), "=c" (varECX), "=d" (varEDX) : "a" (3)); sprintf(str, "%08X", varEDX); //ie xxxx-xxxx-XXXX-XXXX-xxxx-xxxx sprintf(PSN, "%s-%C%C%C%C-%C%C%C%C", PSN, str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]); sprintf(str, "%08X", varECX); //ie xxxx-xxxx-xxxx-xxxx-XXXX-XXXX sprintf(PSN, "%s-%C%C%C%C-%C%C%C%C", PSN, str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]); } int main() { char PSN[30]; //24 Hex digits, 5 '-' separators, and a '\0' getPSN(PSN); printf("%s\n", PSN); //compare with: lshw | grep serial: return 0; } 

该程序将帮助您以编程方式运行Linux命令:

 char* GetSystemOutput(char* cmd) { int buff_size = 32; char* buff = new char[buff_size]; char* ret = NULL; string str = ""; int fd[2]; int old_fd[3]; pipe(fd); old_fd[0] = dup(STDIN_FILENO); old_fd[1] = dup(STDOUT_FILENO); old_fd[2] = dup(STDERR_FILENO); int pid = fork(); switch(pid) { case 0: close(fd[0]); close(STDOUT_FILENO); close(STDERR_FILENO); dup2(fd[1], STDOUT_FILENO); dup2(fd[1], STDERR_FILENO); system(cmd); //execlp((const char*)cmd, cmd,0); close (fd[1]); exit(0); break; case -1: cerr << "GetSystemOutput/fork() error\n" << endl; exit(1); default: close(fd[1]); dup2(fd[0], STDIN_FILENO); int rc = 1; while (rc > 0) { rc = read(fd[0], buff, buff_size); str.append(buff, rc); //memset(buff, 0, buff_size); } ret = new char [strlen((char*)str.c_str())]; strcpy(ret, (char*)str.c_str()); waitpid(pid, NULL, 0); close(fd[0]); } dup2(STDIN_FILENO, old_fd[0]); dup2(STDOUT_FILENO, old_fd[1]); dup2(STDERR_FILENO, old_fd[2]); return ret; } 

API用法: GetSystemOutput("/usr/bin/lsb_release -a")

并遵循以下命令:

 cat /proc/cpuinfo = tells you CPU information