OpenHW Lab · 智能硬件开放实验室 · 面向普通用户 / 开发者。约 40–60 分钟。
用一台吃灰的魔百和 CM201-1 机顶盒 + 一台 USB 打印机,做成一台局域网共享打印服务器:
手机扫码传文件打印、电脑用 IPP/网络打印机、盒子屏幕全屏显示二维码、可打印二维码贴纸。
本项目在 魔百和 CM201-1(Amlogic S905L / Android 4.4.2 / armv7 / 1GB)实测通过。
总思路:盒子里 chroot 一个 Ubuntu 20.04(armhf) 子系统(/data/linux),里面装 CUPS(打印服务)+ 网页打印门户 printd(:8080)+ 打印机守护 printerwatch;
盒子屏幕装一个 打印桌面 App(开机即进,全屏显示打印页);开机自动拉起全部服务。
getprop ro.product.cpu.abi # 期望 armv7 getprop ro.build.version.release; getprop ro.build.version.sdk # 4.4.2 / 19 cat /proc/meminfo | head; df -k getprop ro.product.model # CM201-1 之类
记下:架构 / 安卓版本 / 内存 / 分区。
本盒子是 Amlogic S905L(armv7),所以要装 armhf 的 Ubuntu。内存只有 1GB,空间要省着用。
adb connect 192.168.1.100:5555 # 换成你的盒子 IP adb devices
start adbd 再 adb connect。CM201-1 这 ROM 的 adb 有时要先经串口把 adbd 拉起来,再走网络 adb。
在盒子(root)里,把一个 Ubuntu 20.04 armhf 根文件系统放到 /data/linux:
本项目用的是 ubuntu-base tar 解出来的目录(不是 loop 镜像),挂好后再补挂内核文件系统:
# 子系统目录 = /data/linux(Ubuntu 20.04 armhf) busybox mount -t proc proc /data/linux/proc busybox mount -t sysfs sysfs /data/linux/sys busybox mount -o bind /dev /data/linux/dev
⚠ 子系统里必须有/proc和/sys,否则 libusb / 打印机枚举读不到 USB。
apt install 在 chroot 里会报 socket: Permission denied(禁了 unix socket 创建),
所以 直接 apt-get install 装不了包。绕法(在电脑上备好包,再进盒子装):
① 在电脑上(Jetson/PC)用用户态 apt 配置,把需要的 armhf .deb 整套下载下来:
# 示例(注意按你的环境改路径/镜像;国内走 tuna 或官方 ports 镜像)
apt-get -o Dir::State=/tmp/aptu/state -o Dir::Cache=/tmp/aptu/cache \
-o Dir::Etc::sourcelist=/tmp/aptu/sources.list \
-o APT::Architecture=armhf -o APT::Sandbox::User=$(id -un) download <包名 ...>
# sources.list 用 mirrors.tuna.tsinghua.edu.cn/ubuntu-ports 或 ports.ubuntu.com/ubuntu-ports
② 推到盒子 → 在 chroot 里 dpkg -i 安装:
adb push *.deb /data/linux/root/debs/ adb shell "busybox chroot /data/linux /bin/bash -c 'dpkg -i /root/debs/*.deb'"
③ 装前先放 policy-rc.d,阻止 postinst 去起服务(沙盒里起不来,还可能卡住安装):
printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d && chmod +x /usr/sbin/policy-rc.d
更深入见 docs/系统改造手册.md。
按第 3 步的用户态 apt 方式,把这套 armhf 包下载 → 推 → dpkg -i:
cups cups-filters printer-driver-foo2zjs # HP 主机型(ZJS):1018/1020/1022/1022n printer-driver-brlaser # 联想 / 兄弟主机型 printer-driver-cups-pdf # 测试用 PDF 队列 python3-pil fonts-droid-fallback # 二维码贴纸 + 中文打印 qrencode
cups 打印服务;printer-driver-foo2zjs = HP 主机型驱动;printer-driver-brlaser = 联想/兄弟激光;python3-pil + fonts-droid-fallback 用于生成「二维码贴纸」,也顺带让中文能正常打印。本盒子 chroot 只能走 HTTP 出网,而且 apt 本身用不了,所以驱动一律离线备好再 dpkg 安装。
HP 主机型(ZJS)打印机必须灌固件才能用。包内 install/firmware/ 提供了 HP 原厂固件:
hp1018.img / hp1020.img / hp1022.img / hp1022n.img,放到 chroot 的固件目录并改名:
adb push install/firmware/hp1018.img /data/linux/lib/firmware/hp/sihp1018.img adb push install/firmware/hp1020.img /data/linux/lib/firmware/hp/sihp1020.img adb push install/firmware/hp1022.img /data/linux/lib/firmware/hp/sihp1022.img adb push install/firmware/hp1022n.img /data/linux/lib/firmware/hp/sihp1022n.img
部署服务(一键或手动):
一键(电脑上,切到 install/ 目录):
./一键安装.sh 192.168.1.100
它会:把 打印服务.py / printerwatch.py / 二维码贴纸.py 推进子系统 /root/;装打印桌面 App;并提示后续步骤。
手动:
adb push 打印服务.py /data/linux/root/printd.py adb push printerwatch.py /data/linux/root/printerwatch.py adb push 二维码贴纸.py /data/linux/root/qrsheet.py
⚠ 本盒子内核无 usblp → 固件走 libusb(pyusb) 直接发(就是 printerwatch.py 干的事)。
配置 CUPS 开局域网(子系统里,/etc/cups/cupsd.conf:Listen 0.0.0.0:631,各 <Location> 加 Allow all):
dbus-daemon --system --fork # 起不来也不影响 CUPS/printd /usr/sbin/cupsd python3 /root/printd.py & # 网页打印门户 :8080 python3 /root/printerwatch.py & # 打印机守护(自动灌固件 + 建队列 + 设默认)
printerwatch.py 每 8 秒扫一次 USB,认出后 自动灌固件 + 建 CUPS 队列(foo2zjs 默认驱动)+ 设为默认,插上就能打。http://<盒子IP>:8080/setup,打开即自动带出 USB 打印机型号并列出内置匹配驱动,选定即用;也可在管理页「更换驱动」。.ppd 即可。adb push 桌面.apk /sdcard/printsrv.apk adb shell 'pm install -r /sdcard/printsrv.apk' # 让它成为默认桌面(包名 com.openhardwarelab.printsrv;若还有别的桌面应用,禁用/卸载旧的)
装好后盒子屏幕就是打印服务器界面:
ipp://<IP>:631/printers/<名>)CM201-1 这 ROM 用私有 action bestv.ott.action.launcher 去启运营商桌面(不是标准 HOME),
所以要让打印服务和桌面开机自动起,做法是改 boot 镜像的 init.rc,加一个 oneshot 服务:
service printstart /system/bin/sh /data/printstart.sh
class main
oneshot
on boot
start printstart
/data/printstart.sh(Android 侧,见 install/开机自启-盒子.sh)负责:
等子系统就绪 → 挂 proc / sysfs / dev → chroot 跑 /root/printstart.sh → 末尾延时 am start 起打印桌面(把运营商桌面盖掉):
busybox chroot /data/linux /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/root \ /bin/bash /root/printstart.sh # 开机自动全屏显示「打印桌面」(覆盖运营商桌面) busybox setsid sh -c 'busybox sleep 28; am start -n com.openhardwarelab.printsrv/.MainActivity' >/dev/null 2>&1 &
子系统启动脚本见 install/开机自启-子系统.sh(即 /root/printstart.sh):
依次拉起 dbus(可选)→ cupsd → printd → printerwatch。
装好后重启复查:http://<盒子IP>:8080/ 能开、桌面显示打印界面。
http://<盒子IP>:8080/,选/拖文件 → 打印。ipp://<盒子IP>:631/printers/<打印机名>(首页可一键复制)。python3-pil + 中文字体。http://<盒子IP>:8080/tv 全屏二维码,适合盒子接电视常显。—— OpenHW Lab · 智能硬件开放实验室 · hi@openhwlab.com