下一页 上一页 目录

10. 你应该了解的有趣程序

10.1 什么是 setserial?

这部分内容出现在 3 个 HOWTO 中:Modem、Serial 和 Text-Terminal。根据它出现在哪个 HOWTO 中,会存在一些细微的差异。

Setserial 在使用软猫和笔记本电脑时的问题

如果串口是用于软猫(例如 ttySHCF0),则 setserial 程序似乎不起作用。如果您有笔记本电脑 (PCMCIA),请在阅读 笔记本电脑:PCMCIA 之前不要使用 setserial

简介

setserial 是一个程序,用户可以使用它与串行设备驱动程序进行通信。通常情况下,您永远不需要使用它,前提是您只使用 PC 的标准配置所带的一个或两个串口。即使在其他情况下,大多数额外的串口也应该能被现代内核自动检测到。除非您拥有通过物理硬件上的跳线设置的旧式 ISA 串口,或者您的内核(例如 2.2 或更旧版本)无法检测和设置您的附加 PCI 串口,否则您才需要使用 setserial。

setserial 允许您(或 shell 脚本)与串行软件进行通信。但是还有另一个程序,tt/stty/,它也处理串口,并用于设置端口速度等。

setserial 处理串口的底层配置,例如处理 IRQ(例如 5)、端口地址(例如 3f8)等。它的一个主要问题是它不能设置或配置串口硬件:它不能将 IRQ 或端口地址设置到硬件中。此外,当它看似报告硬件的配置时,有时是错误的,因为它实际上并没有探测硬件,除非您明确告诉它这样做。即使这样,它也不会进行现代类型的总线探测,并且某些硬件可能永远无法被它找到。尽管如此,它显示的内容在大多数情况下都是正确的,但是如果您在使串口工作时遇到问题,那么很有可能它显示的内容是错误的。

在过去,当 IRQ 和端口地址通过串口卡上的跳线设置时,人们会使用 setserial 来告诉驱动程序这些跳线是如何设置的。今天,当即插即用方法检测到无跳线串口是如何设置的时,除非您遇到问题或使用旧硬件,否则实际上不再需要 setserial。此外,如果 setserial 使用的配置文件是错误的,那么就会出现问题。在这种情况下,如果您使用 setserial 试图找出端口是如何配置的,它可能只会重复配置文件中的不正确信息。

setserial 有时可以帮助找到串口。但是只有当您知道端口地址并使用正确的选项时,它才有用。对于现代端口,通常有更好的方法通过即插即用方法来查找它们。

因此,名称 setserial 有些用词不当,因为它并没有在硬件中设置 I/O 地址或 IRQ,它只是在驱动程序软件中“设置”它们。驱动程序天真地相信 setserial 告诉它的内容,即使它与驱动程序通过使用即插即用方法找到的内容相冲突。遗憾的是,它未能至少为此类冲突发出警告消息。由于设备驱动程序被认为是内核的一部分,因此在其他文档中经常使用“内核”一词,而没有提及任何“串行驱动程序”。

某些发行版(和版本)将系统设置为在启动时通过初始化 shell 脚本(在 /etc 目录树中)运行 setserial。但是此脚本使用的配置文件可能位于 /etc 树或 /var 树中。在某些情况下,如果您希望 setserial 在启动时运行,您可能需要采取一些操作。如果没有内置于内核或作为模块加载的串行支持,setserial 将无法工作。如果您(或脚本)尝试使用 setserial,则模块可能会自动加载。

虽然可以使 setserial 探测硬件 I/O 端口地址以尝试确定 UART 类型和 IRQ,但这有严重的局限性。请参阅 探测。它不能在 PnP 或 PCI 串口的硬件中设置 IRQ 或端口地址(但串行驱动程序的即插即用功能可能会做到这一点)。它也不能直接读取存储在硬件配置寄存器中的 PnP 数据。但是由于设备驱动程序可以读取这些寄存器,并且 setserial 告诉您设备驱动程序的想法,因此它可能是正确的。或者它可能是在告诉您 setserial 之前(可能错误地)告诉驱动程序的内容。在进行其他检查之前,无法确定。

串行驱动程序(对于 Linux Kernel 2.4+)会查找一些“标准”的旧式串口、ISA 总线上的 PnP 端口以及 PCI 总线上的所有受支持端口硬件。如果它正确找到了您的端口,则无需使用 setserial。驱动程序不会探测旧式 IRQ,可能会弄错这些 IRQ,并且可能会错过使用卡上跳线设置的旧式 ISA 串口。

