4. 内核打印机设备

并行端口有两个完全不同的设备驱动程序;您使用的是哪个取决于您的内核版本(您可以使用以下命令查找):uname -a)。驱动程序在 Linux 2.1.33 中发生了更改;基本上所有当前的系统都将运行内核 2.2 或更高版本,因此您可能需要跳到 parport 驱动程序部分。

对于两种驱动程序样式,一些细节是相同的。最值得注意的是,许多人发现,除非他们在 PC BIOS 中禁用“即插即用”,否则 Linux 将无法检测到他们的并行端口。(这不足为奇;Windows 和其他地方的非 PCI 设备的 PnP 记录一直有点灾难)。

4.1. lp 设备(内核 <=2.1.32)

Linux 内核(<=2.1.32),假设您已编译或加载了 lp 设备(cat /proc/devices的输出应包括设备 lp,如果已加载),提供一个或多个 /dev/lp0/dev/lp1/dev/lp2。 这些不是动态分配的,而是每个都对应于特定的硬件 I/O 地址。 这意味着您的第一台打印机可能是 lp0lp1,具体取决于您的硬件。 只需都尝试一下即可。

一些用户报告说,如果他们使用较旧的单向打印机电缆,则无法检测到他们的双向 lp 端口。 检查您是否有一条像样的电缆。

在任何给定的端口上,不能同时运行 plip 和 lp 驱动程序(在 2.0 下,无论如何)。 但是,您可以随时手动加载其中一个或另一个驱动程序,或者通过 kerneld 和版本 2.x(以及更高版本的 1.3.x)内核加载。 通过仔细设置中断等,您应该可以在一个端口上运行 plip,在另一个端口上运行 lp。 有人通过编辑驱动程序来做到这一点; 我热切期待有人仅通过巧妙的命令行成功报告。

有一个名为tunelp的小实用程序在流传,您可以使用它(以 root 用户身份)调整 Linux 2.0 lp 设备的 中断使用、轮询速率和其他选项。

当 lp 驱动程序内置到内核中时,内核将接受lp=选项来设置中断和 io 地址
When the lp driver is built in to the kernel, you may use the
LILO/LOADLIN command line to set the port addresses and interrupts
that the driver will use.

Syntax:      lp=port0[,irq0[,port1[,irq1[,port2[,irq2]]]]]

For example:   lp=0x378,0   or   lp=0x278,5,0x378,7 **

Note that if this feature is used, you must specify *all* the ports
you want considered, there are no defaults.  You can disable a
built-in driver with lp=0.

当作为模块加载时,可以在 insmod 命令行(或在 /etc/conf.modules 中,以便影响 kerneld)上使用常用的模块参数语法来指定 io 地址和中断线。 参数是io=port0,port1,port2irq=irq0,irq1,irq2。 有关此内容的更多信息,请阅读 insmod 的手册页。

**对于那些永远找不到您需要的标准端口号的人,它们如上面的第二个示例所示。 另一个端口 (lp0) 在 0x3bc。 我不知道它通常使用什么中断。

Linux 2.0 并行端口驱动程序的源代码位于 /usr/src/linux/drivers/char/lp.c。

4.2. parport 设备(内核 >= 2.1.33)

从内核 2.1.33 开始(并作为内核 2.0.30 的补丁提供),lp 设备仅仅是新 parport 设备的客户端。 parport 设备的添加纠正了困扰旧 lp 设备驱动程序的许多问题 - 它可以与其他驱动程序共享端口,它可以动态地将可用的并行端口分配给设备号,而不是强制 I/O 地址和端口号之间的固定对应关系等等。

parport 设备的出现使大量新的并行端口驱动程序能够用于 Zip 驱动器、Backpack CD-ROM 驱动器和磁盘等。 其中一些也以 2.0 内核的版本提供; 在网络上搜索一下。

就打印而言,您会注意到的主要区别是,基于 parport 的内核动态地将 lp 设备分配给并行端口。 因此,在 Linux 2.0 下的 lp1 很可能在 Linux 2.2 下是 lp0。 如果您从 lp 驱动程序内核升级到 parport 驱动程序内核,请务必检查这一点。

此设备最常见的问题似乎源于配置错误

发行版

