Yoga 14s 2021上Arch Linux安装细节及软件(上)

renyuneyun 2022年07月03日(周日) 1 mins

之前写了篇文章简单谈了谈Yoga 14s 2021款的硬件及Linux兼容性。更早(多年)之前也有一些文章介绍Linux装机等相关话题。由于现在的新机器有了不少新特性,但相关说明似乎并不多见,故而借此文介绍我的机器相关的信息,以供有需要的人参考。

本文分上下两部分:上部分主要讲系统安装维护相关的内容,下部分主要讲新近功能及当前软件配置相关的内容(含美化)。

系统安装

我上次写Arch Linux的安装还是在2011年的文章中,当时还在用Acer 5745G,使用Grub (2)引导。而后换用XPS 13 (9343)后,便来到了UEFI和SSD,但并没有更新说明——因为当时arch的wiki中的安装指导很完善,所以在之前的文章上贴了个告示了事。

时至今日,arch wiki的安装指导仍然是最主要的参考对象。但其中一些地方是「可以这样,可以那样」,并要跳转到对应页面,对不了解的人并不友好——这样那样的选项导致的不同结果不够明确。

当然了,wiki页面的大部分内容还是挺顺畅的,其主要问题存在于硬盘分区和引导器的选择上。这里以我的选择及原因为例,给出一个参考。

硬盘分区

顺手一感慨:我打字的时候两次顺手打成「磁盘」。但现在已经是SSD了,已经不再用磁了……

我的机器预装有Windows,而且我希望保留双系统,所以需要Linux和Windows共存。

首先当然是在Windows中使用自带的磁盘管理,从系统盘切下大部分为Linux所用。我给Windows留下了200G,其他的全部划归Linux使用。

由于使用UEFI引导,Windows会在系统盘之前分配一些额外分区。其中第一个是ESP,给UEFI使用的,是UEFI标准的一部分;另外两个我没有去花费时间弄明白。在Linux中我们仍然需要给ESP写入一些文件。

然后就是给Linux设计分区。这里的确是按各人需求可以有各种不同的设计方法。我的需求如下:

  • 用户数据需要加密,系统不需要加密
  • 系统会进行日常备份(使用snapper,下文会写)
  • 可能会多装几个发行版,但暂时仅是arch
  • 我有16G内存,可能会进行休眠(挂起到硬盘)
  • 空间不嫌多,可以透明压缩就透明压缩

于是,对于我来说,很自然的选择就是系统分区使用BTRFS,并把系统的根作为子卷。而由于BTRFS不支持对子卷进行加密,故而用户数据放在单独的用户分区中并对分区进行加密(使用LUKS,即通过cryptsetup命令)。

UEFI最好的地方之一就是引导器装在ESP中,且引导器可以提供对复杂文件系统的支持。这样就不需要像以前BIOS时代一样得把/boot单独划出。这样/boot留在系统分区中,不需要额外设置或考虑,且备份可以自动进行。

最终结果上,我的Linux相关分区长成这样:

├─nvme0n1p5 259:5    0    16G  0 part  [SWAP]
├─nvme0n1p6 259:6    0    90G  0 part  /
└─nvme0n1p7 259:7    0   169G  0 part
  └─home    254:0    0   169G  0 crypt /home

其中nvme0n1p5是我的SWAP分区;nvme0n1p6是我的系统分区;nvme0n1p7是加密的用户分区,它解密后就是那个home。

出于多发行版及备份需求,我在系统分区中创建了一个子卷,叫做/@root-arch,用来存放我的archlinux根分区。挂载时需要额外设定/@root-arch

另外,挂载时额外设置compress=zstd:3来进行透明压缩——使用zstd的3级压缩,一般被认为是压缩率和速度之间的较好平衡。

一开始我是给/boot单独划了一个分区出来的。但后来随着使用了snapper,那个分区变得不太合适,最终决定不再给/boot单独分区。

引导器的选择

UEFI出现并普及的一大原因就是解决了BIOS时代引导的复杂及难以维护。但同时,出于各种因素,UEFI时代引导的选择也多了起来,某种意义上更加复杂了。当然,随着时间的推移,应当可以converge到有限的几个选项中,只是现在还没完全到那个时候。

UEFI时代不再需要写MBR,而是在UEFI固件(的设置空间)中添加引导项。这里的引导项也不受MBR空间限制,而是需要作为文件放在ESP中。

主要的引导方式有两种:

  • 直接通过UEFI进行引导
  • 通过UEFI加载引导器,然后从引导器加载系统内核(类似BIOS时代的做法)