除了 setserial 的 man 手册之外,还可以查看 /usr/doc/setserial...//usr/share/doc/setserial 中的信息。这应该会告诉您在您的 Linux 发行版中如何处理 setserial。虽然 setserial 在所有发行版中的行为都相同,但运行它的脚本、如何配置这些脚本(包括自动配置)以及脚本文件的名称和位置等都取决于发行版。

串行模块卸载

如果串行模块被卸载,则驱动程序将忘记之前由 setserial 所做的更改。但是,虽然驱动程序忘记了它,但发行版提供的脚本可能会将其保存在某个文件中,以便在重新加载模块时可以恢复它。

给出 setserial 命令

请记住,setserial 无法在硬件中设置任何 I/O 地址或 IRQ。这是通过即插即用软件(由驱动程序运行)或旧式串口的跳线来完成的。即使您通过 setserial 将 I/O 地址或 IRQ 提供给驱动程序,它也不会设置这些值,而是假定它们已被设置。如果您给它错误的值,串口将无法正常工作(如果能工作的话)。

对于旧式端口,如果您知道 I/O 地址但不知道 IRQ,您可以命令 setserial 尝试确定 IRQ。

您可以通过仅输入不带参数的 setserial 来查看可能的命令列表。但这未能向您显示单字母选项,例如用于详细模式的 -v,您通常在进行故障排除时应使用该选项。请注意,setserial 将 I/O 地址称为“端口”。如果您输入

setserial -g /dev/ttyS*
您将看到一些关于设备驱动程序如何为您的端口配置的信息。在许多情况下,您会看到某些端口显示的信息乍一看似乎是错误的 IRQ 和地址。但是,如果您还看到:"UART: unknown",则只需忽略整行,因为该地址上不存在串口。

如果您将 -a 添加到 -g 选项,您将看到更多信息,尽管很少有人需要处理(或理解)这些额外信息,因为您看到的默认设置通常可以正常工作。在正常情况下,硬件的设置方式与 “setserial” 报告的方式相同。但是,如果您遇到问题,则很有可能 setserial 弄错了。实际上,您可以运行 “setserial” 并分配一个完全虚构的 I/O 端口地址、任何 IRQ 以及您想要的任何 uart 类型。然后,下次您键入 “setserial ...” 时,它将显示您提供给驱动程序的这些虚假值。它们也将在内核中正式注册,如 “scanport” 命令(Debian)在屏幕顶部显示的那样。当然,如果您尝试使用这样的端口,串行端口驱动程序将无法正常工作(如果能工作的话)。因此,在向 setserial 提供参数时,“一切皆有可能”。嗯,几乎是这样。如果您为一个端口分配一个已分配的基本地址(例如 3e8),它可能不会接受它。但是如果您使用 3e9,它将接受它。不幸的是,3e9 实际上已被分配,因为它在以基本地址 3e8 开头的范围内。因此,这个故事的寓意是在使用 setserial 分配资源之前,请确保您的数据是正确的。

配置文件

虽然通过 setserial 进行的分配在 PC 关机后会丢失,但是配置文件可能会在 PC 再次启动时恢复它们。在较新版本中,您通过 setserial 更改的内容可能会自动保存到配置文件中。当 setserial 运行时,它会使用来自配置文件的信息。

此配置文件的位置取决于您的发行版。查看 /etc/ 树中的启动脚本(例如 /etc/init.d/ 或 /etc/rc.d/),并阅读 “serial” 或 “setserial” 或类似的启动脚本。它应该显示配置文件所在的位置。在 Debian 中,有 4 个选项用于使用此配置文件

  1. 完全不使用此文件。在每次启动时,串行驱动程序单独检测端口,而 setserial 永远不会运行。(“kernel” 选项)
  2. 在系统首次关机时保存 setserial 报告的内容,并将其放入配置文件中。之后,即使有人通过在命令行上运行 setserial 命令然后关闭系统进行了更改,也永远不要对配置文件进行任何更改。(“autosave-once” 选项)
  3. 每次关机时,将 setserial 检测到的任何内容保存到配置文件中。(“autosave” 选项)
  4. 手动编辑配置文件以设置配置。永远不要对其进行任何自动保存。(“manual” 选项)

在过去(可能在 2000 年之前),没有任何配置文件,并且配置是在运行 setserial 的 shell 脚本内部手动设置(硬编码)的。请参阅 编辑脚本(2.15 版本之前)

探测

