WindowsとUbuntuを別ドライブで共存

## 概要

- Ubuntuのインストールでの想定されるエラーと回避策の記述
- ここに記載されている内容には環境によって必要なものと不要なものがある。
- BIOSによって設定方法が変わることに注意。

## 使用端末

- マウスコンピュータ G-Tune
- CPU i9
- GPU MSI rtx 2080 ti x2 SLI
- 元はWindowsがインストールしてある。
- Windowsとは別のSSDにUbuntuをインストールする。

## 構築方法と説明

### 1. BIOS

現在は主にレガシーBIOSとUEFIの２種類が存在しており、UEFIの方が新しく大容量のドライブを扱う（2TB以上）の場合はこちら。

また、利用するパーティションに関して、レガシーBIOSはMBRを、UEFIはGPTを使用するという違いがある。

Ubuntuの起動画面も若干違う。

##### SecureBoot関係

![screen004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76058/b73461fb-0dc2-5a25-c425-504dffbecbe0.png)

各メーカー毎にBIOSの設定画面は異なるが、基本的には`secure boot`を`disabled`にする必要がある。GPUを使わない場合ならばそれだけでも使えるが、さらにUEFI関係の制限で**GPUをまったく認識しない場合があるので**、今回は、以下の手順で`Windows 10 WHQL Support`の項目は、UEFIからCSMに変更した。

1. BIOS画面で左メニューの`SETTINGS`
2. `Advanced`
3. `Windows OS Configuration`
4. `Windows 10 WHQL Support` の項目を `UEFI`から`CSM`に変更した。

このあたりの設定はUbuntuのSecure Bootを使用できるようにできれば不要になるかもしれないが、試していない。

##### Windowsブート関係

今回使用した端末の仕様かもしれないが、Hard Disk / SSDでUEFIを利用する場合に何かしらの制限があるらしく、以下の手順でWindowsのブートを無効にする必要があった。

1. BIOS画面で左メニューのSETTINGS
2. Boot
3. UEFI Hard Disk Drive BBS Priorities
4. `Boot Option` の`Windows Boot Manager ...`（ドライブの名前）を`Disabled`にする。

### 2. ブートメニュー

![screen001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76058/d4b3b5e3-5873-96be-d3a8-c45785188634.png)

BIOSの画面を終了すると、ブートメニューが表示される。

1. UEFIの起動画面になったら、素早く`e`ボタンを押すと、ブートメニューが切り替わる
2. `quiet splash`の箇所を`acpi=off`に書き換える。
3. オプションの設定が終わったら`Ctrl + x`を押して次に進む。

#### 解説

- ブートメニューでは、ハードウェアで何らかの問題がある場合にオプションをつけて起動させることで問題を回避できる可能性がある。
- 今回はハードウェアに`ACPI`という機能が無いモデルであったので、このままブートしようとすると、画面が黒くなり何も出来なくなるので`acpi=off`を使用する。
- `quiet splash`の箇所はスプラッシュ画面と呼ばれる画面を起動時に表示するもので、見た目は良いが逆にエラーがわかりにくいので消しておく。
- その他`acpi=off`以外にもブートオプションで`noapic`、`nolapic`、`edd=on`、`nodmraid`、`nomodeset`等がある。
- 特に、GPUで問題がある場合のオプションは、`nomodeset nouveau.nomodeset=1 nvidia-drm.nomodeset=1 i915.nomodeset=1 amdgpu.nomodeset=1`等がある。なお、今回は使用していない。
- ディスプレイで問題がある場合は`set gfxpayload=keep`の箇所を変更する。テキスト表示のみにする場合は`set gfxpayload=text`にしたり、解像度を変更するには`set gfxpayload=1280x768x32`のように幅、高さ、色深度の設定をする。今回は使用していない。

### 3. install起動画面

![screen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76058/94402b58-70ad-ec70-2772-e05bdf1d6b9b.png)

今回はインストーラと同時にターミナルも使いたいのでライブモードで作業をする。そのため、`Try Ubuntu`の方を選択する。

#### 使いやすくするためにSSH

`Try Ubuntu`で起動したらターミナルを起動して以下を実行することで外部からSSH接続ができる。

```bash
# 接続するユーザ名
USER_NAME=user
# ユーザ作成
sudo adduser ${USER_NAME}
# sudo権限
sudo gpasswd -a ${USER_NAME} sudo
# opensshインストール
sudo apt update
sudo apt install -y openssh-server
# ip確認
ip a
```

