3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

任意の EDID を Linux Kernel に読み込ませる方法

Last updated at Posted at 2019-07-16

日本語の情報があまり見つからなかったので記載してみました。
以下のようなニッチなユースケースくらいしかないと思いますので、ほぼ自分用の備忘録になるかと。。。

(2022/2/10 追記)
このページは自分の備忘録以外に需要がないと思っていたのですが、
予想外なことに、実開発で困っている方がこのページに辿り着いたらしいということを聞きました。
情報も古くなっていますし、せっかくですので比較的新しい Kernelで再確認しました。

  • ディスプレイが部分的に壊れてEDIDが取得できない
  • 強制的に任意の解像度を指定したい
  • 仕事で開発中の評価ボード等で何か問題があって、ダミーのEDIDを読ませたい

ただし、Kernel v5.1.5 以前の環境では脆弱性が指摘されている(CVE-2019-12382)ので、
対策されていない環境での利用は推奨しません。

なお、2019/6/27 時点で Upstream Kernel (Linus のTree) の master ブランチには
対策パッチが入っていませんでしたが、
DRM Subsystem の drm-next ブランチには対策パッチが入っていましたので、
じきにマージされるはずですし、シンプルな修正の為、容易に Cherry-pick できると思います。
(2022/2/10 追記)
Linux Kernel v5.10.41 にはマージされていることを確認しました。

確認環境
  • Linux Kernel v4.14.75 ltsi
  • Linux Kernel v5.10.41 (2022/2/10 追記)

手順

1. menuconfig で CONFIG_DRM_LOAD_EDID_FIRMWARE を有効化してKernel Imageをビルドする

(ビルド手順はこちら)

$ make menuconfig

Linux Kernel v4.14.75 ltsi の場合

Symbol: DRM_LOAD_EDID_FIRMWARE [=y]
Type  : boolean
Prompt: Allow to specify an EDID data set instead of probing for it
 
Location:
   -> Device Drivers
      -> Graphics support
         -> Allow to specify an EDID data set instead of probing for it

(2022/2/10 追記) Linux Kernel v5.10.41 の場合

Symbol: DRM_LOAD_EDID_FIRMWARE [=y]
Type  : bool
Prompt: Allow to specify an EDID data set instead of probing for it
 
Location:
   -> Device Drivers
      -> Graphics support
         -> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)
            -> Allow to specify an EDID data set instead of probing for it

2. Linux Kernel に読み込ませる EDID のバイナリを作成する

CONFIG_DRM_LOAD_EDID_FIRMWARE が有効になると、以下の解像度については
Kernel Image に bulit-in で組み込まれるため、それ以外の解像度を指定したいときに
自分で EDID のバイナリを指定することになります。

  • 800x600
  • 1024x768
  • 1280x1024
  • 1600x1200
  • 1680x1050
  • 1920x1080

作り方については Documentation/EDID/HOWTO.txt もご参照ください。
(2022/2/10 追記)
Kernel v5.7以降は Documentation/admin-guide/edid.rst に変更になりました。

$ cd ${WORK}/${KERNEL_TREE}/Documentation/EDID/
$ cp 1024x768.S WIDTHxHEIGHT.S
$ vi WIDTHxHEIGHT.S
$ make

作成したバイナリの中身については以下のコマンドで確認できます。

$ edid-decode WIDTHxHEIGHT.bin
例 (クリックすると展開されます)
$ edid-decode 1920x1080.bin
1罹2x袰$YJ% PT兩:q8-@X,E・inux #0=BD
      鑅inux FHD
   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:
  1920x1080@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
Monitor ranges (GTF): 59-61Hz V, 66-68kHz H, max dotclock 150MHz
Monitor name: Linux
Checksum: 0x5 (valid)
EDID block does NOT conform to EDID 1.3!
        Detailed block string not properly terminated
 

また、PC や 評価ボード側に問題があって EDID が取得できない場合には
別の PC とディスプレイを取得して、 PC がディスプレイから取得した EDID を
そのままバイナリ化しても良いと思います。

$ find /sys/devices/ -name edid
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1/card1-HDMI-A-2/edid
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1/card1-DVI-D-1/edid
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1/card1-DVI-I-1/edid
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1/card1-DP-1/edid
/sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-HDMI-A-1/edid
/sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-VGA-1/edid
$ cat /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1/card1-DP-1/edid > DISPLAY.bin

3. 作成したバイナリを Rootfs にコピーする

$ sudo cp WIDTHxHEIGHT.bin ${ROOTFS}/lib/firmaware/edid/WIDTHxHEIGHT.bin

4. Kernel の bootargs に "drm_kms_helper.edid_firmware" を追加する

例:

drm_kms_helper.edid_firmware=edid/WIDTHxHEIGHT.bin

前述していますが、以下の指定をした場合には EDID が built-in されていますので、
Rootfs にバイナリが無くても動作します。

  • drm_kms_helper.edid_firmware=800x600.bin
  • drm_kms_helper.edid_firmware=1024x768.bin
  • drm_kms_helper.edid_firmware=1280x1024.bin
  • drm_kms_helper.edid_firmware=1600x1200.bin
  • drm_kms_helper.edid_firmware=1680x1050.bin
  • drm_kms_helper.edid_firmware=1920x1080.bin

(2022/2/10 追記)
Kernel v5.10.41 では "drm_kms_helper.edid_firmware" ではなく、"drm.edid_firmware"になるようです。

built-in されるバイナリについては "drivers/gpu/drm/drm_edid_load.c" 内の
"static const char * const generic_edid_name[]" で列挙されています。

制限事項 ? マルチディスプレイ環境

シングルディスプレイの場合には問題ありませんが、
マルチディスプレイ環境で "drm_kms_helper.edid_firmware" を指定してしまうと
全てのディスプレイが指定した EDID を使用してしまうようで、
1つのディスプレイだけ設定したい、ということが出来ないようです。
(仕様なのか私の環境固有の問題なのかは未調査です)
(2022/2/10 追記)
改めて確認したところ、Kernel の bootargs に "drm_kms_helper.edid_firmware (drm.edid_firmware)" を追加する際に
以下のように"connector"を指定することで、ディスプレイ毎にEDIDを指定できるようです。
Documentation/admin-guide/kernel-parameters.txt に記載がありました。

drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]

例 (Linux Kernel v5.10.41 の場合):

drm.edid_firmware=HDMI-A-1:edid/1280x1024.bin,HDMI-A-2:edid/1920x1080.bin
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?