2012-12-03 123 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); 
    } 
相關問題