在使用inb_p( )读取端口时,我遇到了一个分段错误。我正在一个运行2.6.6内核的Debian系统上编译这个程序,该系统运行在英特尔的D525双核系统(Advantech PCM 9389 SBC)上。这里是一个示例程序,它说明了分段故障。
可能的原因是什么?我该怎么解决这个问题?
目前,我没有任何设备连接。这会导致分段故障吗?我本来希望得到一个零字节或一些随机字节,但不是分段错误。
我尝试过的其他事情: 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 */输出:
root@debian:/home/howard/sources# ./ioexample
begin
read the dipswitch with pause
Segmentation fault编辑: /proc/ioports没有列出地址0x100上的任何内容,所以我尝试了列出的其他几个端口地址,结果相同。然后,我决定尝试输出到一个已知的并口位置(0x0378),outb没有导致分段错误。但是,试图读取0x378或0x379确实会导致分段错误。我开始怀疑这个问题与硬件有关。
发布于 2012-12-05 17:15:59
我发现了问题。对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);
}https://stackoverflow.com/questions/13688196
复制相似问题