Plug-and-Play 就是自动配置(低层)计算机中的插卡和其他设备, 然后告诉对应的设备都做了什么. Plug-and-Play 的任务是把物理设备和软件(设备驱动程序)相配合, 并操作设备, 在每个设备和它的驱动程序之间建立通信通道. 换种说法, PnP 分配下列资源给设备和硬件: I/O 地址, IRQ, DMA 通道, 内存段. 假如你不理解这 4 项, 看下面的. 一旦这些资源被分配, 设备(名字在 /dev 目录中)就准备好被使用(倘若这些物理设备在你的 PC 中).
PnP 配置资源, 但仅是一定程度上的配置资源. 尽管使用了 PnP, 许多设备仍不是被 PnP 来配置. 如调制解调器的配置, 'init string' 被通过 I/O 地址通道送给调制解调器, 尽管 I/O 地址通道是由 PnP 分配的, 但 'init string' 与 PnP 无关. 设置串口的速度是由用户执行程序来做的而不由 PnP. 所以当说起 PnP 的时候, '资源'意味著资源中的一部分, '配置'意味著某些类型的配置.
计算机包括 CPU 来运算, 内存来存储程序和数据. 还有一些设备, 如磁盘驱动器, 显示卡, 键盘, 网卡, modem 卡, 声卡, 串口和并口, 等等. 还有电源提供电能, 主板上的各种总线把设备和 CPU 连在一起, 机箱把它们装起来.
过去, 许多设备都是插卡(印刷线路板). 今天, 除了插卡之外, 许多设备已经小到一块芯片被做在主版上. 主版上的插卡也许包含不止一个设备. 内存有时也被认为是设备但不是此 HOWTO 中的 plug-and-play.
计算机要正常工作, 每个设备必须在它的驱动程序(它也是操作系统的一部分, 在CPU上运行)控制下运行. 驱动程序与 /dev 目录下的特殊文件联系在一起, 尽管他们不是真正的文件. 它们有象 hda1, ttyS0, eth1 等这样的名字. 麻烦的是选择特殊设备的驱动程序, 就说 eth1 吧, 依赖于你使用的网卡的类型. 这样 eht1 就不能分配给除了可以使你安装的网卡正常工作的驱动程序外的其它驱动程序. 为了控制设备, CPU (在驱动程序的控制下)向设备发送命令和从设备读取信息. 要这样做, 每个设备驱动程序必须知道设备的接口地址, 比如用于通信的地址. 知道这样的地址就如同建立了一条通信通道, 即使这个通道是 PC 里的许多设备共享的数据总线.
PC 有 3 类地址空间: 内存, I/O, 和配置(仅限于 PCI 总线). 只有前两个(内存, I/O)被 PnP 配置. 在 PC 里这3种类型的地址共享同样的总线. (另外: 对于 PCI 总线, 它用于传输数据). 但是由特定电路来告诉设备地址是在 I/O 空间或在内存空间.(译者注: 其实就是总线控制电路中的内存使能线, 当它为 0 电平时, 表示当前地址是内存地址, 为 1 电平时, 表示当前地址是 I/O 地址.) 设备通常使用 I/O 地址空间. 分配 I/O 地址主要有两步.
第三步是在 /dev 目录中给设备和它的驱动程序取一个名字, 如 hda, ttyS0, 或 eth1. 前两步就象解决在一条街道上找某人的住宅号码的问题. 你必须知道住宅号码并且某人必须把号码放在住宅前面, 你才可以找到它. 在计算机中, 驱动程序必须知道接口地址, 并且硬件必须设置为相同的地址, 当然这些地址应是插卡寄存器地址中的一个. 这两样都要做, 错误的是有些人仅做了其中一样, 然后却对计算机找不到设备感到奇怪. 下面解释上面的: IRQ's, DMA 通道 IRQ, DMA 通道, 和 内存地址, 所有这些都叫"资源".
看过下面的简略介绍, 你也许还想看更详细的 中断 -- 详解. 简述: 除了地址外, 还有中断需要处理(如 IRQ5). 把它叫中断号. 我们在上面已经说过设备驱动程序为了能通信必须知道插卡的地址. 那么反过来怎么办呢? 设备如何与驱动程序通信呢? 所以设备需要知道驱动程序的地址, 这样设备就可以呼叫驱动程序了. 例如: 设备接收到一些需要传送到主存的数据, 它需要告诉驱动程序马上来拿这些数据, 并把数据从设备的缓冲区送到主存.
设备呼叫驱动程序用把一个中断电路连线(总线的一部分)的电平抬高的方法. 有16个这样的连线, 每个连线与一个特定的设备驱动程序关联. 每根连线有一个特定的 IRQ(Interrupt ReQuest) 号. 设备需要把中断放到恰当的连线上, 并且驱动程序必须侦听同一连线. 究竟使用哪根连线取决于存贮在设备中的中断号, 此中断号必须被驱动程序知道, 这样它才知道需要侦听那根中断线.
DMA 代表 'Direct Memory Access'(直接内存访问). 就是允许设备从 CPU 手中接管系统总线, 并直接把数据传送到主内存. 通常 CPU 分两步来传送数据: 1. 从设备的 I/O 存储空间读数据, 把数据放在 CPU 内部. 2. CPU 把数据从其内部送到主内存. DMA 方式通常用一步就可把数据从设备直接送到主内存. 设备硬件必须内置有这种能力并不是所有的设备都可以使用 DMA 的. 从 DMA 传输占用系统总线开始的传输过程中 CPU 就不做什么了.
当一个设备试图进行 DMA 时, 它会发出一个请求(用改变总线的 DMA 请求连线的电平的方式). DMA 请求也可以用中断的方式来实现, 但会有一定的延时, 所以为了快速, 就用一种特殊类型的中断 'DMA-请求' 来实现. 象中断一样, 把 'DMA-请求线' 编号来识别是哪个设备发出的请求. 这些编号就叫 DMA-通道. 因为 DMA 传输使用系统总线(同一时间只能有一个使用), 所以它们实际上用同一个通道, 编号主要用来识别谁在使用通道. 主板上的硬件寄存器纪录各通道的当前状态. 要发出一个 DMA 请求, 设备必须知道自己的 DMA 通道号, 通道号由物理设备存储在自己内部.
像 I/O 地址一样, 一些设备在主内存中分配有地址. 当你插这样的卡时, 你实际上也插了一块内存模块(主内存, 不是 I/O 内存). 这段内存被设备和 CPU 共享(运行设备驱动程序后). 这块内存意味著设备和主内存之间'直接'传输数据. 其实不是真正的传输, 设备把数据放到它自己的内存中同时也就放到了主内存中. 插卡和设备驱动程序必须知道内存块的地址.
必须把设备驱动程序和他们控制的硬件联系起来. 这由向他们提供相同的资源来解决. 例如: 串行口使用两个资源: 一个 IRQ 和 一个 I/O 地址. 这些资源必须提供给设备驱动程序和物理设备两者. 驱动程序(和它的设备)被命名(如 ttlyS1). 地址和 IRQ 号被插卡存储在自己的内存中(或主板的一个芯片中).
PC 体系只提供有限的 IRQ, DMA 通道, I/O 地址,等. 假如只有几种设备并且设备都使用标准的资源, 把驱动程序和设备联系在一起没什么问题. 每个设备有一个固定的资源并且不与机器中的其他设备冲突. 没有两个设备使用相同的 I/O 地址, IRQ, 等. 编写驱动程序时把这些资源写进去即可. 这样事情就简单了.
但实际情况不是这样. 今天不仅有许多不同的设备且它们极有可能发生冲突, 而且同时又要使用不只一个同种类型的设备. 例如一个人可能想使用几个不同的磁盘驱动器, 几个串口, 等等. 所以设备必须有一定的灵活性这样可以把它们设置为任意的地址, IRQ, 等等. 因为要避开资源冲突. 但是一些 IRQ 和 地址是相当标准的如时钟和键盘. 它们不需要这样的灵活性.
除了资源冲突之外, 还有一个问题是告诉驱动程序错误的资源信息. 例如: 你根据猜想在配置文件中输入 IRQ4, 可设备实际使用的是 IRQ5. 这是资源分配的另一种错误.
资源分配, 如果做的正确, 可以在硬件和它们的驱动程序之间建立通信通道. 例如, 一个特定的 I/O 地址范围分配给一个设备驱动程序和一块硬件, 那么就可在它们之间建立通信通道. 驱动程序可以向设备送命令和信息. 实际上不只一条通道, 因为驱动程序可用读设备寄存器的方式得到信息. 但是设备不能用这种方式通信. 分配一个 IRQ, 把它作为驱动程序和设备可以交互的另一条通信通道.