確認したIPを使って外部端末からSSH接続ができるようになる。

### 4. grub以外をインストール

GUI上のターミナルで以下を実行する。`-b`オプションをつけることで後述するgrub以外をインストールするインストーラーが起動する。

```bash
ubiquity -b
```

1. 言語の選択、`キーボードレイアウトの選択`、`アップデートと他のソフトウェア`の設定は好みで設定して良い。
2. `インストールの種類`項目は`それ以外`を選択。
3. インストールするドライブに既に何かインストールされている場合はドライブを選択して`新しいパーティションテーブル`を選択して空の状態にする。
4. まずはEFIシステムパーティションを作成するので、`空き領域`を選択して`+`ボタンを押して`パーティションを作成`ウィンドウに移り、以下の内容にする。

- サイズ　`200M`
- 新しいパーティションのタイプ　`基本パーティション`
- 新しいパーティションの場所　`この領域の始点`
- 利用方法　`EFIシステムパーティション`

5. 残りにシステム本体を入れるので、以下の内容で設定

- サイズ　残りの領域
- 新しいパーティションのタイプ　`基本パーティション`
- 新しいパーティションの場所　`この領域の始点`
- 利用方法　`ext4 ジャーナリングファイルシステム`
- マウントポイント `/`
- フォーマットの項目が存在しており、チェックが入っていない場合はチェックを入れる。

![screen003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76058/2c8424a2-c7af-7113-2803-74b20ef4775f.png)

`ubiquity -b`のインストーラーは通常のインストーラーと違い、このとき`ブートローダーをインストールするデバイス`項目が無い。

6. `お住まいの地域`の項目は適当に設定。
7. `あなたの情報を入力してください。`の項目も適当に設定。
8. インストーラーが開始され完了まで待ち、インストール終了後は、`試用を続ける`を選択し作業を続行。

#### 通常のインストーラではエラーになる場合がある

`try Ubuntu` で起動した場合、デスクトップに`Install Ubuntu 20.04.4 LTS`というインストーラーがある。ハードウェアで問題が無い場合はこちらから通常通りにインストールが可能だが、例えば別ドライブにWindowsや別Linuxがすでにインストールされている等の理由で、インストール中に`grub-install`でエラーが発生する場合は今回のように`ubiquity -b`によるインストール作業が必要となる。

ちなみにUbuntu 20.04では通常のインストーラーでブートローダーを指定してもWindowsのドライブにあるEFIに書き込みがされるらしい。そのため`ubiquity -b`を使う。

##### WindowsのドライブにUbuntuのブートローダーがある場合

WindowsがインストールされているドライブにあるEFIシステムパーティションに別のUbuntuのブートローダーが残っていた場合は、以下のURLの手順で、その部分を削除することができる。

> 削除手順
> https://itlogs.net/ubuntu-grub-delete-uefi-bios/

### 5. BIOS Boot Partition

`grub-install`コマンドでEFIパーティションに起動関連のデータを作成するのだが、通常通りに`grub-install`コマンドを実行すると以下のようなエラーが表示されることがある。

```error
grub-install /dev/sdb の実行に失敗しました。これは致命的なエラーです。
```

```error
grub-efi-amd64-signedパッケージを/target/にインストールできません。
```

これは、GPTとブートローダーが原因で発生することがある。MBRフォーマットと違い、パーティションがGPTの場合、通常通りインストーラーでパーティションを区切っても、最初のパーティションの前に1MBの容量が空いてしまう。これが原因で`grub-install`実行時に上記のようなエラーが起きる。

> https://www.miraclelinux.com/tech-blog/qwi8ni

対応策として、空いている1MBにBIOS Boot Partitionで埋める。

> https://conveniencedailylife.blog.fc2.com/blog-entry-282.html
> https://www.miraclelinux.com/tech-blog/qwi8ni
> https://bugs.launchpad.net/ubuntu/+source/grub2-signed/+bug/1872212

1. 新しいTerminal上で`sudo lsblk --scsi`等でドライブ名を確認し、`sudo gdisk /dev/sdb`（`sdb`は今回使用するドライブ名）を実行する。
2. `gdisk`のコンソールになるので、`n`を入力しEnter。
3. 対話式で入力するが、最後以外はデフォルトで良いと思われる。

```bash
sudo gdisk /dev/sdb

Partition number (3-128, default 3): 
First sector (34-2047, default = 34) or {+-}size{KMGTP}: 
Last sector (34-2047, default = 2047) or {+-}size{KMGTP}: 
```

