• Как я оживил LaserJet 1320 и Color LaserJet CP1025 на macOS 27 — разбор по логам CUPS
• “Filter failed” и «legacy USB class driver»: анатомия двух поломок печати на M1
Дано:
macOS 27 на M1, два древних принтера HP, одно и то же сообщение «ПО принтера несовместимо с этим устройством». Выглядит как один диагноз — «драйверов под ARM нет, покупай новый принтер». На деле это две совершенно разные поломки: одна лечится одной командой, вторая не лечится вообще и требует замены драйвера на open‑source. Ниже — разбор по логам CUPS, file, nm и strings, с рабочими решениями для обоих случаев.
Исходные данные
MacBook Air M1, macOS 27.0 (build 26A428). Два USB‑принтера:
HP LaserJet 1320 — лазерник 2004 года, умеет PCL 5e, PCL 6 и PostScript Level 2 emulation, то есть растрирует сам.
HP Color LaserJet CP1025 — host‑based, он же «GDI‑принтер»: своего интерпретатора нет, всю растеризацию делает компьютер и отдаёт готовый поток ZjStream.
Эта разница между ними и окажется ключевой.
Симптомы поначалу выглядели одинаково: принтер определяется,так как до этого были установлены пакеты драйверов (как бы для apple m), в диалоге печати виден, при отправке задания — либо «ПО несовместимо», либо задание молча повисает на паузе.
Единственная команда, с которой стоит начинать
tail -40 /var/log/cups/error_log
Всё, что пишет диалог печати в macOS, — это бесполезная обобщённая формулировка. Настоящая причина лежит в логе CUPS, и она в обоих случаях оказалась совершенно конкретной. Я потратил время на форумные советы («сбросьте систему печати», «поставьте HP Smart», “переустановите драйверы”) ровно потому, что не начал с этой команды.
Случай А. LaserJet 1320: не хватает Rosetta 2
Симптом
$ lpstat -p printer HP_LaserJet_1320_series disabled since Mon Sep 28 13:01:49 2026 - Unable to use legacy USB class driver.
В логе на каждое задание:
E [Job 2101] Unable to use legacy USB class driver. E [cups-deviced] PID 1539 (hpfax) stopped with status 86! E [cups-deviced] PID 1549 (gutenprint53+usb) crashed on signal 6!
status 86 — это ENOEXEC/“bad CPU type”, то есть система отказалась запускать бинарник. Первый намёк на архитектуру.
Разбор
Проверяем фильтр, который прописан в PPD очереди:
$ grep -a cupsFilter /etc/cups/ppd/HP_LaserJet_1320_series.ppd *cupsFilter: "application/vnd.cups-postscript 0 /Library/Printers/hp/filter/hpPostProcessing.bundle/Contents/MacOS/hpPostProcessing" $ file /Library/Printers/hp/filter/hpPostProcessing.bundle/Contents/MacOS/hpPostProcessing Mach-O 64-bit executable x86_64
Вот откуда «ПО несовместимо»: фильтр печати — только Intel. Но задание падало раньше, чем доходило до фильтра, — в бэкенде. Смотрим, что внутри бэкенда:
$ strings -a /usr/libexec/cups/backend/usb | grep -i legacy USB_LEGACY_STATUS Unable to use legacy USB class driver. DEBUG: Started usb(legacy) backend (PID %d) DEBUG: usb(legacy) backend %d crashed on signal %d DEBUG: usb(legacy) backend %d stopped with status %d DEBUG: usb(legacy) backend running native again
Это механика из usb-darwin.c в CUPS: если у USB‑устройства в IORegistry прописан вендорный class driver, который нельзя загрузить в текущем процессе, бэкенд перезапускает самого себя другим слайсом. Исторически это писалось для перехода PPC → Intel, сейчас работает как Intel → ARM.
Кто прописывает устройству вендорный драйвер? Пакет HP. Находим codeless‑кекст:
$ plutil -p /Library/Extensions/hp_io_enabler_compound.kext/Contents/Info.plist | grep -c idProduct 323 $ plutil -p .../Info.plist | grep -A1 '"idProduct" => 4114' "IOClass" => "AppleUSBMergeNub" "USB Printing Class" => "/Library/Printers/hp/Frameworks/HPDM.framework/Runtime/HPIOPrinterClassDriver.plugin"
HP IO Enabler 3.4.0 (2016), AppleUSBMergeNub, 323 USB product ID вендора 0x03F0 — то есть практически вся линейка HP. Каждому подходящему устройству он навешивает свойство USB Printing Class с путём к своему class driver. А драйвер вот такой:
$ file .../HPIOPrinterClassDriver.plugin/Contents/MacOS/HPIOPrinterClassDriver Mach-O 64-bit bundle x86_64
2017 год, только Intel. Бэкенд usb собран как universal (x86_64, arm64e, arm64e.x1), поэтому он честно пытается перезапуститься x86-слайсом. И вот финальная деталь:
$ ls /Library/Apple/usr/libexec/oah RosettaLinux $ pgrep -x oahd # пусто
Rosetta 2 не установлена. Запускать x86-слайс нечем → Unable to use legacy USB class driver → задание не доезжает, очередь уходит в disabled.
Решение
sudo softwareupdate --install-rosetta --agree-to-license
Затем удалить очередь принтера и добавить заново — одна Rosetta уже залипшую очередь не оживила. Перезагрузка не нужна. Новая очередь встала на тот же PPD от HP, с тем же x86-фильтром hpPostProcessing, и под Rosetta печатает.
Проверка:
pgrep -x oahd # демон Rosetta должен быть жив lpstat -p # idle, enabled — а не disabled
Если Rosetta нельзя
Два обходных пути, оба рабочие по логике механизма:
1. Убрать кекст HP — тогда устройству достанется родной универсальный class driver Apple:
$ file /System/Library/Printers/Libraries/USBGenericPrintingClass.plugin/Contents/MacOS/USBGenericPrintingClass Mach-O universal binary with 3 architectures: [x86_64] [arm64e] [arm64e.x1]
sudo mv /Library/Extensions/hp_io_enabler_compound.kext ~/Desktop/ # бэкапом sudo kmutil install --update-all # перезагрузка
Очередь при этом заводить без фильтров HP:
sudo lpadmin -p HP1320 -E -v 'usb://...' -m drv:///sample.drv/generic.ppd
drv:///sample.drv/generic.ppd — это «Generic PostScript Printer», Level 2, ровно под эмуляцию 1320.
2. Ethernet вместо USB — у 1320n встроенный JetDirect:
sudo lpadmin -p HP1320 -E -v socket://192.168.1.50:9100 -m drv:///sample.drv/generic.ppd
Так мы обходим и USB‑бэкенд, и весь код HP целиком. Это самый долговечный вариант: ни одного вендорного бинарника в цепочке.
Случай Б. Color LaserJet CP1025: драйвер починить нельзя
Дальше я взялся за второй принтер — уверенный, что Rosetta уже всё решила. Не решила.
Симптом
[Job 2112] PdfColorSpace::initProfile CMGetDefaultProfileBySpace error:-192 [Job 2112] CMOpenProfile error -192 [Job 2112] PID 7774 (/Library/Printers/hp/laserjet/cp1020series/hpcp1020filter.plugin/.../hpcp1020) crashed on signal 11. [Job 2112] printer-state-message="Filter failed"
USB‑часть в порядке: в логе выше видно, что загрузился Apple‑овский USBGenericPrintingClass.plugin, соединение открыто, первые байты ушли. Падает растеризатор — signal 11, то есть SIGSEGV.
Разбор
$ nm -u /Library/Printers/hp/laserjet/cp1020series/hpcp1020filter.plugin/Contents/Resources/hpcp1020 _CMCloseProfile _CMCopyProfile _CMGetDefaultProfileBySpace _CMGetProfileMD5 _CMOpenProfile
Это Carbon ColorSync — API, которого в macOS больше нет. Драйвер (HP, 2012) просит цветовой профиль, получает -192, не проверяет результат и разыменовывает NULL.
Принципиальная разница со случаем А: под Rosetta бинарник запускается нормально. Проблема не в архитектуре, а в отсутствующих функциях системы. Их не вернуть ни Rosetta, ни установкой старых пакетов. А поскольку CP1025 host‑based — без этого фильтра растрировать нечем, и принтер превращается в кирпич.
Решение: foo2zjs
Нужен open‑source драйвер, который сам умеет в ZjStream. Это foo2zjs, и под macOS на Apple Silicon есть готовая сборка: github.com/ardabeh/hp‑legacy‑mac. Ставит foo2zjs и свой arm64-ghostscript в /Library/Printers/hp-legacy-mac — важно, что не в /usr/local и не в /opt/homebrew: песочница CUPS в macOS запрещает запуск оттуда, поэтому brew‑версия ghostscript тут не годится.
curl -fsSL https://raw.githubusercontent.com/ardabeh/hp-legacy-mac/main/install.sh -o /tmp/hp-legacy-mac.sh sudo sh /tmp/hp-legacy-mac.sh
Итоговая цепочка вместо упавшего фильтра HP:
gs -sDEVICE=pksmraw -r1200x600 -g10200x6600 (arm64, из бандла) → foo2zjs -z3 -c → /usr/libexec/cups/backend/usb → принтер
И вот тут меня ждали две ловушки, каждая из которых ломала уже работавшее.
Ловушка 1: при двух USB‑принтерах установщик перенастраивает не ту очередь
В install.sh:
DEVICE_URI="$(lpstat -v 2>/dev/null | sed -nE 's/.*: (usb:.*)/\1/p' | head -1)" QUEUE="$(lpstat -v 2>/dev/null | grep -i 'usb:' | awk '{print $3}' | sed 's/:$//' | head -1)"
head -1 по списку очередей. Модель он определил верно — подобрал PPD HP-LaserJet_Pro_CP1025nw. А вот очередь и device URI взял первые из lpstat -v, то есть от LaserJet 1320. Результат: драйвер CP1025 записан в очередь 1320, с USB‑адресом 1320.
$ grep -a NickName /etc/cups/ppd/HP_LaserJet_1320_series.ppd *NickName: "HP LaserJet Pro CP1025nw Foomatic/foo2zjs-z3 (recommended)"
Два принтера сломаны одним запуском. Спасает то, что CUPS при замене PPD сохраняет прежний как .ppd.O — оттуда 1320 и восстановилась.
Если USB‑принтеров больше одного, очередь надо заводить руками. Берём PPD из бандла, вырезаем его строки *cupsFilter и подставляем фильтр бандла:
gunzip -c /Library/Printers/hp-legacy-mac/ppd/HP-LaserJet_Pro_CP1025nw.ppd.gz > /tmp/cp1025.ppd grep -v '^\*cupsFilter' /tmp/cp1025.ppd > /tmp/t && mv /tmp/t /tmp/cp1025.ppd printf '*cupsFilter: "application/vnd.cups-pdf 0 hp-legacy-mac"\n' >> /tmp/cp1025.ppd sudo lpadmin -p CP1025 \ -v 'usb://Hewlett-Packard/HP%20LaserJet%20CP1025?serial=XXXXXXXX' \ -P /tmp/cp1025.ppd -E -o printer-error-policy=retry-job
Плюс конфиг очереди, который читает фильтр (имя файла должно совпадать с именем очереди):
sudo tee /Library/Printers/hp-legacy-mac/queues/CP1025.conf <<'EOF' DRIVER="foo2zjs-wrapper -z3 -P -L0" COLOR_CAPABLE=1 COLOR_FLAGS="-c -C gs9" EOF
Ловушка 2: драйвер HP возвращается сам
Настроил, проверил, работает. Выключил принтер кнопкой, включил — снова CMOpenProfile error -192 и signal 11. Смотрим на времена файлов:
$ ls -l /etc/cups/ppd/ /etc/cups/printers.conf* -rw-r--r-- 385518 Sep 28 15:12 HP_LaserJet_CP1025.ppd # снова 385 КБ — это PPD от HP -rw------- 1906 Sep 28 15:12 printers.conf -rw------- 1069 Sep 28 15:11 printers.conf.O
При переподключении устройства автонастройка печати в macOS пересобрала очередь и выбрала «самый подходящий» установленный драйвер — а это драйвер HP 2012 года, лежащий в системных папках. PPD из бандла она не видит: он не в /Library/Printers/PPDs.
Лечение — унести драйвер HP физически, чтобы выбирать было нечего:
sudo mkdir -p /Library/Printers/hp-legacy-mac/hp-driver-disabled sudo mv /Library/Printers/hp/laserjet/cp1020series \ /Library/Printers/hp-legacy-mac/hp-driver-disabled/ cd /Library/Printers/PPDs/Contents/Resources sudo mv "HP LaserJet CP 1025.gz" "HP LaserJet CP 1025nw.gz" \ "HP LaserJet CP1025.gz" "HP LaserJet CP1025nw.gz" \ /Library/Printers/hp-legacy-mac/hp-driver-disabled/
И назвать свою очередь иначе, чем назвала бы система. Я назвал CP1025, оставив имя HP_LaserJet_CP1025 системе под пустышку. Печатать — на CP1025.
Быстрая проверка в любой момент:
$ grep cupsFilter /etc/cups/ppd/CP1025.ppd *cupsFilter: "application/vnd.cups-pdf 0 hp-legacy-mac" # хорошо # hpcp1020 в этой строке = драйвер HP вернулся, повторить вынос
После этого печать пережила и выключение принтера, и переподключение кабеля.
Как определить свой случай
Тип принтера |
Примеры |
Что ломается |
Решение |
|---|---|---|---|
Растрирует сам (PostScript / PCL) |
LaserJet 1160, 1320, 2100, серия 4000, сетевые офисные лазерники |
x86-only class driver и фильтр HP; без Rosetta бэкенд не может перезапуститься x86-слайсом |
Rosetta 2 + пересоздать очередь. Ещё лучше — Generic PostScript по |
Host‑based / GDI / winprinter |
Color LaserJet CP1025, CP1215, LaserJet 1000/1005/1018/1020/1022, P1005–P1008, M12, M1132 |
фильтр HP зовёт вырезанный ColorSync → SIGSEGV; без фильтра растрировать нечем |
заменить драйвер на foo2zjs, драйвер HP вынести из системных папок |
Универсальная диагностика для любого вендора, не только HP:
tail -40 /var/log/cups/error_log # что именно упало file <путь к фильтру из cupsFilter в PPD> # только x86_64? → пробовать Rosetta nm -u <тот же путь> | grep '^_CM' # есть _CM*? → ColorSync мёртв, драйвер не спасти
Механика общая: то же сообщение «ПО несовместимо» встречается на Samsung ML-1640, а он тоже host‑based (там нужен foo2qpdl), так что логика второго случая применима и к нему.
Выводы
Диалог печати в macOS не говорит ничего.
/var/log/cups/error_logговорит всё.«Принтер определяется, но не печатает» на Apple Silicon — чаще не отсутствие драйвера, а отсутствие Rosetta 2. Проверяется одной командой
pgrep -x oahd.Если драйвер импортирует символы
_CM*, дальше можно не искать: этот код мёртв навсегда, нужен open‑source аналог.Автонастройка печати в macOS — активный участник событий. Она пересобирает очереди при переподключении устройства и выбирает драйвер сама. Пока сломанный драйвер лежит в системных папках, он будет возвращаться.
Если у железа есть Ethernet и оно понимает PostScript, сеть плюс Generic PostScript — самое долговечное решение: в цепочке не остаётся ни одного вендорного бинарника, которому может что‑то понадобиться от системы.
Мой первый пост, надеюсь поможет кому‑то. Я долго бился с этой проблемой, даже таскал старый ноут на винде для печати.
Shaman_RSHU
Вероятно я невнимательно прочитал статью, но фундаментальный вывод по «Случаю А» (LaserJet 1320) ошибочен. Ошибка «ПО несовместимо» и падение с
status 86возникают исключительно из-за попытки насильно установить устаревший проприетарный пакет драйверов HP (с x86-бинарниками и codeless-kext 2016 года). Это не только не нужно, но и нарушает принципы безопасности.HP LaserJet 1320 аппаратно поддерживает PostScript Level 2 и PCL. macOS на Apple Silicon имеет встроенные универсальные (Universal Binary: arm64 + x86_64) драйверы. Принтер работает нативно, без Rosetta и без вендорного мусора.
Вот как у меня на MacBoook Pro M5 MacOS 27: