Macbook Early 2016にUbuntu MATE 16.10をインストールする

  • 3
    いいね
  • 0
    コメント

はじめに

SRA Advent Calendarの14日目です。
ネットワークシステムサービス第1事業部の ふじまき です。

MacBook Early 2016(Model:A1534)でLinuxを動かそうとするとわりと面倒という情報を入手したのでヨドバシで買ってきてUbuntu MATEをインストールしてみました。

https://wiki.archlinux.org/index.php/MacBook#April_2016_12.22_-_Version_9.2C1
https://wiki.archlinuxjp.org/index.php/MacBook#April_2016_12.22_-_.E3.83.90.E3.83.BC.E3.82.B8.E3.83.A7.E3.83.B3_9.2C1

注意事項

  • このページの情報は無保証です。試す場合は自己責任でお願いします。
  • MacOSに未練がある人はリカバリ手段を確保してから行ってください。
  • キーボード、トラックパッドは動作しません。USB接続のキーボード、マウスは必須です。
    • Archのwikiに記載のとおり、Work In Progressなドライバが存在しますが、それを入れる作業の際にキーボードが必要です。なお、このドライバは2015年版のMacBookでは動きません(今のところ)
  • デフォルト設定でインストールすると通常起動はUbuntu MATEになります。MacOSは(自動では)起動しなくなります
  • 802.11acが不安定です。(パケットが流れなくなる。原因不明)アクセスポイントが802.11ac対応かつ802.11acのみを無効化できない場合、まともに生活出来ません
  • 音は鳴りません。(録音は出来るらしいですが未確認)
  • ここで説明する手順はインストーラーをカスタマイズしてMacbookにUbuntu MATEをインストールします。なので、インストーラー作成用のマシンが別途必要です。
  • 2015年版のMacBookにはおそらくインストールできますが、キーボードとトラックパッドを動かす手段が見つかっていないのでお勧めしません。

MacBook Early 2016へのUbuntu MATE 16.10インストール

Arch LinuxのWikiを見るとkernel 4.6以上ならインストーラー起動後、コンソールで

# modprobe nvme
# echo 106b 2003 > /sys/bus/pci/drivers/nvme/new_id

と入力すれば内蔵NVMeコントローラーが動作するはずですが、Ubuntu MATE 16.10(kernel 4.8)の場合、"D3 stateから復帰できない~"みたいなエラーが出て内蔵SSDを認識できず。Debian StretchインストーラーAlpha7(kernel 4.6)だと内蔵SSDを認識するがインストール中に頻繁にフリーズしてまともにインストールが出来ませんでした。(Debianは5,6回リトライし続けてかろうじてインストール出来ましたが)

なのでUbuntu MATE 16.10のインストーラーのカーネルを差し替えて、さくっとインストール出来るインストーラーを作ります。

インストーラーカスタマイズ用の作業環境作成

適当なマシン(仮想でもOK)にUbuntu MATE 16.10をインストールします。ハードディスクの容量は50GBくらいあった方がよいです。(40GBだとギリギリ)

以降、この環境を「作業環境」と呼びます。

作業環境のカーネル更新

sshで作業するので、openssh-serverをインストール

$ sudo apt-get update
$ sudo apt-get -y install openssh-server

カーネルパッケージ作成に必要なパッケージをインストール

$ sudo apt-get -y install dpkg-dev 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 libudev-dev autoconf automake libtool uuid-dev xmlto \
 docbook-utils transfig sharutils asciidoc

ホームディレクトリに作業ディレクトリ"work"を作成してその中にカーネルソースをダウンロード。
(launchpad.netからlinux_4.8.0.orig.tar.gzをダウンロードするのは時間がかかるのでミラーサイトからダウンロードしてコンバートしています)

$ mkdir ~/work
$ cd ~/work
$ wget http://ftp.jaist.ac.jp/pub/Linux/kernel.org/linux/kernel/v4.x/linux-4.8.tar.xz
$ xz -dc linux-4.8.tar.xz | gzip -9 > linux_4.8.0.orig.tar.gz
$ rm linux-4.8.tar.xz
$ wget https://launchpad.net/ubuntu/+archive/primary/+files/linux_4.8.0-27.29.diff.gz

カーネルソースを展開し、パッケージのパッチを適用

