Aug 2018 [EN||]

Ryzen 移动平台上安装 Gentoo Linux

Linux 内核对于跟进支持 Ryzen 移动低压 CPU 的热情似乎和市面上寥寥无几的 Ryzen 笔记本热度十分吻合。虽然从 Linux 4.11 起就对 Ryzen 桌面 CPU 有较好的支持,但是 4.17 以下的内核在其移动 CPU 上甚至无法正常载入。撰写本文时(2018.07),绝大多数发行版的默认内核版本皆 < 4.17,所以存在的几个激进的 Linux 发行版是我仅有的选择,Gentoo 便是其一。

翻阅了相较之前更为友善的 Gentoo Handbook 再加之这回有了一定折腾必要性。使用 Gentoo 的兴致就这么(又)被点燃了 😂,于是有了记录几个安装要点的本文。

使用 Arch Linux 安装镜像

Gentoo 官方提供的滚动更新的安装镜像匪夷地不支持 UEFI 启动 (2018.07)。它的确提供了一个产于 2016 年的支持 UEFI 启动的镜像。不过我清楚这个镜像在我的设备上一定无法正常加载,所以使用最新内核的 Arch 镜像似乎是最好的选择。

「Gentoo 安装镜像现在可以 UEFI 启动」
更新: Gentoo Handbook 的内容现在已经被更新。「As of August 23, 2018 the official Minimal CDs are capable of booting in UEFI mode. Previous versions boot in BIOS (MBR) mode only. Readers looking to make their system UEFI bootable must download the latest ISO.」正如它所说的,最新的 ISO 已经支持 UEFI 启动了。所以从现在开始,使用 Arch Linux 的安装镜像是不必要的了。

分区并准备使用 EFISTUB 引导

我的分区方案是遵从 Handbook 中的 Preparing the disks 章节,将 /root 分区挂载到 /mnt/gentoo 而后参考 EFI system partition 将 EFI 分区挂载到 /mnt/gentoo/esp,再将 /esp/EFI/Gentoo 挂载到 /mnt/gentoo/boot

这样一来,在保持 ESP 分区的整洁的同时,内核文件被更新后也不需要手动更新 /boot 中的文件。届时只需要使用老方法:把 /boot 下的一系列文件复制到 /esp/EFI/Gentoo 即可。

下载 Stage3 镜像

了解网络配置部分内容可参阅 Network configuration

Handbook 中推荐使用 Links 访问镜像站下载 Stage3 的镜像。Arch Linux 镜像不自带 Links,所以应该先使用 pacman 安装 Lynx 或 Links 来完成这一操作。我的做法是在制作 Arch Linux 引导盘时,提前将下载好的 Stage3 镜像复制到启动盘中,然后复制到 /mnt/gentoo 目录下。

修改预编译参数

需要在 make.conf 中添加或更改某些参数以增加对 Ryzen 的支持。

其中在 CFLAGS-march 后添加 znver1 是 Ryzen CPU 必须修改的参数。如果设备使用 Vega 的 GPU,那么应该加入 VIDEO_CARDS 参数 radeonsi。笔记本用户应加入 Synaptics 的支持。除此之外,GENTOO_MIRRORS 选择了速度十分可观的吞拿鱼 🐟,MAKEOPTS 参数遵循 CPU 核心数加一的原则,以 Ryzen 2700U 为例,即 -j5

以下是一个完整的 make.conf 的示例:

CFLAGS="-march=znver1 -O2 -pipe"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j5"
VIDEO_CARDS="amdgpu radeonsi"
INPUT_DEVICES="evdev synaptics"
LANGUAS="zh_CN"
GENTOO_MIRRORS="https://mirrors.tuna.tsinghua.edu.cn/gentoo"

其它的参数可参考 Configuring compile options

Rsync mirrors 的选择

Gentoo 允许通过编辑 portage 仓库的配置文件来指定 rsync 镜像服务器的地址。当然可以选择吞拿鱼或是 USTC 的源。

