在 Linux 中使用 C/C++ 获取机器序列号和 CPU ID
- 2024-11-08 09:04:00
- admin 原创
- 32
问题描述:
如何在Linux系统中获取机器序列号和CPU ID?
非常感谢示例代码。
解决方案 1:
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
", eax & 0xF);
printf("model %d
", (eax >> 4) & 0xF);
printf("family %d
", (eax >> 8) & 0xF);
printf("processor type %d
", (eax >> 12) & 0x3);
printf("extended model %d
", (eax >> 16) & 0xF);
printf("extended family %d
", (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
", edx, ecx);
}
这篇维基百科文章CPUID
提供了有关如何使用该指令的很好的参考。
编辑Wikipedia 文章称,序列号是 Pentium III 引入的,但由于隐私问题,在后续型号中不再使用。在 Linux 系统上,您可以通过以下方式检查此功能 (PSN 位) 是否存在:
grep -i --color psn /proc/cpuinfo
如果没有显示任何内容,则表示您的系统不支持处理器序列号。
解决方案 2:
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
解决方案 3:
您可以从中提取有关处理器的信息/proc/cpuinfo
。
要获取序列号,您应该查看dmidecode
。我现在没有查看那里,但dmidecode
可以向您显示序列号,所以我会从那里开始。
解决方案 4:
#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
", PSN); //compare with: lshw | grep serial:
return 0;
}
解决方案 5:
该程序将帮助你以编程方式运行 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
" << 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
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD