笔记本电脑显示器和 HDMI 显示器上的 initramfs 中的启动分辨率更改

笔记本电脑显示器和 HDMI 显示器上的 initramfs 中的启动分辨率更改

我的笔记本电脑上有 Linux Mint 17。我还使用 HDMI 电缆将 22 英寸显示器连接到笔记本电脑。我的磁盘已使用 LUKS 和 LVM 完全加密。启动时,我收到图形提示,要求输入加密分区的密码。要求输入密码时,笔记本电脑和外接显示器上的屏幕分辨率都是错误的。图形提示和 linux mint 徽标移至两台显示器的左上角,其余空间为黑色。只有在我登录我的个人资料后,分辨率才是正确的。这是xrandr我登录时显示的内容:

Screen 0: minimum 320 x 200, current 3286 x 1080, maximum 32767 x 32767
LVDS1 connected 1366x768+1920+312 (normal left inverted right x axis y axis) 344mm x 194mm
   1366x768       60.1*+   40.1
   1360x768       59.8     60.0
   1024x768       60.0
   800x600        60.3     56.2
   640x480        59.9
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 531mm x 298mm
   1920x1080      60.0*+
   1680x1050      59.9
   1600x900       60.0
   1280x1024      75.0     60.0
   1280x800       59.9
   1152x864       75.0
   1280x720       60.0
   1024x768       75.1     60.0
   832x624        74.6
   800x600        75.0     60.3
   640x480        75.0     60.0
   720x400        70.1
DP1 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

安装加密磁盘后,我可以使用xrandr命令更改显示器上的分辨率。但该命令在initramfs.

我最近正在使用initramfs脚本修复另一台笔记本电脑启动时的屏幕亮度,并且它有效。该脚本通过将正确值回显到 to 来设置亮度/sys/class/backlight/acpi_video0/brightness。我还可以使用类似的东西以某种方式改变屏幕分辨率吗?

更新

我尝试过@mikeserv解决方案:

  1. 来自显示器的 EDID 文件(不确定它们是否正确):

    # cat /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/edid > /lib/firmware/edid/1366x768.bin
    # cat /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-HDMI-A-1/edid > /lib/firmware/edid/1920x1080.bin
    
    # hexdump /lib/firmware/edid/1366x768.bin
    0000000 ff00 ffff ffff 00ff e430 033b 0000 0000
    0000010 1600 0401 2290 7813 610a 9ed5 5b5e 269a
    0000020 501a 0054 0000 0101 0101 0101 0101 0101
    0000030 0101 0101 0101 1de2 b456 0050 3038 3024
    0000040 0035 c258 0010 1900 13ec c656 0050 302e
    0000050 3024 0035 c258 0010 1900 0000 fe00 3500
    0000060 4833 3935 3180 3635 4857 0a34 0000 0000
    0000070 0000 3141 0096 0000 0100 0a01 2020 ac00
    0000080
    
    # hexdump /lib/firmware/edid/1920x1080.bin 
    0000000 ff00 ffff ffff 00ff d109 78a5 5445 0000
    0000010 1626 0301 3580 781e b72e a4d5 5456 279f
    0000020 500c a554 806b 0081 c081 8081 c0a9 00b3
    0000030 c0d1 0101 0101 3a02 1880 3871 402d 2c58
    0000040 0045 2a13 0021 1e00 0000 ff00 4c00 4339
    0000050 3030 3537 3039 3931 200a 0000 fd00 3200
    0000060 1e4c 1153 0a00 2020 2020 2020 0000 fc00
    0000070 4200 6e65 2051 4c47 3432 3035 200a d900
    0000080
    
  2. initramfs 的挂钩脚本,加载i915模块并将EDID文件包含到/lib/firmware/edid/内部目录中initramfs(我已经检查过并且EDID文件位于 initramfs 内)

    # cat /etc/initramfs-tools/hooks/include-edid-data 
    #!/bin/sh
    
    PREREQ="udev"
    prereqs()
    {
       echo "$PREREQ"
    }
    
    case $1 in
    prereqs)
       prereqs
       exit 0
       ;;
    esac
    
    . /usr/share/initramfs-tools/hook-functions
    # Begin real processing below this line
    
    if [ ! -e "${DESTDIR}/lib/firmware/edid" ]; then
        mkdir -p "${DESTDIR}/lib/firmware/edid"
    fi
    
    if [ -r "/lib/firmware/edid/1366x768.bin" ]; then
       cp "/lib/firmware/edid/1366x768.bin" "${DESTDIR}/lib/firmware/edid/"
    fi
    
    if [ -r "/lib/firmware/edid/1920x1080.bin" ]; then
       cp "/lib/firmware/edid/1920x1080.bin" "${DESTDIR}/lib/firmware/edid/"
    fi
    
    manual_add_modules i915
    
    exit 0
    
    # chmod a+rx /etc/initramfs-tools/hooks/include-edid-data
    # update-initramfs -u
    
  3. 重新启动时,我添加了启动参数(不确定它应该是 HDMI-1 还是 HDMI1 还是其他参数)

    drm_kms_helper.edid_firmware=HDMI1:/lib/firmware/edid/1920x1080.bin
    
  4. 它没有改变任何东西。所以我也尝试过:

    drm_kms_helper.edid_firmware=HDMI-1:/lib/firmware/edid/1920x1080.bin
    drm_kms_helper.edid_firmware=HDMI1:edid/1920x1080.bin
    drm_kms_helper.edid_firmware=HDMI-1:edid/1920x1080.bin
    

