###### tags: `Gentoo` # Gentoo Installation (amd64) [TOC] 幾乎所有的作業系統安裝流程都是分割硬碟、格式化硬碟、複製檔案或解壓縮檔案到硬碟上、設定 bootloader,最後在 chroot 環境裡根據硬體及使用環境做完一些基本設定後重新開機。大部分的作業系統安裝程式都被包裝成可以無腦安裝的形式,安裝 Gentoo 則需要手動進行這些流程。 ## 開機及啟用 sshd 參閱官方 [Gentoo AMD64 Handbook](https://wiki.gentoo.org/wiki/Handbook:AMD64) 的 [choosing the right installation medium](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Media)。 1. 到 [Gentoo 官網](https://www.gentoo.org/downloads/)下載 amd64 的 Minimal Installation CD。 * 如果需要使用 USB 隨身碟開機,下載 [Rufus](https://rufus.ie/) 製作開機隨身碟。 2. 在 BIOS 設定成以 USB 隨身碟開機。 * 如為 legacy 開機模式,會先看到 boot: 提示符號,在這後面輸入 `gentoo-nofb nox`。 3. 用 `ifconfig` 確認主機 IP 位址供後續 ssh 連線用。 * 在有 DHCP server 的環境下進行安裝的話在這步驟只要看 IP 位址就好。 * 沒有 DHCP server 的環境必須依照 [configuring the network](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Networking) 的說明設定網路。 4. 設定 root 密碼。 5. 執行 `rc-service sshd start` 啟動 sshd。 * 如有必要的話先用 `nano -w /etc/ssh/sshd_config` 編輯相關設定再啟動,某些特定情況下會需要設定 `PasswordAuthentication yes`。 6. 回到自己電腦以慣用的 ssh client 連線到主機進行後續安裝。 ## 磁碟分割及格式化 參閱 handbook 的 [preparing the disks](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Disks),這裡以安裝 UEFI 系統至 `/dev/sda` 為例。 1. 執行 `parted -a optimal /dev/sda` 開始分割硬碟。 2. 輸入 `mklabel gpt` 建立 GPT 分割表。 3. 依序輸入下列指令建立磁碟分割區: ``` mkpart primary fat32 0% 3mb name 1 grub set 1 bios_grub on mkpart primary fat32 3mb 153mb name 2 boot set 2 boot on mkpart primary ext4 153mb 60.2gb name 3 rootfs mkpart primary ext4 60.2gb 90.2gb name 4 var mkpart primary linux-swap 90.2gb 122.2gb name 5 swap mkpart primary ext4 122.2gb -1s name 6 home ``` :::info * 較為正式的系統,`/` 會分割 15 ~ 30GB,`/usr` 會分割 50 ~ 70GB (如果不想獨立分割 `/usr` 則與 `/` 合併計算),`/var` 分割 20 ~ 30GB,`swap` 會分割 32GB,其餘分割給 `/home`;部分軟體的資料如 mysql server 的預設 database 路徑會使用 `/var`,建議修改它的設定檔放到 `/home` 去;商用套裝軟體有時會被安裝在 `/opt` 下,但一般沒有特別獨立出 `/opt` 分割區,所以會佔用到 `/` 的空間,這種時候會建議建立符號連結將 `/opt` 指到 `/home` 分割區下的某個路徑。 * boot 分割區是 UEFI 系統需要用到的,一般掛在 `/boot/efi` 這個路徑下,而且必須是 `fat32` 格式,通常只要能容納約 128KB 的 `grubx64.efi`。習慣上 UEFI 系統不單獨分割 `/boot` 分割區,只會把 `/boot/efi` 獨立出來。 * 非 UEFI 系統也需要一個 boot 分割區,一般掛在 `/boot` 這個路徑下,不需要是 `fat32` 檔案系統,必須夠大且能容納 kernel 及 initramfs。 * 如果需要獨立的 `/usr` 分割區,做 kernel 時需要一併製作 initramfs 將該檔案系統對應的 fsck 工具放進去,ext4 檔案系統的 fsck 工具在 /sbin 目錄中,不需要這個步驟。 * 如果不想要使用 interactive mode 進行分割,上述指令也能當參數銜接在 `parted /dev/sda` 之後,譬如 `parted /dev/sda mklabel gpt`,需要以 script 大量部署機器時可以考慮使用。 * 如果虛擬機器內的虛擬磁碟機設定在實體機器的 SSD 上,建議在傳統硬碟上另外造一個 swap 空間專用的虛擬磁碟機,否則在記憶體分配不夠大的情況下使用 `make -j<N>` 會對 swap 空間進行大量的寫入操作,SSD 的壽命損耗速度會很驚人。 ::: :::warning * 不使用 swap 空間的話必須確保系統上有安裝足夠的記憶體,否則在使用 emerge 以 `make -j<N>` 編譯套件原始碼時可能出現記憶體不足的錯誤。在虛擬機器內因為常分配較少的記憶體,沒有 swap 空間且 N 值夠大時容易造成 make 失敗。 ::: 4. 輸入 `print` 指令確認分割結果: ``` Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 3146kB 2097kB fat32 grub bios_grub 2 3146kB 153MB 150MB fat32 boot boot, esp 3 153MB 60.2GB 60.0GB ext4 rootfs 4 60.2GB 70.2GB 10.0GB ext4 var 5 70.2GB 122.2GB 32.0GB linux-swap swap 6 122.2GB 300GB 177.8GB ext4 home ``` :::warning * `set 1 bios_grub on` 和 `set 2 boot on` 容易被遺忘,沒執行到的話這邊不會出現對應的 flags,務必做好檢查。 ::: 5. 輸入 `quit` 退出 parted。 6. 依序執行以下指令格式化分割區: ``` mkfs.vfat -F 32 /dev/sda2 mkfs.ext4 /dev/sda3 mkfs.ext4 /dev/sda4 mkswap /dev/sda5 mkfs.ext4 /dev/sda6 ``` 7. 執行 `swapon /dev/sda5` 啟用 swap 空間。 8. 依序執行下列指令建立空目錄及掛載分割區: ``` mount /dev/sda3 /mnt/gentoo mkdir /mnt/gentoo/var mkdir /mnt/gentoo/home mkdir -p /mnt/gentoo/boot/efi mount /dev/sda2 /mnt/gentoo/boot/efi mount /dev/sda4 /mnt/gentoo/var ``` :::info * /home 分割區在安裝階段不需要掛載。 * 先前有建立 /usr 分割區的在這階段也需建立對應目錄及掛載。 ::: ## 安裝 stage3 並進入 chroot 環境 參閱 [installing the Gentoo installation files](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Stage) 及 [installing the Gentoo base system](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base) 前半部分。 1. 回到 [Gentoo 官網](https://www.gentoo.org/downloads/)下載 amd64 的 stage3 tarball,這裡選用 [openrc](https://wiki.gentoo.org/wiki/OpenRC) 的版本。如有需求,也可以在此選用 [systemd](https://wiki.gentoo.org/wiki/Systemd) 的版本。 2. 在 `/mnt/gentoo` 以 tar 指令解開 stage3 tarball,tar 解壓縮參數使用 `xpvf <filename> --xattrs-include='*.*' --numeric-owner`。 3. 執行 `nano -w /mnt/gentoo/etc/portage/make.conf` 編輯 make.conf,修改內容如下: ```! # built this stage. # Please consult /usr/share/portage/config/make.conf.example for a more # detailed example. COMMON_FLAGS="-O3 -pipe -fomit-frame-pointer -march=native -mtune=native" CFLAGS="${COMMON_FLAGS}" CXXFLAGS="${COMMON_FLAGS}" FCFLAGS="${COMMON_FLAGS}" FFLAGS="${COMMON_FLAGS}" MAKEOPTS="-j8 -l8" # WARNING: Changing your CHOST is not something that should be done lightly. # Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing. CHOST="x86_64-pc-linux-gnu" USE="aes avx avx2 fma3 mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3 -bindist threads vim-syntax" # NOTE: This stage was built with the bindist Use flag enabled PORTDIR="/usr/portage" DISTDIR="/usr/portage/distfiles" PKGDIR="/usr/portage/packages" # This sets the language of build output to English. # Please keep this setting intact when reporting bugs. LC_MESSAGES=C GENTOO_MIRRORS="http://ftp.twaren.net/Linux/Gentoo/ http://ftp.iij.ad.jp/pub/linux/gentoo/" ACCEPT_LICENSE="*" ACCEPT_KEYWORDS="~amd64" FEATURES="splitdebug" GRUB_PLATFORMS="emu efi-32 efi-64 pc" ``` :::info * `PORTDIR`、`DISTDIR`、`PKGDIR` 在新版 stage3 提供的 make.conf 預設會放在 /var 下面,這些檔案有相當程度的大小,可根據磁碟分割方式自行決定位置。 * MAKEOPTS 必須根據 CPU threads 數做調整。 * USE 當中的 `aes avx avx2 fma3 mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3` 必須根據 CPU 特性調整,參考 `/proc/cpuinfo` 的內容。 * `ACCEPT_KEYWORDS` 選用 `~amd64` 是選用 amd64 平台的 testing 套件分支,詳情參閱[官網的說明](https://wiki.gentoo.org/wiki/KEYWORDS)。 * 使用 `valgrind` 除錯需要各套件是在啟用 `splitdebug` 這項 feature 的前提下編譯出來的。 * 如果是要在 `docker build` 的環境下建立 Gentoo 系統的 docker image,FEATURES 應加上 `-ipc-sandbox -pid-sandbox -mount-sandbox -network-sandbox`。 * `GENTOO_MIRRORS` 這行可以使用 `mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf` 產生,需要在國外安裝主機時需要從這裡重新選取。 ::: 4. 執行下列指令建立預設的 ebuild repository 設定檔 ```! mkdir -p /mnt/gentoo/etc/portage/repos.conf cp -a /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf ``` 5. 執行 `nano -w /mnt/gentoo/etc/portage/repos.conf/gentoo.conf` 將內容修改如下: ``` [DEFAULT] main-repo = gentoo [gentoo] location = /usr/portage sync-type = rsync sync-uri = rsync://rsync.tw.gentoo.org/gentoo-portage auto-sync = yes sync-rsync-verify-jobs = 1 sync-rsync-verify-metamanifest = yes sync-rsync-verify-max-age = 24 sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc sync-openpgp-keyserver = hkps://keys.gentoo.org sync-openpgp-key-refresh-retry-count = 40 sync-openpgp-key-refresh-retry-overall-timeout = 1200 sync-openpgp-key-refresh-retry-delay-exp-base = 2 sync-openpgp-key-refresh-retry-delay-max = 60 sync-openpgp-key-refresh-retry-delay-mult = 4 sync-webrsync-verify-signature = yes ``` :::info * 第一個修改點是將 `location` 修改為 `/usr/portage`,這個跟 `make.conf` 中的 `PORTDIR` 對應。 * 第二個修改點是將 `sync-uri` 修改為 `rsync://rsync.tw.gentoo.org/gentoo-portage`。如果要在台灣以外的地方安裝系統,可以透過 `mirrorselect -i -r -o` 選取適合的 rsync server。 ::: 6. 使用 `date` 指令確認時間,如果不正確,執行 `ntpd -q -g` 或 `ntpdate clock.stdtime.gov.tw` 校正時間。 * 此時尚未設定 timezone,應留意使用 `date` 檢查時間時,其輸出時區是 `UTC`。 7. 執行 `cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf` 複製 DNS server 設定。 8. 執行下列指令掛載特殊檔案系統並進入 chroot 環境 ``` mount --types proc /proc /mnt/gentoo/proc mount --rbind /sys /mnt/gentoo/sys mount --rbind /dev /mnt/gentoo/dev chroot /mnt/gentoo /bin/bash source /etc/profile export PS1="(chroot) ${PS1}" ``` :::info * `export PS1="(chroot) ${PS1}"` 用來變更命令列提示符號,提醒自己是在 chroot 環境下,可以隨意自訂。 ::: 選用 systemd profile 的話在 chroot 前還需要額外執行這兩行: ``` mount --make-rslave /mnt/gentoo/sys mount --make-rslave /mnt/gentoo/dev ``` ## 初始化套件系統及更新 world 參閱 [installing the Gentoo base system](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base) 後半部分。 1. 修改 `/etc/locale.gen` 並執行 `locale-gen`,建議的 `/etc/locale.gen` 內容如下: ``` C.UTF8 UTF-8 en_US.UTF-8 UTF-8 zh_CN.UTF-8 UTF-8 zh_TW.UTF-8 UTF-8 zh_TW BIG5 ``` 2. 使用 `eselect locale set <N>` 選取系統預設的 locale,列表可用 `eselect locale list` 查看,一般建議使用 `C.UTF-8`。 3. 執行 `emerge-webrsync` 下載 portage tree。 4. 執行 `emerge --sync` 同步最新的 portage tree。如果結束後提示要更新 portage 套件 (`* An update to portage is available. It is _highly_ recommended that you update portage now, before any other packages are updated.`),做完後面兩步選完 profile 和設完時區後,執行 `emerge --oneshot sys-apps/portage` 進行更新。提示執行 `eselect news read` 閱讀注意事項時 (`* IMPORTANT: 5 news items need reading for repository 'gentoo'. Use eselect news read to view new items.`),可以照著執行一次讀完全部,或者執行 `eselect news list` 後再用 `eselect news read <N>` 來閱讀指定的項目。 :::info * 在系統預設 python 版本變遷的過渡時期,執行 `emerge --oneshot sys-apps/portage` 可能遭遇套件相依性問題,此時應閱讀 news 的內容來自力救濟。 * 看到下面的訊息時通常是 rsync server 中風,暫時更換 `/etc/portage/repos.conf/gentoo.conf` 裡的 `sync-uri` 或者新增一行 `sync-allow-hardlinks = no` 通常可以解決: ```! * Verifying /usr/portage/.tmp-unverified-download-quarantine ...!!! Manifest verification failed: Manifest mismatch for app-vim/project/Manifest __exists__: expected: True, have: False ``` ::: 5. 使用 `eselect profile set <N>` 選取 profile,列表可用 `eselect profile list` 察看,一般建議選取 `default/linux/amd64/<version>/no-multilib (stable)`。如果先前下載的 stage3 為 systemd 版而不是 openrc 版,這邊應選擇 `default/linux/amd64/<version>/systemd (stable)`。 6. 執行下列指令設定時區 ``` echo "Asia/Taipei" > /etc/timezone emerge --config sys-libs/timezone-data ``` 7. 如果記憶體夠大,可以參閱官方文件 [Portage TMPDIR on tmpfs](https://wiki.gentoo.org/wiki/Portage_TMPDIR_on_tmpfs) 將 build 套件的暫存目錄放到記憶體上,官方推薦使用這個方式來延緩 SSD 壽命的損耗。大致上的做法是在 `/etc/fstab` 裡加上下面這行後執行 `mount -a`: ``` tmpfs /var/tmp/portage tmpfs size=4G,uid=portage,gid=portage,mode=775,nosuid,noatime,nodev 0 0 ``` 8. . 執行 `emerge -vp gcc` 確認套件系統中的 GCC 是否比目前安裝的版本還新,如果是的話,執行 `emerge gcc` 更新 GCC。更新完 GCC 後再執行 `gcc-config <N>` 切換系統 GCC 版本,可用 `gcc-config -l` 查詢可用選項。切換完系統 GCC 版本後,執行 `source /etc/profile` 更新當前 shell 環境變數。 9. 執行 `emerge -e @world` 重新編譯整個 world 的所有套件,如果上個步驟中已經編譯過 GCC 的話,可以改用 `emerge -e --exclude=sys-devel/gcc @world` 節省時間。 * 如果對於系統效能不感興趣,這一步按照官方 handbook 使用 `emerge --update --deep --newuse @world` 更新 world 即可。 10. 如果更新完 world 後看見下面的訊息,應該執行 `perl-cleaner --all` 重新安裝 perl 模組,否則可能會在安裝其它套件時遇到類似 `Can't locate Locale/gettext.pm in @INC` 的錯誤訊息: ``` * Messages for package dev-lang/perl-<version>: * UPDATE THE PERL MODULES: * After updating dev-lang/perl the installed Perl modules * have to be re-installed. In most cases, this is done automatically * by the package manager, but subsequent steps are still recommended * to ensure system consistency. * * You should start with a depclean to remove any unused perl dependencies * that may confuse portage in future. Regular depcleans are also encouraged * as part of your regular update cycle, as that will keep perl upgrades working. * Recommended: emerge --depclean -va * * You should then call perl-cleaner to clean up any old files and trigger any * remaining rebuilds portage may have missed. * Use: perl-cleaner --all ``` 11. 如果更新完 world 看見 `Use emerge @preserved-rebuild to rebuild packages using these libraries` 的提示,執行 `emerge @preserved-rebuild`。 12. 如果前面更新過 GCC,可以使用 `emerge --unmarge =sys-devel/gcc-<version>` 移除舊版 GCC。 13. 使用 `dispatch-conf` 指令來協助合併 `/etc` 裡的各種設定檔,或者使用 `find /etc -name '._cfg*'` 找出因為舊版設定檔存在而被擱置的新版設定檔,自己決定要覆蓋或是手動合併。 ## 編譯及安裝 kernel 參閱 [configuring the Linux kernel](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel)。 ### Option 1: 安裝 distribution kernel 適合懶人使用,比用 `genkernel` 還懶。 * 執行 `emerge sys-kernel/gentoo-kernel`,或者執行 `emerge sys-kernel/gentoo-kernel-bin` 安裝預先編譯好的 kernel。 * 這個安裝方式不適用於選用 systemd profile 的場合,但是想辦法偷 distribution kernel 的 `.config` 檔來小幅修改成適合在 systemd 環境用的版本是可行的。參閱[從 distribution kernel 換成自訂 kernel 的說明](https://hackmd.io/@tinlans/gentoo-maintenance#%E5%BE%9E-distribution-kernel-%E6%8F%9B%E6%88%90%E8%87%AA%E8%A8%82-kernel)先安裝 distribution kernel 再取出 `.config` 檔就行,不過因為沒有實際以這個 kernel 開機,所以是從 `/usr/src/linux/.config` 來獲取而不是去 `/proc/config.gz` 取得。實際上手動操作 `ebuild` 應該可以直接取出這個檔案而不用花時間編譯 distribution kernel,這個部分可以自行嘗試。 ### Option 2: 手動設定及安裝 kernel :::info * 如果要加快編譯速度,這裡可以使用 `make` 的 `-j<N>` 參數。假設 CPU 有 8 threads,下面用到 `make` 指令的地方都可以使用 `make -j8`。 * 預設使用 ld.gold 當 linker 的場合,編譯 kernel 時的 `make` 參數需要加上 `LD=ld.bfd` 強制使用傳統的 BFD linker,譬如 `make LD=ld.bfd -j8`,因為 kernel 的編譯不支援 gold linker。 * 選用 systemd profile 的場合,必要的 kernel 選項參閱[官方的說明頁](https://wiki.gentoo.org/wiki/Systemd)。 ::: 1. 執行 `emerge lshw` 及 `emerge pciutils` 安裝顯示硬體資訊的套件,透過這些工具來協助認識硬體配備和對應的驅動程式名稱。 2. 用 `emerge sys-kernel/gentoo-sources` 安裝 kernel source code,會裝在 `/usr/src` 下面,並建立一個符號連結 `/usr/src/linux`。 3. 執行下列指令進入 kernel 設定選單: ``` cd /usr/src/linux make menuconfig ``` :::info 如果打算從 distribution kernel 的設定來修改,可以執行 `ebuild /usr/portage/sys-kernel/gentoo-kernel/gentoo-kernel-<version>.ebuild configure` 後把 `/var/tmp/portage/sys-kernel/gentoo-kernel-<version>/work/build/.config` 放到 `/usr/src/linux` 目錄下再做 `make menuconfig`;記得執行 `ebuild /usr/portage/sys-kernel/gentoo-kernel/gentoo-kernel-<version>.ebuild clean` 清除先前的工作目錄。 ::: 4. 執行`make; make install` 編譯及安裝 kernel。 :::info 如果出現編譯失敗,可能是 `cpio` 沒有安裝,執行 `emerge cpio` 可以解決。 ::: 5. 執行 `make modules_install` 安裝 kernel modules,kernel modules 會被安裝到 `/lib/modules/<kernel version>/kernel` 裡面。 :::info * 如果先前有單獨建立 /usr 分割區且 roofs 的檔案系統不是 ext4 的話,需要先安裝對應的檔案系統工具,並額外安裝 `dracut` 並執行 `dracut -f --host-only --kver=<version>` 產生對應的 initramfs 檔案,其中 `<version>` 是 `/usr/src/linux` 的連結目錄名稱去除 `linux-` 的前綴,譬如 `5.11.4-gentoo`。 * 檔案系統工具可參考 [filesystem tools](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Tools#Filesystem_tools) 裡的表格。 * 如果有把各種驅動程式都編譯成 kernel modules 而不是內建在 kernel 裡的習慣,一般也需要 initramfs,譬如某些虛擬硬碟可能需要額外的驅動程式才能載入,這會導致 rootfs 所對應的裝置無法被 kernel 找到。 * 製作好 initramfs 之後,建議以 `lsinitrd /boot/initramfs-<version>.img | grep <driver name>` 的方式檢查需要的驅動程式是否已被放在裡面。 ::: ### 開機自動載入 kernel modules * 大部分的 kernel modules 在開機時會由 udevd 自動偵測並載入,只有無法自動偵測到的情況需要手動添加。 * 建立 `/etc/modules-load.d` 這個目錄,在裡面建立 `*.conf` 檔來自動載入需要的 kernel modules。 ### firmware 安裝 * 有些硬體 (特別是網路卡) 的驅動程式還需要搭配韌體才能正常運作,這時需要用 `emerge linux-firmware` 安裝韌體包。 ## 設定 bootloader 參閱 [configuring the bootloader](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Bootloader)。這邊以安裝 `grub2` 為例,近年有人推薦 `rEFInd` 可自行嘗試,可參閱 [rEFInd 的說明頁面](https://wiki.gentoo.org/wiki/Refind)。 1. `emerge grub` 2. `grub-install --target=x86_64-efi --efi-directory=/boot/efi` * 非 UEFI 系統執行 `grub-install /dev/sda` 或 `grub-install --no-floppy /dev/sda` * 如果開機光碟不是 Gentoo 官方的 minimal installation CD,可能會出現 `Could not prepare Boot variable: Read-only file system` 的錯誤,執行 `mount -o remount,rw /sys/firmware/efi/efivars` 即可正常執行 `grub-install`。 :::info 如果未來打算把硬碟拔去別台機器開機,這裡可以改執行 `grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable` 將 BOOTX64.EFI 安裝到 /boot/efi/EFI/BOOT 裡,而不是將 grubx64.efi 安裝到 /boot/efi/EFI/gentoo 並透過 efibootmgr 等工具記錄在 EFI BIOS 上。 ::: 3. 視需求修改 `/etc/default/grub`。 * 較舊的 CPU 可能會需要設定 `GRUB_CMDLINE_LINUX_DEFAULT="mitigations=off"` 犧牲安全性來提高效能,參閱 [HOWTO make Linux run blazing fast (again) on Intel CPUs](https://linuxreviews.org/HOWTO_make_Linux_run_blazing_fast_(again)_on_Intel_CPUs)。 :::info 如果選用 systemd profile 且不打算使用 initramfs 的話,應該在 `GRUB_CMDLINE_LINUX` 裡加入 `init=/lib/systemd/systemd`。如果有使用 dracut 產生 initramfs,通常 systemd 已經被放進去,就不需要加上。 ::: 4. 執行 `grub-mkconfig -o /boot/grub/grub.cfg` 產生 `grub.cfg`,會掃描 `/boot/vmlinuz*` 和 `/boot/initramfs*` 來產生開機選單。 ## 設定系統 參閱 [configuring the system](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/System)、[installing system tools](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Tools) 及 [finalizing the installation](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Finalizing)。 ### OpenRC 和 systemd 的共通部分 1. 建立 `/etc/fstab` 如下: ``` # <fs> <mountpoint> <type> <opts> <dump/pass> UUID=47B6-7C16 /boot/efi vfat noauto,noatime 1 2 UUID=03be0c9d-2bc6-4d3b-8414-a49615d12e52 / ext4 noatime 0 1 UUID=51e02091-906f-4610-8854-e2c870decc8d /var ext4 noatime 0 2 UUID=19ea6cfa-6c44-4989-b262-cb238e312c36 /home ext4 noatime 0 2 UUID=33ba0cd8-ce60-4bd9-9ac5-9825ea0f2ab0 none swap sw 0 0 ``` :::info * 上述 UUID 不可照抄,應使用 `blkid` 或 `ls -l /dev/disk/by-uuid` 確認。 * 可以用 `blkid` 的 `PARTLABEL` 欄位資料來確認對應關係,這是先前在使用 `parted` 分割磁碟時所設定的名稱。其中 `rootfs` 的對應 mountpoint 為 `/`,`swap` 的 mountpoint 為 `none`。 * 使用 `blkid` 查詢 `UUID` 時要留意 `PARTUUID` 和 `UUID` 是不同的,應該使用 `UUID` 欄位,如果不放心的話建議用 `ls -l /dev/disk/by-uuid` 來對照最終的 `/etc/fstab` 做雙重確認。 ::: 2. 在 `/etc/inputrc` 的適當處加入下列設定讓上下鍵可以進行 history search: ``` ## arrow up "\e[A": history-search-backward ## arrow down "\e[B": history-search-forward ``` :::info 這個功能是如果先前已經執行過 `docker build --no-cache -f <name>.dockerfile -t <name>:0.0.1 .` 這道指令的話,只要再輸入 `docker b` 這樣前半段相同的部分指令內容,再按:arrow_up:就能把 match 到的歷史指令 `docker build --no-cache -f <name>.dockerfile -t <name>:0.0.1 .` 叫出來,前提是那道指令還在 history buffer 裡。 ::: 3. 如果需要啟用 root 帳號,使用 `passwd` 修改 root 密碼。 4. 使用 `useradd` 指令新增使用者,使用 `passwd` 指令修改使用者密碼。 5. 安裝 `sudo` 套件,使用 `visudo` 進行設定。 6. 修改 `/etc/ssh/sshd_config`,如果要啟用 root 登入需要 `PermitRootLogin yes` 這項設定。習慣使用 public key authentication 方式登入的話,在這裡要記得把 public keys 放到指定帳號的 `~/.ssh/authorized_keys` 檔案中。 :::info * OpenSSH 8.8 開始預設禁止 ssh-rsa 形式的 key,如果要重新啟用,在 `/etc/ssh/sshd_config` 加入下面這兩行: ``` PubkeyAcceptedAlgorithms=+ssh-rsa HostKeyAlgorithms=+ssh-rsa ``` ::: 7. 安裝 `gentoolkit` 增加套件系統管理的便利性,其中 `equery` 是最常被使用到的指令,可參閱其[說明頁面](https://wiki.gentoo.org/wiki/Equery)。 8. 如果想要使用 [NetworkManager](https://wiki.gentoo.org/wiki/NetworkManager) 代替 OpenRC 的 [netifrc](https://wiki.gentoo.org/wiki/Netifrc) 或 systemd 的 [networkd service](https://wiki.gentoo.org/wiki/Systemd#systemd-networkd),需要執行 `emerge networkmanager` 安裝它。然後在 OpenRC 系統,執行 `rc-update add NetworkManager default` 讓它在開機時啟動,在 systemd 系統則需要執行 `systemctl enable NetworkManager.service`。`NetworkManager` 在純文字模式使用 `nmtui` 指令進行設定,並將設定內容儲存在 `/etc/NetworkManager/system-connections/*`。 :::info * 如果不希望 `NetworkManager` 接管某些網路卡並擅自啟用 DHCP,可以編輯 `/etc/NetworkManager/NetworkManager.conf` 並加入以下內容: ``` [main] plugins=keyfile [keyfile] unmanaged-devices=interface-name:eno3,interface-name:eno4 ``` 這個例子是避免讓 `NetworkManager` 接管 `eno3` 和 `eno4` 兩張網路卡。 ::: 9. 修改密碼複雜度限制 某個時間點開始 Gentoo 也要求密碼必須符合一定程度的複雜度限制,修改 `/etc/security/passwdqc.conf` 可以還原回舊版的設定: ``` min=8,8,8,8,8 max=40 passphrase=3 match=4 similar=deny random=47 enforce=everyone retry=3 ``` ### OpenRC 系統設定 1. 編輯 `/etc/conf.d/hostname` 加入主機名稱,譬如 `hostname="my-server1"`。 2. 選用 `NetworkManager` 的話,執行 `nmtui` 設定網路。選用 `netifrc` 的話則編輯 `/etc/conf.d/net` 內容如下: ``` modules="dhcpcd" dns_domain_lo="tinlans.org" config_eth0="dhcp" ``` :::info * 網路卡名稱不一定是 `eth0`,應根據 `ifconfig` 的輸出結果來判斷。 * 如果區域網路上沒有 DHCP server 需要設定固定 IP,可以仿照下列格式設定: ``` dns_domain_lo="tinlans.org" config_eth0="10.168.100.99 netmask 255.255.255.0 brd 10.168.100.255" routes_eth0="default via 10.168.100.254" ``` * 完整設定範例參考 `/usr/share/doc/netifrc-<version>/net.example.bz2`,可以使用 `bzcat` 或 `bzless` 指令閱讀。 ::: 3. 選用 `netifrc` 的話,執行下列指令讓系統在開機時自動啟用網路,必須代換 `eth0` 成實際的 interface name: ``` cd /etc/init.d ln -fs net.lo net.eth0 rc-update add net.eth0 default ``` 4. 將 `/etc/hosts` 裡 `127.0.0.1` 這行做適當修改,譬如 hostname 為 `my-server1` 的話,可以修改成 `127.0.0.1 my-server1.tinlans.org my-server1 localhost`。 5. 確認系統時鐘是否使用 UTC 時間,修改 `/etc/conf.d/hwclock` 的內容為 `clock="UTC"` 或 `clock="local"`,一般使用 `clock="local"`。 6. 執行 `rc-update add sshd default` 在開機完成後接受 SSH 登入。 7. 安裝 `sysklogd` 或 `syslog-ng` 並利用 `rc-update add` 設定開機自動啟動,讓系統 log 被寫入 `/var/log/*` 裡。 8. 安裝 `logrotate` 避免 log 檔爆掉。 9. 安裝 `cronie` 並執行 `rc-update add cronie default` 讓系統支援 cron jobs。 10. 其它還有什麼要裝的等重開進安裝好的系統裡之後再裝。 ### systemd 系統設定 參閱 Gentoo 官方的 [systemd 說明頁面](https://wiki.gentoo.org/wiki/Systemd)。如果是從 OpenRC 轉到 systemd 但不熟悉指令差異的話,可以參閱 Gentoo 官方提供的 [OpenRC to systemd Cheatsheet](https://wiki.gentoo.org/wiki/OpenRC_to_systemd_Cheatsheet)。 在 systemd 文件中提及有一組 [preset services](https://wiki.gentoo.org/wiki/Systemd#Preset_services) 可以使用 `systemctl preset-all` 一口氣啟用。如果想知道裡面有什麼並且自行決定啟用哪些部分,可以閱讀 `/lib/systemd/system-preset/90-systemd.preset` 這個檔案的內容,而在這裡的範例並不打算使用該指令開啟 preset services。 systemd 系統的設定幾乎只能重開到安裝後的系統裡才能做,所以要先按照後面的[重開機流程](https://hackmd.io/@tinlans/gentoo-installation#%E9%87%8D%E9%96%8B%E6%A9%9F%E9%80%B2%E5%85%A5%E5%AE%89%E8%A3%9D%E5%BE%8C%E7%9A%84%E7%B3%BB%E7%B5%B1%E8%A3%A1)開進安裝後的系統再進行設定。重開之後,執行 `systemctl status` 確認 systemd 已經在運作中,再按照下面流程設定系統: 1. 執行 `systemd-machine-id-setup` 產生 machine ID 並自動建立 `/etc/machine-id`。如果是從 stage4 tarball 安裝,先執行 `rm -f /etc/machine-id` 刪除該檔後再執行。 2. 執行 `hostnamectl set-hostname <hostname>` 修改主機名稱,這個指令會將主機名稱寫入 `/etc/hostname` 檔中。 3. 執行 `timedatectl set-timezone Asia/Taipei` 設定時區。 4. 設定網路: * 選用 `NetworkManager` 的話,先執行下列指令啟用 `NetworkManager` 再執行 `nmtui` 設定網路: ``` systemctl enable NetworkManager.service systemctl start NetworkManager.service ``` 如果所有網路卡都使用 DHCP 獲取 IP 則不需要設定,但還是建議執行 `nmtui` 檢查設定。 * 選用 `networkd` service 的話,如果使用 DHCP 獲取 IP 位址,新增一個檔案 `/etc/systemd/network/50-dhcp.network`,內容為: ``` [Match] Name=eth0 [Network] DHCP=yes ``` 如果使用靜態 IP,新增一個檔案 `/etc/systemd/network/50-static.network`,內容為 ``` [Match] Name=eth0 [Network] Address=10.168.100.99/24 Gateway=10.168.100.254 DNS=10.168.100.3 ``` 其中 `eth0` 為網路卡名稱,更詳細的設定格式可參閱 [systemd.network(5)](https://man7.org/linux/man-pages/man5/systemd.network.5.html)。依序執行以下指令以啟用網路: ``` systemctl enable systemd-networkd.service systemctl start systemd-networkd.service ``` 5. 如果透過 DHCP 獲取 DNS server 設定,編輯 `/etc/systemd/resolved.conf` 將預設搜尋網域加入 `Domains=`,譬如 `Domains=skymirror.com.tw`,然後依序執行以下指令以啟用 resolved service,並使用它所產生的 `resolv.conf` 檔: ``` rm -f /etc/resolv.conf systemctl enable systemd-resolved.service systemctl start systemd-resolved.service ln -fs /run/systemd/resolve/resolv.conf /etc/resolv.conf ``` 6. 將 `/etc/hosts` 裡 `127.0.0.1` 這行做適當修改,譬如 hostname 為 `my-server1` 的話,可以修改成 `127.0.0.1 my-server1.tinlans.org my-server1 localhost`。 7. 執行以下指令以啟用 sshd: ``` systemctl enable sshd.service systemctl start sshd.service ``` 8. 以 `emerge cronie` 安裝 `cronie`,再執行以下指令啟用它以支援 crontab: ``` systemctl enable cronie.service systemctl start cronie.service ``` 雖然官方文件建議安裝 `systemd-cron` 並啟用 `cron.target` 來模擬 cron 的行為,但這裡還是推薦使用 `cronie` 以獲得完整的使用體驗。另外,systemd 也推薦使用 [timer service](https://wiki.gentoo.org/wiki/Systemd#Timer_services) 來代替 cron,但不習慣的人還是很多,因此這邊還是建議安裝 `cronie`。 9. 預設啟動的 `journald` service 替代了以往的 `sysklogd` 或 `syslog-ng` 這類 log service 的角色,使用 [journalctl](https://wiki.gentoo.org/wiki/Systemd#Handling_of_log_files) 指令讀取 log,一般使用者如果要讀取 log 必須加入 `systemd-journal` 群組。預設最大使用 4GB 的空間,可以透過編輯 `/etc/systemd/journald.conf` 修改 `SystemMaxUse` 來調整,譬如 `SystemMaxUse=10G`。 10. 安裝 `logrotate` 防止會自行寫 log files 的程式把硬碟寫爆,安裝完後要執行 `systemd-tmpfiles --create /usr/lib/tmpfiles.d/logrotate.conf`。 11. `tmp.mount` 預設會將把 `tmpfs` 掛上 `/tmp`,最大可以佔用系統記憶體的 50%。變更它預設值的方式很多,systemd 推薦使用 `/etc/fstab` 的形式。首先執行 `systemctl cat tmp.mount` 查看設定,找到 `[Mount]` 段的 `Options` 的設定值,如果看到的內容是 `mode=1777,strictatime,nosuid,nodev,size=50%,nr_inodes=400k` 的話,對應的 `/etc/fstab` 設定如下: ``` tmpfs /tmp tmpfs mode=1777,strictatime,nosuid,nodev,size=50%,nr_inodes=400k 0 0 ``` 如果想將記憶體佔用量修改成 2GB,將 `size=50%` 修改成 `size=2G` 後重新開機即可。如果想讓設定立即生效,可以先執行 `systemctl stop tmp.mount` 後再執行 `mount -a`。因為 `tmp.mount` 只要發現系統上已經掛載 `/tmp` 就不會有任何動作,所以重新開機後會以 `/etc/fstab` 裡掛載 `/tmp` 的設定為主。 ## 重開機進入安裝後的系統裡 參閱 [rebooting the system](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Bootloader#Rebooting_the_system)。 1. 執行 `exit` 退出 chroot 環境。 2. 執行 `cd` 回到 `/root` 下,總之不能停留在 `/mnt/gentoo` 底下的任何路徑。 3. 執行 `umount -l /mnt/gentoo/dev{/shm,/pts,}` 和 `umount -R /mnt/gentoo`,如果無法 umount,確認上一步是否確實做到。 4. 執行 `reboot`,拔除 USB 隨身碟或取出安裝光碟,並進入 BIOS 設定中確認開機順序是否符合預期。 ## 其它常用套件 * `net-misc/ntp`: ntpdate, ntpd * `net-misc/netkit-telnetd`: telnet, telnetd * `net-ftp/ftp`: ftp * `net-misc/netkit-fingerd`: finger, fingerd * `net-misc/whois` * `net-dns/bind-tools`: host, nslookup, dig * `net-analyzer/traceroute` * `net-analyzer/tcptraceroute` * `net-analyzer/tcpdump` * `sys-apps/ethtool` * `sys-apps/ipmitool` * `sys-apps/lshw` * `dev-vcs/git` * `app-misc/screen` * `app-misc/tmux` ## stage4 tarball stage3 通常已經提供了一個預先編譯好的 world 環境,只需要自行編譯 kernel 並設定 bootloader 即可完成安裝;而 stage4 則是連 kernel 都編譯好,並且在 world 中可能還會預先安裝一些額外的套件,只要設定好 bootloader 即可完成安裝。Gentoo 官方並不會提供 stage4 tarball,需要自行製作。 ### 製作 stage4 tarball 參閱 [Mkstage4 - Stage 4 Tarballs Made Easy](https://www.tutorials.chymera.eu/blog/2014/05/18/mkstage4-stage4-tarballs-made-easy/)。 1. `emerge mkstage4` 2. `cd /home` 或選擇其它空間較大的分割區。 3. `mkstage4 -s <tarball name>`,會提示實際的指令內容是 `tar -cpP --ignore-failed-read --xattrs-include='*.*' --numeric-owner -j --exclude=/dev/* --exclude=/var/tmp/* --exclude=/media/* --exclude=/mnt/*/* --exclude=/proc/* --exclude=/run/* --exclude=/sys/* --exclude=/tmp/* --exclude=/var/lock/* --exclude=/var/log/* --exclude=/var/run/* --exclude=/var/lib/docker/* --exclude=/home/<tarball name>.tar.bz2 --exclude=/usr/portage/* --exclude=/usr/portage/distfiles/* -f /home/<tarball name>.tar.bz2 /`,按 yes 即會製作出 stage4 tarball,或者可以自行修改指令內容後手動執行。 ### 使用 stage4 tarball 安裝系統 按照標準安裝流程以[光碟開機](https://hackmd.io/@tinlans/gentoo-installation#%E9%96%8B%E6%A9%9F%E5%8F%8A%E5%95%9F%E7%94%A8-sshd)、[分割硬碟、格式化、掛載分割區](https://hackmd.io/@tinlans/gentoo-installation#%E7%A3%81%E7%A2%9F%E5%88%86%E5%89%B2%E5%8F%8A%E6%A0%BC%E5%BC%8F%E5%8C%96)後,把原本[解開 stage3 tarball](https://hackmd.io/@tinlans/gentoo-installation#%E5%AE%89%E8%A3%9D-stage3-%E4%B8%A6%E9%80%B2%E5%85%A5-chroot-%E7%92%B0%E5%A2%83) 的步驟改成解開原先自己製作好的 stage4 tarball 再 chroot,跳過 world 及 kernel 的編譯流程,直接[安裝 bootloader](https://hackmd.io/@tinlans/gentoo-installation#%E8%A8%AD%E5%AE%9A-bootloader) 並[設定系統](https://hackmd.io/@tinlans/gentoo-installation#%E8%A8%AD%E5%AE%9A%E7%B3%BB%E7%B5%B1)後即可[重新啟動](https://hackmd.io/@tinlans/gentoo-installation#%E9%87%8D%E9%96%8B%E6%A9%9F%E9%80%B2%E5%85%A5%E5%AE%89%E8%A3%9D%E5%BE%8C%E7%9A%84%E7%B3%BB%E7%B5%B1%E8%A3%A1)完成安裝。 解壓 stage4 tarball 時並不需要加入任何複雜的參數,使用 `tar xvjpf <tarball name>.tar.bz2` 即可,官方 handbook 推薦的 stage3 tarball 解壓參數 `--xattrs-include='*.*' --numeric-owner` 已經在製作 stage4 tarball 時加入。 :::info * 務必記得修改完 /etc/fstab 再重開機,否則無法正確掛載分割區。 * 使用 systemd 系統的話,重開機後要產生新的 machine id: ``` rm /etc/machine-id systemd-machine-id-setup ``` :::