仅当您怀疑端口已被启用(通过 PnP 方法、BIOS、跳线等)时,才使用 setserial 探测端口。否则,setserial 探测永远不会找到它,因为它的地址不存在。一个问题是软件在指定的 I/O 地址查找端口的位置。在使用 “setserial” 进行探测之前,可以运行 “scanport”(Debian)命令以在一个扫描中检查所有可能的端口。它对某些端口上的内容进行粗略的猜测,但不确定 IRQ。这是一个快速的初步尝试。它可能会使您的 PC 挂起,但到目前为止,对我来说效果很好。请注意,非 Debian 发行版似乎不提供 “scanport”。还有其他扫描程序吗?

使用适当的选项,setserial 可以(在给定的 I/O 地址)探测串口,但您必须猜测 I/O 地址。例如,如果您要求它探测 /dev/ttyS2,它将仅在它认为 ttyS2 所在的地址 (2F8) 进行探测。如果您告诉 setserial ttyS2 位于不同的地址,那么它将在该地址进行探测,依此类推。请参阅 探测

这种探测的目的是查看那里是否存在 uart,如果存在,则查看它的 IRQ 是什么。主要将 setserial 用作最后的手段,因为有更快的方法可以尝试,例如使用 wvdialconf 检测调制解调器、查看非常早期的启动时消息,或使用 pnpdump --dumpregs 或 lspci -vv。但是,如果您想使用 setserial 检测硬件,请使用例如
setserial /dev/ttyS2 -v autoconfig
如果结果消息显示 uart 类型(例如 16550A),则表示一切正常。如果相反,它显示 uart 类型为 “unknown”,则表示该 I/O 地址根本没有串口。一些廉价的串口无法正确识别自己,因此如果您看到 “unknown”,您可能仍然在那里有一个串口。

除了自动探测 uart 类型之外,setserial 还可以自动探测 IRQ,但这也不总是有效。在一种情况下,它首先给出了错误的 irq,但是当命令重复时,它找到了正确的 irq。在 setserial >= 2.15 的版本中,您上次探测测试的结果可以自动保存并放入特定于发行版的配置文件中,例如 /etc/serial.conf/etc/sysconfig/serial 或 Debian 的 /var/lib/setserial/autoserial.conf。下次启动 Linux 时将使用此配置文件。

可能两个串口在硬件中都设置了相同的 I/O 地址。当然,这通常在 ISA 总线上是不允许的,但有时仍然会发生。探测检测到一个串口,但实际上有两个。但是,如果它们具有不同的 IRQ,则 IRQ 探测可能会显示 IRQ = 0。对我来说,只有当我首先使用 setserial 为 IRQ 提供一个虚构的值时,才会发生这种情况。

启动时配置

虽然 setserial 可以通过初始化脚本运行,但在加载串行模块时(或者当内核启动内置串行驱动程序(如果已编译到内核中)时),也会更早地运行类似于 setserial 的程序。因此,当您在屏幕上观看启动消息时,它可能看起来运行了两次,而实际上确实如此。

如果第一条消息是针对旧式端口的,则显示的 IRQ 可能不正确,因为它没有探测 IRQ。如果存在第二个串行端口报告,则可能是诸如 /etc/init.d/setserial 之类的脚本的结果。它通常不进行探测,因此可能对硬件的实际设置方式不正确。它仅显示保存在配置文件中的配置数据。在 setserial 2.15 之前的旧方法是将此类数据直接手动写入脚本。

当内核加载串行模块时(或者如果将“模块等效项”内置到内核中),则会检测到所有受支持的 PnP 端口。对于旧式(非 PnP)端口,仅自动检测 ttyS{0-3},并且驱动程序设置为仅使用 IRQ 4 和 3(无论硬件中实际设置了哪些 IRQ)。不对 IRQ 进行探测,但是可以手动进行探测。您会看到启动时消息,就像运行了 setserial 一样。

为了纠正 IRQ 中可能存在的错误(或出于其他原因),可能在某处有一个脚本文件运行 setserial。不幸的是,如果此文件中的某些 IRQ 是错误的,则内核仍将具有有关 IRQ 的不正确信息。此文件通常是启动时完成的初始化的一部分。它是否运行取决于您(和/或您的发行版)如何设置。它也可能取决于运行级别。

在修改配置文件之前,您可以通过在命令行上键入 “proposed” setserial 命令来对其进行测试。在某些情况下,当您关闭计算机时,使用 setserial 的结果将自动保存到某处,例如 /etc/serial.conf(或 autoserial.conf 或 serial)。因此,如果它工作正常(并解决了您的问题),则无需修改任何配置文件。请参阅 使用 /etc/serial.conf 等的配置方法

编辑脚本(2.15 版本之前需要)