一点运气都没有。一切都和我从上面迈出脚步之前一样。

我还想补充一点,当 HDMI 显示器 ID 断开连接时,笔记本电脑显示器上的分辨率是正确的。

我究竟做错了什么?

更新2

还是行不通。我采取的步骤:

  1. 找到我的显示器的正确名称:

    $ for p in /sys/class/drm/*/status; do if [ "$(cat "$p")" == "connected" ]; then echo -n "$p" | awk -F '/' '{print $5}'; fi; done
    card0-HDMI-A-1
    card0-LVDS-1
    
  2. 安装linux-doc(获取描述自定义创建的文档EDIDdos2unixmake(用于编译EDID文件)包

    $ sudo apt-get install linux-doc dos2unix make
    
  3. 创建编译临时目录并复制源文件EDID

    $ mkdir ~/Tmp/edid
    $ cd ~/Tmp/edid
    $ cp /usr/share/doc/linux-doc/EDID/* .
    $ rm *.S
    $ cp /usr/share/doc/linux-doc/EDID/1920x1080.S .
    $ cp /usr/share/doc/linux-doc/EDID/1920x1080.S 1366x768.S
    
  4. 编辑文件1366x768.S正确价值观,编译,复制到/lib/firmware/edid

    • 获取我的笔记本电脑屏幕的当前工作模式

      $ xvidtune -show
      "1366x768"     76.50   1366 1402 1450 1546    768  771  776  824 -hsync -vsync
      

      它们依次是:resolution, clock MHz, hdisp, hsyncstart, hsyncend, htotal, vdisp, vsyncstart, vsyncend,vtotal

    • 计算值:

      CLOCK = 76500
      XPIX    = hdisp                               = 1366
      XBLANK  = htotal - hdisp        = 1546 - 1366 = 180
      XOFFSET = hsyncstart - hdisp    = 1402 - 1366 = 36
      XPULSE  = hsyncend - hsyncstart = 1450 - 1402 = 48
      
      YPIX    = vdisp = 768
      YBLANK  = vtotal - vdisp             = 824 - 768      = 56
      YOFFSET = 63 + vsyncstart - vdisp    = 63 + 771 - 768 = 66
      YPULSE  = 63 + vsyncend - vsyncstart = 63 + 776 - 771 = 68
      
      TIMING_NAME "Linux HDR"
      CRC 0xcd
      
    • 最终版本1366x768.S

      $ cat 1366x768.S
      /* EDID */
      #define VERSION 1
      #define REVISION 3
      
      /* Display */
      #define CLOCK 76500 /* kHz */
      #define XPIX 1366
      #define YPIX 768
      #define XY_RATIO XY_RATIO_16_9
      #define XBLANK 180
      #define YBLANK 56
      #define XOFFSET 36
      #define XPULSE 48
      #define YOFFSET 66
      #define YPULSE 68
      #define DPI 96
      #define VFREQ 60 /* Hz */
      #define TIMING_NAME "Linux HDR"
      #define ESTABLISHED_TIMINGS_BITS 0x00 /* none */
      #define HSYNC_POL 1
      #define VSYNC_POL 1
      #define CRC 0xcd
      
      #include "edid.S"
      
    • 编译文件并使用edid-decode( sudo apt-get install edid-decode) 检查是否没有错误:

      $ make clean && make
      rm 1920x1080.o 1366x768.o
      
      $ ls -1 *.bin
      1366x768.bin
      1920x1080.bin
      
      $ edid-decode 1366x768.bin
      Extracted contents:
      header:          00 ff ff ff ff ff ff 00
      serial number:   31 d8 00 00 00 00 00 00 05 16
      version:         01 03
      basic params:    6d 23 14 78 ea
      chroma info:     5e c0 a4 59 4a 98 25 20 50 54
      established:     00 00 00
      standard:        8b c0 01 01 01 01 01 01 01 01 01 01 01 01 01 01
      descriptor 1:    e2 1d 56 b4 50 00 38 30 24 30 35 00 63 c8 10 00 00 1e
      descriptor 2:    00 00 00 ff 00 4c 69 6e 75 78 20 23 30 0a 20 20 20 20
      descriptor 3:    00 00 00 fd 00 3b 3d 30 32 08 00 0a 20 20 20 20 20 20
      descriptor 4:    00 00 00 fc 00 4c 69 6e 75 78 20 48 44 52 0a 20 20 20
      extensions:      00
      checksum:        cd
      
      Manufacturer: LNX Model 0 Serial Number 0
      Made week 5 of 2012
      EDID version: 1.3
      Analog display, Input voltage level: 0.7/0.7 V
      Sync: Separate Composite Serration 
      Maximum image size: 35 cm x 20 cm
      Gamma: 2.20
      DPMS levels: Standby Suspend Off
      RGB color display
      First detailed timing is preferred timing
      Established timings supported:
      Standard timings supported:
        1360x816@60Hz
      Detailed mode: Clock 76.500 MHz, 355 mm x 200 mm
                     1366 1402 1450 1546 hborder 0
                      768  771  776  824 vborder 0
                     +hsync +vsync
      Serial number: Linux #0
          Monitor ranges: 59-61HZ vertical, 48-50kHz horizontal, max dotclock 80MHz
      Monitor name: Linux HDR
         Checksum: 0xcd
      
      $ edid-decode 1920x1080.bin
      Extracted contents:
      header:          00 ff ff ff ff ff ff 00
      serial number:   31 d8 00 00 00 00 00 00 05 16
      version:         01 03
      basic params:    6d 32 1c 78 ea
      chroma info:     5e c0 a4 59 4a 98 25 20 50 54
      established:     00 00 00
      standard:        d1 c0 01 01 01 01 01 01 01 01 01 01 01 01 01 01
      descriptor 1:    02 3a 80 18 71 38 2d 40 58 2c 45 00 f4 19 11 00 00 1e
      descriptor 2:    00 00 00 ff 00 4c 69 6e 75 78 20 23 30 0a 20 20 20 20
      descriptor 3:    00 00 00 fd 00 3b 3d 42 44 0f 00 0a 20 20 20 20 20 20
      descriptor 4:    00 00 00 fc 00 4c 69 6e 75 78 20 46 48 44 0a 20 20 20
      extensions:      00
      checksum:        05
      
      Manufacturer: LNX Model 0 Serial Number 0
      Made week 5 of 2012
      EDID version: 1.3
      Analog display, Input voltage level: 0.7/0.7 V
      Sync: Separate Composite Serration 
      Maximum image size: 50 cm x 28 cm
      Gamma: 2.20
      DPMS levels: Standby Suspend Off
      RGB color display
      First detailed timing is preferred timing
      Established timings supported:
      Standard timings supported:
        1920x1152@60Hz
      Detailed mode: Clock 148.500 MHz, 500 mm x 281 mm
                     1920 2008 2052 2200 hborder 0
                     1080 1084 1089 1125 vborder 0
                     +hsync +vsync
      Serial number: Linux #0
          Monitor ranges: 59-61HZ vertical, 66-68kHz horizontal, max dotclock 150MHz
      Monitor name: Linux FHD
         Checksum: 0x5
      
    • 将文件复制到/lib/firmware/edid

      $ sudo cp *.bin /lib/firmware/edid
      
  5. 更新initramfs,钩子脚本应该添加 edid 文件(它们在那里,我已经检查过)

    $ sudo update-initramfs -u
    
  6. 启动时,编辑 grub 命令行(在启动时按 Shift 键显示 grub 菜单,然后按e):

    linux   /vmlinuz-3.13.0-24-generic root=/dev/mapper/mint--vg-root ro   quiet splash $vt_handoff
    

    linux   /vmlinuz-3.13.0-24-generic root=/dev/mapper/mint--vg-root ro   quiet splash $vt_handoff drm_kms_helper.edid_firmware=card0-LVDS-1:/lib/firmware/edid/1366x768.bin drm_kms_helper.edid_firmware=card0-HDMI-A-1:/lib/firmware/edid/1920x1080.bin
    

