感谢支持
我们一直在努力

Linux小于ox3ff端口读取

读取bios接口原来需要这些东西,Linux下设置端口权限的系统调用有两个:ioperm和iopl。


一、ioperm和iopl介绍。


1.ioperm


功能描述:


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


用法:


#include <unistd.h> /* for libc5 */
#include <sys/io.h> /* 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 <sys/io.h>


   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 <stdio.h>


#include <unistd.h>


#include <sys/io.h>


 


#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 < 0){


           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 < 0){


           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 <stdio.h>


#include <unistd.h>


#include <sys/io.h>


 


#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 < 0){


           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 < 0){


           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翻转。

赞(0) 打赏
转载请注明出处:服务器评测 » Linux小于ox3ff端口读取
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