⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch14s07.html

📁 真正LDD3中文
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html xmlns:cf="http://docbook.sourceforge.net/xmlns/chunkfast/1.0"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>14.7.&#160;热插拔</title><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="ch14.html" title="第&#160;14&#160;章&#160;Linux 设备模型"><link rel="prev" href="ch14s06.html" title="14.6.&#160;集成起来"><link rel="next" href="ch14s08.html" title="14.8.&#160;处理固件"></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">14.7.&#160;热插拔</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch14s06.html">上一页</a>&#160;</td><th width="60%" align="center">第&#160;14&#160;章&#160;Linux 设备模型</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch14s08.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="Hotplug.sect1"></a>14.7.&#160;热插拔</h2></div></div></div><p>有 2 个不同方法来看热插拔. 内核看待热插拔为硬件, 内核和内核驱动之间的交互. 用户看待热插拔是内核和用户空间的通过称为 /sbin/hotplug 的程序的交互. 这个程序被内核调用, 当它想通知用户空间某种热插拔事件刚刚在内核中发生.</p><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="DynamicDevices.sect2"></a>14.7.1.&#160;动态设备</h3></div></div></div><p>术语"热插拔"最普遍使用的意义产生于当讨论这样的事实时, 几乎所有的计算机系统现在能够处理当系统有电时设备的出现或消失. 这非常不同于只是几年前的计算机系统, 那时程序员知道他们只需要在启动时扫描所有的设备, 并且他们从不必担心他们的设备消失直到整个机器被关电. 现在, 随着 USB 的出现, CardBus, PCMCIA, IEEE1394, 和 PCI 热插拔控制器, Linux 内核需要能够可靠地运行不管什么硬件从系统中增加或去除. 这产生了一个额外的负担给设备驱动作者, 因为现在他们必须一直处理一个没有任何通知而突然从地下冒出来的设备.</p><p>每个不同的总线类型以不同方式处理一个设备的消失. 例如, 当一个 PCI , CardBus, 或者 PCMCIA 设备从系统中去除, 在驱动通过它的去除函数被通知之前常常是一会儿. 在发生这个前, 所有的从 PCI 的读返回所有的位集合. 这意味着驱动需要一直检查它们从 PCI 总线读取的值并且能够正确处理 0xff 值.</p><p>这个的一个例子可在 drivers/usb/host/ehci-hcd.c 驱动中见到, 它是一个 PCI 驱动给一个 UBS 2.0(高速)控制卡. 它有下面的代码在它的主握手循环中来探测是否控制块已经从系统中去除.</p><pre class="programlisting">result = readl(ptr);if (result == ~(u32)0)  /* card removed */ return -ENODEV; </pre><p>对于 USB 驱动, 当一个 USB 驱动被绑定到的设备被从系统中去除, 任何挂起的已被提交给设备的 urbs 以错误 -ENODEV 失败. 如果发生这个情况, 驱动需要识别这个错误并且正确清理任何挂起的 I/O .</p><p>可热插拔的设备不只限于传统的设备, 例如鼠标, 键盘, 和网卡. 有大量的系统现在支持整个 CPU 和内存条的移出. 幸运地, Linux 内核正确处理这些核心"系统"设备的加减, 以至于单个设备驱动不需要注意这些事情.</p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="ThesbinhotplugUtility.sect2"></a>14.7.2.&#160;/sbin/hotplug 工具</h3></div></div></div><p>如同本章中前面提过的, 无论何时一个设备从系统中增删, 都产生一个"热插拔事件". 这意味着内核调用用户空间程序 /sbin/hotplug.  这个程序典型地是一个非常小的 bash 脚本, 只传递执行给一系列其他的位于 /etc/hot-plug.d/ 目录树的程序. 对于大部分的 Linux 发布, 这个脚本看来如下:</p><pre class="screen">DIR="/etc/hotplug.d"for I in "${DIR}/$1/"*.hotplug "${DIR}/"default/*.hotplug ; do if [ -f $I ]; then test -x $I &amp;&amp; $I $1 ; fidoneexit 1</pre><p>换句话说, 这个脚本搜索所有的有 .hotplug 后缀的可能对这个事件感兴趣的程序并调用它们, 传递给它们许多不同的环境变量, 这些环境变量已经被内核设置. 更多关于 /sbin/hotplug 脚本如何工作的细节可在程序的注释中找到, 以及在 hotplug(8)手册页中.</p><p>如同前面提到的, /sbin/hotplug 被调用无论何时一个 kobject 被创建或销毁. 热插拔程序被用一个提供事件名子的单个命令行参数调用. 核心内核和涉及到的特定子系统也设定一系列带有关于发生了什么的信息的环境变量(下面描述). 这些变量被热插拔程序使用来判定刚刚在内核发生了什么, 以及是否有任何特定的动作应当采取.</p><p>传递给 /sbin/hotplug 的命令行参数是关联这个热插拔事件的名子, 如同分配给 kobject 的 kset 所决定的. 这个名子可通过一个对属于本章前面描述过的 kset 的 hotplug_ops 结构的 name 函数的调用来设定; 如果那个函数不存在或者从未被调用, 名子是 kset 自身的名子.</p><p>一直为 /sbin/hotplug 设定的缺省的环境变量是:</p><div class="variablelist"><dl><dt><span class="term"><span>ACTION </span></span></dt><dd><p>这个字符串 add 或 remove, 只根据是否这个对象是被创建或者销毁.</p></dd><dt><span class="term"><span>DEVPATH </span></span></dt><dd><p>一个目录路径, 在 sysfs 文件系统中, 它指向在被创建或销毁的 kobject. 注意 sysfs 文件系统的加载点不是添加到这路径, 因此是由用户空间程序来决定这个. </p></dd><dt><span class="term"><span>SEQNUM </span></span></dt><dd><p>这个热插拔事件的顺序号. 顺序号是一个 64-位 数, 它每次产生热插拔事件都递增. 这允许用户空间以内核产生它们的顺序来排序热插拔事件, 因为对一个用户空间程序可能乱序运行.</p></dd><dt><span class="term"><span>SUBSYSTEM </span></span></dt><dd><p>同样的字符串作为前面描述的命令行参数传递.</p></dd></dl></div><p>许多不同的总线子系统都添加它们自己的环境变量到 /sbin/hotplug 调用中, 当关联到总线的设备被添加或从系统中去除. 它们在它们的热插拔回调中做这个, 这个回调在分配给它们的总线(如同在"热插拔操作"一节中描述的)的 struct kset_hotplug_ops 中指定. 这允许用户空间能够自动加载必要的可能需要来控制这个被总线发现的设备的模块. 这里是一个不同总线类型的列表以及它们添加到 /sbin/hotplug 调用中的环境变量. </p><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="IEEE1394FireWire.sect3"></a>14.7.2.1.&#160;IEEE1394(火线)</h4></div></div></div><p>任何在 IEEE1394 总线, 也是火线, 上的设备, 由 /sbin/hotplug 参数名和 SUBSYSTEM 环境变量设置为值 ieee1394. ieee1394 子系统也总是添加下列 4 个环境变量:</p><div class="variablelist"><dl><dt><span class="term"><span>VENDOR_ID </span></span></dt><dd><p>IEEE1394 的 24-位 供应者 ID. </p></dd><dt><span class="term"><span>MODEL_ID </span></span></dt><dd><p>IEEE1394 的 24-位型号 ID.</p></dd><dt><span class="term"><span>GUID </span></span></dt><dd><p>设备的 64-位 GUID.</p></dd><dt><span class="term"><span>SPECIFIER_ID </span></span></dt><dd><p>24-位值, 指定设备的协议规格的拥有者.</p></dd><dt><span class="term"><span>VERSION </span></span></dt><dd><p>指定设备协议规格的版本的值</p></dd></dl></div></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="Networking.sect3"></a>14.7.2.2.&#160;网络</h4></div></div></div><p>所有的网络设备都创建一个热插拔事件, 当设备注册或者注销在内核. /sbin/hotplug 调用有参数 name 和 SUBSYSTEM 环境变量设置为 net, 并且只添加下列环境变量:</p><div class="variablelist"><dl><dt><span class="term"><span>INTERFACE </span></span></dt><dd><p>已经从内核注册或注销的接口的名子. 这个的例子是 lo 和 eth0.</p></dd></dl></div></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="PCI.sect3"></a>14.7.2.3.&#160;PCI 总线</h4></div></div></div><p>任何在 PCI 总线上的设备有参数 name 和 SUBSYSTEM 环境变量设置为值 pci. PCI 子系统也一直添加下面 4 个环境变量:</p><div class="variablelist"><dl><dt><span class="term"><span>PCI_CLASS </span></span></dt><dd><p>设备的 PCI 类号, 16 进制.</p></dd><dt><span class="term"><span>PCI_ID </span></span></dt><dd><p>设备的 PCI 供应商和设备 ID, 16进制, 结合成这样的格式 供应者:设备.</p></dd><dt><span class="term"><span>PCI_SUBSYS_ID </span></span></dt><dd><p>PCI 子系统供应商和子系统设备 ID, 以 子系统供应者:子系统设备 的格式结合.</p></dd><dt><span class="term"><span>PCI_SLOT_NAME </span></span></dt><dd><p>PCI 插口"名", 内核给予这个设备的. 它以这样的格式 域:总线:插口:功能. 一个例子可能是: 0000:00:0d.0.</p></dd></dl></div></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="Input.sect3"></a>14.7.2.4.&#160;输入</h4></div></div></div><p>对所有的输入设备(鼠标, 键盘, 游戏杆, 等等), 一个热插拔事件当设备从内核增减时产生. /sbin/hotplug 参数和 SUBSYSTEM 环境变量被设置为值 input. 输入子系统也总是添加下面的环境变量:</p><div class="variablelist"><dl><dt><span class="term"><span>PRODUCT </span></span></dt><dd><p>一个多值字符串, 用 16 进制列出值没有前导 0. 它的格式是 bustype:vender:product:version.</p></dd></dl></div><p>下列环境变量可能出现, 如果设备支持它:</p><div class="variablelist"><dl><dt><span class="term"><span>NAME </span></span></dt><dd><p>输入设备的名子, 如同设备给定的.</p></dd><dt><span class="term"><span>PHYS </span></span></dt><dd><p>输入子系统给这个设备的设备的物理地址. 它假定是稳定的, 依赖设备所插入的总线的位置.</p></dd>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -