📄 ch17s12.html
字号:
<html xmlns:cf="http://docbook.sourceforge.net/xmlns/chunkfast/1.0"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>17.12. 定制 ioctl 命令-Linux设备驱动第三版(中文版)- - </title><meta name="description" content="驱动开发- - " /><meta name="keywords" content="Linux设备驱动,中文版,第三版,ldd,linux device driver,驱动开发,电子版,程序设计,软件开发, " /><meta name="author" content=" www.21cstar.com QQ:610061171" /> <meta name="verify-v1" content="5asbXwkS/Vv5OdJbK3Ix0X8osxBUX9hutPyUxoubhes=" /><link rel="stylesheet" href="docbook.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.69.0"><link rel="start" href="index.html" title="Linux 设备驱动 Edition 3"><link rel="up" href="ch17.html" title="第 17 章 网络驱动"><link rel="prev" href="ch17s11.html" title="17.11. MAC 地址解析"><link rel="next" href="ch17s13.html" title="17.13. 统计信息"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">17.12. 定制 ioctl 命令</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch17s11.html">上一页</a> </td><th width="60%" align="center">第 17 章 网络驱动</th><td width="20%" align="right"> <a accesskey="n" href="ch17s13.html">下一页</a></td></tr></table><hr></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="CustomioctlCommands"></a>17.12. 定制 ioctl 命令</h2></div></div></div><p>我们硬件看到给 socket 实现的 ioctl 系统调用; SIOCSIFADDR 和 SIOCSIFMAP 是 "socket ioctls" 的例子. 现在我们看看网络代码如何使用这个系统调用的 3 个参数.</p><p>当 ioctl 系统调用在一个 socket 上被调用, 命令号是 <linux/sockios.h>中定义的符号中的一个, 并且 sock_ioctl 函数直接调用一个协议特定的函数(这里"协议"指的是使用的主要网络协议, 例如, IP 或者 AppleTalk).</p><p>任何协议层不识别的 ioctl 命令传递给设备层. 这些设备有关的 ioctl 命令从用户空间接收一个第 3 个参数, 一个 struct ifreq*. 这个结构定义在 <linux/if.h>. SIOCSIFADDR 和 SIOCSIFMAP 命令实际上在 ifreq 结构上工作. SIOCSIFMAP 的额外参数, 定义为 ifmap, 只是 ifreq 的一个成员.</p><p>除了使用标准调用, 每个接口可以定义它自己的 ioctl 命令. plip 接口, 例如, 允许接口通过 ioctl 修改它内部的超时值. socket 的 ioctl 实现认识 16 作为接口私有的个命令: SIOCDEVPRIVATE 到 SIOCDEVPRIVATE+15.<sup>[<a name="id518991" href="#ftn.id518991">53</a>]</sup></p><p>当这些命令中的一个被识别, dev->do_ioctl 在相关的接口驱动中被调用. 这个函数接收与通用 ioctl 函数使用的相同的 struct ifreq * 指针.</p><pre class="programlisting">int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); </pre><p>ifr 指针指向一个内核空间地址, 这个地址持有用户传递的结构的一个拷贝. 在 do_ioctl 返回之后, 结构被拷贝回用户空间; 因此, 驱动可以使用这些私有命令接收和返回数据.</p><p>设备特定的命令可以选择使用结构 ifreq 中的成员, 但是它们已经传达一个标准意义, 并且不可能驱动使这个结构适应自己的需要. 成员 ifr_data 是一个 caddr_t 项( 一个指针 ), 是打算用做设备特定的需要. 驱动和用来调用它的 ioctl 命令的程序应当一致地使用 ifr_data. 例如, ppp-stats 使用设备特定的命令来从 ppp 接口驱动获取信息.</p><p>这里不值得展示一个 do_ioctl 的实现, 但是有了本章的信息和内核例子, 你应当能够在你需要时编写一个. 注意, 但是, plip 实现使用 ifr_data 不正确, 不应当作为一个 ioctl 实现的例子.</p><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id518991" href="#id518991">53</a>] </sup>注意, 根据 <linux/sockios.h>, SIOCDEVPRIVATE 命令是被不赞成的. 应当使用什么来代替它们是不明确的, 但是, 并且不少在目录树中的驱动还使用它们.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch17s11.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="ch17.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="ch17s13.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">17.11. MAC 地址解析 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 17.13. 统计信息</td></tr></table></div></body></html><div style="display:none"><script language="JavaScript" src="script.js"></script> </div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -