3

I was wondering how to reliably obtain the Processor Serial Number (PSN) on GNU Linux.

For now I'm using this

#include <stdio.h>
#include <cpuid.h>

unsigned int level = 1;
unsigned eax = 3 /* processor serial number */, ebx = 0, ecx = 0, edx = 0;
__get_cpuid(level, &eax, &ebx, &ecx, &edx);

// byte swap
int first = ((eax >> 24) & 0xff) | ((eax << 8) & 0xff0000) | ((eax >> 8) & 0xff00) | ((eax << 24) & 0xff000000);
int last = ((edx >> 24) & 0xff) | ((edx << 8) & 0xff0000) | ((edx >> 8) & 0xff00) | ((edx << 24) & 0xff000000);

printf("PSN: %08X%08X", first, last);

It gives me PSN: A7060200FFFBEBBF,
which matches with

sudo dmidecode | grep -P '^\s+ID: ([0-9A-F]{2} ){7}[0-9A-F]{2}$'

output: ID: A7 06 02 00 FF FB EB BF

I only tested on Intel Core i processors, so perhaps it's only working for this type of CPU.

I know that the "Serial Number" is the same across identical CPU model, and is thus not unique.

Also, I'm looking forward for a way of achieving that, that does not rely on executing a shell command and parsing the output.

anni
  • 1,403
  • 1
  • 24
  • 33
  • Hope [this](http://stackoverflow.com/questions/6491566/getting-the-machine-serial-number-and-cpu-id-using-c-c-in-linux) helps. – GAVD Jan 16 '17 at 09:47
  • Thanks, my code snippet is already inspired from that answer, but unfortunately it's for Intel Pentum III. He is also using asm volatile code that is for x86 only, which I'm avoiding. He were also not using same value, level used was 0, which was not working for me, and he was using different registers, ecx edx, whereas me eax edx. – anni Jan 16 '17 at 09:55
  • It will work for AMD, but not for all of the ARM processors – David C. Rankin Jan 16 '17 at 09:58
  • Ok. But then why does the example for the Intel Pentium III uses different level to obtain PSN ? – anni Jan 16 '17 at 10:06
  • Hello @Bap, have you got any chance to test out your code on other x86/64 processors ? (Xeon perhaps?). Does it work ? – atari83 May 23 '20 at 21:05

1 Answers1

0

you can use popen and then parse the result

unsigned char *pk = new unsigned char[100];
    FILE *source = popen("lscpu", "r");
    while (!feof(source)) {
        fread(pk, 100, 1, source);
        for(int i=0;i<100;++i)
        {
            printf("%c",pk[i]);
        }
        printf("\n");
    }
    pclose(source);
sam
  • 1,363
  • 1
  • 20
  • 32
  • Thank you, but I am seeking a solution that does not rely on executing a shell command and retrieving the output. – anni Jan 16 '17 at 10:02