136 votes

Comment savoir si un système Linux est big endian ou little endian ?

Je sais que certains processeurs sont Big Endian et que d'autres sont Little Endian. Mais existe-t-il une commande, bash script, Python script ou une série de commandes qui peuvent être utilisées à la ligne de commande pour déterminer si un système est Big Endian ou Little Endian ? Quelque chose comme :

if <some code> then
    echo Big Endian
else
    echo Little Endian
fi

Ou est-il plus simple de déterminer le processeur utilisé par le système et de s'en servir pour déterminer son Endienneté ?

0voto

Kaz Points 477

Une exigence légèrement différente : J'ai besoin d'un test comme celui-ci dans un programme build configure script afin de déterminer si le compiler la machine cible est bit ou little endian, sans exécuter de code . Le script doit déposer #define HAVE_LITTLE_ENDIAN 1 en un config.h ou bien #define HAVE_LITTLE_ENDIAN 0 .

La machine cible de la compilation peut être différente de la machine de construction, puisque nous pouvons faire de la compilation croisée, ce qui explique aussi pourquoi le test ne doit pas essayer d'exécuter un code compilé. Il est hors de question d'avoir un petit programme en C avec un printf qui donne la réponse.

Une solution possible est la suivante. Nous générons un fichier appelé conftest.c qui contient ceci :

#define USPELL(C0, C1, C2, C3) \                                             
  ((unsigned) C0 << 24 | \                                              
   (unsigned) C1 << 16 | \                                              
   (unsigned) C2 << 8 | (unsigned) C3)                                       

unsigned x[6] = {                                                       
  0,                                                                         
  USPELL('L', 'I', 'S', 'P'),                                                
  USPELL('U', 'N', 'I', 'X'),                                                
  USPELL('C', 'O', 'R', 'E'),                                                
  USPELL('D', 'W', 'I', 'M'),                                                
  0                                                                          
};

Maintenant, nous compilons ceci en conftest.o en utilisant :

$ /path/to/cross-compiling/cc conftest.c -c

Alors on court :

$ strings conftest.o
PSILXINUEROCMIWD

Si la chaîne PSILXINUEROCMIWD se produit, la cible est little-endian. Si la chaîne LISPUNIXCOREDWIM se produit, il est big-endian. Si aucune des deux chaînes n'apparaît ou, plus étonnant encore, si les deux apparaissent, alors le test a échoué.

Cette approche fonctionne parce que les constantes "fourcc" calculées dans le programme ont des valeurs indépendantes de la machine, désignant les mêmes entiers indépendamment de l'endienneté. Leur représentation de stockage dans le fichier objet suit l'endianness du système cible, et cela est visible via la vue basée sur les caractères sous strings .

Les deux mots de garde zéro garantissent que la chaîne est isolée. Ce n'est pas strictement nécessaire, mais cela permet de s'assurer que la chaîne que nous recherchons n'est pas intégrée dans une autre chaîne, ce qui signifie que strings l'affichera sur une ligne à part.

P.S. le USPELL ne met pas les insertions d'arguments entre parenthèses car elle est conçue dans ce but précis, et non pour être réutilisée.

0voto

Voici une solution qui implique une mauvaise utilisation des codes de sortie posix Shell :

gawk/mawk/mawk2/nawk 'BEGIN { # system() returns 1 
                              # if little-endian.
                              # to check BE, change that -c 2 to -c 5
     print system("
          exit \140<<<\47\47 gnu-od | grep -c 2\140") }'

\47 = guillemet simple ascii, et \140 est un accent grave ascii

  • sauf gnu- bouche bée -S le mode sandbox, qui désactive système( )

ce que cela fait c'est d'exécuter ce ->

exit ` <<<'' god | grep -c 2 ``

à l'intérieur d'un sh posix Shell, demandant essentiellement à gnu-od de vous montrer un octal par défaut de 2 octets d'un simple \n (d=10) caractère.

sur les systèmes little-endian, il apparaît comme 000012 . Mais sur les systèmes big-endian, l'octet de remplissage supplémentaire amène gnu-od à décaler les octaux vers le haut. décimal de 10*256=2560=5x8x8x8, de sorte que l'octal à 2 octets résultant est 005000 . Ensuite, utilisez la fonction de compteur grep pour localiser soit le 2, soit le 5.

les codes de sortie sont censés être que 0 signifie le succès et chaque nombre plus grand signifie une sorte d'erreur. mais puisque le compteur grep nous a déjà aidé à inverser cela, le "code de sortie" retourné de la commande système est déjà dans le sens booléen d'awk de vrai(1) et faux(0).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X