一些 GNU/Linux 发行版没有附带正确设置的 /etc/modules.conf(或 /etc/conf.modules),因此当您需要时,驱动程序无法正确加载。 使用最新的 modutils,modules.conf 中正确的神奇行似乎是
alias /dev/printers lp             # only for devfs?
alias /dev/lp*      lp             # only for devfs?
alias parport_lowlevel parport_pc  # missing in Red Hat 6.0-6.1

BIOS

许多 PC BIOS 会将并行端口变成即插即用设备。 这只是为一个几乎总是存在的完美简单设备增加了不必要的复杂性; 如果 Linux 驱动程序未检测到您的并行端口,请关闭并行端口(在许多 BIOS 中为“LPT1”)的 PnP 设置。 正确的设置通常称为“传统”、“ISA”或“0x378”,但可能不是“禁用”。

您还可以阅读内核源代码中的 parport 文档,或查看 parport 网站

4.3. 串行设备

串行设备通常在 Linux 下称为类似于 /dev/ttyS1 的名称。 实用程序stty将允许您以交互方式查看或设置串行端口的设置;setserial将允许您控制一些扩展属性,并为非标准端口配置 IRQ 和 I/O 地址。 有关 Linux 下串行端口的进一步讨论,请参见 Serial-HOWTO

当使用带流量控制的慢速串行打印机时,您可能会发现某些打印作业被截断。 这可能是由于串行端口引起的,串行端口的默认行为是在端口设备关闭后 30 秒清除其缓冲区中任何未传输的字符。 缓冲区最多可容纳 4096 个字符,如果您的打印机使用流量控制并且速度足够慢,以至于在打印软件关闭串行端口后 30 秒内无法接收缓冲区中的所有数据,则缓冲区内容的尾部将丢失。 如果命令cat file > /dev/ttyS2对于短文件产生完整的打印输出,但对于较长的文件产生截断的打印输出,您可能遇到这种情况。

30 秒的间隔可以通过 setserial 的“closing_wait”命令行选项进行调整(版本 2.12 及更高版本)。 机器的串行端口通常通过在 rc.serial 启动文件中调用 setserial 来初始化。 可以修改打印串行端口的调用,以便在设置该端口的其他参数的同时设置 closing_wait。

4.4. USB 设备

4.4.1. USB 1.1

Linux 对 USB 的支持非常好。 USB 应该适用于任何较新的 2.2 内核以及任何 2.4 内核或更高版本。 当然,您需要内核对 USB 的支持,无论是链接到内核还是通过模块(推荐)。

如果您有模块化内核,则需要加载以下模块

  • usb-core.o

  • usb-uhci.o 或 uhci.o 或 usb-ohci.o

  • printer.o

您需要 usb-uhci.o、uhci.o 或 usb-ohci.o 中的哪一个取决于您拥有的主板或适配器的类型。 Intel 和 Via 主板以及基于 Via 的适配器是 UHCI(您可以使用 usb-uhci.o 或 uhci.o 中的任何一个)。 您可以使用 lspci -v|grep HCI 找出您拥有的 HCI(主机控制器接口)类型

4.4.2. USB 2.0

要从支持 USB 2.0 的设备中获得高速传输,您必须将其连接到 USB 2.0 控制器并使用 EHCI 驱动程序 (ehci-hcd.o)。 如果您想使用 USB 2.0,建议使用最新的 2.4 内核或更高版本。

4.4.3. 提示

要记住的一件事是 USB 设备是动态分配的。 USB 打印机在打开或连接时会分配到一个设备文件 (/dev/usb/lp*)。 这可能意味着打印作业被发送到错误的打印机,因为您以某种顺序打开了它们。 CUPS 使用包含制造商、型号和打印机序列号的特殊 URI 来保持将作业发送到正确的物理打印机。

尽管大多数 USB 打印机在 Linux 上都能正常工作,但也存在例外。 例如,来自 Epson 的新型多功能设备(Stylus CX3200/CX5200)在通过 IOCTL 轮询 IEEE-1284 ID 字符串时返回乱码,例如使用 CUPS “usb”后端代码。 然而,可以通过 Epson 专有方法轮询 ID 字符串。

Till Kamppeter 编写了一些工具来检索 USB 打印机的设备 ID 字符串。 getusbprinterid.plusb_id_test.c 是相同的东西,但分别是 Perl 和 C 语言版本。 如上所述,来自 Epson 的新型多功能设备是一个例外,但 “Epson 专有方法”已在 MTink 软件包的 ttink 工具中实现。

有关 USB 的更多文档,请访问 Linux USB 网站