MacBook (Retina, 12-inch, 2017) にArchLinuxを導入する過程
Overview
つまづきメモ, 基本的なインストラクション, etc.
インストール前にやっておくといいこと
- 必要なら起動時のサウンド(ドゥーーーーーーン)をミュートにする
(Arch側でこれをdisableする方法がわかっていない) - ディスプレイのEDIDを取得し、バイナリに起こしておく
ioreg -lw0 -r -c "IODisplayConnect" -d 2 | grep IODisplayEDID
で取得できるので、適当に切り出してバイナリ化する (参考: stackoverflow)
ちゃんと抜き出せているか確認したいなら、timvideos/edid-decodeをビルドしてファイルごと渡せばOK
インストール時に困ったこと
- インストール
- 基本的に公式のインストラクションに則れば問題ないと思う, 今回は躊躇なくmacOSごと吹き飛ばしてインストールした(ブートローダにはGRUBを採用)
- macOSを吹き飛ばした後にmacの環境が欲しくなってしまった場合は、起動時に ⌘+R してネットワーク復元を実行すれば(めちゃくちゃ限られた範囲で)使える
今回はディスプレイのEDIDを取ってこられなかったのでここでioreg
を叩いた - ターミナルの右と下が切れる(ディスプレイの表示領域をはみ出てしまう) ←後述
応急処置:stty cols 144 rows 45
- ネットワーク周り
-
iwctl
はarch-chroot
環境だと動かせないので、インストール時にiwd
を入れてから再起動して設定すればよい - 設定後
systemd-resolved
をenableするのを忘れないこと (名前解決ができなくてハマる)
-
- パッケージ周り
- インストールメディアが古いと
(package) is corrupted
みたいなエラーでコケることがある(インストール中何度か遭遇)
署名鍵の問題っぽい?pacman -Syu archlinux-keyring
してあげれば通った
- インストールメディアが古いと
解決できていないこと
- ディスプレイの解像度がおかしい
-
公式の仕様を見る限り、ディスプレイの物理的な解像度は
2304x1440
スケーリング可能な解像度として1440x900
,1280x800
,1024x640
が提示されている - しかし
fbset
を叩くと2560x1600
が返る -
edid-decode
に通すとこんなことを言い出す:曰く% cat macbook_edid.bin | ./edid-decode/edid-decode EDID version: 1.4 Manufacturer: APP Model a027 Serial Number 0 Made in week 27 of 2015 Digital display 8 bits per primary color channel DisplayPort interface Maximum image size: 26 cm x 16 cm Gamma: 2.20 Supported color formats: RGB 4:4:4 Display x,y Chromaticity: Red: 0.6533, 0.3339 Green: 0.2998, 0.6201 Blue: 0.1464, 0.0498 White: 0.3125, 0.3291 Established timings supported: Standard timings supported: Detailed mode: Clock 262.500 MHz, 259 mm x 162 mm 2560 2592 2624 2659 hborder 0 1600 1603 1609 1646 vborder 0 +hsync -vsync VertFreq: 59 Hz, HorFreq: 98721 Hz Detailed mode: Clock 218.750 MHz, 259 mm x 162 mm 2304 2352 2384 2464 hborder 0 1440 1443 1449 1481 vborder 0 +hsync -vsync VertFreq: 59 Hz, HorFreq: 88778 Hz Detailed mode: Clock 328.000 MHz, 259 mm x 162 mm 2880 2908 2936 2964 hborder 0 1800 1803 1809 1845 vborder 0 +hsync -vsync VertFreq: 59 Hz, HorFreq: 110661 Hz Monitor name: Color LCD Checksum: 0x34 (valid)
2560x1440
,2304x1440
,2880x1800
をサポートしてまっせ!とのこと
いやでもキミHW的に2304px以上表示できなくない?
-
公式の仕様を見る限り、ディスプレイの物理的な解像度は
何も考えずにインストールすると全てが狂い出す
-
fbset
は2560x1600
-
neofetch
は2304x1440
もう全てがめちゃくちゃ
tput cols lines
は 160x50
が返るけど、ディスプレイをはみ出さないギリギリのコンソールサイズは 144x45
くらい
デフォルトフォント(多分default8x16.psfu.gz
)の縦横比が2:1であることを考えると、160x50
は 160x100
、144x45
は144x90
となり、アス比はいずれも 16:10
gcd(160, 144) = 16, 16×144 = 2304 であることから、単純にフレームバッファの左上から表示できる部分を描画しているだけになっている可能性が高い
例えば dmesg --color=always | less -R
してしばらくだーっと流してから、cat /dev/fb0 > fb.bin
してフレームバッファの画像を見るとこんな感じ:
表示範囲外にもちゃんと書き込まれてるけど、実際にディスプレイに表示されるのは赤枠の領域だけ!
これどうするんだマジで
整理
-
物理的な解像度は
2304x1440
である (参考: MacBook(Retina,12-inch,2017) 技術仕様)- OS的に対応できる解像度は
1440x900
,1280x800
(デフォルト),1024x640
の三種類
- OS的に対応できる解像度は
-
macOSの
ioreg
で取得すると、2560x1600
,2304x1440
,2800x1800
が返る- HWの解像度より大きな値, 最初のものはMacBook Proと同じサイズ
- Retinaの横幅1280pxは実際には2560pxなので、横幅2304pxの液晶にそのまま表示することは物理的に不可能なはず
- 余談だが、
2304x1440
=2560x1600
× 0.9
-
パッケージread-edidの
get-edid
の出力をparse-edid
に通すと、2304x1440
のみが返る-
ioreg
で渡した時のものとは異なるバイナリが返ってくるようす (参考: 実際の実行結果) - macOS側でEDIDをオーバライドしている可能性がある?
-
-
起動時にGRUB Terminalに入り
videoinfo
すると、2560x1600
が返る- なんで?
-
fbsetの
vxres
,vyres
はそれぞれ2560, 1600となっている- 上書きできない (
fbset -vxres 2304
とかやっても効かない) -
xres
,yres
は上書きできる
- 上書きできない (
GPUのデフォの解像度がそれなのでは?と思ったけど、その記載はちょっと見つからなかった
(参考: Intel m3-7Y32)
皮肉にも nomodeset
をカーネルパラメータに追加すると全てがうまくいくんだよな…
解像度問題
ttyの右と下が見切れてしまう現象が発生する。これは(直接的には)フレームバッファの解像度とディスプレイの解像度が合っていないためと考えられる。
インストール後の(特段の設定をしていない)状態では、フレームバッファ/dev/fb0
の解像度は 2560x1600 となっている:
# fbset
mode "2560x1600"
geometry 2560 1600 2560 1600 32
timings 0 0 0 0 0 0 0
rgba 8/16,8/8,8/0,0/0
endmode
一方、接続されているディスプレイのモードを読み出すと2304x1440が返る(余談だが、 neofetch
はこちらの値を参照している):
# cat /sys/class/drm/*/modes
2304x1440
MacBook Retina 12inch, 2017に搭載されているディスプレイの(物理的な)解像度は 2304x1440 である[1]ため、後者の値が正確(?)だと思われる。
しかしフレームバッファのサイズはディスプレイのそれよりも大きくなってしまっている。これが原因で上記のような現象が発生する。
macOSだとどうなのか
このモデルでは、macOSは 1440x900
, 1280x800
(デフォルト), 1024x640
の三種類の解像度に対応している。Retinaディスプレイなので実際の解像度はそれぞれ4倍となり、例えば 1280x800
は実際には2560x1600
となる…はずである。しかし実際のディスプレイの横幅は2304pxであり、2560pxを表示できる領域はどこにもない。
素人の勝手な妄想だが、2560x1600
でレンダリングしたものを90%に縮小しているのかもしれない(2560×0.9=2304, 1600×0.9=1440)…? 実際の描画としては1280x800
を180%に拡大している(1280×1.8=2304, 800×1.8=1440)ことになるのだろうか?
応急処置
ターミナルのサイズ(行数/列数)は stty
で変更できる[2]ため、stty cols 144 rows 45
とすればとりあえず見切れることはなくなる。しかしフレームバッファ自体のサイズは変わっていないため、/dev/fb0
から画像データを起こすと画面右部および下部に余白が生じる。
対応策: 1. fbsetでフレームバッファのサイズを変更する
fbset
でフレームバッファのサイズを変更しようとしたものの、virtual resolution, 仮想解像度 (vxres, vyres)は変更されなかった。fbset -match
も機能せず。
# fbset -g 2304 1440 2304 1440 32
# fbset
mode "2304x1440"
geometry 2304 1440 2560 1600 32
timings 0 0 0 0 0 0 0
rgba 8/16,8/8,8/0,0/0
endmode
実行後に setterm --resize
すると stty size
が 144 45
を返すようになったので、「画面に表示できる領域は2304x1440
である」と教えることはできていそう。ただし内部的にフレームバッファのサイズが変わったわけではないため、/dev/fb0
を画像に変換すると相変わらず右と下に余白が生じてしまう。
nomodeset
を追加する
対応策: 2. カーネルパラメータに かなり本末転倒だが、そもそもKMSを使わないという方法がある:
# nomodesetを追加する
GRUB_CMDLINE_LINUX_DEFAULT="nomodeset loglevel=3 quiet"
これを適用して起動すると、まるで最初から2560x1600のディスプレイがつながっているかのような動作を示す。
# fbset
mode "2560x1600"
geometry 2560 1600 2560 1600 32
timings 0 0 0 0 0 0 0
rgba 8/16,8/8,8/0,0/0
endmode
# cat /sys/class/drm/*/modes
2560x1600
そもそもディスプレイの認識が異なっている:
# ll /sys/class/drm
total 0
drwxr-xr-x 2 root 0 Mar 22 14:40 .
drwxr-xr-x 71 root 0 Mar 22 14:40 ..
lrwxrwxrwx 1 root 0 Mar 22 14:35 card0 -> ../../devices/platform/simple-framebuffer.0/drm/card0
lrwxrwxrwx 1 root 0 Mar 22 14:35 card0-Unknown-1 -> ../../devices/platform/simple-framebuffer.0/drm/card0/card0-Unknown-1
-r--r--r-- 1 root 4.0K Mar 22 14:40 version
# ll /sys/class/drm
total 0
drwxr-xr-x 2 root 0 Mar 22 14:46 .
drwxr-xr-x 71 root 0 Mar 22 14:46 ..
lrwxrwxrwx 1 root 0 Mar 22 14:46 card1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1
lrwxrwxrwx 1 root 0 Mar 22 14:46 card1-DP-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-1
lrwxrwxrwx 1 root 0 Mar 22 14:46 card1-eDP-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-eDP-1
lrwxrwxrwx 1 root 0 Mar 22 14:46 card1-HDMI-A-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-HDMI-A-1
lrwxrwxrwx 1 root 0 Mar 22 14:46 renderD128 -> ../../devices/pci0000:00/0000:00:02.0/drm/renderD128
-r--r--r-- 1 root 4.0K Mar 22 14:46 version
フレームバッファからスクリーンショットを取得しても余白が生じることはなく、また実際に表示されている内容も見切れることはない。なんとも不可思議な状態を再現できる。
抜き出してきたEDIDファイルを配置したところ表示が完全に崩れた(同期が狂ってるような感じ、表示が左上に揺れていく)
KMSの早期開始 が有効になってるので、EDIDファイルはinitramfsに組み込んでいる
KMS自体を遅延させてみるのもひとつアリかもしれない?
ダメでした 症状変わらず
i915.modeset=0
でGUIセットアップしてみて問題なく動くようならこれでいく i915がRetinaをうまく処理できてないんじゃないかなという仮説
現状KDE Plasmaが正常に動いています…うーん…これでいいっちゃいいのかなあ…
まった!!i915有効にするとクソ速い!!
Plasmaのパフォーマンスが段違いだ やっぱり無理してたのかあれは