免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 995 | 回复: 0
打印 上一主题 下一主题

Linux下设置端口权限的系统调用—ioperm和iopl [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-29 12:43 |只看该作者 |倒序浏览
Linux下设置端口权限的系统调用有两个:ioperm和iopl。

一、ioperm和iopl介绍。
1.ioperm
该系统调用的介绍参考了以下链接中的内容:
http://blog.chinaunix.net/u2/76419/showart_1404294.html

功能描述:
为调用进程设置I/O端口访问权能。ioperm的使用需要具有超级用户的权限,只有低端的[0-0x3ff] I/O端口可被设置,要想指定更多端口的权能,可使用iopl函数。这一调用只可用于i386平台。

用法:
#include  /* for libc5 */
#include  /* for glibc */
int ioperm(unsigned long from, unsigned long num,
int turn_on);
      
参数:
from:起始端口地址。
num:需要修改权能的端口数。
turn_on:端口的新权能位。1为开启,0为关闭。
返回说明:
成功执行时,返回0。失败返回-1,errno被设为以下的某个值
EINVAL:参数无效
EIO:这一调用不被支持
EPERM:调用进程权能不足。

2. iopl
功能描述:该调用用于修改当前进程的操作端口的权限。可以用于所有65536个端口的权限。因此,ioperm相当于该调用的子集。和ioperm一样,这一调用仅适用于i386平台。

用法:
#include
   int
iopl(int level);
参数:
level: 端口的权限级别。为3时可以读写端口。默认权能级别为0,用户空间不可读写。
返回说明:成功执行时,返回0。失败返回-1,errno被设为以下的某个值
EINVAL:level值大于3
ENOSYS:未实现该调用
EPERM:调用进程权能不足。

二、程序示例
1. ioperm.c
操作低于0x3FF的端口
该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。
/*Godbach. Dec 18, 2008
Description:This function is used to test ioperm()*/
#include
#include  
#include  

#define PORT_ADDR 0x3FF

int main(void)
{
      int ret;
      char port_val;

      /*set r/w
permission of port_addr on, only one port*/
      ret =
ioperm(PORT_ADDR, 1, 1);
      if(ret
           perror("ioperm
set error");
           return 0;
      }
      port_val =
inb(PORT_ADDR);
      printf("Original
value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);
      
      /*reverse the
least significant bit */
      outb(port_val^0x01,
PORT_ADDR);
      port_val =
inb(PORT_ADDR);
      printf("Current
value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);   
      
      /*set r/w
permission of PORT_ADDR off, only one port*/
      ret =
ioperm(PORT_ADDR, 1, 0);
      if(ret
           perror("ioperm
set error");
           return 0;
      }
      return 0;
}

程序执行的结果是:
[root@localhost misc-progs]# ./a.out
Original value of port 0x3ff is : 00
Current value of port 0x3ff is : 01
[root@localhost misc-progs]# ./a.out
Original value of port 0x3ff is : 01
Current value of port 0x3ff is : 00
该程序执行几次,将进行几次的LSB翻转。
这里有一个问题值得注意:在2.4(RH9)的内核上,当端口值大于0x3FF时,执行该程序则会报错:ioperm set error: Invalid
argument。即IO端口的值设置有问题,超出了限制。但是在2.6内核下并没有报错,而且执行结果也符合程序既定的结果。但是man ioperm中仍然说明了0x3FF的限制。暂且存疑。

2. iopl.c
该程序可以操作所有65536个端口。
该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。
代码如下:
/*Godbach. Dec 18, 2008
Description:This function is used to test iopl()*/
#include
#include  
#include  

#define PORT_ADDR 0x3FF

int main(void)
{
      int ret;
      char port_val;

      /*set r/w
permission of all 65536 ports*/
      ret = iopl(3);
      if(ret
           perror("iopl
set error");
           return 0;
      }
      port_val =
inb(PORT_ADDR);
      printf("Original
value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);
      
      /*reverse the
least significant bit */
      outb(port_val^0x01,
PORT_ADDR);
      port_val =
inb(PORT_ADDR);
      printf("Current
value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);   
      
      /*set r/w
permission of  all 65536 ports*/
      ret = iopl(0);
      if(ret
           perror("iopl
set error");
           return 0;
      }
      return 0;
}
程序执行结果:
[root@linux misc-progs]# ./a.out
Original value of port 0x3ff is : 01
Current value of port 0x3ff is : 00
[root@linux misc-progs]# ./a.out
Original value of port 0x3ff is : 00
Current value of port 0x3ff is : 01
该程序执行几次,将进行几次的LSB翻转。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/79779/showart_1947219.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP