概述
Linux下设置端口权限的系统调用有两个:ioperm和iopl函数。
ioperm
功能描述
为调用进程设置I/O端口访问权限,从端口地址from起始,共设置num个值为turn_on。ioperm的使用需要具有超级用户的权限,只有低端的[0-0x3ff] I/O端口可被设置,要想指定更多端口的权能,可使用iopl函数。
此系统调用只适用于i386体系结构,在许多其它体系结构不存在或将总是返回一个错误。i386是32位版,x86-64是64位版,PPC是苹果电脑版。
函数原型
#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:Invalid values for from or num.(参数错误)
EIO:(on ppc) This call is not supported.(不支持此调用)
EPERM:The calling process has insufficient privilege to call ioperm(); the CAP_SYS_RAWIO capability is required.(调用进程没有权限)
iopl
功能描述
用于修改当前进程的操作端口的权限。可以用于所有65536个端口的权限。因此,ioperm相当于该调用的子集。
和ioperm一样,这一调用仅适用于i386平台。
iopl()是特定于linux的,不能移植到其他系统中去使用。
函数原型
#include <sys/io.h>
int iopl(int level);
参数说明
level:端口的权限级别。为3时可以读写端口。默认权能级别为0,用户空间不可读写。
返回值
成功返回0;失败返回-1,并且errno被设为以下的某个值:
EINVAL:level is greater than 3.(参数错误,level值大于3)
ENOSYS:This call is unimplemented.(未实现该调用)
EPERM:The calling process has insufficient privilege to call iopl(); the CAP_SYS_RAWIO capability is required.(调用进程没有权限)
outb, outw, outl, outsb, outsw, outsl, inb, inw, inl, insb, insw, insl, outb_p, outw_p, outl_p, inb_p, inw_p, inl_p - 端口I / O
功能描述
- outb() :I/O 上写入8位数据 (1字节)
- outw() :I/O 上写入16位数据 (2字节 )
- outl() :I/O 上写入32位数据 (4字节)
- inb() :I/O 上读取 8 位数据 (1字节)
- inw() :I/O 上读取16位数据 (2字节)
- inl () :I/O 上读取32位数据 (4字节)
这一函数族用于执行低层次的端口输入和输出。out*功能进行端口输出,in*功能进行端口输入;b后缀函数为字节宽度,w后缀函数为字宽;_p后缀函数暂停直到I/O完成。
在申请了I/O端口区域之后,就可以放心地访问,Linux使用inb(p)、inw(p)、insb(p,d,l)、insw(p,d,l)、outb(v,p)、outw(v,p)、outl(v,p)、outsb(p,d,l)、outsl(p,d,l)等宏来访问I/O端口,他们在include/asm/io.h中进行定义。
宏中in表示从端口输入,out表示从输出到端口。
b表示访问字节,w表示访问字,l表示访问长整数,s表示流数据。
参数p表示要访问的I/O端口号,v表示要输出的数值,d表示内存缓存起始地址,l表示输出输入的量。
它们主要是为内核使用而设计的,但是可以从用户空间使用。
必须使用-O或-O2或类似的语言进行编译。这些函数被定义为内联宏,在没有启用优化的情况下不会被替换,这会在链接时导致未解析的引用。
可以使用ioperm(2)或iopl(2)告诉内核允许用户空间应用程序访问相关的I/O端口。如果不这样做,应用程序将收到一个 seg‐mentation 的错。
函数原型(部分)
#include <asm/io.h>
void outb (unsigned char data, unsigned short int port);
void outw (unsigned short data, unsigned short int port);
void outl (unsigned int data, unsigned short int port);
static __iniine unsigned char inb(unsigned short int port);
static __iniine unsigned short inw(unsigned short int port);
static __iniine unsigned int inl(unsigned short int port);
最后
以上就是执着金毛为你收集整理的Linux下用户空间访问I/O端口的相关函数的全部内容,希望文章能够帮你解决Linux下用户空间访问I/O端口的相关函数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复