$ tar zxf linux_4.8.0.orig.tar.gz
$ cd linux-4.8/
$ gzip -dc ../linux_4.8.0-27.29.diff.gz | patch -p1

Linux4.8のNVMeドライバはMacBook Early 2016のNVMeコントローラーのProduct IDが入っていないので追加します。

$ cp -p drivers/nvme/host/pci.c drivers/nvme/host/pci.c_orig
$ vi drivers/nvme/host/pci.c

以下のとおり変更

--- drivers/nvme/host/pci.c_orig        2016-10-03 08:24:33.000000000 +0900
+++ drivers/nvme/host/pci.c     2016-11-20 14:17:53.892000000 +0900
@@ -1635,7 +1635,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->dev, "detected Apple NVMe controller, set "
                        "queue depth=%u to work around controller resets\n",
@@ -2121,6 +2121,7 @@
                .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
        { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
+       { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, nvme_id_table);

バックアップファイル削除

$ rm drivers/nvme/host/pci.c_orig

上記の修正は http://lists.infradead.org/pipermail/linux-nvme/2016-May/004618.html より。前半の部分はオリジナルのパッチでは不要とされてましたがインストール中は明らかにあったほうが良いので追加。(無いとパーティショニングのところで高確率でフリーズします、という突破出来ない)

カーネルパッケージビルド。環境依存かもしれませんが、手元の環境だとsshログインした状態でカーネルパッケージ作成を行うと途中で通信が切れるのでここだけローカルでログインした状態で実行した方がよいかも。

$ dpkg-buildpackage -rfakeroot -us -uc --build=binary

正常に完了すると一つ上のディレクトリにカーネルパッケージが作成されます。
移動してカーネルパッケージをインストール

$ cd ~/work/
$ sudo dpkg -i linux-headers-4.8.0-27_4.8.0-27.29_all.deb \
  linux-headers-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-image-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-image-extra-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-tools-4.8.0-27_4.8.0-27.29_amd64.deb \
  linux-tools-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-tools-common_4.8.0-27.29_all.deb

インストール後、再起動

$ sudo reboot

再起動後ログイン。修正したNVMeドライバにProduct IDが追加されていることを確認

$ modinfo nvme
filename:       /lib/modules/4.8.0-27-generic/kernel/drivers/nvme/host/nvme.ko
version:        1.0
license:        GPL
author:         Matthew Wilcox <willy@linux.intel.com>
srcversion:     A270F19E73A377AD815935F
alias:          pci:v0000106Bd00002003sv*sd*bc*sc*i*   /* d00002003があればOK */
alias:          pci:v0000106Bd00002001sv*sd*bc*sc*i*
(以下略)

aliasのところにDevice-ID==2003があることを確認。作成したカーネルパッケージはこの後のインストーラーのカスタマイズでも使用(インストール)します。

インストーラーのカスタマイズ

参考サイト

インストーラーの中身をファイルシステム上に展開して、カーネルをNVMeドライバを修正したものと差し替えます。

インストーラーの展開

作業環境でUbuntu MATE 16.10のインストーラーを/mnt/にマウント

$ sudo mount /dev/sr0 /mnt/

インストーラーの中身を/opt/cd-imageにコピー

$ sudo mkdir /opt/cd-image
$ sudo rsync -av /mnt/ /opt/cd-image/

作業ディレクトリとして/opt/workを作成し、インストーラーのルートファイルシステム(Squashfs)を展開。"squashfs-root"というディレクトリが作成されその中に展開されます。

$ sudo mkdir /opt/work
$ cd /opt/work
$ sudo unsquashfs /opt/cd-image/casper/filesystem.squashfs

インストーラーのinitrd変更

インストーラーの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

Ubuntu MATE 16.10のインストーラーのカーネルは"4.8.0-22"というバージョンでinitrdの中身も4.8.0-22になっています。これを作業環境にインストールした"4.8.0-27"に差し替えます。

差し替えの事前準備として作業環境のinitrdにaufsを追加

$ echo aufs | sudo tee -a /etc/initramfs-tools/modules
$ sudo update-initramfs -c -k all

更新した作業環境のinitrdを/opt/work/basesystem-initrdに展開

$ sudo mkdir /opt/work/basesystem-initrd
$ cd /opt/work/basesystem-initrd/
$ gzip -dc /boot/initrd.img-4.8.0-27-generic | sudo cpio -imvd --no-absolute-filenames

この時点でインストーラーのinitrdを/opt/work/installer-initrd/ 、作業環境のinitrdを/opt/work/basesystem-initrdに展開した状態になっています。
/opt/work/installer-initrd/から"4.8.0-22"関連を削除

$ sudo rm -rf /opt/work/installer-initrd/lib/modules/4.8.0-22-generic
$ sudo rm -rf /opt/work/installer-initrd/lib/firmware/4.8.0-22-generic
$ sudo rm /opt/work/installer-initrd/lib/modprobe.d/blacklist_linux_4.8.0-22-generic.conf

代わりにNVMeドライバを修正した作業環境の"4.8.0-27"関連ファイルを/opt/work/installer-initrd/へコピー

$ sudo cp -a /opt/work/basesystem-initrd/lib/modules/4.8.0-27-generic /opt/work/installer-initrd/lib/modules/
$ sudo cp -a /opt/work/basesystem-initrd/lib/firmware/4.8.0-27-generic /opt/work/installer-initrd/lib/firmware/
$ sudo cp -p /opt/work/basesystem-initrd/lib/modprobe.d/blacklist_linux_4.8.0-27-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

インストーラーのカーネル更新

ファイルを1個コピーするだけ。

$ sudo cp /boot/vmlinuz-4.8.0-27-generic  /opt/cd-image/casper/vmlinuz.efi

インストーラーのファイルシステム編集

Squashfsを展開した中へchrootして編集します。
事前準備として/proc等をSquashfs展開先にマウント。

$ 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/

作業環境のカーネル更新でパッケージを作成したディレクトリもSquashfs展開先にマウントしておきます。

$ 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内作業(プロンプトが"#")

修正したカーネルパッケージをインストール
(chroot内でのコマンド実行でlocale関連のWarningが出ますが無視してOK)

# cd /work/
# dpkg -i linux-headers-4.8.0-27_4.8.0-27.29_all.deb \
  linux-headers-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-image-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-image-extra-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-tools-4.8.0-27-generic_4.8.0-27.29_amd64.deb \
  linux-tools-4.8.0-27_4.8.0-27.29_amd64.deb \
  linux-tools-common_4.8.0-27.29_all.deb

不要パッケージ(古いカーネルパッケージ)を削除

# apt-get purge linux-signed-image-4.8.0-22-generic \
  linux-signed-image-generic linux-signed-generic \
  linux-headers-4.8.0-22-generic linux-headers-4.8.0-22 \
  linux-image-4.8.0-22-generic linux-image-extra-4.8.0-22-generic \
  linux-tools-4.8.0-22 linux-tools-4.8.0-22-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

インストーラーイメージ再作成

インストーラーのカーネルオプション変更。インストール時に必要なnoapicを追加。(isolinuxとgrubの両方を変えていますがMacBookで使われるのはgrub)

$ sudo sed -i 's/initrd.lz quiet/initrd.lz noapic quiet/' /opt/cd-image/isolinux/txt.cfg
$ sudo sed -i 's/quiet splash/quiet noapic 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 IMAGE=/opt/newimage/custom.iso BUILD=/opt/cd-image/  mkisofs -r -V "Custom Test" -cache-inodes -J -l \
 -b isolinux/isolinux.bin -c isolinux/boot.cat \
 -no-emul-boot -boot-load-size 4 -boot-info-table \
 -o /opt/newimage/custom.iso /opt/cd-image/

/opt/newimage/custom.iso に1.4GBくらいのハイブリッドイメージが出来るのでUSBメモリに書き出しておきます。

カスタムインストーラーを使ったMacBook Early 2016へのUbuntu MATE 16.10インストール

カスタマイズしたインストーラーで起動しUbuntu MATEをインストールします。
説明は特に必要ないと思いますが、注意点としては

  • MacOSも使い続けたい場合は事前にMacOS上で空きパーティションを作っておいた方がよいでしょう。
  • インストール中にネットワークに繋げるとせっかくNVMeドライバを修正したカーネルが上書きされてしまう恐れがあるので、インストール中はネットワークに繋げない方が確実です。
この投稿は SRA Advent Calendar 201614日目の記事です。