Яркость экрана на ноутбуке под Linux регулируется не одной программой, а цепочкой: ACPI прошивки, драйвер GPU, класс backlight в ядре и лишь затем утилиты вроде xbacklight или brightnessctl. На ноутбуках с Intel и AMD эта цепочка ломается в предсказуемых местах: горячие клавиши меняют одно устройство, панель слушает другое, а xbacklight выдаёт ошибку про отсутствие свойства. Ниже разобрано, как устроен интерфейс подсветки, где выбирать правильное устройство и что делать, если стандартные инструменты молчат. Рецепты актуальны для свежих выпусков дистрибутивов, но работают и на старых ядрах с поправкой на порядок регистрации устройств.

Каталог sysfs как единая точка управления подсветкой

Ядро сводит все доступные каналы регулировки яркости в класс устройств /sys/class/backlight. Каждый подкаталог там это один независимый канал с одинаковым набором файлов: brightness текущее значение, max_brightness верхняя граница, actual_brightness реальное значение после округления драйвером.

ls /sys/class/backlight/
cat /sys/class/backlight/intel_backlight/max_brightness

Верхняя граница сильно различается между машинами: где-то это 15 ступеней от ACPI-интерфейса, а у нативного драйвера Intel ступеней несколько тысяч, что даёт плавную регулировку. Запись идёт обычной командой:

echo 800 | sudo tee /sys/class/backlight/intel_backlight/brightness

Значение задаётся в абсолютных ступенях, а не в процентах, и попытка записать число выше max_brightness вернёт ошибку. Семантика числа зависит от драйвера: для acpi_video0 ноль часто означает минимум, а для некоторых vendor-интерфейсов кривая яркости нелинейна, и первые ступени почти не видны глазу. Именно поэтому утилиты предпочитают вычислять процент от max_brightness, а не писать наугад.

Файл actual_brightness полезен при диагностике: если после записи в brightness значение actual_brightness не меняется, канал выбран неверно, и панель физически управляется другим устройством. Все утилиты регулировки, от xbacklight до brightnessctl, крутятся вокруг этих трёх файлов, поэтому понимание sysfs экономит часы поисков.

Имена устройств intel_backlight, amdgpu_bl0 и acpi_video0

Имя подкаталога подсказывает, кто владеет каналом. intel_backlight создаёт драйвер i915 на ноутбуках с Intel, amdgpu_bl0 или amdgpu_bl1 создаёт драйвер amdgpu на современных AMD, radeon_bl0 остаётся от старого драйвера radeon, а acpi_video0 регистрирует модуль acpi_video через методы ACPI прошивки. Отдельные vendor-интерфейсы вроде thinkpad_screen дают специфичные для производителя каналы. На ноутбуках с гибридной графикой или с кривыми таблицами ACPI нередко живут сразу два каталога, и регулируемый ими канал не совпадает: клавиши двигают acpi_video0, а подсветка панели физически управляется через amdgpu_bl0. Внешне регулировка выглядит рабочей, но ничего не делает.

Число в имени тоже несёт смысл: при нескольких панелях появляются amdgpu_bl1 и выше, а acpi_video0 соседствует с acpi_video1, когда ACPI описывает несколько видеоустройств, и лишь один из них привязан к реальной панели.

Со времён переработки подсистемы backlight в ядре 6.1 выбор устройства стал умнее: ядро само предпочитает нативный драйвер GPU, когда тот доступен, и заводские таблицы ACPI подключает лишь при их отсутствии. Поэтому на свежих ядрах лишние каталоги встречаются реже, чем на ядрах пятилетней давности, а старые рецепты с ручным выбором часто становятся ненужными.

Установка и работа xbacklight под X11 на ноутбуках

Утилита xbacklight ставится из стандартных репозиториев:

sudo apt install xbacklight
sudo pacman -S xorg-xbacklight

Она не пишет в sysfs напрямую, а работает через свойство BACKLIGHT протокола RandR у X-сервера, то есть регулирует яркость ровно того устройства, которое драйвер зарегистрировал в RandR.

xbacklight -get
xbacklight -set 50
xbacklight -inc 10 -time 1500 -steps 30
xbacklight -dec 20