好奇心驱使我翻阅了 Gentoo 官方提供的 Gentoo rsync mirrors 页面,然而并没有找到来自中国大陆的镜像站 (2018.07),或许因为现有的中国大陆不论是高校还是企业的镜像站并没有达到 Gentoo 的标准?可是台湾同胞的源的速度又难以恭维。我无意中找到了由 KAIST 提供的 rsync 源。尽管只支持 IPv4,却有着令人十分满意的速度。这算是一个意外的发现吧。

恭喜清华喜托中国大陆唯一一个可用的 rsync mirror,现在这就是一个更好的选择了。

关于 --make-rslave

Mounting the necessary filesystems 中提到启用 Systemd 的支持需要 mount 后加入 --make-rslave 参数。mount 命令的 man page 表明这将递归地赋予目录以 slave 的 propagation type,即目录包括其下所有子目录跟随 master 变化,而自身变化时不通知 master 发生改变。

如果不使用 Systemd,也可以加入这个参数,这样一来则不可以使用 umount -R 强行卸载分区。

选择 Profile

使用 eselect 选择 profile 的时候,需要注意观察内核版本。对于 Gentoo 来说,撰写本文时(2018.07)4.17 版本的 Linux 内核仍然是实验性的内核,所以选项是在列表靠下方的位置。

如果和我一样意图最小化安装 Gentoo,应该选择附加安装项目最少(也就是文字最短)的选项。特别是要避开带有桌面环境的选项,即使在以后需要,也不建议将这项任务放置在安装流程中,以免 CPU 短时间内的工作负担过重。大家都不愿意自己的笔记本亲自把自己的手烹调成铁板狗爪子。

USE Flags 的配置

USE Flags 是 Gentoo 的魅力所在,它提供了精简化系统的可能性,帮助保持系统的简洁,最大化效率。但是其配置并不是一蹴而就的。我倾向于设置较少的全局 USE Flags,而针对每一个包设置局部的 USE Flags。

但这虽然是一个需要一定时日维护积累出来的成果,在一开始可以配置 -qt4 -qt5 -kde 来避免一些不必要的依赖。平日就要避免安装软件依赖于 Qt 等已经被禁止的 Flags。除此之外,Handbook 中 USE Flags 页面是很好的深入了解渠道。

手动编译内核

选择 genkernel 是一个比较无痛的编译内核的方法,但这意味着内核就不能开启 Ryzen 的相关参数了。保守的方式应该是 genkernel all 后再加入相关的内核参数并重新编译一次内核。这种方式的缺点就是耗时和耗资源,编译出来的内核并不小而美。

先通过 emerge linux-firmware 来安装 AMD Zen 的微码

emerge --ask sys-kernel/linux-firmware

别忘了安装 AMD GPU 的相关驱动

emerge --ask x11-drivers/xf86-video-amdgpu

使用 menuconfig 开启下面提及的几个参数以提供对 Ryzen 和 AMD GPU 的支持,也开启 EFISTUB 相关的内核选项。

Processor type and features --->
    [*] Symmetric multi-processing support
    [*] AMD ACPI2Platform devices support
    [*] /dev/cpu/microcode - microcode support
    [*] AMD microcode patch loading support
    [*] MTRR (Memory Type Range Register) support

    Processor family (Opteron/Athlon64/Hammer/K8) --->
        (X) Opteron/Athlon64/Hammer/K8

    [*] Supported processor vendors --->
        [*] Support AMD processors (NEW)

    [*] SMT (Hyperthreading) scheduler support
    [*] Multi-core scheduler support
    [*] Machine Check / overheating reporting
    [*] AMD MCE features

Processor family (MZEN) --->
(X) AMD Zen

Performance monitoring --->
<*> AMD Processor Power Reporting Mechanism

    [*] AMD microcode loading support

    [*] EFI runtime service support
    [*] EFI stub support
    [ ] EFI mixed-mode support

    [*] Built-in kernel command line
    (root=PARTUUID=)

Power management and ACPI options --->
    CPU Frequency scaling --->
        <*> AMD Opteron/Athlon64 PowerNow!
        <*> AMD frequency sensitivity feedback powersave bias