这是在 setserial 2.15 (1999) 之前完成的方式。目的是修改(或创建)/etc 树中的一个脚本文件,该文件在启动时运行 setserial。大多数发行版都提供了这样的文件(但它最初可能没有位于 /etc 树中)。

因此,在 2.15 (1999) 版本之前,它更简单。您所做的只是编辑一个脚本。没有 /etc/serial.conf 文件(或类似的)来配置 setserial。因此,您需要找到在启动时运行 “setserial” 的文件并对其进行编辑。如果它不存在,您需要创建一个(或将命令放在一个在启动时早期运行的文件中)。如果当前正在使用这样的文件,则它很可能位于 /etc 目录树中的某个位置。但是 Redhat <6.0 已在 /usr/doc/setserial/ 中提供了它,但在使用它之前需要将其移动到 /etc 树中。

脚本 /etc/rc.d/rc.serial 在过去很常用。Debian 发行版使用 /etc/rc.boot/0setserial。曾经使用过的另一个文件是 /etc/rc.d/rc.local,但它可能运行得不够早。据报道,其他进程可能会在 rc.local 运行之前尝试打开串口,从而导致串行通信失败。后来,它很可能在 /etc/init.d/ 中找到,但通常不打算对其进行编辑。

如果提供了这样的文件,则它可能包含许多注释掉的示例。通过取消注释其中的一些和/或修改它们,您可以正确地进行设置。重要的是为 setserial 使用有效的路径,并使用有效的设备名称。您可以通过手动执行此文件(只需以超级用户身份键入其名称)来进行测试,以查看它是否正常工作。像这样的测试比重复重启以使其正确要快得多。

对于 >= 2.15 的版本(前提是您的发行版实现了更改,Redhat 最初没有实现),这样做可能更棘手,因为在启动时运行 setserial 的文件 /etc/init.d/setserial 或类似的,不打算由用户编辑。请参阅 使用 /etc/serial.conf 等的配置方法

此类脚本中的示例行是

/sbin/setserial /dev/ttyS3 irq 5 uart 16550A  skip_test

或者,如果您希望 setserial 自动确定 ttyS3 的 uart 和 IRQ,您将使用类似这样的命令

/sbin/setserial  /dev/ttyS3 auto_irq skip_test autoconfig

这是为每个您想要自动配置的串口完成的,使用您机器上确实存在的设备名称。在某些情况下,由于硬件原因,它无法正常工作。

使用 /etc/serial.conf 等的配置方法

在 setserial 2.15 (1999) 版本之前,配置 setserial 的方法是手动编辑在启动时运行 setserial 的 shell 脚本。请参阅 编辑脚本(2.15 版本之前)。这很简单,但是这种简单明了的方法已更改为不必要的复杂方法。如今,脚本和配置文件是两个不同的文件,而不是一个文件。此 shell 脚本不进行编辑,而是从配置文件(例如 /etc/serial.conf/var/lib/setserial/autoserial.conf)获取其数据。

此外,您甚至可能不需要编辑 serial.conf(或类似的),因为在命令行上使用 “setserial” 命令可能会自动导致 serial.conf 被适当地编辑。这样做是为了让您无需编辑任何文件即可设置(或更改)每次启动 Linux 时 setserial 执行的操作。

经常发生的情况是这样的:当您关闭 PC 时,在启动时运行 “setserial” 的脚本会再次运行,但是这次它仅执行 “stop” 情况的部分所说的操作:它使用 “setserial” 来找出 “setserial” 的当前状态,并将该信息放入串行配置文件中,例如 serial.conf。因此,当您运行 “setserial” 来更改 serial.conf 文件时,它不会立即更改,而只会当且仅当您正常关机时才会更改。

现在您或许可以猜到可能会出现什么问题。假设您没有正常关机(有人关闭电源等),并且更改没有被保存。假设您尝试使用 “setserial” 并忘记最后一次运行它以恢复原始状态(或在恢复原始状态时犯了错误)。然后,您的 “实验性” 设置将被保存。最糟糕的是,除非您知道配置文件中设置了哪些选项,否则您不知道会发生什么。Debian(以及其他发行版)中的一个选项称为 “AUTOSAVE-ONCE”,它仅在您第一次使用 setserial 命令进行更改时保存更改。

