Linux下設置端口權限的系統調用有兩個:ioperm和iopl

Linux下設置端口權限的系統調用有兩個:iopermiopl

 

一、iopermiopl介紹。

1.ioperm

該系統調用的介紹參考了以下鏈接中的內容:

http://blog.chinaunix.net/u2/76419/showart_1404294.html

 

功能描述:

爲調用進程設置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。失敗返回-1errno被設爲以下的某個值

EINVAL:參數無效
EIO
:這一調用不被支持
EPERM
:調用進程權能不足。

 

2. iopl

功能描述:該調用用於修改當前進程的操作端口的權限。可以用於所有65536個端口的權限。因此,ioperm相當於該調用的子集。和ioperm一樣,這一調用僅適用於i386平臺。

 

用法:

#include <sys/io.h>

   int iopl(int level);

參數:

level 端口的權限級別。爲3時可以讀寫端口。默認權能級別爲0,用戶空間不可讀寫。

返回說明:成功執行時,返回0。失敗返回-1errno被設爲以下的某個值

EINVALlevel值大於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.4RH9)的內核上,當端口值大於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翻轉。

注:這裏再次使用0x3FF端口,主要個人對端口的理解還不很深入,其他高於0x3FF的端口進行測試的時候,沒有得到既定的結果。這裏權且還使用這個端口,藉此對iopl的用法熟悉一下即可。至於在真正使用中,如果系統的某個端口是可以進行配置的,那麼執行這個程序應該是可以得到既定結果的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章