2012-12-03 46 views
0

尝试使用inb_p()读取端口时出现分段错误。我正在使用英特尔D525双核系统(Advantech PCM 9389 SBC)上运行2.6.6内核的Debian系统编译此文件。这里是一个示例程序,它说明了段错误。在调用inb_p()时会导致分段错误的原因是什么?

可能的原因是什么?我该如何解决?

目前,我没有任何设备挂钩。这是否会导致段错误?我本来希望得到一个零或一些随机字节,但不是段错误。

我试过的其他东西: 1)声明输入变量为int而不是char。 2)使用IOPL()而不是ioperm()

/* 
* ioexample.c: very simple ioexample of port I/O 
* very simple port i/o 
* Compile with `gcc -O2 -o ioexample ioexample.c', 
* and run as root with `./ioexample'. 
*/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/io.h> 

#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 */ 

输出:

[email protected]:/home/howard/sources# ./ioexample 
begin 
read the dipswitch with pause 
Segmentation fault 

编辑:的/ proc/ioports没有列出地址为0x100任何东西,所以我尝试了其他几个端口地址是被列出,结果相同。然后我决定尝试输出到已知的并行端口位置(0x0378),并且outb不会导致段错误。但是,试图读取0x378或0x379 确实导致段错误。我开始怀疑问题与硬件有关。

+1

是你作为root运行? – ninjalj

+0

是的,我以root身份运行。 –

回答

3

我发现了这个问题。除了要读取的端口之外,对inb_p()的调用还需要访问端口0x80。

显然,当我尝试iopl()时,我没有正确地调用它,因为这应该起作用。

下面的代码消除了段错误:

/* 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); 
    } 
相关问题