背景
HP LaserJet 1020 是一款经典但”难搞”的老打印机。它属于 GDI 打印机(也叫 Winprinter),本身没有完整的打印描述语言,需要靠主机每次发送固件才能工作。在 ARM 架构的飞牛(fnOS)上,由于驱动兼容性、USB 控制器识别、固件自动加载等问题,配置起来比 x86 平台要折腾不少。
本教程记录在飞牛 ARM 设备上,通过 CUPS + foo2zjs 驱动 + udev 自动发固件脚本,让 HP 1020 稳定工作的完整过程。
一、安装 CUPS 和 foo2zjs 驱动
SSH 登录飞牛,切换到 root:
sudo apt-get update
sudo apt-get install cups hplip printer-driver-foo2zjs -y
验证驱动安装:
dpkg -l | grep foo2zjs
应该看到 printer-driver-foo2zjs 和 printer-driver-foo2zjs-common 两个包,架构为 arm64。
二、配置 CUPS 局域网访问
编辑 CUPS 配置:
sudo cp /etc/cups/cupsd.conf /etc/cups/cupsd.conf.bak
sudo nano /etc/cups/cupsd.conf
修改 1:把 Listen localhost:631 改成:
Listen 0.0.0.0:631
修改 2:在三段 <Location> 配置里各加一行 Allow all:
<Location />
Order allow,deny
Allow localhost
Allow all
</Location>
<Location /admin>
Order allow,deny
Allow localhost
Allow all
</Location>
<Location /admin/conf>
AuthType Default
Require user @SYSTEM
Order allow,deny
Allow localhost
Allow all
</Location>
保存退出(Ctrl+O 回车,Ctrl+X),把飞牛用户加入打印管理组:
sudo usermod -a -G lpadmin 你的用户名
sudo systemctl restart cups
浏览器打开 http://飞牛IP:631,能看到 CUPS 管理页面就说明配置成功。
三、准备固件文件
HP 1020 需要的固件文件 sihp1020.dl,最可靠的来源是从 HPLIP 官方包中提取:
sudo apt install hplip -y
sudo hp-plugin -i # 按提示下载固件
sudo mkdir -p /usr/share/foo2zjs/firmware/
sudo gunzip -c /usr/share/hplip/data/firmware/hp_laserjet_1020.fw.gz > /tmp/sihp1020.dl
sudo cp /tmp/sihp1020.dl /usr/share/foo2zjs/firmware/sihp1020.dl
验证文件大小(应该在 70–125KB 之间):
ls -lh /usr/share/foo2zjs/firmware/sihp1020.dl
网上流传的第三方镜像源(如
opt.cn2qq.com)经常失效或文件损坏,建议用 HPLIP 官方来源。如果下载到的文件是 0 字节或只有十几字节,说明下载失败。
四、解决 USB 识别问题(ARM 平台常见坑)
在 ARM 飞牛上,HP 1020 可能会遇到 USB 枚举失败,dmesg 报错:
usb 1-2: device descriptor read/64, error -71
usb usb1-port2: unable to enumerate USB device
error -71(EPROTO)是 USB 协议通信错误,常见原因:
- 插在了 USB 3.0 口(日志显示
using xhci-hcd)——HP 1020 是 USB 2.0 全速设备,部分 xHCI 控制器兼容性差 - USB 线质量差或太长
- 打印机 USB 接口板老化
解决办法:
- 换到主板上的 USB 2.0 黑色口
- 换一根 1 米以内、确认能传数据的 USB 线
- 用 U 盘交叉验证 USB 口本身是否正常
- 把打印机接到 Windows 电脑验证,确认是线/打印机问题还是主机兼容性问题
验证设备是否被识别:
lsusb
正常应该能看到:
Bus 001 Device 013: ID 03f0:2b17 HP, Inc LaserJet 1020
五、手动绑定 usblp 并发送固件
lsusb 能看到设备,但 /dev/usb/lp0 不存在时,需要手动绑定:
# 停掉 CUPS,避免接口被占用
sudo systemctl stop cups
# 确认设备接口路径
ls /sys/bus/usb/devices/ | grep 1-2
# 输出应有:1-2 和 1-2:1.0
# 手动绑定到 usblp
echo "1-2:1.0" | sudo tee /sys/bus/usb/drivers/usblp/bind
# 验证设备节点
ls -l /dev/usb/lp0
# 应输出:crw-rw---- 1 root lp 180, 0 ... /dev/usb/lp0
发送固件激活打印机:
sudo cat /usr/share/foo2zjs/firmware/sihp1020.dl > /dev/usb/lp0
重启 CUPS:
sudo systemctl start cups
六、在 CUPS 中添加打印机
浏览器打开 http://飞牛IP:631,进入 Administration → Add Printer。
6.1 选择连接方式
在 Local Printers 里选择:
HP LaserJet 1020 (HP LaserJet 1020)
注意:不要选带 USB S45CJ0M HPLIP 字样的选项,那是 HPLIP 的 libusb 直连方式,会和 usblp 内核驱动冲突。
如果添加后想修改连接方式,在打印机页面点 Modify Printer,把连接改成:
usb://HP/LaserJet%201020?serial=S45CJ0M
6.2 选择驱动(关键)
在 Model 选择页面,务必选:
HP LaserJet 1020 Foomatic/foo2zjs-z1 (recommended)
不要选 hpcups 或带 requires proprietary plugin 字样的驱动,那会导致任务卡在 “Rendering completed” 之后发不出去。
如果驱动列表里找不到 foo2zjs-z1,点 Select Another Make/Manufacturer,厂商选 Foomatic/foo2zjs 或 HP,再找。
或者手动上传 PPD:
dpkg -L printer-driver-foo2zjs | grep -i 1020
# 找到类似 /usr/share/ppd/foo2zjs/HP-LaserJet_1020.ppd.gz 的路径
sudo gunzip -c /usr/share/ppd/foo2zjs/HP-LaserJet_1020.ppd.gz > /tmp/HP1020.ppd
在 CUPS 页面底部”上传一个 PPD 文件”处上传。
6.3 勾选共享
记得勾选 Share This Printer,让局域网其他设备也能用。
6.4 测试打印
cancel -a
lp -d HP1020 /usr/share/cups/data/testprint
如果出纸,说明基础配置成功。
七、配置开机自动发固件(udev + 脚本)
HP 1020 每次断电、拔插 USB、重启飞牛后,固件都会丢失,必须重新发送。用 udev 规则 + 脚本实现自动化。
7.1 让 usblp 开机自动加载
echo "usblp" | sudo tee /etc/modules-load.d/usblp.conf
7.2 创建自动发固件脚本
sudo nano /usr/local/bin/hp1020-firmware.sh
写入:
#!/bin/bash
# HP LaserJet 1020 固件自动加载脚本
# 先停 CUPS,避免它抢占 USB 接口
systemctl stop cups
sleep 2
# 绑定 usblp
for dev in /sys/bus/usb/devices/*/idVendor; do
if [ "$(cat $dev 2>/dev/null)" = "03f0" ]; then
dir=$(dirname $dev)
iface="$dir:1.0"
if [ -e "$iface" ] && [ -e /sys/bus/usb/drivers/usblp/bind ]; then
echo -n "$(basename $iface)" > /sys/bus/usb/drivers/usblp/bind 2>/dev/null
fi
fi
done
# 等待设备节点
for i in $(seq 1 15); do
[ -e /dev/usb/lp0 ] && break
sleep 1
done
# 发固件
if [ -e /dev/usb/lp0 ] && [ -e /usr/share/foo2zjs/firmware/sihp1020.dl ]; then
cat /usr/share/foo2zjs/firmware/sihp1020.dl > /dev/usb/lp0
logger "HP 1020 固件已自动加载"
fi
# 解绑 usblp,把接口还给 CUPS
if [ -e /dev/usb/lp0 ]; then
for dev in /sys/bus/usb/devices/*/idVendor; do
if [ "$(cat $dev 2>/dev/null)" = "03f0" ]; then
dir=$(dirname $dev)
iface="$dir:1.0"
if [ -e /sys/bus/usb/drivers/usblp/unbind ]; then
echo -n "$(basename $iface)" > /sys/bus/usb/drivers/usblp/unbind 2>/dev/null
fi
fi
done
fi
# 重启 CUPS
systemctl start cups
赋予可执行权限:
sudo chmod +x /usr/local/bin/hp1020-firmware.sh
脚本逻辑说明:先停 CUPS → 绑定 usblp → 发固件 → 解绑 usblp → 重启 CUPS。这样既发了固件,又把 USB 接口还给 CUPS 用于实际打印。
7.3 创建 udev 规则
sudo nano /etc/udev/rules.d/99-hp1020.rules
写入:
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="2b17", ACTION=="add", RUN+="/usr/local/bin/hp1020-firmware.sh"
重载 udev 规则:
sudo udevadm control --reload-rules
sudo udevadm trigger
八、验证自动化
8.1 检查 dmesg 日志
sudo dmesg | grep -i -E "hp1020|usblp"
正常应该看到成对出现的绑定/解绑记录:
usblp 1-2:1.0: usblp0: USB Bidirectional printer dev 13 ...
usblp0: removed
usblp 1-2:1.0: usblp0: USB Bidirectional printer dev 14 ...
usblp0: removed
每一对就是一次”绑定 → 发固件 → 解绑”的完整循环。
8.2 检查脚本执行日志
journalctl -t hp1020-firmware.sh --no-pager | tail -10
应该能看到 HP 1020 固件已自动加载 的记录。
8.3 端到端测试
- 关闭打印机电源,等 10 秒
- 打开打印机电源
- 等 20 秒(让脚本跑完)
- 直接打印:
cancel -a
lp -d HP1020 /usr/share/cups/data/testprint
能出纸 → 全部搞定,以后断电、重启飞牛、拔插 USB 都能自动恢复。
注意:/dev/usb/lp0 在脚本跑完后会消失(因为脚本解绑了 usblp 把接口还给 CUPS),这是正常的,不代表失败。
九、常见问题排查
问题 1:打印任务卡在 “Rendering completed”
原因:驱动选错,用了 hpcups 而不是 foo2zjs-z1。
解决:在 CUPS 里 Modify Printer,驱动改成 HP LaserJet 1020 Foomatic/foo2zjs-z1。
问题 2:lsusb 能看到设备但 /dev/usb/lp0 不存在
原因:usblp 没有绑定到打印机接口。
解决:手动绑定(见第五节),或者检查 udev 脚本是否正确执行。
问题 3:dmesg 报 error -71
原因:USB 3.0 控制器兼容性问题,或线材质量差。
解决:换 USB 2.0 口、换短的好线、交叉验证。
问题 4:重启后打印不出来
原因:固件丢失,需要重新发送。
解决:检查 udev 规则和脚本是否生效,用 journalctl -t hp1020-firmware.sh 看日志。
问题 5:CUPS 连接方式选哪个
usb://HP/LaserJet%201020?serial=xxx→ 走内核 usblp 驱动(推荐)hp:/usb/HP_LaserJet_1020?serial=xxx→ 走 HPLIP libusb 直连(和 usblp 互斥)
两者只能选一个。用 foo2zjs 驱动时推荐前者。
十、总结
HP LaserJet 1020 在 ARM 飞牛上的配置,核心难点有三个:
- USB 识别:老设备的 USB 2.0 全速模式和主机的 USB 3.0 控制器兼容性差,需要换口换线
- 驱动选择:必须用
foo2zjs-z1而不是hpcups,否则任务卡住 - 固件自动加载:HP 1020 是 GDI 打印机,每次断电都要重新发固件,需要用 udev + 脚本自动化
整套方案的关键是理解 usblp 内核驱动和 CUPS/libusb 是互斥的,所以脚本的设计思路是”临时借用接口发固件,发完立刻还给 CUPS”。这样既保证了固件加载,又不影响 CUPS 正常打印。
配置完成后,打印机在断电重启、飞牛重启、USB 拔插后都能自动恢复,无需人工干预。
参考
- CUPS 官方文档:https://www.cups.org/
- foo2zjs 项目:https://github.com/koenkooi/foo2zjs
- HPLIP 官方:https://developers.hp.com/hp-linux-imaging-and-printing

💬 评论区 0