如果设置了选项 “###AUTOSAVE###” 并且您手动编辑 serial.conf,那么您的编辑将在您关机时被破坏,因为它会被更改回关机时 setserial 的状态。有一种方法可以禁用在关机时更改 serial.conf,那就是从 serial.conf 的第一行删除 “###AUTOSAVE###” 或类似的内容。在 Debian 发行版中,在您首次安装后首次关机后,曾经自动完成从第一行删除 “###AUTOSAVE###”。为了保留这种效果,创建了 “AUTOSAVE-ONCE” 选项,该选项仅在系统首次关机时(在您安装或更新 setserial 程序之后)进行保存。

现在,最常用于在启动时运行 setserial(符合配置文件)的文件是 /etc/init.d/setserial (Debian) 或 /etc/init.d/serial (Redhat) 等,但通常不应对其进行编辑。对于 2.15 版本,Redhat 6.0 只有一个文件 /usr/doc/setserial-2.15/rc.serial,如果您希望 setserial 在启动时运行,则必须将其移动到 /etc/init.d/。

要禁用端口,请使用 setserial 将其设置为 “uart none”。这不会被保存。/etc/serial.conf 的格式似乎与命令行上 “setserial” 后面的参数格式相同,每个端口一行。如果您不使用自动保存,则可以手动编辑 /etc/serial.conf。

为了强制将 setserial 设置的当前设置保存到配置文件 (serial.conf) 而无需关机,请执行通常在关机时发生的操作:运行 shell 脚本 /etc/init.d/{set}serial stop。“stop” 命令将保存当前配置,但串口仍能正常工作。

在某些情况下,您可能会同时安装旧的和新的配置方法,但希望只有其中一种在启动时运行。Debian 将过时的文件标记为 “...pre-2.15”。

IRQ

默认情况下,ttyS0 和 ttyS2 将共享 IRQ 4,而 ttyS1 和 ttyS3 共享 IRQ 3。但是,虽然共享串行中断(在运行程序中使用它们)对于 PCI 总线来说是可以的,但对于 ISA 总线来说是不允许的,除非您:1. 拥有内核 2.2 或更高版本,并且 2. 您已编译对此的支持,并且 3. 您的串行硬件支持它。请参阅

中断共享和内核 2.2+ 如果您只有两个串口,ttyS0 和 ttyS1,那么您仍然可以正常工作,因为 IRQ 共享冲突对于不存在的设备是不存在的。

如果您添加旧式内置调制解调器(不带即插即用)并保留 ttyS0 和 ttyS1,那么您应该尝试找到未使用的 IRQ 并将其设置在您的串口(或调制解调器卡)中,然后使用 setserial 将其分配给您的设备驱动程序。如果 IRQ 5 未用于声卡,则可以将其用于调制解调器。

笔记本电脑:PCMCIA

如果您有笔记本电脑,请阅读 PCMCIA-HOWTO 以获取有关串行配置的信息。对于主板上的串口,setserial 的使用方式与台式机相同。但是对于 PCMCIA 卡(例如调制解调器),情况就不同了。PCMCIA 系统的配置应自动运行 setserial,因此您无需运行它。如果您确实运行它(通过脚本文件或通过 /etc/serial.conf),则可能会有所不同并导致问题。serial.conf 的自动保存功能不应为 PCMCIA 卡保存任何内容(但 Debian 在 2.15-7 之前是这样做的)。当然,始终可以使用 setserial 来了解驱动程序是如何为 PCMCIA 卡配置的。

10.2 什么是 isapnp?

isapnp 是一个程序,用于配置 ISA 总线上的即插即用 (PnP) 设备,包括内置调制解调器。它包含在一个名为 “isapnptools” 的软件包中,并包含另一个程序 “pnpdump”,该程序查找所有 ISA PnP 设备,并以可以添加到 PnP 配置文件 /etc/isapnp.conf 的格式显示配置它们的选项。它也可以与 --dumpregs 选项一起使用,以显示调制解调器串口的当前 I/O 地址和 IRQ。可以将 isapnp 命令放入启动文件中,以便每次启动计算机时都运行它,从而配置 ISA PnP 设备。即使您的 BIOS 不支持 PnP,它也能够做到这一点。请参阅 Plug-and-Play-HOWTO。

10.3 什么是 wvdialconf?

wvdialconf 将尝试查找哪个串口 (ttyS?) 上连接了调制解调器。它还为 wvdial 程序创建一个配置程序。wvdial 用于使用 PPP 协议简化拨号连接到 ISP。它还可以查找当前未使用的调制解调器。它将自动为调制解调器设计一个 “合适的” 初始化字符串,但有时会出错。由于此命令没有选项,因此使用起来很简单,但您必须为其提供文件名以将初始化字符串(和其他数据)放入其中。例如,键入:wvdialconf my_config_file_name。


下一页 上一页 目录