Lecture/ecriture des msr (model specific register) en c sous linux

Description

Alors voilà une petite explication :
Chaque processeur x86 vient avec un ensemble de registres spécifiques qui permettent de connaître et de modifier dans certains cas la configuration du processeur... Les numéros des MSR et leur rôle est décrit dans la documentation du processeur. Ils sont bien entendu spécifiques à chaque processeur, alors quel est l'intérêt?

Sur les Pentium M, il existe 2 MSR très intéressants : les 0x198 et 0x199. Ils sont utilisés dans la gestion de l'energie, et permettent de modifier le coefficient multiplicateur et le voltage du processeur. Ceci permet d'underclocker le processeur et de réduire le voltage afin d'augmenter l'autonomie et de diminuer le dégagement de chaleur.
Sous Windows des logiciels comme NHC le font, mais pas sous Linux.

Les deux programmes joints permettent de lire et d'écrire des MSR, grâce à l'interface kernel /dev/cpu/0/msr (En effet l'instruction assembleur ne peut pas être executée directement à cause des privilèges définis par Intel). Il faut donc que le module msr soit chargé ("modprobe msr" en root), ou alors que le kernel soit configuré proprement.

Ce code a été testé avec un kernel 2.6.12 sur un P-M 760.

Un lien vers un site sur ces MSR du Pentium M :

http://www.x86-secret.com/articles/cm/g5m100-n/itxpm-8.htm

Source / Exemple :


/* Programme d'écriture de MSR - Utilise l'interface kernel 	*/
/* Donc que le support soit compilé dans le noyau ou que le 	*/
/* module msr soit chargé (modprobe msr) 			*/

/* D'après /usr/src/linux/arch/i386/kernel/msrc.c :		*/

/*

  • msr.c
*
  • x86 MSR access device
*
  • This device is accessed by lseek() to the appropriate register number
  • and then read/write in chunks of 8 bytes. A larger size means multiple
  • reads or writes of the same register.
*
  • This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
  • an SMP box will direct the access to CPU %d.
  • /
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { unsigned long long int value; unsigned int number; int fd; printf("Write MSR - Write Specifc Model Register\n"); if(argc < 3) { fprintf(stderr,"\nUsage : %s <MSR number> <value>\nValues MUST be given in Hexadecimal format\n",argv[0]); exit(0); } sscanf(argv[1],"%x",&number); sscanf(argv[2],"%Lx",&value); printf("MSR number :\t0x%x\nMSR value :\t0x%Lx\n",number,value); if(setuid(0) != 0) // On prend les droits root pour pouvoir ouvrir le fichier { fprintf(stderr, "\nYou must be root to run this program or have the setuid bit set.\n"); exit(-1); } if((fd = open("/dev/cpu/0/msr",O_WRONLY)) == -1) { fprintf(stderr,"\nOpen error on /dev/cpu/0/msr\n"); exit(-1); } if(lseek(fd,number,SEEK_SET) == -1) { fprintf(stderr,"\nSeek error in /dev/cpu/0/msr\n"); exit(-1); } if(write(fd,&value,8) != 8) { fprintf(stderr,"\nWrite error in /dev/cpu/0/msr\n"); exit(-1); } close(fd); return 0; }

Conclusion :


Pour compiler aucune option particulière à signaler : gcc write_msr.c -o write_msr.

Juste un détail : il faut que le programme soit lancé en root (à cause des protections d'accès toujours...)

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.