直接通过UEFI进行引导需要被引导的内核支持(即需要EFIStub,对arch来说不需要额外配置,因为默认已经启用),且需要为每一个内核(及每一个内核引导配置)增加一个UEFI引导项。我只在XPS 13时试过一次,后来嫌麻烦就再也没用过了。

这次也是一样,我仍然选择通过UEFI加载引导器,然后再加载内核。BIOS时代的Grub 2支持UEFI,但它的界面有些过时,而且明明用了framebuffer但仍然是字符界面。于是我选择了rEFInd这个专门为UEFI设计,且有图形界面的引导器。

rEFInd

安装说明参照wiki上的rEFInd页面即可。主要是需要将引导器安装在ESP中(注意并非/boot),然后调整启动项的配置。

对于Linux来说,rEFInd的启动项配置主要是两部分:

  1. 写在程序配置文件$ESP/EFI/refind/refind.conf中的静态引导项
  2. 从写在某个可识别处(如/boot下)的refind_linux.conf文件的内容动态创建的引导项

这里的可识别包含rEFInd预置的搜索路径,如相关分区/文件系统根目录下,或一些典型目录。对于Linux,rEFInd会自动根据实际存在的内核动态生成引导项(arch不用调整内核文件命名结构,而其他发行版或许需要编辑$ESP/EFI/refind/refind.conf)。

我最初只写了第二种,即在refind_linux.conf文件内声明诸多引导项:

"Boot with standard options"  "i915.enable_psr=0 i8042.dumbkbd root=/dev/nvme0n1p6 rootflags=subvol=@root-arch splash quiet"
"Boot with testing options (full)"  "i915.enable_psr=0 intel_idle.max_cstate=1 i8042.dumbkbd root=/dev/nvme0n1p6 rootflags=subvol=@root-arch  initrd=\intel-ucode.img initrd=\initramfs-%v.img"
"Boot to single-user mode"    "i915.enable_psr=0 i8042.dumbkbd root=/dev/nvme0n1p6 rootflags=subvol=@root-arch single"
"Boot with minimal options"   "i915.enable_psr=0 i8042.dumbkbd ro root=/dev/nvme0n1p6"

这么做主要是为了方便调试,尤其是刚拿到这台电脑后的那段时间中(参见《联想Yoga 14s 2021款装机小记》)。这样做还有一个前提,那就是我的/boot最初放在单独的分区中。但如果不是这样(比如我后来废除这个分区后),且仍然想要使用动态的引导项,则需要编辑$ESP/EFI/refind/refind.conf以告诉rEFInd去哪里(对我来说就是@root-arch/boot)找动态的引导条目配置:

also_scan_dirs @root-arch/boot

一些关注细节的人可能看到,我的这几个引导参数不完全一样,尤其是第一项standard options中加了quiet splash,而其他的没有。这两个参数是为了显示plymouth提供的splash,即加载动画;而其他条目没有则是因为它们更多用于调试,所以我更希望显示完整的加载报告。由于plymouth不是功能性的东西,所以放在下篇中讲。

但在用了许久之后,我的引导参数趋于稳定。而后在使用了snapper之后,便换为了使用$ESP/EFI/refind/refind.conf。这些见后文snapper相关章节。

使用snapper进行自动备份(快照)

前文提到我的根文件系统类型是BTRFS,这么做的一个目的便是可以使用快照,并配合snapper进行自动备份。有了自动备份,我便可以随时回滚到某个版本。这在某个更新后不好用时尤其有用。

之前还提到,我的根目录是作为一个BTRFS子卷存在的。这个模式非常适合配合snapper进行自动备份。也有人玩一些更灵活的配置(参考这里),但我没有进行。一是没时间,二是看起来会带来别的副作用。

对snapper的设置其实不复杂,参照wiki上的snapper页面即可。主要是要在其配置文件中设置好要备份的对象及备份选项(如何时备份),然后启用对应的守护单元(主要是snapper-timeline.timersnapper-cleanup.timer)。

Tip

我的配置是保留2份月备份,2份周备份,2份日备份。

注意,snapper本身是openSUSE上所用的,并非arch所开发的。所以pacman默认是不会使用snapper在更新时进行备份的。为了让它支持,我安装了snap-pac这个包——这个包提供了对应的pacman钩子,会在更新前后各自动创建一个快照。

Tip

当然了,由于机制所致,更新前后的快照中pacman数据库锁仍然处于加锁状态。对于我来说,这不是个问题,反而可以提醒我这是在快照中。

这样,我的快照就会自动创建在/.snapshots/目录之下。使用snapper对应命令可以列出并操作它们。