Device Drivers --->
    Generic Driver Options --->
        (amd-ucode/microcode_amd_fam17h.bin) External firmware blobs to build into the kernel binary
        (/lib/firmware) Firware blobs root directory

    Graphics support --->
        <*/M> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) --->
            [*] Enable legacy fbdev support for your modesetting driver
        <> ATI Radeon
         AMD GPU
            [ /*] Enable amdgpu support for SI parts
                (only needed for Southern Islands GPUs with the amdgpu driver)
            [ /*] Enable amdgpu support for CIK parts 
                (only needed for Sea Islands GPUs with the amdgpu driver)
            [*] Enable AMD powerplay component
            
            ACP (Audio CoProcessor) Configuration --->
            [*] Enable AMD Audio CoProcessor IP support (CONFIG_DRM_AMD_ACP)

            Display Engine Configuration --->
                [*] AMD DC - Enable new display engine
                [ /*] DC support for Polaris and older ASICs
                    (only needed for Polaris, Carrizo, Tonga, Bonaire, Hawaii)
                [ /*] AMD FBC - Enable Frame Buffer Compression
                [ /*] DCN 1.0 Raven family
                    (only needed for Vega RX as part of Raven Ridge APUs)
        <*/M> HSA kernel driver for AMD GPU devices
        
    <*/M> Sound card support --->
        <*/M> Advanced Linux Sound Architecture --->
            [*] PCI sound devices --->
                HD-Audio --->
                    <*> HD Audio PCI
                    [*] Support initialization patch loading for HD-audio
                    <*> whatever audio codec your soundcard needs
                    <*> Build HDMI/DisplayPort HD-audio codec support
                (2048) Pre-allocated buffer size for HD-audio driver

Firmware Drivers --->
    EFI (Extensible Firmware Interface) Support --->
        <*> EFI Variable Support via sysfs

[*] IOMMU Hardware Support --->
    [*] AMD IOMMU support
    <*> AMD IOMMU Version 2 driver

-*- Enable the block layer --->
    Partition Types --->
        [*] Advanced partition selection
        [*] EFI GUID Partition support

Processor type and features 中的 Built-in kernel command line 需填入 /rootinitrd 的路径,如

root=/dev/nvme0n1p3 rw initrd=/EFI/Gentoo/initramfs-linux.img

Handbook 中关于 RyzenAMDGPUAMD_microcode 的章节为本小节的内容提供了很大的帮助。

创建 fstab 文件

倘若依照上文关于 EFISTUB 的配置,fstab 关于 EFI 分区的几行需要说明绑定挂载的关系。以下是一个例子:

/dev/nvme0n1p1   /esp   vfat    defaults,noatime    0   0
/esp/EFI/Gentoo  /boot  none    defaults,bind       0   0
/dev/nvme0n1p2   none   swap    sw                  0   0
/dev/nvme0n1p3   /      btrfs   ssd,noatime         0   1

使用 blkid 获取文件系统各自的 UUID 更换其分区或设备名称是推荐的做法,要记得加上 UUID= 的前缀。若 SSD 支持 TRIM 命令,可以加入 mount 参数 discard 提升其读写性能。如果使用 Btrfs 作为文件系统,可以加入 mount 参数 ssd,但根据 Btrfs Wiki 中关于 optimization for SSD 的描述,加入了 ssd 参数则无法支持 TRIM/discard,官方也推荐使用 ssd 以获得更好的兼容性。

添加 UEFI 启动入口

关于 UEFI 启动入口,Gentoo Handbook 和其它发行版 Wiki 的推荐是使用 efibootmgr 管理。efibootmgr 着实简洁方便,却不能识别 nvme 设备分区信息,如 /dev/nvme0n1p1 即为非法 disk 参数。鉴于 efibootmgr 只对 sda 情有独钟,于是根据 UEFI Shell 相关章节,我使用 Shell 手动添加了入口。

安装无线网络相关包

再按照 Handbook 配置完网络,不要忘记安装无线网络的相关包,届时四处寻找网线而后蹲在路由器边上的样子可一点也不优雅 😎

emerge --ask net-wireless/iw net-wireless/wpa_supplicant

结语

话说回来,如果不是 Ryzen 给了我充足的理由,也许我不会上 Gentoo 的船。不论怎样,感谢它给我的这次丰富的折腾体验。接下来的几个月里,请多多关照 💗