Как запустить старые принтеры на Mac с Apple Silicon: два разных сбоя под одной ошибкой «ПО несовместимо»
• Восстановление 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 (сборка 26A428). Используются два USB-принтера:
-
HP LaserJet 1320 — монохромный лазерник 2004 года выпуска, поддерживает PCL 5e, PCL 6 и эмуляцию PostScript Level 2, то есть самостоятельно выполняет растрирование.
-
HP Color LaserJet CP1025 — устройство класса host-based (также известное как GDI-принтер): собственного процессора для интерпретации данных у него нет, всю работу по растрированию выполняет компьютер, отправляя готовый поток ZjStream.
Именно это архитектурное различие станет определяющим фактором.
Внешне симптомы выглядели идентично: принтер распознается (поскольку ранее инсталлировались пакеты драйверов якобы для Apple Silicon), отображается в интерфейсе печати, но при отправке документа либо сообщает о несовместимости ПО, либо мертვо зависает в режиме паузы.
Единая команда, с которой следует начинать диагностику
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 («неверный тип процессора»), что прямо указывает на отказ системы запускать исполняемый файл.
Разбор
Исследуем фильтр, прописанный в 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: если в реестре IORegistry для USB-периферии зарегистрирован вендорный класс драйвера, несовместимый с текущим процессом, бэкенд перезапускает самого себя в другом режиме совместимости. Исторически эта логика создавалась для миграции с PowerPC на Intel, а сейчас задействована при переходе с Intel на ARM.
Кто назначает устройству фирменный драйвер? Пакет от HP. Обнаруживаем специальное расширение без исполняемого кода (codeless kext):
$ 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 идентификатора продуктов вендора 0x03F0, то есть практически весь модельный ряд HP. Каждому подходящему девайсу он принудительно прописывает параметр USB Printing Class со ссылкой на собственный драйвер. А сам драйвер представляет собой:
$ file .../HPIOPrinterClassDriver.plugin/Contents/MacOS/HPIOPrinterClassDriver
Mach-O 64-bit bundle x86_64
Компиляция 2017 года, только под Intel. Сам USB-бэкенд собран как универсальный бинарник (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 — в таком случае устройство автоматически переключится на стандартный универсальный системный класс драйверов 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 активирует универсальный PostScript-принтер (Level 2), идеально подходящий для эмуляции модели 1320.
2. Использование Ethernet-подключения — у модификации 1320n присутствует встроенный сетевой интерфейс JetDirect:
sudo lpadmin -p HP1320 -E -v socket://192.168.1.50:9100 -m drv:///sample.drv/generic.ppd
Этот метод исключает из цепочки и проблемный USB-бэкенд, и весь проприетарный код вендора. Это наиболее надежный подход: в системе не остается ни одного стороннего бинарника.
Случай Б. 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-соединение работает стабильно: лог подтверждает успешную загрузку системного модуля USBGenericPrintingClass.plugin, инициализацию порта и передачу пакетов. Сбой происходит на этапе работы растрировщика — код сигнала 11 означает критическую ошибку сегментации памяти (SIGSEGV).
Разбор
$ nm -u /Library/Printers/hp/laserjet/cp1020series/hpcp1020filter.plugin/Contents/Resources/hpcp1020
_CMCloseProfile
_CMCopyProfile
_CMGetDefaultProfileBySpace
_CMGetProfileMD5
_CMOpenProfile
Перед нами вызовы устаревшего интерфейса Carbon ColorSync, полностью удаленного из современных версий macOS. Драйвер 2012 года запрашивает цветовой профиль, получает код ошибки -192, игнорирует проверку результата и пытается обратиться по нулевому указателю.
Фундаментальное отличие от первого случая заключается в том, что под управлением Rosetta исполняемый файл стартует корректно. Проблема кроется не в архитектурных ограничениях, а в физическом отсутствии необходимых системных API. Их невозможно вернуть ни силами Rosetta, ни установкой старых пакетов. Поскольку модель CP1025 относится к типу host-based устройств, без исправного фильтра подготовка печати невозможна, и принтер превращается в бесполезный объект.
Решение: пакет foo2zjs
Требуется альтернативный драйвер с открытым исходным кодом, способный генерировать ZjStream. Таким инструментом является foo2zjs, причем для архитектуры Apple Silicon подготовлена специализированная сборка: github.com/ardabeh/hp-legacy-mac. Она инсталлирует сам пакет и автономную ARM64-версию Ghostscript в директорию /Library/Printers/hp-legacy-mac. Крайне важно, что файлы располагаются именно здесь, а не в /usr/local или /opt/homebrew: изолированная среда (песочница) CUPS блокирует запуск утилит из этих папок, поэтому стандартный 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. Однако параметры очереди и URI были взяты для самого первого устройства в выводе lpstat -v, то есть для LaserJet 1320. В результате драйвер модели CP1025 был ошибочно привязан к очереди и адресу принтера 1320.
$ grep -a NickName /etc/cups/ppd/HP_LaserJet_1320_series.ppd
NickName: "HP LaserJet Pro CP1025nw Foomatic/foo2zjs-z3 (recommended)"
Оба принтера оказались выведены из строя одним скриптом. Ситуацию спасло лишь то, что при замене PPD-файлов CUPS сохраняет прежние версии с расширением .ppd.O — именно оттуда настройки LaserJet 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-версии драйвера и фильтра 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 является самым долговечным решением: в цепочке обработки не остается ни единого проприетарного компонента, зависящего от капризов ОС.
Это моя первая публикация, надеюсь, она окажется кому-то полезна. Я потратил много времени на борьбу с этой задачей, в какой-то момент даже подключая старый ноутбук на Windows исключительно ради печати документов.
Производитель систем охлаждения раскрыл характеристики AMD Epyc Verano: новый сокет, до 72 ядер Zen 6 и частота до 5 ГГц
Портативный Kubernetes: строим частное ARM64-облако своими руками
130 отделений «Лавки» подключили к доставке роботами Яндекса
Рынок резервного копирования в России достиг 5,8 млрд рублей за полугодие
Как я добавил прямой выбор входов в QUAD 3: реверс ARM-прошивки, бинарный патч и 64 байта здравого смысла
HR-платформа «ИТ и СБ решений» получила чаты, встречи и обучение МТС Линк
Тест китайского ИИ-ускорителя PPU Zhenwu 810E от Alibaba в работе с LLM
Смартфоны Huawei подорожают из-за роста себестоимости более чем на $200