0%

Linux重启机器后亮度无法恢复的问题

Linux重启机器后亮度无法恢复的问题

背景

使用Ubuntu已经好些年头了,一直都有启动机器后无法恢复亮度的问题。之前大多是使用台式电脑,基本无需解决,调整到最大亮度后,直接设置显示器,调整到合适的亮度就不再管了。现在换用了笔记本,这种策略不再好用。两方面, 一是笔记本内置显示器不带单独的配置,无法在外部调整亮度。二是笔记本的使用场景不固定,客厅,卧室,阳台等,场景不同受到的环境光照影响也就不同,一直不调节亮度这种就很难受了,遂决定解决。

问题

问题描述

环境: Ubuntu20.04 kenal 5.11+, Gnome3 硬件: cpu amd4700U 核心显卡,无板载和独立显示芯片。其他硬件对此问题无影响。

亮度调节:菜单调节显示器亮度有效,可以正确调整亮度。但是每次重新开机后,亮度都会被设置成最大值。菜单划条位置显示在1%左右的位置。调节后,实际亮度与菜单划条一致。(说的可能不是很明确,就是每次稍微一调节,就会导致亮度忽然变很暗,因为亮度划条的位置几乎初始在最暗的位置上)

日志内容

使用journalctl查看日志内容:

1
journalctl -b0 -p4

得到输出如下, 无关内容已经被删除。

1
2
3
4
5
6
7
8
9
2月 04 18:22:47 redmi-book kernel: acpi PNP0C14:01: duplicate WMI GUID 05901221-D566-11D1-B2F0-00A0C9062910 (first instance was on PNP0C14:00)
2月 04 18:22:48 redmi-book kernel: amdgpu 0000:03:00.0: Direct firmware load for amdgpu/renoir_ta.bin failed with error -2
2月 04 18:22:48 redmi-book kernel: ath10k_pci 0000:01:00.0: failed to fetch board data for bus=pci,vendor=168c,device=003e,subsystem-vendor=11ad,subsystem-device=0847 from ath10k/QCA6174/hw3.0/board-2.bin
2月 04 18:22:49 redmi-book systemd-backlight[627]: Failed to get backlight or LED device 'backlight:acpi_video0': No such device
2月 04 18:22:49 redmi-book systemd[1]: systemd-backlight@backlight:acpi_video0.service: Failed with result 'exit-code'.
2月 04 18:22:49 redmi-book systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:acpi_video0.
2月 04 18:22:49 redmi-book systemd-backlight[630]: amdgpu_bl0: Failed to write system 'brightness' attribute: No such device or address
2月 04 18:22:49 redmi-book systemd[1]: systemd-backlight@backlight:amdgpu_bl0.service: Failed with result 'exit-code'.
2月 04 18:22:49 redmi-book systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:amdgpu_bl0.

从日志来看,背光亮度相关的日志内容有两条:

  1. acpi_video0 无法找到。
  2. amdgpu_bl0 无法找到。

分析

针对上面日志提到的内容,我查看ls /sys/class/backlight/。发现其中仅有一个文件夹,它是amdgpu_bl0, 根本没有acpi_video0。所以,对于第一个报错日志来说,确实正确反馈了这个情况。那么针对此条,本文方案1进行了修复,可以达到修复的目的。

但是,对于日志第二条,明显对应不上,我这里确实是有这个设备的,它应该正确的工作才是。

解决方案

针对现象的有效解决方案有两个,他们有各自的问题。后面就逐个说明一下。

方案1

原理

针对第一条日志内容,从中看来,服务尝试使用acpi_video0来设定亮度,然而我的机器上没有这个。看起来acpi应该是某个规范或者是总线类型,先搞清楚它是什么。阅读了 acpi介绍以后,发现它是os和硬件中间的一层抽象,那么没有它的话,可能是我机器就没有启用acpi,或者没有给他配置。那么问题就简单了,我们添加和检查一下配置就是了。

操作

添加内核参数 acpi_backlight=video 在/etc/default/grub文件中,GRUB_CMDLINE_LINUX_DEFAULT条目后添加内和参数acpi_backlight=video保存。 重新生成grub配置,并更新。

1
grub-mkconfig -o /boot/grub/grub.cfg

重启。

修复情况

重启后观察,可以正确恢复关机前的亮度了,且日志中报错的信息消除了。

副作用

但是,dmesg 日志内容中多出了一条无法识别显卡型号的日志,我不确定此时是否使用了正确的显卡驱动(或者全特性支持的驱动)。从视频测试上来看,播放youtube2k分辨率的视频,cpu占用率大概在20%-30%之前浮动。之前应该是在15%-20%浮动,看起来,这么做了之后多少还是影响了显示性能的。没有其他明显副作用。

方案2

原理

一开始我是懵逼的,于是我按照日志李的服务手动start了一下,竟然发现它成功了,而且没有任何报错,而且成功设置了亮度。于此时,我几乎可以肯定是这个服务的启动时机有问题了,也许这个服务被执行的时候,amdgpu的显卡驱动或者什么的还没有初始化好,所以导致了失败,那么,把时机往后延一下,应该就能解决问题了。

操作

  1. /etc/systemd/system/目录下,创建一个新的systemctl unit, 我把它命名为 backlight-restore.service, 当然,这里名字不重要。

  2. 编辑unit内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [Unit]
    Description=Dummy service for attempting to start the problematic amdgpu_bl0 service

    [Service]
    Type=simple
    ExecStart=systemctl start systemd-backlight@backlight:amdgpu_bl0

    [Install]
    WantedBy=multi-user.target

    实际上这个服务就是在机器启动后再次调用恢复亮度的服务而已,只是它的时机比较晚。

  3. 启动这个service sudo systemctl start backlight-restore.service

  4. 检查这个service的启动输出和状态 sudo systemctl status backlight-restore.service

  5. 没问题了的话,就设置为自启动 sudo systemctl enable backlight-restore.service

  6. 重启机器 sudo reboot

修复情况

重启后发现,亮度可以正常恢复了。但是之前的日志报错还是在(预期中)。

副作用

暂未发现有什么副作用。

其他方案

当然还有其他几个方案。

其中包括

1.编辑内核模块文件,内核启动时加载amdgpu模块。但此方案在内核升级时就需要再操作一次,ubuntu也经常更新内核,所以我不采取。 2.网上流行的一种非主流做法,编辑rc.local文件,跳过系统机制,在启动后手动 往亮度文件中写值。但是rc.local已经被标记为废弃了,不再是标准内容说不准哪个版本就给作废了呢,也不采取。

遗留问题

以上两种方案多多少少都有些问题,方案1会降低一些gpu性能,自然也就降低了一些续航,我个人对电池续航非常看重,所以不推荐方案1. 方案2采用事后补偿的方式,虽然解决了问题,但是启动前阶段并没有接入,所以报错的日志依然会出现。

总结

我个人使用了方案2,暂时还不错。