2017/10/26

[MacBook Pro] Triple boot with MacOS / Ubuntu 16.04 / Window 10 (Bootcamp)

首先,我得說這是一個很慘痛的經驗,為了在MacBook Pro上保有macOS/Windows之下,灌Ubuntu,我嘗試了好幾種方式,失敗的下場就是整台電腦要重灌,前前後後也重灌了4次,弄到Option-Command-R組合鍵超級熟。終於達到我覺得還不錯的方案。

先說結論:我推薦買一個外接式硬碟,然後把Ubuntu灌在這顆硬碟中


相關資訊:
1. MacBook Pro 2015 (512GB SSD) with macOS High Sierra
2. Windows 10 by Bootcamp
3. Ubuntu 16.04

事前準備:
1. Ubuntu 16.04 live USB stick
2. USB外接硬碟 <--- 灌Ubuntu使用
3. 一台MacBook Pro

買一顆外接硬碟的好處是:
1. MacBook Pro可以直接透過Bootcamp刪除Windows,因為這樣不會影響到硬碟的分割,好維持MacBook Pro的硬碟管理
2. 減少SSD的損耗
3. 灌Ubuntu失敗後,要刪除此區硬碟,不用慘痛的重灌整台MacBook Pro

先說我嘗試過的方式:
1. 參考這篇,先透過Bootcamp在MacBook Pro上安裝Win10,再利用diskutil分割一塊磁碟給Ubuntu --> 失敗,灌完之後Win10無法開機

2. 參考這篇,先透過Bootcamp在MacBook Pro上安裝Win10;接著在同一個SSD上分割多個空間給Ubuntu --> 失敗,因為灌完Ubuntu之後,用Bootcamp灌的Win10無法從USB開機來修復Windows,所以此方法下的Windows無法開機

就從上面兩個方式的嘗試,同一顆硬碟之下,就算有特別分割EFI區給Ubuntu,Windows依然會在Ubuntu灌完之後無法開機。

所以最後決定保持整個SSD的完整性,也為了日後刪除Bootcamp的方便,所以決定用一顆外接式硬碟來灌Ubuntu。

======分隔線======

大致上整個流程是參考這篇,但有些package在Ubuntu 16.04找不到,像是mactel-boot等等。概念上其實就是在外接硬碟灌Ubuntu,然後把原本Ubuntu原生的EFI Boot改成Apple相容的HFS+格式,目的是可以在MacBook Pro開機的時候,按下Alt/Option key可以看到開機選單,當然包含原本Bootcamp的Windows10和macOS。

首先要灌Ubuntu,插入USB live stick和USB外接式硬碟,然後按下Alt/Option,選擇EFI Boot,然後選try Ubuntu without installing。

打開Ubuntu的terminal,然後輸入底下指令。這個步驟非常的重要,不然Ubuntu會把Mac的bootloader取代掉,一定要注意。
$ ubiquity --no-bootloader

接下來就是灌Ubuntu的過程,選Erase disk and install Ubuntu,然後選擇要灌Ubuntu的USB硬碟,理論上在這裡應該會有兩個硬碟可以選,選擇USB的硬碟。如果沒有,那就在terminal用fdisk -l看看USB硬碟是不是有正確運轉,試著插拔幾次,直到讀取到USB硬碟。重複上一個動作,重新開始。然後就等著灌好Ubuntu。

灌好之後,重開機後按Alt/Option,然後選擇EFI Boot的Ubuntu installer,接著按著c鍵,我們要利用grub來設定從灌好的Ubuntu硬碟開機。
grub>

