其他分享
首页 > 其他分享> > 在调用inb_p()时导致分段错误的原因是什么?

在调用inb_p()时导致分段错误的原因是什么?

作者:互联网

尝试使用inb_p()读取端口时出现分段错误.我正在英特尔D525双核系统(Advantech PCM 9389 SBC)上运行2.6.6内核的Debian系统上进行编译.这是一个示例程序,说明了段错误.

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

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

我试过的其他事情:
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确实会导致段错误.我开始怀疑这个问题与硬件有关.

解决方法:

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

显然,当我尝试iopl()时,我没有正确地调用它,因为那应该有效.

以下代码消除了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);
  }

标签:c-3,linux,debian,io,segmentation-fault
来源: https://codeday.me/bug/20191003/1848251.html