手元のデスクトップ環境をLinuxに切り替えました。2009年頃からmacOS(当時はMac OS X)を使っていたけど、QEMUやFUSEを不自由なく使える方がPlan 9との相性が良いので、Linuxの方がいいかなと思ったのでした。
やったこと
MacBook10,1 (Retina, 12-inch, 2017)にArch Linuxをインストールしました。このハードウェアではネットワークなど一通り使えていますが、バージョンによっては使えないケースもあるようです。MacBook Proの対応状況はState of Linux on the MacBook Pro 2016 & 2017にまとまっていますが、MacBookのものは無いので、近いハードウェアから推測する必要があります。
バックアップを取得
事前にMacBookのバックアップを取得しましょう。Time Machineがいちばんお手軽ですし、Linuxにデータを渡すことも考えるならexFATなディスクにコピーしておくと便利です。
また、macOSのインストーラを用意しておくと、困った場合に安心です。Mac App StoreからOSインストーラをダウンロードすると/Applicationsにインストーラが作られるので、以下のコマンドを実行します。
% sudo /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/createinstallmedia --volume /Volumes/Mobile
詳細は、公式ドキュメントのmacOS の起動可能なインストーラを作成する方法を参照してください。
Arch Linuxインストーラを準備
Arch Linuxのイメージをダウンロードから探して、USB インストールメディアの「BIOS・UEFI ブータブル USB」に書かれている手順を実行します。
% diskutil unmountDisk /dev/diskX
% sudo dd if=archlinux-2021-04-01-x86_64.iso of=/dev/rdiskX bs=1M
余談ですがこのISOイメージは、ddコマンドを使ってそのままUSBメモリに書き込むだけで使えるように作られています。xorrisoとUEFIブート再び[その1]に詳細が書かれているけれどハック感があって面白いです。
インストール
上で作ったUSBメモリからインストーラを起動して、セットアップしていきます。事前に以下のドキュメントを読んでおくといいでしょう。
MacBook Proのインストール事例だけどこれも参考になりました。
インストーラを起動するとすぐにプロンプトが表示されるので必要なコマンドを入力していけばいいのですが、MacBookの場合はどうやら画面の下数行*1が見切れてしまっているようで、コマンド入力や結果の確認が困難です。なのでカーソルが画面の中央あたりまで到達したときは、次のコマンドを入力する前にCtrl+Lやclearなどでカーソルを1行目に戻してから入力すると安全です。
まずインターネットへ接続するためWi-Fiの設定をします。ドキュメントはIwdです。この設定はインストーラにおけるネットワークの設定で、再起動すると消えてしまうので、後でもう一度、同じ設定が必要です。
# iwctl [iwd]# device list wlan0 dc:a9:04:xx:xx:xx on phy0 station [iwd]# station dc:a9:04:xx:xx:xx scan [iwd]# station dc:a9:04:xx:xx:xx get-networks [iwd]# station dc:a9:04:xx:xx:xx connect SSID [iwd]# exit
時刻合わせです。これも再起動すると消えるので、後でもう一度設定します。
# timedatectl set-ntp true
準備ができたらパーティションを分割していきます。GPTで管理するので、fdiskではなくgdiskを使います。分割自体は好みでレイアウトすればいいのですが、最初のEFIパーティションはsystemd-bootで利用するのでそのまま残しておきます。手元では、Linux用のパーティションは特に分割などせず、1つだけ作りました。また、スワップファイルの方が便利そうなので、swapパーティションは作りませんでした。
# gdisk /dev/nvme0n1 ...
パーティションの用意ができたら、インストール先となるパーティションを/mntにマウントします。
# mkfs.ext4 /dev/nvme0n1p2 # mount /dev/nvme0n1p2 /mnt
そのまま必須パッケージを/mntにインストールします。
# pacstrap /mnt base linux linux-firmware
/etc/fstabを更新します。
# genfstab -U /mnt >>/mnt/etc/fstab
ブートローダはsystemd-bootを使うので、EFIパーティションを/mnt/bootにマウントしてからarch-chrootします。
# mount /dev/nvme0n1p1 /mnt/boot # arch-chroot /mnt
systemd-boot
ブートローダの選択肢はいくつかありますが、Arch Linuxのドキュメントに、MacBookではいちばん簡単な方法と書かれていたのでsystemd-bootを使いました。ドキュメントはsystemd-bootです。
ここでマイクロコードも一緒にロードしておきましょう。12インチMacBookはIntelのCPUなので、パッケージはintel-ucodeです。
# pacman -S systemd-boot intel-ucode # bootctl --path=/boot install
設定ファイルを2つ作ります。/boot/loader/entries/arch.confはカーネルや/となるパーティションを設定するものです。UUIDの値は、blkidコマンドで/dev/nvme0n1p2の値を調べました。
title Arch Linux linux /vmlinuz-linux initrd /intel-ucode.img initrd /initramfs-linux.img options root=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e rw
ブートしたいカーネルが複数あるなら、このファイルを必要なだけ作ります。次に、ローダ自体の設定です。これは/boot/loader/loader.confに書きます。
default arch timeout 3 console-mode max editor no
正しく設定ができていれば、bootctlコマンドで設定した内容を読めるはずです。
# bootctl list Boot Loader Entries: title: Arch Linux (default) id: arch.conf source: /boot/loader/entries/arch.conf linux: /vmlinuz-linux initrd: /intel-ucode.img /initramfs-linux.img options: root=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e rw (この時点では、インストーラのエントリがいくつかあるけど再起動すると消える)
ネットワークの設定
上で行ったネットワークの設定をもう一度実施します。こちらは再起動した後で使われるものです。インストーラと異なり、ブート後の環境にはまだiwdパッケージがインストールされていないので、ここで追加しておきます。
# pacman -S iwd
設定自体は上のものと同じですが、以下のコマンドを使うと1行で行なえます。
# iwctl station wlan0 connect <SSID>
SSIDごとに、設定は/var/lib/iwd/<SSID>.<enc>へ保存されます。あとは、ホスト名の設定と、ブート時の再接続を入れておきましょう。
/etc/hostname
linux-pc
/etc/systemd/network/20-wlan0.network
[Match] Name=wlan0 [Network] DHCP=ipv4
コマンドはこのような。
# systemctl enable iwd.service # systemctl enable systemd-networkd.service # systemctl enable systemd-resolved.service # networkctl list
時間の設定
NTPとタイムゾーンの設定です。
# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime # hwclock --systohc # timedatectl set-ntp true # timedatectl status
言語の追加
en_US.UTF-8とja_JP.UTF-8を追加します。
# echo 'en_US.UTF-8 UTF-8' >>/etc/locale.gen # echo 'ja_JP.UTF-8 UTF-8' >>/etc/locale.gen # locale-gen
これ以降、/etc/locale.confにLANGを設定すると日本語化されますが、フォントがない状態でされても文字が読めなくて困るだけなので、これは後で設定します。
rootのパスワード
設定しておきます。
# passwd
systemd-homed
ホームディレクトリの管理もsystemd-homedを使うようにしました。ドキュメントはsystemd-homedです。ついでにviとsudoも入れておきます。
# systemctl enable systemd-homed.service # homectl create lufia # pacman -S vi sudo # visudo # gpasswd -a lufia wheel
vimパッケージもありますが、簡単なテキストの編集にしか使わないのでviパッケージで十分でした。
スワップファイルの追加
swapパーティションを作らなかったので、ここでスワップファイルを設定します。ドキュメントはスワップです。
# fallocate -l 512M /swapfile # chmod 600 /swapfile # mkswap /swapfile # swapon /swapfile
/etc/fstabにエントリを追加。
/swapfile none swap defaults 0 0
デスクトップ環境
Waylandを使おうとしているので、色々と面倒が少なそうなGNOMEをインストールしました。
# pacman -S gnome # systemctl enable gdm # pacman -S noto-fonts noto-fonts-cjk
これで特に何もしなくても、再起動すればGNOMEのセッションマネージャが使えます。ログイン後に環境変数XDG_SESSION_TYPEをみると、WaylandかX11のどちらが使われているかを調べられます。XDG_SESSION_TYPEがx11の場合、セッションマネージャの右下にある設定ボタンからGNOMEを選んでログインするとwaylandに変わります。
ディスプレイの設定
RetinaディスプレイはHiDPIディスプレイとも呼ばれるようです。GNOMEでは、デフォルトでサイズ調整は200%と設定されていたと思いますが、好みに応じてGNOMEの設定アプリから変更しましょう。
言語の設定
上で言語の追加をしましたが、グラフィックスを使えるようになったので、必要ならここで切り替えます。
# echo 'LANG=ja_JP.UTF-8' >/etc/locale.conf
スリープでD3coldへ遷移させない
12インチMacBookでは、D3coldへ遷移すると、うまく復帰できない問題があるそうです。実際に試したところ、スリープから復帰したログイン画面でパスワードを入力しても、先へ進むことができませんでした。そのため、D3coldへの遷移を止めます。
d3cold_allowedファイルへ0を書き込むことで無効となりますが、再起動するたびに入力するのは面倒なので、systemdを使って自動化します。まずはユニットファイルを/etc/systemd/system/d3cold-disable.serviceに作りました。
[Unit] Description=Disables sleep from stopping nvme hardware on MacBook [Service] ExecStart=/sbin/d3cold 0 Type=oneshot RemainAftrExit=yes [Install] WantedBy=multi-user.target
ExecStart=で実行しているコマンドは以下の内容です。
#!/bin/bash v=${1:-0} echo $v > /sys/bus/pci/devices/'0000:01:00.0'/d3cold_allowed
これを有効にします。
$ sudo chmod +x /sbin/d3cold $ sudo systemctl enable d3cold-disable.service
サーマルスロットリング
12インチMacBookはファンレスなこともあり、Go自身のコンパイルをしていると突然スリープに落ちたりします。それでは困るので、thermald.serviceを有効にします。
# pacman -S thermald # systemctl enable thermald.service
CPU 周波数スケーリングによると、他にも便利なものはあるようですが、今のところ特には困っていないのでいいかな。
/sys/devices/system/cpu/cpu?/cpufreq/scaling_governorを読むと、どのgovernorがセットされているか調べられますし、/sys/class/thermal/cooling_device?/typeでデバイスの種類が分かります。
$ grep . /sys/devices/system/cpu/cpu?/cpufreq/scaling_governor /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:powersave /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor:powersave /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor:powersave /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor:powersave $ grep . /sys/class/thermal/cooling_device?/type /sys/class/thermal/cooling_device0/type:Processor /sys/class/thermal/cooling_device1/type:Processor /sys/class/thermal/cooling_device2/type:Processor /sys/class/thermal/cooling_device3/type:Processor /sys/class/thermal/cooling_device4/type:intel_powerclamp /sys/class/thermal/cooling_device5/type:LCD
CPUクロックや温度はlscpuと/sys/class/thermal/thermal_zone?/tempで読めます。tempファイルの値は、33300は33.3℃のようです。
$ lscpu | grep 'CPU MHz' CPU MHz: 2084.082 $ grep . /sys/class/thermal/thermal_zone?/temp /sys/class/thermal/thermal_zone0/temp:33300 /sys/class/thermal/thermal_zone1/temp:43000
再起動
ここで再起動します。ログイン画面が表示されたら、さきほど作成した一般ユーザーでログインしましょう。
ログイン後は主に個人環境に対する設定を行います。
CapsLockをControlにする
実現方法はいくつかありますが、GNOMEの設定で対応しました。もともとlv3:ralt_switch
が含まれていたので、そこに追記した形です。
$ gsettings set org.gnome.desktop.input-sources xkb-options "['lv3:ralt_switch', 'ctrl:nocaps']"
サウンドの設定
MacBookでは追加のドライバが必要です。このドライバのインストールスクリプトではsymlinksコマンドが必要なので、先にAURからインストールしておきます。
$ git clone https://aur.archlinux.org/symlinks.git $ cd symlinks $ sudo pacman -S fakeroot $ makepkg -si
GitHubから12インチMacBook用のドライバをインストールします。
$ git clone https://github.com/leifliddy/macbook12-audio-driver.git
$ cd macbook12-audio-driver
$ sudo ./install.cirrus.driver.sh
MacBook Pro用のドライバもありますが、こちらは12インチMacBookでは認識しませんでした。
Bluetoothの設定
12インチMacBook用のBluetoothドライバです。インストール方法はサウンドの時と同じ。
$ git clone https://github.com/leifliddy/macbook12-bluetooth-driver.git
$ cd macbook12-bluetooth-driver
$ sudo ./install.bluetooth.sh
手元にはBluetoothキーボードとトラックパッドがあるので、それぞれ接続しました。ドキュメントはBluetoothにあります。
$ sudo pacman -S bluez bluez-utils $ sudo systemctl enable bluetooth $ bluetoothctl [bluetooth] agent on [bluetooth] scan on [bluetooth] devices [bluetooth] pair 00:00:00:00:00:00 [agent] PIN code: xxxxxx Pairing successful [bluetooth] connect 00:00:00:00:00:00 Connection successful [bluetooth] pair 11:11:11:11:11:11 Pairing successful [bluetooth] connect 11:11:11:11:11:11 Connection successful
再起動した後に自動接続されるように、/etc/bluetooth/main.confへ設定をしておきます。
[Policy] AutoEnable=true
外部ディスプレイを繋いでいるときはスリープしない
クラムシェルとかリッドクローズドと呼ばれているものです。/etc/systemd/logind.confを以下のように変更しました。とはいえ、GNOMEによって電源管理されているようなので、この設定がどの程度有効かは分かりません。
--- /etc/systemd/logind.orig 2021-03-29 22:36:55.053860982 +0900 +++ /etc/systemd/logind.conf 2021-03-29 22:56:55.439920429 +0900 @@ -24,8 +24,8 @@ #HandleSuspendKey=suspend #HandleHibernateKey=hibernate #HandleLidSwitch=suspend -#HandleLidSwitchExternalPower=suspend -#HandleLidSwitchDocked=ignore +HandleLidSwitchExternalPower=suspend +HandleLidSwitchDocked=ignore #HandleRebootKey=reboot #PowerKeyIgnoreInhibited=no #SuspendKeyIgnoreInhibited=no
トラックパッド
Waylandではlibinputが動作していて、トラックパッドを接続した後は特に何も設定する必要はありませんでしたが、タップでクリックなどいくつか変更しています。ここは完全に好みです。
$ gsettings list-recursively org.gnome.desktop.peripherals.touchpad org.gnome.desktop.peripherals.touchpad tap-button-map 'default' org.gnome.desktop.peripherals.touchpad click-method 'fingers' org.gnome.desktop.peripherals.touchpad edge-scrolling-enabled false org.gnome.desktop.peripherals.touchpad disable-while-typing true org.gnome.desktop.peripherals.touchpad two-finger-scrolling-enabled true org.gnome.desktop.peripherals.touchpad send-events 'enabled' org.gnome.desktop.peripherals.touchpad speed 0.0 org.gnome.desktop.peripherals.touchpad tap-and-drag true org.gnome.desktop.peripherals.touchpad natural-scroll true org.gnome.desktop.peripherals.touchpad middle-click-emulation false org.gnome.desktop.peripherals.touchpad left-handed 'mouse' org.gnome.desktop.peripherals.touchpad tap-to-click true org.gnome.desktop.peripherals.touchpad tap-and-drag-lock true
日本語入力
一般的に、IBusまたはFcitxのうちどちらかと、MozcまたはSKKのどちらかを組み合わせて使うことになると思います。Linuxのかな漢字変換の興亡でSKKが勧められていたので、ここではibus-skkを使うようにします。Mozcの方が簡単だろうけれど、どのみちPlan 9ではSKKを使うことになるし、合わせておくのもいいかなと思ったのでした。
$ sudo pacman -S ibus-skk skk-jisyo
Waylandを使っているので、IBusを使うための環境変数を~/.pam_environmentに追加します。
GTK_IM_MODULE DEFAULT=ibus XMODIFIERS DEFAULT=@im=ibus QT_IM_MODULE DEFAULT=ibus
また、SKKのキーボードレイアウトは日本語配列になっているので、/usr/share/ibus/component/skk.xmlのlayoutを変更します。
--- /usr/share/ibus/component/skk.orig 2021-03-21 00:03:32.931254445 +0900 +++ /usr/share/ibus/component/skk.xml 2021-03-21 20:26:27.483580937 +0900 @@ -17,7 +17,7 @@ <license>GPL</license> <author>Daiki Ueno <ueno@unixuser.org></author> <icon>/usr/share/ibus-skk/icons/ibus-skk.svg</icon> - <layout>ja</layout> + <layout>us</layout> <longname>SKK</longname> <description>SKK Input Method</description> <rank>70</rank>
せっかくなので追加の辞書を入れました。
$ git clone https://github.com/tokuhirom/jawiki-kana-kanji-dict.git
$ cd jawiki-kana-kanji-dict
$ echo ';; -*- coding: utf-8 -*-' >~/.config/ibus-skk/SKK-JISHO.jawiki
$ cat SKK-JISHO.jawiki >>~/.config/ibus-skk/SKK-JISHO.jawiki
あとは、ibus-setupの「入力メソッド」にSKKを追加して、そこへSKK-JISHO.jawikiの辞書も追加すれば終わりです。ただし、SKK-JISHO.jawikiは必ずシステム辞書として追加しましょう。ユーザー辞書として追加しても動作はしますが、候補を確定するときすべてのユーザー辞書へ更新が行なわれるらしく、確定する度に2、3秒待たされることになります。
$ ibus-setup
今の設定はこんな雰囲気。
- ~/.config/ibus-skk/user.dict (ユーザー辞書)
- /usr/share/skk/SKK-JISHO.L (システム辞書)
- ~/.config/ibus-skk/SKK-JISHO.jawiki (システム辞書)
- localhost:1178 (サーバ)
参考情報
Firefox
Firefoxを使っているので、言語パックも一緒にインストールします。
$ sudo pacman -S firefox firefox-i18n-ja
標準ではCtrl+H
キーに履歴の表示をトグルするショートカットキーが割り当てられていますが、個人的にはCtrl+H
をバックスペースとして使うのでとてもイライラするので変更します。対応するための方法はいくつかありますが、GNOME側でキーテーマをEmacs風なものに変更すると、FirefoxでもCtrl+H
でバックスペースを入力できるようになります。
$ gsettings set org.gnome.desktop.interface gtk-key-theme 'Emacs'
これで、Ctrl+A
で行頭にカーソルを移動させられたりなど好みの挙動になりました。それぞれのキーに何が割り当てられているかは、/usr/share/themes/Emacs/gtk-3.0/gtk-keys.cssを読むとなんとなく分かると思います。
ターミナル
FirefoxはCtrl+C
でコピーするけどターミナルではCtrl+Shift+C
でコピーするのは、どちらかに統一したいですね。ターミナルはCtrl+C
で割り込みを発生させるので難しいかなと思っていたけれど割り込みはCtrl+Alt+C
でも起こせたので、以下のコマンドでキーマップを変更しました。
$ gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ copy '<Control>c' $ gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ paste '<Control>v'
これで、どのアプリでも、Ctrl+C
でコピーしてCtrl+V
で貼り付けができる。
クリップボード
クリップボードにはPRIMARY*2とCLIPBOARDの2種類あるようで、テキストを選択してマウスの中ボタンで扱うような暗黙的なコピーはPRIMARYを参照して、明示的にコピーをする動作はCLIPBOARDを参照するようです。日本語版のWikiより英語版の方が詳しいのでClipboardのSelectionを読みましょう。GNOMEのPrimary Selectionにも色々と書かれています。
Waylandでコマンドラインからクリップボードを操作するためにwl-clipboardを入れておきます。
$ sudo pacman -S wl-clipboard
別件で、最後に選択したテキストがマウスの中ボタンでペーストされてしまうのは誤操作の原因になるので止めてしまいます。
$ gsettings set org.gnome.desktop.interface gtk-enable-primary-paste false
Firefoxは別の設定になるようです。about:configのmiddlemouse.pasteをfalseに切り替えます。
バックアップ
rsyncでコピーする方法がRsync によるフルシステムバックアップで紹介されていますが、rsyncは転送先でそのままファイルとして扱えるため便利ではあるものの、転送先のファイルシステムがPOSIX準拠でない場合に色々な問題が発生するのであまり使いたくはありません*3。なのでBorg Backupを使ってみることにしました。exFATでフォーマットされているMOBILEディスクにbackupsディレクトリを作成して、それをBorgのリポジトリにします。borg init -e repokey
で暗号化しています。また、紛失しないようにリポジトリの鍵をエクスポートして保管しておきます。
$ sudo pacman -S borg $ borg init -e repokey /run/media/lufia/MOBILE/backups $ borg key export /run/media/lufia/MOBILE/backups repo.key
上では手元のディスクを使いましたが、Google Cloudを使っているならCloud Storage FUSEの方が便利かもしれません。
$ git clone https://aur.archlinux.org/gcsfuse.git
$ cd gcsfuse
$ sudo pacman -S fakeroot # なければ入れる
$ makepkg -si
これで後はバックアップを作成するだけです。毎回コマンドを組み立てるのは面倒なので以下のスクリプトを書きました。
#!/bin/bash set -eu if [[ $# -ne 1 ]] then echo usage: $(basename $0) repo >&2 exit 1 fi h=$(hostnamectl --static) d=$(date +%Y-%m%d) sudo borg create --progress "$1::$h-$d" / --exclude-from ~/lib/borg.exclude
コピーする必要のないファイルもあるので、borg.excludeはシステムメンテナンスを参考にこのような内容です。
/dev/* /proc/* /sys/* /tmp/* /run/* /mnt/* /media/* /lost+found /var/run/* /swapfile /home/*.home /home/*/.cache /home/*/.local/share/Trash/* /home/*/Downloads/*
ところで、systemd-homedを使っていると、/home/$user.homeに大きなファイルが作られています。これはホームディレクトリのLUKSイメージらしく、ユーザーがログインするなどでアクティベートされると/home/$userにマウントされます*4。このイメージは、手元では300GBほどあって、毎回のバックアップで対象とするには大きく時間がかかります。上のスクリプトではどうせ一人しか使わないので、必ずホームディレクトリはマウントされているものとして扱うことにしました。ちなみにアクティベートされたユーザはhomectl list
すると分かりますし、homectl activate
でアクティベートするようです。
$ homectl list NAME UID GID STATE REALNAME HOME SHELL lufia 60331 60331 active lufia /home/lufia /bin/bash 1 home areas listed.
参考情報
- 圧縮、暗号化、リモート対応の差分バックアップを作成できる「Borg Backup」の使い方
- Data structures and file formats
- 2020年はsystemd-homedの登場でLinuxのユーザー管理が大きく変わるぞ
感想など
トラックパッドに慣性スクロールが欲しいなど、まだ気になるところはありますが、これならデスクトップ環境として使えると思えるところまで設定しました。購入して電源を入れるだけで快適に使えるmacOSはすごいなと思うものの、一度設定してしまえばLinuxでもそんなに困らないはずだし、癖や好みの話でもあるので、しばらくこのままLinuxデスクトップで生活してみる予定です。
*1:10行程度?
*2:SECONDARYもあるらしい
*3:symlinkの未サポートやファイル名のcase-insensitiveなど
*4:イメージの種類によりファイル名の末尾が.homedirなどに変わる