尋找Ubuntu是哪一個硬碟。
grub> ls (hd2,gpt1)/boot/grub
error: file `/boot/grub' not found.

重複這個動作,找到有/boot/grub這資料夾為止。這樣代表我們找到USB的Ubuntu硬碟了。如果沒找到,請確認USB硬碟是不是有正確運轉。
grub> ls (hd4,gpt2)/boot/grub
gfxblacklist.txt unicode.pf2

設定開機碟。
grub> set root=(hd4,gpt2)

記住UUID,等等用得到。
grub> ls -l (hd4,gpt2)
        Partition hd4,gpt2: Filesystem type ext... UUID e0b7559d-86dc-42cb-bc4d-801185ae1eda - Partition start at...

設定開機,包含剛剛的UUID。
grub> linux /boot/vmlinuz-4.10.0-37-generic.efi.signed root=UUID={Your UUID}
grub> initrd /boot/initrd.img-4.10.0-37-generic
grub> boot

開機進入Ubuntu,接著安裝等等要把Ubuntu的EFI partition改成HFS+格式的工具們。
$ sudo apt-get update
$ sudo apt-get install hfsprogs gdisk grub-efi-amd64

安裝mactel-boot。
$ wget http://www.codon.org.uk/~mjg59/mactel-boot/mactel-boot-0.9.tar.bz2
$ tar -jxf mactel-boot-0.9.tar.bz2
$ cd mactel-boot-0.9
$ make PRODUCTVERSION=UBUNTU
$ sudo cp hfs-bless /usr/sbin

看硬碟資訊。
$ sudo fdisk -l
Disk /dev/sda: 465.9Gib, 500277790720 bytes, 977155060 sectors
...

Disk /dev/sdb: 698.7 Gib, 750156374016 bytes, 1465149168 sectors
...

主角是/dev/sdb

現在要把/dev/sdb的sdb1換成Apple的HFS+格式。
$ sudo gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
  MBR: hybrid
  BSD: not present
  APM: not present
  GPT: present
Found valid GPT with hybrid MBR; using GPT.

Command (? for help):

刪除第一個partition,格式是EF00的硬碟區。
Command (? for help): p
Disk /dev/sdb: ...
...
Number  Start (sector)  End (sector)  Size     Code   Name

   1         2048         1050623  512.0 MiB   EF00   EFI System Partition
...

Command (? for help): d
Partition number (1-3): 1

創出一個硬碟區,為了給HFS+格式使用
Command (? for help): n
Partition number (1-128, default 1): 1

格式輸入AF00。
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): AF00
Changed type of partition to 'Apple HFS/HFS+'

Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.

改變sdb1硬碟區格式,-v為此區的名稱,可以依個人喜好改變,這邊用Ubuntu
$ sudo mkfs.hfsplus /dev/sdb1 -v Ubuntu
Initialized /dev/sdb1 as a 512 MB HFS Plus volume

改完之後整個硬碟狀態會呈現


修改/etc/fstab
$ sudoedit /etc/fstab

把/boot/efi的兩行刪除,然後存檔
# /boot/efi was on /dev/sda1 during installation
UUID=......  /boot/efi       vfat    defaults        0       1

目前的/boot/efi還是在/dev/sda1
$ mount | grep /boot/efi
/dev/sda1 on /boot/efi ...

把sda1改成sdb1
$ sudo umount /dev/sda1
$ sudo bash -c 'echo UUID=$(blkid -o value -s UUID /dev/sdb1) /boot/efi auto defaults 0 0 >> /etc/fstab'
$ sudo mount /boot/efi
$ mount | grep /boot/efi
/dev/sdb1 on /boot/efi type hfsplus (rw,relatime,umask=22,uid=0,gid=0,nls=utf8)

然後要產生一個EFI Data給EFI的partition。
$ sudo mkdir -p "/boot/efi/EFI/$(lsb_release -ds)/"
$ sudo bash -c 'echo "This file is required for booting" > "/boot/efi/EFI/$(lsb_release -ds)/mach_kernel"'
$ sudo bash -c 'echo "This file is required for booting" > /boot/efi/mach_kernel'

$ sudo grub-install --target x86_64-efi --boot-directory=/boot --efi-directory=/boot/efi --bootloader-id="$(lsb_release -ds)"
$ sudo hfs-bless "/boot/efi/EFI/$(lsb_release -ds)/System/Library/CoreServices/boot.efi"

最後修改grub的config檔案。
$ sudo gedit /etc/default/grub

註解有GRUB_HIDDEN的兩行,然後把timeout修改成0.1秒;因為我們進Ubuntu不需要選其他系統,所以就快速跳過grub選單就好。


產生config檔案。注意在這裡,usb的live stick要移除,不然會有錯誤。
$ sudo grub-mkconfig -o /boot/grub/grub.cfg

最後default開機的部分,理論上應該會是原先設定的Mac,如果開機自己進入Ubuntu,則要把Mac Startup Manager有關Ubuntu的部分移除。假設沒有灌Bootcamp的windows,可以忽略這個步驟。
$ sudo mkdir -p /mnt/sda1
$ sudo mount /dev/sda1 /mnt/sda1

避免意外建議EFI檔案備份假設沒有灌Bootcamp的windows,可以忽略這個步驟。
$ sudo cp -r /mnt/sda1/EFI .

然後刪除Ubuntu的部分假設沒有灌Bootcamp的windows,可以忽略這個步驟。
$ sudo rm -r /mnt/sda1/EFI/ubuntu

這樣在開機不按Alt/Option的條件下,應該能夠自己default開機到Mac,大功告成啦。


===[Optional] 使用Ubuntu的icon===
這部份建議使用Mac的diskutil來處理,開機進入Mac,然後從這裡下載OS的icons。

打開mac-icns.dmg,找到os_ubuntu.icns,複製到Mac的資料夾路徑下


然後使用Terminal
$ diskutil list


找到Ubuntu的EFI是在disk2s1
$ diskutil mount disk2s1

複製icon
$ cp Downloads/os_ubuntu.icns /Volumes/Ubuntu/.VolumeIcon.icns
$ diskutil umount disk2s1

重開機,按下Alt/Option,應該就能看到Ubuntu的icon啦。同樣的道理,如果掛載disk0s1,然後把icons中的os_win8.icns複製到/Volumes/EFI/.VolumeIcon.icns,這樣應該可以看到Bootcamp的Win10會變成我們設定的icon。

***2017/11/20更新
有一次Ubuntu開機的時候發生開機的錯誤:
fsck error on boot: /dev/sdb2: UNEXPECTED INCONSISTENCY;
RUN fsck MANUALLY

導致Ubuntu停在initramfs的指令畫面,無法開機。上網找了解法,可以參考這篇

在initramfs下fsck指令就可以了。
(initramfs) fsck /dev/sdb2

然後過程中選擇yes修復所有選項即可。

沒有留言:

張貼留言