我也尝试过将其设置为仅适用于一台显示器。但一点运气都没有。我开始认为这不是分辨率的问题,而是普利茅斯图像本身的问题。当我看到启动图像时,它没有模糊、拉伸或任何其他情况,并且 Linux mint 徽标清晰锐利。它比我的屏幕小一点,放置在我的笔记本电脑和 HDMI 屏幕的左上角。

我发现了这个错误这与我的问题非常相似。所以我想我必须等待他们解决这个问题。

答案1

您的显示器使用称为 EDID 的数字标准提供有关其自身的信息。内核在检测到显示设备时读取此信息,并自动配置其显示以尽可能匹配显示设备的显示本国的解决。事实上,LCD 设备只能支持一种分辨率 - 它们的分辨率本国的分辨率 - 和仿真所有其他人。从维基百科:

扩展显示识别数据(EDID)是数字显示器提供的一种数据结构,用于向视频源(例如显卡或机顶盒)描述其功能。它使现代个人计算机能够知道连接到它的显示器类型。 EDID 由视频电子标准协会 (VESA) 发布的标准定义。 EDID 包括制造商名称和序列号、产品类型、磷光体或滤光片类型、显示器支持的时序、显示器尺寸、亮度数据和(仅适用于数字显示器)像素映射数据。

