OpenHW Lab · 智能硬件开放实验室 · 面向普通用户 / 开发者。约 40–60 分钟。
用一台吃灰的魔百和 CM201-2 机顶盒 + 一台 USB 打印机,做成局域网共享打印服务器:
手机扫码/网页传文件打印、电脑用 IPP/网络打印机、盒子屏幕全屏显示二维码、可打印二维码贴纸。
本项目在 魔百和 CM201-2(海思 Hi3798MV300 / Android 4.4.2 / armv7 / 1GB)实测通过。
ttyAMA0, 115200 8N1。总思路:盒子里 chroot 一个 Ubuntu 20.04(armhf) 子系统(/data/linux),里面装
CUPS(打印服务)+ 网页打印门户 printd(:8080)+ 打印机守护 printerwatch;
盒子屏幕装一个 打印桌面 App(开机即进,全屏显示打印页);开机自动拉起全部服务。
getprop ro.product.model # CM201-2 getprop ro.product.cpu.abi # armeabi-v7a (armv7) getprop ro.build.version.release; getprop ro.build.version.sdk # 4.4.2 / 19 cat /proc/meminfo | head; df -k
记下:架构 / 安卓版本 / 内存 / 分区。
本盒子是 海思 Hi3798MV300(armv7),所以要装 armhf 的 Ubuntu。内存只有 1GB,空间要省着用。
ttyAMA0, 115200 8N1。上电即可拿到 root shell:```
Linux 3.18.24 ... console [ttyAMA0] enabled
...
root@Hi3798MV300:/ #
```
```sh
setprop service.adb.tcp.port 5555
start adbd
```
电脑上 adb connect <盒子IP>:5555。
> 本 ROM 默认 adb 口是 5114(/init.rc),改成 5555 只是方便;开机自启脚本里已带上 start adbd。
在盒子(root)里,把一个 Ubuntu 20.04 armhf 根文件系统放到 /data/linux:
# 电脑上下好 ubuntu-base-20.04.5-base-armhf.tar.gz,推到盒子: adb push ubuntu-base-20.04.5-base-armhf.tar.gz /data/local/tmp/ubuntu20.tar.gz # 盒子上(Android root shell / 串口)解包: mkdir -p /data/linux busybox tar -xzf /data/local/tmp/ubuntu20.tar.gz -C /data/linux # 补挂内核文件系统: busybox mount -t proc proc /data/linux/proc busybox mount -t sysfs sysfs /data/linux/sys busybox mount -o bind /dev /data/linux/dev busybox mount -t devpts devpts /data/linux/dev/pts
⚠ 子系统里必须有/proc和/sys,否则 libusb / 打印机枚举读不到 USB。
apt 可用和 CM201-1 不同,这台盒子的 chroot 里 apt install 可以联网直接装(CM201-1 会 socket: Permission denied)。
所以只要配好 DNS + 源即可:
# /data/linux/etc/resolv.conf nameserver 192.168.31.1 # /data/linux/etc/apt/sources.list (国内走 tuna 镜像) deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal main restricted universe multiverse deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse # 装前放 policy-rc.d,避免 postinst 去起服务 echo '#!/bin/sh' > /data/linux/usr/sbin/policy-rc.d; echo 'exit 101' >> /data/linux/usr/sbin/policy-rc.d chmod 755 /data/linux/usr/sbin/policy-rc.d
⚠️ 安卓自带 shell 没有printf(用echo);busybox 1.16 没有cp -n/grep -x。
进 chroot 跑命令的 helper(放在 /data/local/tmp/cr.sh):
#!/system/bin/sh exec /system/bin/busybox chroot /data/linux /usr/bin/env -i \ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/root LANG=C.UTF-8 \ /bin/bash -lc "$*"
sh /data/local/tmp/cr.sh "apt-get update" sh /data/local/tmp/cr.sh "apt-get install -y --no-install-recommends \ cups cups-daemon cups-filters cups-client \ printer-driver-foo2zjs printer-driver-brlaser printer-driver-gutenprint printer-driver-cups-pdf \ python3 python3-pil python3-usb python3-distutils \ libusb-1.0-0 usbutils qrencode fonts-droid-fallback fontconfig"
cups 打印服务;printer-driver-foo2zjs = HP 主机型驱动;printer-driver-brlaser = 联想/兄弟激光;python3-pil + fonts-droid-fallback 用于「二维码贴纸」,也让中文能正常打印。HP 主机型(ZJS)打印机必须灌固件才能用。install/firmware/ 提供 HP 原厂固件:
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 # 每个再复制一份 .dl (foo2zjs 需要): adb shell 'cd /data/linux/lib/firmware/hp && for m in 1018 1020 1022 1022n; do cp -f sihp$m.img sihp$m.dl; done'
部署服务(一键或手动):
一键(电脑上,切到 install/ 目录):
./一键安装.sh 192.168.31.223
手动:
adb push install/打印服务.py /data/linux/root/printd.py adb push install/printerwatch.py /data/linux/root/printerwatch.py adb push install/二维码贴纸.py /data/linux/root/qrsheet.py adb push install/开机自启-子系统.sh /data/linux/root/printstart.sh
⚠ 本内核无 usblp → 固件走 libusb(pyusb) 直发(正是 printerwatch.py 干的事)。
配置 CUPS 开局域网(子系统里 /etc/cups/cupsd.conf):
sh /data/local/tmp/cr.sh "python3 /root/patch_cups.py" # 见下:确保只监听 0.0.0.0:631
⚠️ 坑:若cupsd.conf同时有Listen localhost:631和Listen 0.0.0.0:631,第二个会报
Address already in use,结果只绑了127.0.0.1。删掉Listen localhost:631,只留Listen 0.0.0.0:631。
起服务:
sh /data/local/tmp/cr.sh "bash /root/printstart.sh" # dbus(可选) + cupsd + printd + printerwatch
printerwatch.py 每 8 秒扫一次 USB,认出后自动灌固件 + 建 CUPS 队列(foo2zjs 默认驱动)+ 设为默认,插上就能打。
br1600, 自动识别 MFG:Lenovo;CMD:PJL,HBP;MDL:M7206W → 建队列 + 设默认 + 出纸正常)。
http://<盒子IP>:8080/setup,打开即自动带出 USB 打印机型号并列出内置匹配驱动, 选定即用;也可在管理页「更换驱动」。认不出的传 .ppd。
adb push install/桌面.apk /data/local/tmp/printsrv.apk adb shell 'pm install -r /data/local/tmp/printsrv.apk'
本 ROM 唯一 HOME 是 com.zte.iptvclient.android.launcher_ah/com.chinamobile.launcherjs.main,
Android 4.4 没有 pm set-home-activity,且 preferred-activities 为空 ——
用外科式禁用旧 HOME 的启动活动让打印桌面接管(只摘 HOME 入口,不卸载整个包):
adb shell 'pm disable com.zte.iptvclient.android.launcher_ah/com.chinamobile.launcherjs.main' # 回滚:pm enable com.zte.iptvclient.android.launcher_ah/com.chinamobile.launcherjs.main
装好后盒子屏幕就是打印服务器界面(左:网页打印界面 + 二维码;右:菜单)。
本 ROM 的 ramdisk init.bigfish.rc 里有 service bigfish-setup /system/etc/init.bigfish.sh
(on boot、root、oneshot)。不需要改 boot.img,直接在 /system/etc/init.bigfish.sh
末尾追加一段后台调用即可:
# 先备好 /data/printstart.sh(见 install/开机自启-盒子.sh) adb push install/开机自启-盒子.sh /data/printstart.sh adb shell 'chmod 755 /data/printstart.sh' # remount /system 可写,备份原文件,追加钩子 adb shell 'mount -o remount,rw /system' adb shell 'busybox cp /system/etc/init.bigfish.sh /system/etc/init.bigfish.sh.bak-orig' adb shell 'cat >> /system/etc/init.bigfish.sh <<EOF ### OpenHW Lab print server (CM201-2) ### if [ -f /data/printstart.sh ]; then /system/bin/busybox setsid /system/bin/sh /data/printstart.sh >/data/printstart.log 2>&1 & fi EOF'
/data/printstart.sh 负责:等子系统就绪 → 挂 proc / sysfs / dev → chroot 跑 /root/printstart.sh
→ 末尾延时 am start 起打印桌面(盖掉运营商桌面)。
装好后重启复查:http://<盒子IP>:8080/ 能开、桌面显示打印界面、/data/printstart.log 里有
printstart done: cupsd=1 printd=1 printerwatch=1。
http://<盒子IP>:8080/,选/拖文件 → 打印。 ipp://<盒子IP>:631/printers/<打印机名>(首页可一键复制)。
python3-pil + 中文字体。http://<盒子IP>:8080/tv 全屏二维码。—— OpenHW Lab · 智能硬件开放实验室 · hi@openhwlab.com