下一页 上一页 目录

15. 串行技巧与杂项

15.1 串行模块

通常,串行驱动程序以模块形式提供,例如 generic_serial.ko。USB 串行端口和多端口卡的驱动程序通常也以模块形式提供。Linux 应该会自动加载任何需要的模块,因此在大多数情况下,您无需执行任何操作。

但有时您需要配置 Linux 以加载某些模块,或为模块或内核提供参数。

此类参数可以为某些模块提供,可以在内核的命令行中,也可以在 /etc/modules、/etc/modules.conf 或 /etc/modprobe.conf 中提供。自内核 2.2 起,您不再编辑 modprobe.conf 文件,而是使用程序 update-modules 来更改它。用于更新 modules.conf 的信息放在 /etc/modutils/ 中。

Debian/GNU Linux 有一个名为 /etc/modutils/setserial 的文件,每次加载或卸载串行模块时,它都会运行 /etc/init.d/ 中的串行脚本。当卸载串行模块时,此脚本会将模块的状态保存在 /var/run/setserial.conf 中。然后,如果再次加载该模块,则会恢复此保存的状态。当串行模块在启动时首次加载时,/var/run/setserial.conf 中没有任何内容,因此状态从 /etc/serial.conf 获取。因此,有两个文件保存状态。其他发行版可能会执行类似的操作。

串行模块位于 /lib/modules/.../kernel/drivers/ 的子目录中。对于多端口卡,请查看 serial 子目录和/或 char。对于 USB 串行,请查看 usb/serial 子目录。模块 parport_serial 适用于包含串行端口和并行端口的 PCI 卡。

作为最后的手段,可以编辑源代码来修改串行驱动程序。大部分串行驱动程序都位于文件 serial.c 中。有关编写串行端口程序的更多信息,请参阅 Serial-Programming-HOWTO。Vern Hoxie 在 1999 年对其进行了修订,但该修订版不在 LDP 上。

15.2 内核配置

15.3 支持的串行端口数量

如果您有超过 4 个(或可能 2 个)串行端口,那么您必须确保内核知道这一点。这可以通过在编译时配置内核,或在内核启动时(启动提示符或内核命令行)给内核一个参数来完成。

内核配置参数:CONFIG_SERIAL_8250_RUNTIME_UARTS=4 和 CONFIG_SERIAL_8250_NR_UARTS=4 将普通串行端口 (UART) 的最大数量设置为 4。如果您有超过 4 个普通串行端口,则需要将 4 更改为任何数量。但是您可以通过内核命令行覆盖此设置,例如:nr_uarts=16(如果串行支持内置于内核中)或 8250.nr_uarts=16(如果串行支持通过模块实现)。可以告知引导加载程序(如 lilo 或 grub)执行此操作。

15.4 串行控制台(串行端口上的控制台)

请参阅内核文档:Documentation/serial-console.txt。内核 2.4+ 有更好的文档。另请参阅 Text-Terminal-HOWTO 中的“串行控制台”。

15.5 线路驱动器

对于文本终端,RS-232 速度足够快,但可用的电缆长度通常太短。平衡技术可以解决这个问题。获得与文本终端平衡通信的常用方法是在串行线路中安装 2 个线路驱动器,以将不平衡转换为平衡(反之亦然)。它们是特殊物品,如果购买新的会很昂贵。

15.6 打印等操作时停止数据流

通常,流量控制和/或应用程序会在需要时停止字节流。但有时它们不会。问题是到串行端口的输出首先要通过 PC 主内存中的大型串行缓冲区。因此,如果您想中止打印,则应删除此缓冲区中的任何内容。当您告诉应用程序停止打印时,它可能不会清空此缓冲区,因此打印会继续直到缓冲区为空。此外,您的打印机也有自己的缓冲区,需要清除。因此,由于这两个缓冲区继续为打印机提供字节,告诉 PC 停止打印可能不起作用。这是打印机软件不了解串行端口以及需要断开调制解调器控制线以停止打印机的问题。

确保打印停止的一种方法是直接关闭打印机。使用较新的串行驱动程序,这可以正常工作。缓冲区被清除,并且打印不会恢复。使用较旧的串行驱动程序,PC 的串行缓冲区不会清除,有时会在重新打开打印机时继续打印。为避免这种情况,您必须等待 setserial 的 closing_wait 指定的时间,然后才能再次打开打印机。您可能还需要从打印队列中删除打印作业,这样它就不会尝试恢复打印。

15.7 已知的 IO 地址冲突

避免与某些显卡发生 IO 地址冲突

IBM 8514 显卡(以及其他显卡)的 IO 地址据称是 0x?2e8,其中 ? 是 2、4、8 或 9。如果串行端口在解码地址时忽略前导 0 十六进制数字(许多端口都这样做),这可能会与地址为 0x02e8 的 ttyS3 的 IO 地址冲突(但如果串行端口设计良好,则不应冲突)。如果您尝试在此 IO 地址使用 ttyS3,那将是坏消息。另一个说法是,Linux 不会检测到您在 ttyS3 上的内置调制解调器,但您可以使用 setserialttyS3 放在此地址,并且调制解调器将正常工作。

与 ide2 硬盘驱动器的 IO 地址冲突

ttyS2 的地址是 3e8-3ef,而硬盘驱动器 ide2 使用 3ee,它在此范围内。因此,在启动 Linux 时,您可能会看到有关此冲突的报告。大多数人不使用 ide2(第三个硬盘驱动器电缆),可能会忽略此冲突消息。您可能在 ide0 上有 2 个硬盘驱动器,在 ide1 上有另外两个,因此大多数人不需要 ide2。

15.8 已知的硬件缺陷

AMD Elan SC400 CPU(单芯片 PC)的问题

这存在 UART 的中断和状态寄存器之间的竞争条件。当 UART 发送器完成字节传输并且 UART 发送缓冲区变空(等待下一个字节)时,会发出中断。但是 UART 的状态寄存器更新速度不够快,无法反映这一点。结果,中断服务例程快速检查并(错误地)确定没有发生任何事情。因此,没有字节被发送到端口进行传输,UART 发送器徒劳地等待永远不会到达的字节。如果中断服务例程在检查状态寄存器之前等待的时间稍长一些,那么它将被更新以反映真实状态,一切都会正常。

有一个通过修补串行驱动程序来解决此问题的提议。但是,是否应该修补 Linux 以适应有缺陷的硬件,特别是如果此补丁可能会损害良好硬件的性能?


下一页 上一页 目录