Флаг -time задаёт длительность перехода в миллисекундах, а -steps число промежуточных шагов, что даёт плавное затухание экрана вместо резкого скачка. Драйвер передаёт в RandR и минимальное значение подсветки, поэтому ноль у части машин означает глубокое затемнение, при котором панель почти не светится, но продолжает работать. Всё это работает только в сессии X11: в Wayland протокола RandR нет, а в X11 всё упирается в наличие свойства подсветки у драйвера.

Ошибка No outputs have backlight property и замены xbacklight

Сообщение No outputs have backlight property означает, что ни один выход не зарегистрировал RandR-свойство яркости. Так бывает на ноутбуках с amdgpu, где драйвер не экспортировал свойство, в Wayland-сессиях и после обновлений ядра, поменявших порядок регистрации устройств. Чинить стоит не xbacklight, а сам подход. Первая замена это brightnessctl, работающая поверх sysfs одинаково в X11 и Wayland:

brightnessctl info
brightnessctl set 40%
brightnessctl -d amdgpu_bl0 set 400

Она показывает доступные устройства с их диапазонами, принимает проценты и абсолютные значения, а с флагом -d обращается к конкретному каналу. Полезные приёмы шире, чем кажется: set 10%+ и set 10%- меняют яркость шагом, --save запоминает текущее значение, --restore возвращает его, а с флагом -m вывод уходит в машиночитаемом виде для скриптов. Вторая замена это acpilight, соблюдающий совместимость: скрипт ставится как xbacklight и поддерживает те же флаги, но читает и пишет sysfs, поэтому работает даже там, где RandR-свойства нет. Отдельная утилита light годами служила третьим вариантом, но её разработка фактически остановилась, и в свежих дистрибутивах предпочтительнее brightnessctl.

Параметр ядра acpi_backlight и его значения

Когда в /sys/class/backlight появляется лишний канал, ручками вперёд выходит параметр ядра acpi_backlight. Значение native регистрирует только нативный интерфейс драйвера GPU, vendor оставляет лишь специфичный для производителя канал, video принудительно включает acpi_video, а none запрещает регистрацию любых интерфейсов подсветки. В новых ядрах есть и варианты video_detect_force_native и video_detect_force_vendor, которые не отключают остальные интерфейсы, а лишь меняют результат автоопределения.

Применение параметра укладывается в короткий порядок действий:

  1. открыть /etc/default/grub и дописать acpi_backlight=native в переменную GRUB_CMDLINE_LINUX_DEFAULT;
  2. обновить конфигурацию загрузчика: update-grub в Debian и Ubuntu, grub2-mkconfig -o /boot/grub2/grub.cfg в RHEL-семействе, grub-mkconfig -o /boot/grub/grub.cfg в Arch;
  3. перезагрузиться и убедиться, что параметр виден в выводе cat /proc/cmdline;
  4. проверить, что в /sys/class/backlight остался один рабочий каталог, например amdgpu_bl0 или intel_backlight;
  5. при неудаче повторить с video_detect_force_native или vendor, потому что часть прошивок врёт о своей поддержке нативного интерфейса.

Для загрузчиков кроме GRUB механика та же: в systemd-boot параметр дописывается в строку options файла записи в /boot/loader/entries, в конфигурациях с grubby или kernelstub меняется только инструмент пересборки. Диагностика выбора интерфейса уходит в dmesg: строки модуля acpi_video с упоминанием backlight показывают, что именно зарегистрировано и по какой причине.

Значения параметра стоит выбирать под сценарий. native выручает на современных ноутбуках, где BIOS отдал управление драйверу GPU. vendor нужен старым машинам, где панель физически слушает прошивка. video спасает, когда vendor-интерфейс сломан, а нативного нет. none используют для чистого эксперимента: если после него ни один каталог не появился, проблема глубже ACPI, и искать её стоит в драйвере GPU или в настройках прошивки. Важный нюанс после обновления до ядра 6.1 и новее: подсистему backlight переписали, и если яркость перестала регулироваться после обновления ядра, первым шагом стоит удалить старый параметр acpi_backlight из конфигурации загрузчика, а не добавлять новый. Нередко корректный выбор заработал бы сам без принуждения.

Права записи, udev-правила и работа без root

