本文介绍了是什么导致调用 inb_p() 时出现分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 inb_p( ) 读取端口时遇到分段错误.我正在一个在 Intel D525 双核系统 (Advantech PCM 9389 SBC) 上运行 2.6.6 内核的 D​​ebian 系统上编译它.这是一个说明段错误的示例程序.

I am getting a segmentation fault when trying to read a port with inb_p( ). I'm compiling this on a Debian system running 2.6.6 kernel on an Intel D525 dual-core system (Advantech PCM 9389 SBC). Here is a sample program which illustrates the segfault.

可能的原因是什么?我该如何解决这个问题?

What is the probable cause? How do I fix this?

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

Currently, I don't have any devices hooked up. Could this cause the segfault? I would have expected to get either a zero or some random byte, but not a segfault.

我尝试过的其他事情:1) 将输入变量声明为 int 而不是 char.2) 使用 iopl() 而不是 ioperm()

Other things I tried:1) Declared the input variable as int instead of char.2) Used iopl() instead of 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
");
  /* Get access to the ports */
  if (ioperm(BASEPORT+DIPSWITCH, 10, 1))
  {
     perror("ioperm");
     exit(EXIT_FAILURE);
  }

  printf("read the dipswitch with pause
");
  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 did 会导致段错误.我开始怀疑问题与硬件有关.

/proc/ioports did not list anything at address 0x100, so I tried several other port addresses that were listed, with the same result. Then I decided to try an output to a known parallel port location (0x0378), and outb did not cause a segfault. However, trying to read either 0x378 or 0x379 did cause a segfault. I am beginning to suspect that the problem is hardware related.

推荐答案

我发现了问题.调用 inb_p() 需要访问端口 0x80 除了要读取的端口.

I found the problem. The call to inb_p() requires access to port 0x80 in addition to the port to be read.

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

Apparently, when I tried iopl(), I didn't call it correctly, because that should have worked.

以下代码消除了段错误:

The following code eliminated the 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);
  }

这篇关于是什么导致调用 inb_p() 时出现分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-21 02:01