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

2024-11-08 09:04:00
admin
原创
312
摘要:问题描述:如何在Linux系统中获取机器序列号和CPU ID?非常感谢示例代码。解决方案 1:Linux 内核似乎使用了以下方法:static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, ...

问题描述:

如何在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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用