По умолчанию файл brightness принадлежит root с правами 0644, и это жёстко зашито в драйверах ядра. Привычные ключи GROUP= и MODE= в udev-правиле здесь не сработают: они управляют узлами в /dev, а у устройства подсветки узла нет, атрибут лежит в sysfs. Рабочая схема это правило с явным вызовом chgrp и chmod:

ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="intel_backlight", RUN+="/usr/bin/chgrp video /sys/class/backlight/intel_backlight/brightness", RUN+="/usr/bin/chmod g+w /sys/class/backlight/intel_backlight/brightness"

Файл сохраняется как /etc/udev/rules.d/90-backlight.rules, затем правила перечитываются и событие запускается вручную:

udevadm control --reload
udevadm trigger --subsystem-match=backlight --action=add

Пользователя добавляют в группу video командой usermod -aG video имя, после чего brightnessctl и acpilight пишут в brightness без sudo. Проверка занимает секунды: обычный пользователь из группы video выполняет brightnessctl set 5%+, и яркость меняется. Если команда всё ещё требует права, правило не сработало: чаще всего виновата опечатка в KERNEL== или забытый udevadm trigger после правки. Пакет acpilight кладёт готовое правило в систему сам, а brightnessctl в некоторых дистрибутивах предлагает установку с setuid-битом, что тоже снимает вопрос прав, хотя правило udev выглядит аккуратнее.

Сохранение яркости, горячие клавиши и особые случаи

Яркость переживает перезагрузку без сторонних скриптов: юнит systemd-backlight@.service сохраняет значение при выключении и восстанавливает при старте, отдельно для каждого устройства. Состояние конкретного экземпляра видно командой journalctl -u systemd-backlight@backlight:intel_backlight.service. Хранилище конкретно: файлы лежат в /var/lib/systemd/backlight, имя файла включает шину устройства и имя интерфейса, поэтому после замены материнской платы или переезда диска в другой ноутбук сохранённое значение теряется. В системах без systemd те же функции вручную дают brightnessctl --save в момент выключения и --restore при старте. Служба заодно защищает от нулевой яркости: минимальные значения ниже нескольких процентов ядро может поднимать при загрузке, чтобы экран не остался чёрным из-за кривой таблицы ACPI.

Горячие клавиши Fn работают по-разному. Часть прошивок меняет яркость сама до передачи управления системе, часть лишь отправляет события, которые окружение рабочего стола превращает в вызовы brightnessctl. Проверить, доходит ли событие, можно утилитой libinput debug-events или xev в X11: если событие есть, клавишу просто привязывают к команде set 10%+ в настройках клавиатуры, а если нет, проблему ищут на уровне ACPI и модулей вроде asus-nb-wmi на ноутбуках Asus. Ползунки окружения на свежих системах работают поверх того же sysfs: службы GNOME и KDE меняют яркость через сервисы управления питанием, поэтому на Wayland ползунок отвечает даже там, где xbacklight молчит.

Нестандартные случаи дают знать о себе по-своему. На ноутбуках Dell XPS отключение legacy-режима загрузки в UEFI ломало подсветку целиком, и лечилось возвратом настройки. На старых лэптопах с инвертированной шкалой помогает параметр модуля, прописанный в /etc/modprobe.d:

options i915 invert_brightness=1

При ранней загрузке модуля в initramfs конфигурацию пересобирают вместе с ним. Совсем древние платформы без ACPI и без нативного интерфейса управляются записью в регистр GPU через setpci, например setpci -s 00:02.0 F4.B=64 для старых Intel, но такое решение живёт в паре со скриптом, восстанавливающим значение после каждой загрузки. Экраны OLED вообще не имеют подсветки: ядро не может им помочь, яркость меняют композитор и цветовые таблицы на уровне сервисов окружения. Наконец, параметр nomodeset, которым часто гасят проблемы графики, на гибридных ноутбуках ломает регулировку яркости целиком, так что cmdline стоит проверять в первую очередь.

Рабочая связка для современного ноутбука выглядит так: нативный интерфейс amdgpu_bl0 или intel_backlight, brightnessctl для ручной регулировки, udev-правило для группы video и systemd-backlight для памяти между загрузками. xbacklight остаётся удобен в старых конфигурациях X11 с полным RandR-свойством, а параметр acpi_backlight выручает, когда прошивку невозможно починить иначе.