这样做的问题是,通常所提供的EDID错误的或以某种方式损坏 - 这通常是由于制造商懒惰或误导,必须将该信息编程到设备的固件中。它甚至可能是由于 HDMI 线损坏造成的,但这种情况的可能性要小得多,因为数字电缆是很多更有可能根本不起作用。但还有其他可能性,如果您使用 KMS,您可能会发现这很有趣:

如今,随着内核模式设置的出现,图形板要么可以正常工作,因为所有组件都遵循标准,要么计算机无法使用,因为屏幕在启动后保持黑暗或显示错误的区域。发生这种情况的情况有:

  • 显卡无法识别显示器。

  • 显卡无法检测到任何 EDID 数据。

  • 图形板错误地将 EDID 数据转发到驱动程序。

  • 显示器不发送或发送虚假 EDID 数据。

  • KVM 发送自己的 EDID 数据,而不是查询连接的显示器。

添加内核参数“nomodeset”在大多数情况下会有所帮助,但会在以后造成限制。

Δ那个Δ摘自kernel.org 自己的 HOWTO.txt对于 KMS EDID。该文本文件位于同一文件夹作为五个标准分辨率 EDID,您可以在启动时通过内核参数和 initramfs 提供内核,以便绕过显示器提供的 EDID。

如果您使用的是开源显示驱动程序之一,则您正在使用内核模式设置,并且可以使用已经提到的五个 KMS EDID 分辨率旁路预设中的任何一个。或者,您可以完全提供自己的 EDID 文件,内核将使用该文件来代替显示设备提供的信息。

本节Arch Linux wiki 的更多信息,但可能这个 AskUbuntu 线程会更好地针对您的发行版。

如果您不使用 KMS,而是使用 nvidia 或 AMD 闭源驱动程序,那么据我所知,您可靠处理启动时分辨率的机会几乎为零。可以在grub或其他引导加载程序中配置这些任何 initramfs 映像都会被安装,但这样做以后在启动时干扰闭源驱动程序自己的分辨率配置的可能性X非常高。如果你是非常幸运的是,您的主板制造商在 UEFI 固件中为您提供了一个用于配置启动时间分辨率的设置,您甚至可以在grub加载任何辅助启动加载程序之前对其进行设置。不过,我个人从未见过如此幸运的人。

相关内容