#はじめに
SRA Advent Calendarの2日目です。
ネットワークシステムサービス第1事業部の ふじまき です。
昨年のネタのアップデートです。 変更点は
- MacBook自身のキーボード、トラックパッドが使用可能になったのでUSB接続キーボード、マウスを用意する必要がなくなりました。
- MacBook Pro Late 2016 のタッチバーのドライバが含まれています。私は持っていませんが、LinuxではデフォルトでESCおよび各種ファンクションキーが表示されるらしいです。
MacBook Proの2016年モデルについては以下にまとまっています。
https://github.com/Dunedan/mbp-2016-linux
#注意事項
冒頭に書いた変更点以外は昨年と同じです。
無線LANの問題はMacBook Pro Late 2016にも存在&Pro無しよりも重症らしいです。
#インストーラーのカスタマイズ作業環境の準備
##Ubuntu Mate 17.10のインストール
適当なマシン(無論、MacBook 2016年モデル以外)にUbuntu Mate 17.10 desktopをインストールします。
仮想の場合、ディスク容量は50GBくらい必要です。
ちなみに、フレーバー固有の部分は無いので、本家Ubuntu 17.10 desktopでも手順は同じです。
##追加パッケージのインストール
最初にsshサーバを入れて、sshログイン経由で作業出来るようにします。
$ sudo apt-get update
$ sudo apt-get -y install openssh-server
後の作業で必要になるパッケージをインストール
$ sudo apt-get install -y dpkg-dev fakeroot debhelper dh-systemd \
kernel-wedge makedumpfile libelf-dev libnewt-dev libiberty-dev \
libdw-dev libpci-dev pkg-config flex bison libunwind8-dev \
liblzma-dev libssl-dev libaudit-dev python-dev gawk libudev-dev \
autoconf automake libtool uuid-dev binutils-dev libnuma-dev \
xmlto docbook-utils transfig sharutils asciidoc python-sphinx \
python-sphinx-rtd-theme xorriso isolinux
キャッシュ削除
$ sudo apt-get clean
以降、この環境を「作業環境」と呼びます。
MacBook向けカーネルパッケージの作成
作業環境でMacBook 2016年モデル(一部Pro)向けの修正、ドライバを追加したカーネルのパッケージを作成します。
作業用のディレクトリを作成し、そこにUbuntuのカーネルパッケージ作成に必要なファイルをダウンロード
$ mkdir ~/work
$ cd ~/work
$ wget http://archive.ubuntu.com/ubuntu/pool/main/l/linux/linux_4.13.0-17.20.diff.gz
$ wget http://ftp.jaist.ac.jp/pub/Linux/kernel.org/linux/kernel/v4.x/linux-4.13.tar.xz
$ xz -dc linux-4.13.tar.xz | gzip -9 > linux_4.13.0.orig.tar.gz
$ rm linux-4.13.tar.xz
ソースを展開してUbuntuのカーネルパッケージのパッチを適用
$ tar zxf linux_4.13.0.orig.tar.gz
$ cd linux-4.13/
$ gzip -dc ../linux_4.13.0-17.20.diff.gz | patch -p1
##カーネルの修正
Ubuntuのパッチに含まれていないものを手動で直します。
###NVMeドライバの修正
デバイスID自体はvanilla kernelに取り込まれていますが、インストール時限定(?)でおかしいので。
修正内容は昨年と同じ。
$ cp -p drivers/nvme/host/pci.c drivers/nvme/host/pci.c_orig
$ vi drivers/nvme/host/pci.c
変更箇所
$ diff -u drivers/nvme/host/pci.c_orig drivers/nvme/host/pci.c
--- drivers/nvme/host/pci.c_orig 2017-11-28 23:11:07.152000000 +0900
+++ drivers/nvme/host/pci.c 2017-11-28 23:11:43.680000000 +0900
@@ -1950,7 +1950,7 @@
* Temporary fix for the Apple controller found in the MacBook8,1 and
* some MacBook7,1 to avoid controller resets and data loss.
*/
- if (pdev->vendor == PCI_VENDOR_ID_APPLE && pdev->device == 0x2001) {
+ if (pdev->vendor == PCI_VENDOR_ID_APPLE && (pdev->device == 0x2001 || pdev->device == 0x2003)) {
dev->q_depth = 2;
dev_warn(dev->ctrl.device, "detected Apple NVMe controller, "
"set queue depth=%u to work around controller resets\n",
バックアップ削除
$ rm drivers/nvme/host/pci.c_orig
###ACPI周りの修正
キーボード&トラックパッドが使えない原因。昨年のネタを書いていた時点ではDSDTを書き換える必要があり、すごい面倒だった(なので、昨年は書かなかった)のですが、kernel 4.14で対応されました。
が、残念ながらUbuntu 17.10のカーネルはまだ4.13なのでパッチを個別に適用します。
https://github.com/Dunedan/mbp-2016-linux#misc
$ wget -O - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=899596e090 | patch -p1
$ wget -O - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=75fc70e073 | patch -p1
$ wget -O - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=630b3aff8a | patch -p1 -F 3
$ wget -O - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=ca9ef3ab68 | patch -p1
ちょっと警告が出ますがとりあえず平気です。
バックアップファイル削除
$ find . -name '*.orig' -exec rm {} \;
###キーボード&トラックパッドのドライバ追加
最初の作者よりも、タッチバーのドライバの作者の方がちょっと新しいので、そちらからダウンロード
$ wget -O - https://github.com/roadrunner2/macbook12-spi-driver/raw/touchbar-driver-hid-driver/applespi.c > drivers/input/misc/applespi.c
Kconfigに追加
$ cp -p drivers/input/misc/Kconfig drivers/input/misc/Kconfig_orig
$ vi drivers/input/misc/Kconfig
変更箇所
$ diff -u drivers/input/misc/Kconfig_orig drivers/input/misc/Kconfig
--- drivers/input/misc/Kconfig_orig 2017-09-04 05:56:17.000000000 +0900
+++ drivers/input/misc/Kconfig 2017-11-28 23:17:16.808000000 +0900
@@ -72,6 +72,13 @@
To compile this driver as a module, choose M here: the
module will be called ad714x-spi.
+config INPUT_APPLE_SPI
+ tristate "MacBook 2016 keyboard and trackpad"
+ depends on SPI
+ help
+ Say Y to enable support MacBook Early 2016/Late 2016
+ Keyboard and Trackpad.
+
config INPUT_ARIZONA_HAPTICS
tristate "Arizona haptics support"
depends on MFD_ARIZONA && SND_SOC
Makefileにも追加
$ cp -p drivers/input/misc/Makefile drivers/input/misc/Makefile_orig
$ vi drivers/input/misc/Makefile
変更箇所
$ diff -u drivers/input/misc/Makefile_orig drivers/input/misc/Makefile
--- drivers/input/misc/Makefile_orig 2017-09-04 05:56:17.000000000 +0900
+++ drivers/input/misc/Makefile 2017-11-28 23:18:23.356000000 +0900
@@ -14,6 +14,7 @@
obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o
obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
+obj-$(CONFIG_INPUT_APPLE_SPI) += applespi.o
obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
バックアップ削除
$ rm drivers/input/misc/Makefile_orig drivers/input/misc/Kconfig_orig
###タッチバーのドライバ追加
ダウンロード
$ wget -O - https://github.com/roadrunner2/macbook12-spi-driver/raw/touchbar-driver-hid-driver/appletb.c > drivers/hid/appletb.c
Kconfigに追加
$ cp -p drivers/hid/Kconfig drivers/hid/Kconfig_orig
$ vi drivers/hid/Kconfig
変更箇所
$ diff -u drivers/hid/Kconfig_orig drivers/hid/Kconfig
--- drivers/hid/Kconfig_orig 2017-09-04 05:56:17.000000000 +0900
+++ drivers/hid/Kconfig 2017-11-28 23:20:27.736000000 +0900
@@ -146,6 +146,12 @@
Say Y here if you want support for Apple infrared remote control.
+config HID_APPLE_TOUCHBAR
+ tristate "Apple Touchbar"
+ depends on (USB_HID)
+ ---help---
+ MacBook Pro 2016 Touchbar support.
+
config HID_ASUS
tristate "Asus"
depends on LEDS_CLASS
Makefileにも追加
$ cp -p drivers/hid/Makefile drivers/hid/Makefile_orig
$ vi drivers/hid/Makefile
変更箇所
$ diff -u drivers/hid/Makefile_orig drivers/hid/Makefile
--- drivers/hid/Makefile_orig 2017-09-04 05:56:17.000000000 +0900
+++ drivers/hid/Makefile 2017-11-28 23:21:36.808000000 +0900
@@ -26,6 +26,7 @@
obj-$(CONFIG_HID_ACRUX) += hid-axff.o
obj-$(CONFIG_HID_APPLE) += hid-apple.o
obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
+obj-$(CONFIG_HID_APPLE_TOUCHBAR) += appletb.o
obj-$(CONFIG_HID_ASUS) += hid-asus.o
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
##パッケージ作成
パッケージのconfigに追加したドライバの記述を追加
$ cp -p debian.master/config/config.common.ubuntu debian.master/config/config.common.ubuntu_orig
$ vi debian.master/config/config.common.ubuntu
変更箇所
$ diff -u debian.master/config/config.common.ubuntu_orig debian.master/config/config.common.ubuntu
--- debian.master/config/config.common.ubuntu_orig 2017-11-28 23:11:07.080000000 +0900
+++ debian.master/config/config.common.ubuntu 2017-11-28 23:23:05.788000000 +0900
@@ -3370,6 +3370,7 @@
CONFIG_HID_ALPS=m
CONFIG_HID_APPLE=m
CONFIG_HID_APPLEIR=m
+CONFIG_HID_APPLE_TOUCHBAR=m
CONFIG_HID_ASUS=m
CONFIG_HID_AUREAL=m
CONFIG_HID_BATTERY_STRENGTH=y
@@ -3955,6 +3956,7 @@
CONFIG_INPUT_ADXL34X_I2C=m
CONFIG_INPUT_ADXL34X_SPI=m
CONFIG_INPUT_APANEL=m
+CONFIG_INPUT_APPLE_SPI=m
CONFIG_INPUT_ARIZONA_HAPTICS=m
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_ATLAS_BTNS=m
モジュールリスト変更
$ cp -p debian.master/abi/4.13.0-16.19/amd64/generic.modules debian.master/abi/4.13.0-16.19/amd64/generic.modules_orig
$ vi debian.master/abi/4.13.0-16.19/amd64/generic.modules
変更箇所
$ diff -u debian.master/abi/4.13.0-16.19/amd64/generic.modules_orig debian.master/abi/4.13.0-16.19/amd64/generic.modules
--- debian.master/abi/4.13.0-16.19/amd64/generic.modules_orig 2017-11-28 23:11:07.028000000 +0900
+++ debian.master/abi/4.13.0-16.19/amd64/generic.modules 2017-11-28 23:25:06.284000000 +0900
@@ -326,7 +326,9 @@
apple_bl
appledisplay
applesmc
+applespi
appletalk
+appletb
appletouch
applicom
aquantia
バックアップ削除
$ rm debian.master/config/config.common.ubuntu_orig
$ rm debian.master/abi/4.13.0-16.19/amd64/generic.modules_orig
個別修正は以上で終わり。
パッケージをビルド
$ dpkg-buildpackage -rfakeroot -us -uc --build=binary
ビルドが完了したらカーネルソースを展開したディレクトリは不要なので削除します。(作業環境のディスクが50GBだとこれを消さないと後の作業中にディスクが溢れます)
$ cd ..
$ rm -rf linux-4.13
#作業環境へのカーネルパッケージインストール
作成したカーネルパッケージを作業環境にインストールします。
$ cd ~/work
$ sudo dpkg -i linux-headers-4.13.0-17_4.13.0-17.20_all.deb \
linux-headers-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-image-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-image-extra-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-libc-dev_4.13.0-17.20_amd64.deb
再起動
$ sudo reboot
再起動後ログインして、追加したモジュールがあることを確認
$ modinfo applespi appletb | grep filename
filename: /lib/modules/4.13.0-17-generic/kernel/drivers/input/misc/applespi.ko
filename: /lib/modules/4.13.0-17-generic/kernel/drivers/hid/appletb.ko
古いカーネルパッケージ削除
$ sudo apt-get purge linux-headers-4.13.0-16 \
linux-headers-4.13.0-16-generic \
linux-image-4.13.0-16-generic \
linux-image-extra-4.13.0-16-generic
#カスタムインストールイメージ作成
ここからがインストーラーのカスタマイズ作業になります。
まず、Ubuntu Mate 17.10 desktop AMD64のDVDを作業環境の/mntにマウント
$ sudo mount /dev/sr0 /mnt/
作業用ディレクトリ /opt/cd-image を作成して、インストーラーの中身をコピー
$ sudo mkdir /opt/cd-image
$ sudo rsync -av /mnt/ /opt/cd-image/
インストーラーのsquashfsを作業用ディレクトリに展開
$ cd /opt/work
$ sudo unsquashfs /opt/cd-image/casper/filesystem.squashfs
別の作業用ディレクトリを作成し、インストーラーのinitrdの中身をその中へ展開
$ sudo mkdir /opt/work/installer-initrd
$ cd /opt/work/installer-initrd/
$ lzma -dc -S .lz /opt/cd-image/casper/initrd.lz | sudo cpio -imvd --no-absolute-filenames
作業環境のinitrdにaufsを追加
$ echo aufs | sudo tee -a /etc/initramfs-tools/modules
$ sudo update-initramfs -c -k all
さらに別の作業用ディレクトリを作成して、作業環境のinitrdを展開
$ sudo mkdir /opt/work/basesystem-initrd
$ cd /opt/work/basesystem-initrd/
$ gzip -dc /boot/initrd.img-4.13.0-17-generic | sudo cpio -imvd --no-absolute-filenames
インストーラーのinitrdを展開したディレクトリから、古いカーネルのファイルを削除
$ sudo rm -rf /opt/work/installer-initrd/lib/modules/4.13.0-16-generic
$ sudo rm -rf /opt/work/installer-initrd/lib/firmware/4.13.0-16-generic
$ sudo rm /opt/work/installer-initrd/lib/modprobe.d/blacklist_linux_4.13.0-16-generic.conf
代わりに稼働中のシステムのinitrdの中身をコピー
$ sudo cp -a /opt/work/basesystem-initrd/lib/modules/4.13.0-17-generic /opt/work/installer-initrd/lib/modules/
$ sudo cp -a /opt/work/basesystem-initrd/lib/firmware/4.13.0-17-generic /opt/work/installer-initrd/lib/firmware/
$ sudo cp -p /opt/work/basesystem-initrd/lib/modprobe.d/blacklist_linux_4.13.0-17-generic.conf /opt/work/installer-initrd/lib/modprobe.d/
修正したinitrdのファイルをアーカイブし直す。
$ cd /opt/work/installer-initrd/
$ sudo find . | sudo cpio --quiet --dereference -o -H newc | lzma -7 | sudo dd of=/opt/cd-image/casper/initrd.lz
稼働中のカーネルイメージをカスタムインストーラーのディレクトリにコピー
$ sudo cp /boot/vmlinuz-4.13.0-17-generic /opt/cd-image/casper/vmlinuz.efi
インストーラーのsquashfsをカスタマイズ。
まず、squashfsを展開したディレクトリ内に/proc等をマウント
$ sudo mount -o bind /proc /opt/work/squashfs-root/proc
$ sudo mount -o bind /dev /opt/work/squashfs-root/dev
$ sudo mount -t devpts none /opt/work/squashfs-root/dev/pts/
$ sudo mount -t sysfs none /opt/work/squashfs-root/sys/
カーネルパッケージを作成したディレクトリもbind mount
$ sudo mkdir /opt/work/squashfs-root/work
$ sudo mount -o bind ~/work/ /opt/work/squashfs-root/work
squashfsを展開した中へchroot
$ sudo chroot /opt/work/squashfs-root/
以下、プロンプト"#"はchroot内での作業
パッチ適用したカーネルパッケージをインストール
# cd work/
# dpkg -i linux-headers-4.13.0-17_4.13.0-17.20_all.deb \
linux-headers-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-image-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-image-extra-4.13.0-17-generic_4.13.0-17.20_amd64.deb \
linux-libc-dev_4.13.0-17.20_amd64.deb
不要となった古いカーネルパッケージを削除
# apt-get purge linux-image-4.13.0-16-generic \
linux-image-extra-4.13.0-16-generic \
linux-signed-image-4.13.0-16-generic \
linux-headers-4.13.0-16-generic
grubのデフォルト設定変更。intremap=nosidを追加
(ここの情報だと不要になっているようですが、私が試したところ必要っぽい)
# sed -i 's/^kopt_params=""/kopt_params="intremap=nosid"/' /usr/share/grub-installer/grub-installer
# ucf --purge /etc/default/grub
# sed -i 's/^GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="intremap=nosid"/' /etc/default/grub
# ucf /etc/default/grub /etc/default/grub
# update-grub
chrootから抜ける
# exit
squashfs展開先にマウントしたディレクトリをアンマウント
$ sudo umount /opt/work/squashfs-root/proc
$ sudo umount /opt/work/squashfs-root/dev/pts
$ sudo umount /opt/work/squashfs-root/dev
$ sudo umount /opt/work/squashfs-root/sys
$ sudo umount /opt/work/squashfs-root/work
一時ディレクトリも削除
$ sudo rmdir /opt/work/squashfs-root/work
squashfsを再作成
$ sudo chmod +w /opt/cd-image/casper/filesystem.manifest
$ sudo chroot /opt/work/squashfs-root dpkg-query -W | sudo tee /opt/cd-image/casper/filesystem.manifest
$ sudo rm /opt/cd-image/casper/filesystem.squashfs
$ sudo mksquashfs /opt/work/squashfs-root /opt/cd-image/casper/filesystem.squashfs -comp xz
インストーラー起動時のカーネルオプション変更
isolinuxとgrubの設定ファイルにintremap=nosidを追加
$ sudo sed -i 's/initrd.lz quiet/initrd.lz intremap=nosid quiet/' /opt/cd-image/isolinux/txt.cfg
$ sudo sed -i 's/quiet splash/quiet intremap=nosid splash/' /opt/cd-image/boot/grub/grub.cfg
ファイルリストとmd5チェックサム生成
$ printf $(sudo du -sx --block-size=1 /opt/work/squashfs-root | cut -f1) | sudo tee /opt/cd-image/casper/filesystem.size
$ sudo rm /opt/cd-image/md5sum.txt
$ cd /opt/cd-image/
$ sudo find -type f -print0 | sudo xargs -0 md5sum | grep -v isolinux/boot.cat | sudo tee md5sum.txt
カスタマイズしたインストーラーのISOイメージ作成
$ sudo mkdir /opt/newimage
$ cd /opt/cd-image/
$ sudo xorriso -as mkisofs \
-o /opt/newimage/custom.iso \
-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \
-c isolinux/boot.cat \
-b isolinux/isolinux.bin \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-eltorito-alt-boot \
-e boot/grub/efi.img \
-no-emul-boot \
-isohybrid-gpt-basdat \
/opt/cd-image/
カスタマイズしたインストーラーのISOイメージが /opt/newimage/custom.iso として生成されます。
MacBookへのインストール
作成したイメージをddでUSBメモリ(デバイス名は適宜変更)に書き込み、MacBookで起動するとインストーラーが起動します。
# dd if=/opt/newimage/custom.iso of=/dev/sdz
毎回カーネルパッケージを作るのは面倒なので、インストール後はカーネルを4.14以上に上げて(野良ビルド)、追加ドライバはdkmsに移行したほうが良いでしょう。(NVMeの修正はインストール後は無くても平気なはず)
作るのが面倒な人向けに、上記の手順で作ったものをここに置いておきます。