初代NUC、DC3217の表示が乱れてしまいました。2個あるHDMIのうちの片方が異常で、もう一方は正常です。WhateverGreen.kextで設定フラグを同一にしたら、両方とも正常になりました。
Table of Contents
症状
DC3217は最初に販売されたCore i搭載NUCで、Ivy Bridge Core i3-3217Uを搭載しています。GPUはIntel HD Graphics 4000です。こちらの構成です。
サーバ的に常時稼働させていて、必要な時は画面共有で接続していました。Clover r5108のアップグレードのためにディスプレイに接続したら、画面が乱れていることに気づきました。ログイン画面がこんな表示になります。横方向の画素数が正しく伝わっていない様子です。ロストテクノロジーのアナログテレビで例えると水平同期が取れていない感じかな。
いつからこうなったのか不明です。前回のClover r5107アップデートか、macOS 10.15.4へのアップデートあたりがきっかけかもしれません。また、このディスプレイはメインマシンで使っているのですが、最近起動直後に色がおかしいことがあります。NUCの問題ではなくディスプレイが不調で、設定情報EDIDがうまく送出できなくなっているのかもしれません。
ig-platform-idの決め方
ig-platform-idは0x01620005にしてあります。config.plistのDevices –> Propertiesセクションには、これのBse64値であるBQBiAQ==が設定してあり、WhateverGreen.kext (WEG)にこの値を伝えてあります。
<key>Devices</key> <dict> <key>Properties</key> <dict> <key>PciRoot(0x0)/Pci(0x2,0x0)</key> <dict> <key>AAPL,ig-platform-id</key> <data>BQBiAQ==</data> </dict> </dict> </dict>
どういう理由でig-platform-idを0x01620005にしたのか、もはや記憶がありません。多分、どこかでNUC DC3217の作例を見て、真似たのだと思います。最近、ig-platform-idのことを調べたので、今なら少し説明できるかと思います。
まずは、Intel HD Graphics 4000で使えそうなig-platform-idを探します。こちらのサイトによると、以下のIDが知られているようです。
- 0x01660000 (desktop, 4 connectors, 24 MB)
- 0x01620006 (desktop, 0 connectors, no fbmem, 0 bytes)
- 0x01620007 (desktop, 0 connectors, no fbmem, 0 bytes)
- 0x01620005 (desktop, 3 connectors, 16 MB)
- 0x01660001 (mobile, 4 connectors, 24 MB)
- 0x01660002 (mobile, 1 connectors, 24 MB)
- 0x01660008 (mobile, 3 connectors, 16 MB)
- 0x01660009 (mobile, 3 connectors, 16 MB)
- 0x01660003 (mobile, 4 connectors, 16 MB)
- 0x01660004 (mobile, 1 connectors, 16 MB)
- 0x0166000A (desktop, 3 connectors, 16 MB)
- 0x0166000B (desktop, 3 connectors, 16 MB)
ここでmobileと書かれたidは、一つのビデオ端子がLVDSになっています。LVDSというのは、LCDのためのインタフェースだそうです。ノートPCを使う場合はこれのどれかを使いますが、NUCもそうですが、デスクトップ構成ではLCDインタフェースは使わないので、desktopのidから選びます。また、端子が無い (0個の) idは、ヘッドレス構成、つまりiGPUにはディスプレイを接続しないで、PCIe接続のグラフィックスカードを使う場合に使います。なので、iGPUを外部ディスプレイに接続するNUCの構成では、desktopで端子ありのidを使うことになります。つまり以下のどれかです。
- 0x01660000 (desktop, 4 connectors, 24 MB)
- 0x01620005 (desktop, 3 connectors, 16 MB) (推奨)
- 0x0166000A (desktop, 3 connectors, 16 MB) (推奨、default, Macmini6,1)
- 0x0166000B (desktop, 3 connectors, 16 MB) (Macmini6,2)
上記のサイトでは、推奨idが0x0166000A (default), 0x01620005 であると書いています。またHackintool.appでは、0x0166000AがMacmini6,1、0x0166000BがMacmini6,2であると表示されます。おそらく、SMBIOSでそれぞれのMac miniのシステムIDを設定すると、何も指定しなければそれぞれ、0x0166000Aまたは0x0166000Bが選択されるのだと思います。
選択肢が4個だけなので、これを全部試してみました。その結果、DC3217では、0x01620005 だけが使えることがわかりました。それ以外の3個では、次のような症状になります:つまり、Cloverの起動ボリューム選択画面の後の林檎マーク表示で、進捗バーが止まります。-vモードで起動すると、文字表示がIOConsoleUsers: …というような表示場所で滞ります。でも、実は表示以外は起動していて、画面共有で接続すると機能しているようでした。
ig-platform-idに0x01620005を設定するには、config.plistのDevices–>Propertiesセクションに以下のように書きます。。
<key>Devices</key> <dict> <key>Properties</key> <dict> <key>PciRoot(0x0)/Pci(0x2,0x0)</key> <dict> <key>AAPL,ig-platform-id</key> <data>BQBiAQ==</data> </dict> </dict> </dict>
症状をもっと調べる
0x01620005を設定することで、長らく正しく表示できていたのですが、最初に述べたように、画面が乱れるようになりました。乱れていても、画面共有で接続すると正しく動いているようです。また、起動時にディスプレイを接続せず、起動した後で接続すると正しく表示されます。先に述べたように設定情報EDID関係なのかもしれません。
さらに、もっと興味深いことを発見しました。DC3217には、2個のHDMI端子がついています。以下、左(電源端子に近い方)をHDMI(1)、右(LAN端子に近い方)をHDMI(2)と呼びます。
画面が乱れる現象は、HDMI(2)で発生します。HDMI(1)を使えば、どのタイミングでディスプレイに接続しても、画面は乱れません。実はHaswell世代のNUC D545250でも、片方のHDMIの調子が悪いことがありました。今回も同じような現象のようです。ディスプレイは1台しか使っていませんので、HDMI(1)だけを使うことにすれば、とりあえず解決します。でも、最近はig-platform-id関連の設定に凝っているので、もう少しなんとかしたいと考えました。
HDMI端子のフラグ値を合わせる
Hackintool.appで0x01620005のコネクタ設定画面を見ました。3個のコネクタの設定があります。これがおそらく端子ごとのデフォルト設定なのだと思います。ここでのコネクタへの設定結果は、config.plistを生成する場合にそれぞれ上からcon0, con1, con2というコネクタ名で反映されます。なのでスクリーンショットにそのラベルを書き込んでおきました。
コネクタは3個ともDP端子になっています。実際にはDC3217には2個のHDMI端子があります。DPからHDMIへの変更は、この画面から設定できて、それを記述するconfig.plistのDevices –> Propertiesセクションも自動生成できます。ただ、どこかで読んだのですが、WEG(?)はDPからHDMIの変換を必要に応じてやってくれるらしく、デフォルトに任せておけば良いようです。
なので、DPであることはこのままで良いようなのですが、よく見ると3個のDPでFlagsの項目が違います。con0は0x00000011ですが、con1とcon2は0x00000107です。Flagsは、その下のリストにあるように、いろいろな設定を行うビットの集まりです。意味は不明ですし、さらにもともと機能が不明 (unknown) なフラグも多いようです。ということで、端子ごとに画面が乱れる・乱れないという振る舞いが違うことは、フラグが違うことにより引き起こされていると考えました。つまりHDMI(1)とHDMI(2)のどちらかが0x00000011で、もう一方は0x00000107になっていると考えられます。ちなみに0x00000011と0x00000107の違いは、いずれもunknownフラグが違うだけなので、違いの意味は不明です。
con1を調べる
まずはcon1を0x00000011に設定してみました。Flagsのカラムに数値を入力しても良いですし、下のConnector Flags:でクリックしても良いです。
この後、Patchタブを選び、Generate Patchボタンを押すと、config.plistが現れます。この時、Generalでは、DeviceProperties, Connectors, Graphic Devicesを選びます。またAdvancedとLSPCONは何も選択しません。コネクターの設定が現れ、かつ他の余分な設定が反映されないように調整すれば良いです。
ここで得られたパッチ部分を、config.plistのconfig.plistのDevices –> Propertiesセクションにコピーして、起動を試みました。この結果、何の変化もありませんでした。con1は、使われていないコネクターのようです。
con2を調べる
次にcon2に対しても、con1とおなじFlags設定、つまり0x00000011への設定を試みました。上で作ったconfig.plistの記述で、con1のframebuffer-con1-flagsの値を、framebuffer-con2-flagsにコピーします。これでcon0, con1, con2の全てのframebuffer-conX-flagsの設定が0x00000011 (Base64表記ではEQAAAA==) になりました。このconfig.plistで起動したところ、なんとHDMI(2)からの映像の乱れが治りました。以上の試みから、
- HDMI(1)はcon0である
- HDMI(2)はcon2である
- flagsを0x00000011にすれば画面が乱れない
ということがわかりました。
config.plistを整える
これでHDMI(1)もHDMI(2)もどちらも正常に動くconfig.plistが得られました。でもDevices –> Propertiesセクションの記述が煩雑に思います。コメントみたいな説明の項目は不要に思われます。とりあえずコメント風の設定を外すと以下になります。
<key>Devices</key> <dict> <key>Properties</key> <dict> <key>PciRoot(0x0)/Pci(0x2,0x0)</key> <dict> <key>AAPL,ig-platform-id</key> <data>BQBiAQ==</data> <key>framebuffer-con0-busid</key> <data>BQAAAA==</data> <key>framebuffer-con0-enable</key> <data>AQAAAA==</data> <key>framebuffer-con0-flags</key> <data>EQAAAA==</data> <key>framebuffer-con0-index</key> <data>AgAAAA==</data> <key>framebuffer-con0-pipe</key> <data>AAAAAA==</data> <key>framebuffer-con0-type</key> <data>AAQAAA==</data> <key>framebuffer-con1-busid</key> <data>BAAAAA==</data> <key>framebuffer-con1-enable</key> <data>AQAAAA==</data> <key>framebuffer-con1-flags</key> <data>EQAAAA==</data> <key>framebuffer-con1-index</key> <data>AwAAAA==</data> <key>framebuffer-con1-pipe</key> <data>AAAAAA==</data> <key>framebuffer-con1-type</key> <data>AAQAAA==</data> <key>framebuffer-con2-busid</key> <data>BgAAAA==</data> <key>framebuffer-con2-enable</key> <data>AQAAAA==</data> <key>framebuffer-con2-flags</key> <data>EQAAAA==</data> <key>framebuffer-con2-index</key> <data>BAAAAA==</data> <key>framebuffer-con2-pipe</key> <data>AAAAAA==</data> <key>framebuffer-con2-type</key> <data>AAQAAA==</data> <key>framebuffer-con3-busid</key> <data>AAAAAA==</data> <key>framebuffer-con3-enable</key> <data>AQAAAA==</data> <key>framebuffer-con3-flags</key> <data>QAAAAA==</data> <key>framebuffer-con3-index</key> <data>AAAAAA==</data> <key>framebuffer-con3-pipe</key> <data>AAAAAA==</data> <key>framebuffer-con3-type</key> <data>AQAAAA==</data> <key>framebuffer-patch-enable</key> <data>AQAAAA==</data> </dict> </dict> </dict>
変更したいのはcon2のflagsに関する設定だけで、あとはデフォルトで良いはずです。このconfig.plistは自動生成されたので、デフォルト値もそのまま書き込まれているようです。ということで、con2のflagsと、共通と思われる項目を除いて、以下のような記述にしました。これ以上、設定を削除すると画面乱れが復活します。なので、これがflagsを変更するための必要最小限の記述項目だと思われます。
<key>Devices</key> <dict> <key>Properties</key> <dict> <key>PciRoot(0x0)/Pci(0x2,0x0)</key> <dict> <key>AAPL,ig-platform-id</key> <data>BQBiAQ==</data> <key>framebuffer-con2-enable</key> <data>AQAAAA==</data> <key>framebuffer-con2-flags</key> <data>EQAAAA==</data> <key>framebuffer-patch-enable</key> <data>AQAAAA==</data> </dict> </dict> </dict>
config.plistの全文は以下に置いておきます。いつものように、シリアル番号は実機とコンフリクトしないことを確認してあります。このままで動作するはずですが、実際に使用する場合は、シリアル番号、UUIDを設定し直してください。
まとめ
初代NUCのDC3217の2個のHDMI端子のうち、片方の端子で画面の乱れが発生しました。Hackintool.appで調べてみると、端子ごとにフラグのデフォルト値が異なっていました。画面が乱れる端子のフラグを、正常に表示される端子のフラグと同じになるよう設定することで、画面が乱れなくなりました。
ディスプレイはどうせ1台しか使わないので、画面が乱れるHDMIポートを封印するだけでも良かったです。でも使わないポートでも、動くように設定できると気持ちが良いです。こういう作業が楽しいと感じられないと、hackintoshは面倒くさいだけかもしれないですね。