# Gentoo 安裝
- 以 UEFI + GPT 開機,systemd 為 init system 為例
- 除了 PVE 的設定外,幾乎都是參考官方手冊,照著手冊做應該不太有問題
- [Gentoo AMD64 Handbook](https://wiki.gentoo.org/wiki/Handbook:AMD64)
- **注意**: 因為官方的手冊是 wiki 的格式,我發現前幾天有被人改過而且內容感覺是錯的
- 現在已經修正回來了,暫時可以安心服用
- 不過建議在貼上指令前多看兩眼
## 建立 VM
- **OS**
- ISO image 選擇 install-amd64-minial
- **System**
- BIOS 選擇 OVMF (UEFI)
- 選擇 UEFI 後,下面會多出 EFI Storage 的選項,選擇選單裡面唯一的那一項

- **Disk**
- 把 SCSI 換成 SATA,UEFI 才能直接讀到 GPT 磁區

- **CPU**
- 建議四到八核
- **Memory**
- 建議 8192 MiB (8GiB)
### UEFI 設定
在 PVE 上使用 UEFI 開機,可能會不能從 ISO Image 開機,需要關閉 secure boot
> 參考 https://github.com/rancher/k3os/issues/792
- 開機一看到畫面後,**按著 Esc** 不放進入 UEFI 的設定介面

- 進到設定介面後,選擇 **Device Manager**

- 用上下鍵選擇,Enter 確認
- 選擇 **Secure Boot Configuration**

- 預設是 Enable

- 用上下鍵控制選項,選擇中間的 **X** 並按 enter,會出現一個視窗,提示我們需要 reset,按下任意鍵可以關閉此視窗

- 按兩次 Esc 退到主畫面,用上下鍵選擇 Reset 並按 Enter 執行

- 如果設定成功,會進入 GRUB 畫面,選擇 Boot LiveCD

- ~~畫面上方有一排企鵝,代表成功用 UEFI 模式開啟~~

- ~~如果沒有企鵝,表示系統使用的是 BIOS~~
- 2024/12/19: 現在版本好像沒有企鵝了 QQ
## Gentoo 安裝
- Gentoo 的開機光碟中包含一個可以開機、執行的作業系統
- 安裝過程中,必須透過這個作業系統分割硬碟磁區、並安裝 Gentoo
- 概念上是透過這個暫時的作業系統編譯出另一個作業系統
- 把編譯的結果存在硬碟中,之後從硬碟開機就會進到編譯好的作業系統中
- 以下稱這個環境為 livecd
- livecd 提供的檔案系統類似 initramfs,是存在 RAM、**暫時性的檔案系統**
- 提供必要的環境、檔案和程式
- 安裝過程中的 **某些設定不會保留到安裝結束** 後
- 後面會用到 chroot 工具,切換系統的 root directory
- **chroot 之前**做的設定通常 **不會被保留**
- 系統最終會放在 livecd 的 */mnt/gentoo* 路徑底下
- */mnt/gentoo* 是安裝完成後,系統的根目錄
- 安裝過程中,放在 ***/mnt/gentoo* 之外的檔案,不會寫到硬碟中**
- 安裝分成下面幾個大步驟
- 分割硬碟
- 下載、解壓縮系統檔案和目錄
- 安裝、設定 Gentoo 系統
- 安裝 Linux kernel
- 設定系統並安裝工具和軟體
- 設定 bootloader (GRUB)
### 選擇鍵盤 Layout
- LiveCD 開機後,會停在下面畫面,詢問使用的鍵盤 Layout

- 一般的鍵盤選擇 us,輸入 43 並按 enter 繼續
- 不同版本可能會有不同的號碼,要依照實際情況輸入對應號碼
- 這邊如果太久沒有輸入,Gentoo 會自動選擇 us 並繼續往下
### 進入 LiveCD
- 最後會進到 livecd 的系統中,接下來的操作方式都和一般 Linux 的操作相同

- 目前狀態下,user 是沒有密碼的 root
### Optional: 安裝過程中使用 SSH
安裝過程中常會用到 `wget` 下載檔案,且檔案的 URL 都很長,所以可以 SSH 的話會比較方便
- SSH 的 user 必須有密碼
- 更改 root 的密碼
```
passwd
```
- 啟動 SSH server
```
/etc/init.d/ssh/sshd start
```
:::warning
**現在設定的密碼不會被儲存**
- 現在是 chroot 前,所有資料都存在 RAM 裡面,**不會存在硬碟中**
- 現在如果設過密碼,後面 **chroot 之後要記得再次設定密碼**
- 如果後面忘記要再設一次密碼,你會得到一台安裝完成但是沒辦法登入的機器
:::
:::info
**SSH 到 PVE 上的 VM**
- 可以透過 tailscale 等工具進行 Hole punching
- 我的作法是在其他 Ubuntu VM 上安裝 tailscale
- 先 SHH 連線到 Ubuntu
- 在 Ubuntu 中用 LAN 的 IP 連上 Gentoo
- 在 Gentoo 上可以直接用 `ifconfig` 或 `ip a` 查看 IP
- 應該會是 192.168.110.XX
:::
## 硬碟分割
至少需要三個磁區
- **boot**: 用於開機的磁區,官方建議 **1GB**
- 如果是 **UEFI** 開機,格式化時要選擇 **fat32** (vfat)
- 如果是 BIOS 開機,格式化時要選擇 xfs
- **swap**: 作為虛擬記憶體的磁區,官方建議是 RAM Size $\times$ 2
- 參考 https://www.atatus.com/blog/what-is-swap-space/
- **root**: 剩下的硬碟空間,儲存系統的所有檔案
- 通常格式化時使用 **xfs**
- 官方文件提到如果磁區小於 8GB,應該使用 ext4
筆記中會把系統安裝在硬碟 /dev/sda,如果要安裝在其他硬碟上,要把指令中的 `/dev/sda` 換成要使用的硬碟
這邊以 32GB 的硬碟為例
| 硬碟名稱 | 掛載點 | 系統格式 | 用途 | 大小 |
|:---------:|:---------:|:--------:|:--------------:|:----:|
| /dev/sda1 | /boot/efi | vfat | EFI 開機 (ESP) | 1GB |
| /dev/sda2 | | swap | Swap | 4GB |
| /dev/sda3 | / | xfs | 根目錄 | 27GB |
### 使用 fdisk 切割硬碟
- 切割 `/dev/sda`
```
fdisk /dev/sda
```
- 輸入 `g` 建立 GPT (GUID Partition Table)
```
Command (m for help):g
Created a new GPT disklabel (GUID: 87EA4497-2722-DF43-A954-368E46AE5C5F).
```
- 輸入 `p` 查看目前硬碟設定
```
Command (m for help):p
Disk /dev/sda: 32.0 GiB, 34359738368 bytes, 67108864 sectors
Disk model: DataTraveler 2.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 87EA4497-2722-DF43-A954-368E46AE5C5F
```
- 檢查倒數第二行,確認使用 GPT
### 建立 ESP
- 輸入 `n` 建立新磁區,並輸入分區資訊,
- 除了 Last sector,其他都可以用預設值,可以直接按 enter
- Last sector 輸入 `+1G`,建立一個大小 1GB 的磁區
```
Command (m for help):n
Partition number (1-128, default 1):
First sector (2048-60549086, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-60549086, default 60549086): +1G
Created a new partition 1 of type 'Linux filesystem' and of size 1 GiB.
```
- 輸入 `t` 設定磁區的類型,輸入 1 把磁區 1 設為 **EFI System**
```
Command (m for help):t
Selected partition 1
Partition type (type L to list all types): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.
```
- 如果不確定 EFI System 對應的編號,可以輸入 `l` 查看所有分區類型和對應的編號
### 建立 Swap
- 輸入 `n` 建立新分區,設定 Last sector 時輸入 `+4G` 建立一個大小 4GB 的分區
```
Command (m for help):n
Partition number (2-128, default 2):
First sector (526336-60549086, default 526336):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (526336-60549086, default 60549086): +4G
Created a new partition 2 of type 'Linux filesystem' and of size 4 GiB.
```
- 輸入 `t`,並在設定類型時選擇 19,將分區 2 設定為 `Linux swap`
```
Command (m for help):t
Partition number (1,2, default 2):
Partition type (type L to list all types): 19
Changed type of partition 'Linux filesystem' to 'Linux swap'.
Creating the root partition
```
### 建立 Root
- 輸入 `n` 建立新分區,使用硬碟剩餘的所有空間
- 可以全部使用預設值,所以一直按 Enter 就可以了
- 輸入 `p` 查看目前硬碟設定
```
Command (m for help):p
Disk /dev/sda: 32.0 GiB, 34359738368 bytes, 67108864 sectors
Disk model: DataTraveler 2.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 87EA4497-2722-DF43-A954-368E46AE5C5F
Device Start End Sectors Size Type
/dev/sda1 2048 526335 524288 1G EFI System
/dev/sda2 526336 8914943 8388608 4G Linux swap
/dev/sda3 8914944 67108830 58193886 27G Linux filesystem
```
- 檢查下方分區設定,需要有 `sda1`~`sda3`
- 類型分別為 `EFI System`、`Linux swap`、`Linux filesystem`
- 大小分別為 `1G`、`4G`、`27G`
### 儲存分區設定
輸入 `w` 寫入設定
```
Command (m for help):w
```
### 格式化分區
- 格式化 `/dev/sda1`
```
mkfs.vfat -F 32 /dev/sda1
```
- 格式化 `/dev/sda3`
```
mkfs.xfs /dev/sda3
```
:::info
若有其他較小型的分區 (小於 8GB),應該使用 ext4 格式
```
mkfs.ext4 -T small /dev/<device>
```
:::
- 初始化 Swap 分區
```
mkswap /dev/sda2
```
- 啟用 Swap
```
swap /dev/sda2
```
### 掛載 root
```
mount /dev/sda3 /mnt/gentoo
```
- 如果 */mnt/gentoo* 不存在,用 `mkdir` 建一個
```
mkdir -p /mnt/gentoo
```
## 下載系統檔案 (stage3)
需使用 `wget` 下載 Gentoo 必要的系統檔案,所以要先確認目前系統上的時鐘。如果誤差太大需要先設定時間,避免無法上網
- 查看目前時間
```
date
```
- 手動設定系統時間,格式是 MMDDhhmmYYYY (月、日、時、分、年)
```
date 092313002023 # 2023/09/23 13:00
```
- 透過 NTP 自動校正
```
chronyd -q
```
### 選擇 Stage
Stage 中包含所有系統必要的檔案,例如資料夾結構、套件、軟體、函式庫 ...
- 根據不同的系統需求,官方有提供不同的 Stage
- 使用 OpenRC 或 Systemd
- 是否使用 Desktop 環境
- 函式庫是 64+32 bit (multilib)、純 32bit 或是純 64bit
- 不管選哪一個都可以順利安裝,並在日後修改
- 但是手動修改這些設定難度很大,建議一開始就選好
- **注意**: CPU 架構選錯可能會裝不起來,**左邊的是 x86** (amd64)
瀏覽器打開 [官方下載頁面](https://www.gentoo.org/downloads/),並複製要使用的 Stage 的下載連結

- 建議選擇只有寫 systemd 的版本 (使用 systemd、沒有 GUI、multilib)
:::success
如果沒辦法成功用 SSH 連線或啟用 xterm.js、也不想手刻連結,可以參考官方文件,使用內建的、文字介面的瀏覽器取得連結
https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Stage#Command-line_browsers
:::
### 下載並解壓縮
- 切換到 */mnt/gentoo*
```
cd /mnt/gentoo
```
- 使用 `wget` 下載,並貼上剛剛的連結
```
wget <URL of Stage3>
```
- 解壓縮下載的檔案
```
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
```
- `x`: 解壓縮
- `p`: 保留檔案權限
- `v`: 詳細模式,會列出被解壓縮的檔案
- `f`: 表示下個參數是要被處理的檔案
## 安裝 Gentoo 系統
### 編譯設定
- livecd 中沒有 `vim`,但可以用 `nano` 編輯
- `nano` 的所有快捷鍵都顯示在畫面下方了
- ^ 表示 Ctrl
- 所以 ^O 表示 Ctrl+o
- `nano` 只有一個模式,所以可以直接編輯檔案
- 打開 */mnt/gentoo/etc/portage/make.conf*
```
nano /mnt/gentoo/etc/portage/make.conf
```
- 可以在 `COMMON_FLAGS` 中加入 `-march=native`,在編譯時針對 CPU 優化
```bash
# Compiler flags to set for all languages
COMMON_FLAGS="-march=native -O2 -pipe"
# Use the same settings for both variables
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
```
- 可以在檔案中加入 `MAKEOPTS`,並設為 `"-j<n>"`,編譯時會開啟 n 個 thread 平行執行
```bash
MAKEOPTS="-j4" # 編譯、安裝時使用 4 個 thread
```
- 在 `nano` 中,按 **Ctrl+o 存檔**,**Ctrl+x 離開**
:::warning
- Thread 的數量不是越多越好,要考慮 CPU 的核心數量和 RAM 的大小
- 後面安裝 Gentoo 系統時,可以選擇安裝預先編譯好的版本或是重新編譯
- 如果選擇**重新編譯**,**每一個 thread 需要 2GB 的 RAM**
- 所以如果只有 8GB RAM,最多就只能有 4 個 thread
:::
### Optional: mirror 設定
- 使用 mirrorselect 指令選擇 mirror 的來源,此指令會進入一個互動式的介面
- 用上下鍵移動游標
- 按空白鍵勾選游標選擇的 mirror site
```
mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf
```
- 建置 Gentoo ebuild repository
```bash
# 在 /etc 底下建立完整目錄
mkdir --parents /mnt/gentoo/etc/portage/repos.conf
```
```bash
# 從共享文件中把設定檔複製到剛才的目錄
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
```
### 複製 DNS 資訊
```
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
```
### 掛載必要的檔案系統
```
mount --types proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev
mount --bind /run /mnt/gentoo/run
mount --make-slave /mnt/gentoo/run
```
### Chroot
> chroot 完記得重設一次密碼