SSブログ

ヘッドレスでのX11サーバ [Raspberry Pi]

先日のRaspberry Pi 4Bをセットアップしてて、うまく行かないことがあった。raspbian標準のvncサーバを起動して、macOSから接続しようとした。ところがPi側でX11サーバがエラーで立ち上がらない。他所様のサイトをみて、/etc/X11/xorg.confを設定したり書き換えたりしたけど症状が変わらない。

どうしようもなくなってから、しかたなく/var/log/X.0.logを真面目に読んだ。
(EE) no screens found(EE)
で終わってた。デバイスドライバの記述を変えたりしても基本的には同じで、何かの拍子に違うエラーメッセージが残った。/dev/fb0というデバイスファイル(フレームバッファの0番目という名前だろうな)を経由してスクリーンを制御しているらしい(スクリーンというのはXサーバが表示先とみなす独立した個々のディスプレイデバイスを仮想化したもの。Xプロトコルは必ずネットワークを経由するので、リモートでも表示できるが、そういう仮想化のレベルを包含した名前で、40年以上前からそうなってる)。その/dev/fb0がない、と言っている。/devの中を探すと確かになかった.....

どうやら、HDMIへ表示しようとすると、接続した時にEDIDという信号をやりとりして接続されたモニタの解像度やリフレッシュレートを知るようになっているらしい。昔のアナログVGA時代に空いたピンを経由してI2Cでディスプレイのデータを渡していたけど、その伝だろう。それでどんなディスプレイがつながっているか知って、それに対応するドライバをロードしてEDIDに従った設定をして/dev/fb0を作るようである。

つまりヘッドレス、すなわちモニタキーボードマウスなしでXサーバを立ち上げようとしても出力用のHDMIディスプレイがないので、デバイスファイルが作られない、デバイスファイルがないのでXサーバには出力先の情報がわからない、ということだった。まあ、あたりまえといえばあたりまえ。

さらにX11サーバにはやることがいっぱいあって、歴史的な理由もあっていろんなところでいろんな設定をするようになっている(らしい。僕がX windowシステムを使い出したX10は簡単だった。40年以上も前の話。ディスプレイはたとえネットワーク上に離れていても、最終的には必ずCPUのメモリ上にマップされていて、OSが初めからディスプレイを知ってる前提でXサーバは書かれていた。みんな知ってるか、X11の前はマジでX10だったんだぞ。いや、昔話はもういい。今では全部把握しようとすると大変な作業になる)。

しかし今ではVNCというヘッドレスでも使える手段があるので、Xサーバもハードウェアデバイスだけを相手にしているのではなく、それに対応しないといけないはずである(いや、40年前からXにとってヘッドレスはあった。でもXサーバ本体はローカルに、つまりハードウェアデバイスを持つOS上のプロセスとして動作するのが前提だった。ああ、ややこしい)。調べてると、そういう場合にむりやりデバイスファイルを作るにはブートのときにそういう設定をすればいいということがわかった。ここに詳しく書いてある。具体的には/boot/config.txtに
hdmi_force_hotplug=1
hdmi_ignore_edid=0xa5000080
hdmi_group=1
hdmi_mode=4
などと書いておけば、これに従った/dev/fb0が作られて、Xサーバはスクリーンを知ることができて、ヘッドレスでも立ち上がる。hdmi_force_hotplug=1がキモで、HDMIがつながっていなくてもHDMIに強制的に出力するというフラグ(ソフトウエァ的にHDMIの19ピンが生きていると見せかけるということだろう)。いや、たぶんHDMIとそのEDIDをフックしてるだけだろうけど、みんなちゃんとしてて偉いなあ。

そして解像度はhdmi_groupとhdmi_modeの組み合わせで設定できる。さっきのページの真ん中辺の大きな表に書いてある。hdmi_ignore_edidの変な16進定数はEDIDを無視するための定数らしい。なんで'yes'、'no'じゃないんだろ。他にもいっぱいあるけど、残りはデフォルトでよさそうである。まだぽろぽろエラーメッセージはでるけどきっと効率の問題かなにかだろう(やっぱり読んでない)。

これまで何台もPi 3BやPi zeroを設定してきたけどこういうトラブルはまったくなかった。どれもディスプレイを繋いだことはほぼない(どうしても立ち上がらない時にブートメッセージを見るために繋いだくらい)。これまでどうなってたんだろ。すっぴんインストールしたstretch以前とbusterとで違ってたのかもしれない。

ところで、この解決はRaspbian特有かもしれない。いくつかx86_64のDebianを動かしてるけど、どれもssh以外使わないのでよくわからない。

ネットを見ると似たような問題や全く同じエラーメッセージで困ってる人がいっぱいいて、親切な人たちがいろいろ教えてくれている。中には「僕んところではこれで動くよ」なんていうのもけっこうあった。 今回の僕の場合、そういったネット情報はまったく役に立たなかった。ネットを徘徊してはxorg.confをいじりまわして半日以上潰してしまった。エラーメッセージって何を言ってるんだか全然わからん、なんてこともあってあまり真面目に読まない癖がついていたけど、さっさとちゃんと読めばよかった(いや、読めよ)。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Raspberry Pi 4B Benc.."Go To"キャンペーン ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。