Linux下使用C/C++获取机器序列号和CPU ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6491566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting the machine serial number and CPU ID using C/C++ in Linux
提问by boom
How can I get the machine serial number and CPU ID in a Linux system?
如何在Linux系统中获取机器序列号和CPU ID?
Sample code is highly appreciated.
示例代码受到高度赞赏。
采纳答案by Andre Holzner
Hereis what the Linux kernel seems to use:
以下是 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));
}
which one then can use as e.g.:
然后可以将其用作例如:
#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);
}
Where a good reference on how to use the CPUID
instruction is in this Wikipedia article.
关于如何使用该CPUID
指令的一个很好的参考在这篇 Wikipedia 文章中。
EDITThe Wikipedia article says that the serial number was introduced with the Pentium III but was not anymore implemented in later models due to privacy concerns. On a Linux system you can check for the presence of this feature (PSN bit) by doing:
编辑维基百科文章说序列号是在奔腾 III 中引入的,但由于隐私问题,在后来的模型中不再实施。在 Linux 系统上,您可以通过执行以下操作来检查此功能(PSN 位)是否存在:
grep -i --color psn /proc/cpuinfo
if this does not show anything, your system does not support a processor serial number.
如果这没有显示任何内容,则您的系统不支持处理器序列号。
回答by Thomas Berger
The Informations about the processor you could extract from /proc/cpuinfo
.
您可以从中提取的有关处理器的信息/proc/cpuinfo
。
To get the Serial Number you should have a look at dmidecode
. I didn't look in there right now, but dmidecode
is able to show you the serial number, so i would start there.
要获得序列号,您应该查看dmidecode
. 我现在没有在那里查看,但dmidecode
能够向您展示序列号,所以我会从那里开始。
回答by Alok Save
This program will help you run Linux commands programmatically:
该程序将帮助您以编程方式运行 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 usage: GetSystemOutput("/usr/bin/lsb_release -a")
接口用法: GetSystemOutput("/usr/bin/lsb_release -a")
And following the commands:
并遵循以下命令:
cat /proc/cpuinfo = tells you CPU information
回答by cppist
There is a cpuinfo.h include in GCC. It is safe, use it.
GCC 中包含一个 cpuinfo.h。这是安全的,使用它。
Sample (I have GCC 4.7+ and feel happy of using "auto" here):
示例(我有 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;
}
Output:
输出:
$ make
g++ --std=c++11 main.cc -o cpuid
$ ./cpuid
Max instruction ID: 6
Vendor ID: GenuineIntel
Vendor name: Intel
回答by Nitinkumar Ambekar
#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); //i.e. 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); //i.e. 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); //i.e. 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 '##代码##'
getPSN(PSN);
printf("%s\n", PSN); //compare with: lshw | grep serial:
return 0;
}