Qu’est-ce qui cause une erreur de segmentation lors d’un appel à inb_p ()?

Je reçois une erreur de segmentation lorsque j’essaie de lire un port avec inb_p (). Je comstack ceci sur un système Debian exécutant un kernel 2.6.6 sur un système double cœur Intel D525 (Advantech PCM 9389 SBC). Voici un exemple de programme illustrant la erreur de segmentation.

Quelle est la cause probable? Comment puis-je réparer ça?

Actuellement, je n’ai aucun appareil connecté. Cela pourrait-il causer la segfault? Je m’attendais à obtenir soit un zéro ou un octet aléatoire, mais pas une erreur de segmentation.

Autres choses que j’ai essayées: 1) Déclaré la variable d’entrée en tant que int au lieu de char. 2) Utilisé iopl () au lieu de ioperm ()

/* * ioexample.c: very simple ioexample of port I/O * very simple port i/o * Comstack with `gcc -O2 -o ioexample ioexample.c', * and run as root with `./ioexample'. */ #include  #include  #include  #include  #define BASEPORT 0x0100 /* iobase for sample system */ #define FLIPC 0x01 #define FLIPST 0x0 #define DIPSWITCH 0x25 int main() { char cinput; cinput = 0xff; setuid(0); printf("begin\n"); /* Get access to the ports */ if (ioperm(BASEPORT+DIPSWITCH, 10, 1)) { perror("ioperm"); exit(EXIT_FAILURE); } printf("read the dipswitch with pause\n"); cinput = inb_p(BASEPORT+DIPSWITCH); // <=====SEGFAULT HERE /* We don't need the ports anymore */ if (ioperm(BASEPORT+DIPSWITCH, 10, 0)) { perror("ioperm"); exit(EXIT_FAILURE); } printf("Dipswitch setting: 0x%X", cinput); exit(EXIT_SUCCESS); } /* end of ioexample.c */ 

Sortie:

 root@debian:/home/howard/sources# ./ioexample begin read the dipswitch with pause Segmentation fault 

Edit: / proc / ioports n’a rien répertorié à l’adresse 0x100; j’ai donc essayé plusieurs autres adresses de port répertoriées, avec le même résultat. Ensuite, j’ai décidé d’essayer une sortie vers un emplacement de port parallèle connu (0x0378), et outb n’a pas causé de erreur de segmentation. Cependant, essayer de lire 0x378 ou 0x379 a causé un segfault. Je commence à soupçonner que le problème est lié au matériel.

J’ai trouvé le problème. L’appel à inb_p () nécessite un access au port 0x80 en plus du port à lire.

Apparemment, lorsque j’ai essayé iopl (), je ne l’ai pas appelé correctement, car cela aurait dû fonctionner.

Le code suivant a éliminé le segfault:

  /* Get access to the ports */ if (ioperm(0x80, 1, 1)) { perror("ioperm"); exit(EXIT_FAILURE); } if (ioperm(BASEPORT+DIPSWITCH, 10, 1)) { perror("ioperm"); exit(EXIT_FAILURE); }