然而这样还不够,我还需要能够自动将其加入引导项,以便有需要的时候直接在引导处进行切换。为了达成这个目的,我使用了refind-btrfs

使用refind-btrfs自动为快照创建引导项

如前文所述,我使用rEFInd作为引导器,它可以支持两种模式的引导项配置。refind-btrfs就是使用了第一种模式,并会自动维护快照的引导项。

使用refind-btrfs主要需要三步:

  1. 创建示例引导项
  2. 调整配置
  3. 创建初次配置

第一步,我们需要在$ESP/EFI/refind/refind.conf中创建一个引导条目。该条目需要是一个可用的引导条目,尤其需要包含正确的子卷的路径。我的条目如下:

menuentry "Arch Linux - Stable" {
    icon /EFI/refind/icons/os_arch.png
    volume "Linux Systems"
    loader /@root-arch/boot/vmlinuz-linux-lily
    initrd /@root-arch/boot/initramfs-linux-lily.img
    options "i915.enable_psr=0 i8042.dumbkbd root=/dev/nvme0n1p6 rootflags=subvol=@root-arch"
    submenuentry "Boot - fallback" {
        initrd /@root-arch/boot/initramfs-linux-lily-fallback.img
    }
    submenuentry "Boot - terminal" {
        add_options "systemd.unit=multi-user.target"
    }
}

条目中每一句话的详细含义请自行对应文档,或凭名称猜测。其中重点的是两部分:

  1. 告诉rEFInd要去哪个分区处理启动项,即volume "Linux Systems"的任务
  2. 写明带子卷的启动项,即loaderinitrdoptions中所有包含@root-arch的部分

Note

我不知道refind-btrfs的作者是否强制要求子卷名称以@开头(上游示例中均包含),但这是许多人都遵守的命名方法,我也是其中之一。

第二步,编辑/etc/refind-btrfs.conf文件,以符合自己的情况。其中主要是这三节中的目录:

  1. [[snapshot-search]]
  2. [snapshot-manipulation]
  3. [boot-stanza-generation]

默认配置就是基于配合snapper考虑而设置的,所以对于大多数人来说保留默认即可。我额外调整了[snapshot-manipulation]中的selection_count来添加更多条目。

第三步就是执行refind-btrfs来初始化并添加相应引导项。这里主要是要注意是否有报错,并解决对应错误。如果一切无误,那么它应当会自动在$ESP/EFI/refind/refind.conf的末尾添加一项include,并在对应文件中添加所要求个数的对应快照的引导项。

在完成这个基本配置并确定可用之后,如果希望自动维护启动项,可以考虑启用refind-btrfs.service这个服务,以自动监视对应目录的变更。

其他杂项

相比早期的安装流程,当下的流程没有结构性区别,但个别细节上有不同。其中最主要的就是不再使用wifi-menu连接WiFi,而是使用iwctl——比wifi-menu功能强大,但没有它易用。

引导器之外,我依然关闭了Secure Boot,因为屡次尝试加上签名都失败了,而且似乎也没有办法给rEFInd加?我知道如红帽和Canonical(Ubuntu的东家)等发行版厂商和微软购买或谈下了签名,而且Arch的ISO似乎是可以在Secure Boot开启的情况下正常引导的。但我始终没找到合适的方案。最接近的是这篇讲rEFInd如何在Secure Boot下启动的文章,但读起来仍然过于复杂了。

一些眼尖的人应当看到了,我用的内核叫linux-lily,而不是默认的linux。这个内核是ArchlinuxCN的百合仙子所维护的(当然,也放在ArchlinuxCN倉庫中),对我来说主要优势在于添加了tty下显示中文的支持,并可以运行Anbox(因其支持ashmem和binder)。

Note

Anbox所需要的这些内核模块(尤其是ashmem)不再能够在5.15(不含)以后的内核上使用DKMS的方式编译,因为允许这么做会存在潜在风险(参考这里的说明)。所以如果想使用Anbox,就需要随着内核编译模块。

最后补一下关于多发行版:前面提到,我分区和文件系统组织的一个目的是可以安装其他发行版以和arch共存,以便万一有意可以轻松迁移。我之前在XPS 13上其实做了和gentoo共存,但由于编译以及对portage的不熟悉导致的麻烦,最终让我没换到gentoo去。后来又看到nixos,但仅在虚拟机中进行了简单的尝试,没有实装。这回做了准备,但由于各种因素,暂时还没有尝试去再装一个发行版。所以这部分就留待以后再写了。


Related posts:

您可以在Hypothesis上的該群組內進行評論,或使用下面的Disqus評論。