以下の質問だけデフォルトではなくBIOS Boot Partitionを示す`ef02`を入力する。

```bash
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef02
```

4. `w`を押して書き込みと終了。

### 6. grubをインストール

起動時に最初に読み込まれるソフトウェアをブートローダーと呼ぶ。Ubuntuのデフォルトはこの`grub`が用いられる。

> https://yuu.nkjmlab.org/diary/20111209.html
> https://guminote.sakura.ne.jp/archives/316

以下の手順を実行することで`chroot`でUbuntu用のドライブにgrubをインストールする。

```bash
sudo apt install -y efibootmgr
# 以下マウント処理
sudo -s
mkdir /chroot
# mount /dev/<ドライブ名><パーティション番号（Ubuntu）> /chroot
mount /dev/sdb2 /chroot
mount --bind /dev /chroot/dev
mount --bind /dev/pts /chroot/dev/pts
mount --bind /proc /chroot/proc
mount --bind /sys /chroot/sys
mount --bind /run /chroot/run
# chrootで作業
chroot /chroot
# mount /dev/<ドライブ名><パーティション番号（UEFIシステムパーティション）> /boot/efi
mount /dev/sdb1 /boot/efi
# device.map ファイルを作成。これを行わないとgrub-installでdevice.mapが見つからない旨が表示される（ただし、エラーとしてgrub-installが終了しないので分かりにくい）。
grub-mkdevicemap
grub-install --efi-directory=/boot/efi --debug --root-directory=/ --target=i386-pc /dev/sdb
# 他にも以下のようなオプションがある。ただし、--recheckを入れるとdevice.mapが消えてエラーになる。
# grub-install --force --efi-directory=/boot/efi --debug --root-directory=/ --target=x86_64-efi --removable --bootloader-id=GrubUbuntu /dev/sdb
```

### 7. /etc/fstabを書き換え

```bash
# chroot /chroot でchrootに入ったままの状態
update-grub
# /dev/sdb1のUUIDを控えておく
blkid /dev/sdb1
# /dev/sdb1: UUID="41F9-4C31" TYPE="vfat" PARTUUID="b235d56d-4e68-4221-9b72-ffd65fdb684d"
# この場合、41F9-4C31を控えておく
# 以下を実行し、編集画面上で同じ桁のUUIDを控えておいたUUIDに書き換える
nano /etc/fstab
```

この場所で間違い入力があった場合、このディスクを使った起動時に`[ FAILED ]` が頻出して起動しなくなる。

### 8. grub.cfgを書き換え

起動時のブートオプションの内容の作成と編集を行う。

> https://mthsky.blogspot.com/2016/06/centos7-restarting-system.html

```bash
# 念の為grub.cfgをバックアップを取って作成
mv /boot/efi/boot/grub/grub.cfg /boot/efi/boot/grub/grub.cfg.old
# デフォルトの設定を変更する。以下を実行して、`GRUB_CMDLINE_LINUX` の末尾に `reboot=p acpi=off`を追記。reboot=pは、システム終了したあとにCUIから電源が切れないため、追加する。
sudo nano /etc/default/grub
# grub.cfgを再出力
grub-mkconfig -o /boot/efi/boot/grub/grub.cfg
```

### 9. アンマウントとchroot解除

再起動したら意味はないが、念の為アンマウント

```bash
umount /boot/efi
exit
umount /chroot/run
umount /chroot/sys
umount /chroot/proc
umount /chroot/dev/pts
umount /chroot/dev
umount /chroot
rm -rf /chroot
exit
```

以上、あとは再起動してBIOSでUbuntuが起動するように設定する。

> https://kledgeb.blogspot.com/2015/11/efibootmgr-2-uefi.html
> https://pc.shigizemi.com/2016/09/01/efibootmgr-not-working/
> https://wiki.ubuntulinux.jp/UbuntuTips/Others/ReinstallGrub2
> WindowsとUbuntuの共存時のエラー
> https://forums.ubuntulinux.jp/viewtopic.php?pid=124598
> https://askubuntu.com/questions/1356436/ubuntu-20-04-fails-to-boot-after-i-ran-bcdedit-set-bootmgr-path-efi-ubuntu
> GRUB_TIMEOUTを0以外にする。
> https://wiki.archlinux.jp/index.php/GRUB
> http://it.english-and-paso.com/ubuntu-dualboot/