加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux 从用户空间的 I/O 存取

发布时间:2020-12-13 23:12:53 所属栏目:Linux 来源:网络整理
导读:刚刚描述的这些函数主要打算被设备驱动使用,但它们也可从用户空间使用,至少在 PC- 类 的计算机. GNU C 库在 sys/io.h 中定义它们. 下列条件应当应用来对于 inb 及其 友在用户空间代码中使用: ? 程序必须使用 -O 选项编译来强制扩展内联函数. ioperm 和 iopl

刚刚描述的这些函数主要打算被设备驱动使用,但它们也可从用户空间使用,至少在 PC- 类 的计算机. GNU C 库在 <sys/io.h> 中定义它们. 下列条件应当应用来对于 inb 及其 友在用户空间代码中使用:

?

  • 程序必须使用 -O 选项编译来强制扩展内联函数.
    • ioperm 和 iopl 系统调用必须用来获得权限来进行对端口的 I/O 操作. ioperm 为单独端口获取许可,而 iopl 为整个 I/O 空间获取许可. 这 2 个函数都是 x86 特有的.
    • 程序必须作为 root 来调用 ioperm 或者 iopl.[34] 34?可选地,一个它的祖先必须已 赢得作为 root 运行的端口权限.

?

如果主机平台没有 ioperm 和 iopl 系统调用,用户空间仍然可以存取 I/O 端口,通过 使用 /dev/prot 设备文件. 注意,但是,这个文件的含义是非常平台特定的,并且对任 何东西除了 PC 不可能有用.

?

技术上,它必须有 CAP_SYS_RAWIO 能力,但是在大部分当前系统中这是与作为 root 运行是同样的.

?

?

例子源码 misc-progs/inp.c 和 misc-progs/outp.c 是一个从命令行读写端口的小工具,在用户空间. 它们希望被安装在多个名子下(例如,inb,inw,和 inl 并且操作字节,字,或者长端口依赖于用户调用哪个名子). 它们使用 ioperm 或者 iopl 在 x86 下,在其他 平台是 /dev/port.

?

程序可以做成 setuid root,如果你想过危险生活并且在不要求明确的权限的情况下使用 你的硬件. 但是,请不要在产品系统上以 set-uid 安装它们; 它们是设计上的安全漏洞.

?

字串操作

?

除了单发地输入和输出操作,一些处理器实现了特殊的指令来传送一系列字节,或者 长字 到和自一个单个 I/O 端口或者同样大小. 这是所谓的字串指令,并且它们完成任务 比一个 C 语言循环能做的更快. 下列宏定义实现字串处理的概念或者通过使用一个单个 机器指令或者通过执行一个紧凑的循环,如果目标处理器没有进行字串 I/O 的指令. 当 编译为 S390 平台时这些宏定义根本不定义. 这应当不是个移植性问题,因为这个平台通 常不与其他平台共享设备驱动,因为它的外设总线是不同的.

?

字串函数的原型是:

?

void insb(unsigned port,void *addr,unsigned long count); void outsb(unsigned port,unsigned long count);

读或写从内存地址 addr 开始的 count 字节. 数据读自或者写入单个 port 端口. void insw(unsigned port,unsigned long count);

void outsw(unsigned port,unsigned long count);

?

读或写 16-位 值到一个单个 16-位 端口.

?

void insl(unsigned port,unsigned long count); void outsl(unsigned port,unsigned long count);

?

读或写 32-位 值到一个单个 32-位 端口.

?

有件事要记住,当使用字串函数时: 它们移动一个整齐的字节流到或自端口. 当端口和主 系统有不同的字节对齐规则,结果可能是令人惊讶的. 使用 inw 读取一个端口交换这些 字节,如果需要,来使读取的值匹配主机字节序. 字串函数,相反,不进行这个交换.

?

?暂停 I/O

?

一些平台 - 最有名的 i386 - 可能有问题当处理器试图太快传送数据到或自总线. 当处 理器对于外设总线被过度锁定时可能引起问题( 想一下 ISA )并且可能当设备单板太慢时 表现出来. 解决方法是插入一个小的延时在每个 I/O 指令后面,如果跟随着另一个指令. 在 x86 上,这个暂停是通过进行一个 outb 指令到端口 0x80 ( 正常地不是常常用到 ) 实现的,或者通过忙等待. 细节见你的平台的 asm 子目录的 io.h 文件.

?

?

如果你的设备丢失一些数据,或者如果你担心它可能丢失一些,你可以使用暂停函数代替 正常的那些. 暂停函数正如前面列出的,但是它们的名子以 _p 结尾; 它们称为 inb_p,outb_p,等等. 这些函数定义给大部分被支持的体系,尽管它们常常扩展为与非暂停 I/O 同样的代码,因为没有必要额外暂停,如果体系使用一个合理的现代外设总线.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读