【DISTRO.0x02】在 Surface Pro 8 上安装 Gentoo

本文最后更新于:2024年5月15日 凌晨

省流:最后装回了 openSUSE Tumbleweed

0x00. 一切开始之前

熟悉的废话环节,可以直接跳过不看:)

熟悉笔者的朋友都知道笔者是一个微软死忠粉( 虽然这位微软死忠粉现在并没有在将由微软开发的操作系统作为主力 ),因此手上自然而然会有一些 Surface 设备(当然绝大部分都出二手回血了,👴只能说学生时代缺钱的穷 b 是这样的),恰好笔者手边有一台闲置的 Surface Pro 8 设备,而 Surface 从这一代设备开始有一个支持方便快捷地自行更换硬盘的设计,同时笔者原有的设备是最低配的版本 (8G 运存 + 128G 存储),因此笔者就想把这台陪伴了笔者大四期间多个夜晚的设备(因为晚上宿舍断电,所以有这样一台续航长的办公本还是很重要的, 当然这里肯定有人要问为什么不用 macbook 了,虽然说 mac 的续航时间确实比 Windows 阵营任何的笔记本要长得多,但是笔者当时并没有钱能够买得起哪怕是一台二手的 macbook,而且既然都买 macbook 了再买二手未免有些寒碜,可能有人又会抬杠说 Surface 都买了怎么买不起 macbook,毕竟最低配的 Surface 价格终究是比最低配的 macbook 要便宜不少,同时还有一个比较重要的原因便是笔者此前很多工作还是需要在 X86 平台上完成,mac 下虽然有 Rosetta 或是 Parallel,但是转译终究还是会带来一定的性能损耗,而且使用起来并不优雅,那这里可能又会有人问为什么不买联想或是其他牌子的同价位办公本,那👴只能说田牌就是信仰 )给简单升级一下,在替换大容量硬盘的同时顺便装一个 Windows + Linux 双系统,前者是为了保留原汁原味的 Surface 体验,后者则是纯粹为了瞎折腾:)

出于各种因素的考虑( 可能是偷工减料 )微软为 Surface Pro 选用了 2230 规格的 SSD,这个规格的 SSD 并不好找,尤其是笔者目前肉身位于地大物穷的位于大洋彼岸离所有国家都很远的澳洲,找了半天才在 CPL 上找到一款镁光的 2230 规格的 2TB SSD,虽然商品页面写着 NOT Compatible with Surface Pro 8/9 ,但是在笔者看来理论上来说不兼容的情况不太可能发生,同时笔者在微软社区上找到了 一篇成功在 Surface Pro 8 上安装这一款 SSD 的帖子,那“不兼容”一说想来应当是无稽之谈(又或者是微软的商业手段,事实证明确实是可以兼容的),因此笔者选了一个风和日丽 但其实下着细雨 的日子前往墨尔本的某家 CPL 线下门店取到了这款 SSD ( 是的这就是发达国家比较常见的购物方式,没有国内那样发达的物流网络说实话👴感觉买啥都不方便,当然出来活动活动筋骨也是好的

价格比国内贵上好几百 RMB,澳洲的大部分电子产品都是如此

接下来是对系统发行版的选择,Windows 自然不用说直接装最新的 Win 11,那么 Linux 该选择哪一种发行版呢?首先考虑比较贴近上游的 Linux 发行版——

  • 出于瞎折腾的角度考虑 Arch Linux 自然是提供了一定的折腾空间以及 AUR 的海量软件包,在为系统带来极高的可定制性的同时你几乎可以在 AUR 上找到任何软件
  • Fedora Workstation 作为 RHEL 的试验田同时也是 Linus 所用的发行版在紧贴上游的同时提供了不弱于 Arch 的先进性,有着来自红帽的强大技术支持,软件更新比一部分滚动发行版还要激进, 更是能第一时间当 RedHat 的小白鼠
  • openSUSE Tumbleweed 则有着 SUSE 那来自德国人的精确与严谨,在兼顾稳定性的同时保持了滚动更新紧贴上游(更有着 Slowroll 这样等着 Tumbleweed 滚稳了再更新的“慢滚”发行版),YaST 更像一个温柔的大姐姐一样能帮你轻松解决相当多的各类需求, 因此这也是笔者的主力笔记本所使用的 Linux 发行版

熟悉笔者的都知道笔者一直都是 SUSE 批.jpg

虽然这些都是笔者比较喜欢的发行版,但思来想去笔者还是决定安装一个不太常规的 Linux 发行版—— Gentoo Linux ,最直接的原因就是这是一个少有的原生从源码安装软件包的滚动 Linux 发行版 ,任何软件都需要自行在自己的机器上进行编译,这意味着所有人的软件的二进制包都是不一样的,虽然说这与目前软工业界所追求的“逐位可重复构建” 似乎完全背道而驰,但从软件安全的角度考虑这意味着 哪怕你知道我的电脑上的某个软件中存在二进制漏洞,你也无法直接通过传统的常规 pwn 手法进行攻击 ,这主要是出于一个原因: 现有的漏洞利用方法通常是控制流劫持导向的,针对软件二进制漏洞利用的方式通常是劫持控制流后再利用软件中原有的代码片段构建执行链完成任意代码执行 ,例如现在针对不同程序的不同版本中存在的某一漏洞进行攻击的办法通常是辨别目标软件版本后利用 ROPgadget 或是其他的一些工具来拼凑 ROP chain ,而这样的攻击方法的可行性得以成立的原因则是包括内核在内的软件二进制通常是由软件源侧完成编译后再分发给用户,这意味着在同一发行版上使用同一版本软件的用户所持有的二进制文件都是相同的,因此对于攻击者而言获取相应软件的二进制文件基本上是没什么难度的, 而所有软件都自行编译则可以很大程度上加大攻击者在传统攻击面的攻击难度 ——这在很大程度上满足了笔者的精神洁癖:)

当然可能有人会抬杠说这没什么意义,毕竟现在 exploit technique 前沿都在各种 data-only attack ,仅是阻挡攻击者获取 code gadget 的方式是无法完成 100% 的防护的, 可能也有人会抬杠说 把 CET 开上不就完事了但对笔者而言能有一定程度的提升那就是有意义的,在笔者看来这并非仅有 0 和 100 的区别 ,同时对于攻击者而言针对所有软件都单独开发 data-only 的攻击手法未免成本就太高了,目前的这类研究还仅集中在操作系统内核或是其他大型软件上

此外,形如 CFI 这样的防御手法在发行版分发的二进制软件包中很多都是未必开启的,而 Gentoo 这样自定义软件编译选项的发行版可以让你快速在系统各个软件中应用这些防护手段,同时定制自己所想要的优化选项,可能不是最好的,但是从精神层面而言一定是最适合自己的

那又有人可能会说每个开源软件都自己手工拉源码编译不就好了干嘛一定要用 Gentoo,笔者的评价是:

男人,什么罐头我说,曼巴出去

当然,除了可以基于自身需求高度定制这个核心动机以外,Gentoo 有着一个强大的包管理器:Portage ,通过配置 USE flag 可以按照需求去编译软件包,实现 如无必要,勿增实体 的哲学(例如你需要使用的部分软件带有 kde 支持,但你其实并不使用 kde,那么只需要在 /etc/portage/make.conf 中添加 USE="-kde" 这一 flag,这是一个全局性的例子;又或者对于某些软件包你想要启用/禁止某些支持而并不想要把这样的配置全局化,你只需要在 /etc/portage/package.use 目录下创建新配置文件来为指定程序声明 USE 标记,例如 kde-plasma/plasma-meta qt5 -sddm 将为 KDE Plasma 桌面编译上 QT 支持的同时不使用 SDDM;当然,滥用 USE flags 有可能会来带循环依赖的问题,那这又是另外一件事情了…), world file 的存在也大幅增添了系统的可重复构建性(硬要说的话在可复现性上肯定比不过 NixOS,但笔者对于 NixOS 这类“不可变系统”的概念说实话不太感冒,反倒觉得对于桌面用户而言这增添了不少没必要的麻烦,不过多学习一门 DSL 倒其实是无所谓的事情,毕竟 reproducible 的体验某种程度上真的很香,但 NixOS 对于笔者而言还有一点劝退的便是 non-FHS compliance ,虽然说 NixOS 可用的软件包确实是数一数二的多,但这样的系统构造在笔者看来并不够优雅)

最重要的是,Richard Stallman 曾经说过:Install Gentoo——

虽然他用的不是 Gentoo 而是 Trisquel.jpg

于是在经历了各种思考之后,笔者最终选择在 Surface Pro 上尝试折腾一下 Gentoo Linux 这一个相对而言比较小众的发行版

0x01. 安装 Windows

因为笔者是要用一块全新的硬盘替换掉原有的硬盘,因此系统安装需要重头开始( 虽然实际上有一些已知的系统迁移方案,但是👴太懒了 ),因为 Windows 很容易对硬盘分区进行预期外的修改,所以在安装双系统的情况下笔者选择先安装 Windows 再安装 Linux

替换硬盘

因为我们后面安装 Linux 要关闭 Secure Boot,因此我们首先需要在设置中关闭 BitLocker,从而确保原硬盘的可用性

否则后面就只能上 https://aka.ms/myrecoverykey 找原有密钥进行恢复了,如果没有登录过微软账户的话那就只能和原硬盘数据彻底说再见了……

这个过程会非常慢,因为 Surface 设备的性能极其拉胯

接下来进 UEFI 中关闭 Secure Boot,在关机状态下按住音量增加键不动,之后再按一次电源键即可进入 Surface 的 UEFI 界面,找到 Secure Boot Configuration 选择 None 即可:

u1s1 Surface 的 UEFI 虽然简介但是凑凑的

解锁之后每次开机都会显示一个大大的红色条和一个🔓:

丑中丑设计,感觉不如把🔓放在 Win logo 旁边并排

然后在关机状态下用手机取卡针在背面的小孔一戳就能更换硬盘了,从 Surface Pro 8 开始微软的设备有了一定的可维护性,不过需要注意的是硬盘螺丝的规格为不太常见的 T3 六角螺丝,以及在完成硬盘更换之后 需要插电才能开机 ,不过无论是通过 surface connect 还是通过雷电 4 接口插电都是可行的

当然,你也可以选择使用牙签

然而仅限于 Surface Pro 系列,也就是只有 Pro 8/9/10(在笔者编写此文时,Pro 10 仅有商业版) 能快捷更换硬盘,Laptop 等其他产品线依然需要繁琐的拆机流程,不过这个便捷拆解设计在笔者看来有点类似之前见过的 ThinkPad 的高端工作站才有的特性🤔 遗憾的是微软如今依然尚未支持更换内存条,否则👴将成为微软的铁血卫士

使用 PE 启动盘进行安装

Windows ISO 在 微软官网 便能进行下载,这里就不再赘叙了

接下来我们在可移动磁盘(如 U 盘、移动硬盘等设备)上创建 Windows 安装介质,不过由于官网下载的 ISO 镜像缺少了分区表,因此我们需要手动进行配置,在 Windows 上你可以很轻松地使用 RUFUS 一类的工具完成这一工作,若你和笔者一样日常使用 Linux 作为工作系统,则暂时没有比较好的解决方案

不过好在使用 PE 启动盘进行安装已经是一个较为成熟的解决方案了,方便起见笔者选择直接使用现有的解决方案进行安装:)

需要注意的是在这个阶段触控屏和原装键盘触摸板都是无法使用的,你必须外接键鼠进行使用

笔者很久以前自制的启动盘,事实证明这些工具虽然老但是都还挺好用

之后就是正常进系统了,不过在更新完成之前原装键盘触摸板依旧用不了

Extra. 手工创建安装介质(not recommended)

如果你希望自己动手丰衣足食,则也可以参照这一节的内容,不过笔者不太推荐(比较浪费时间

主要原因是 Windows 安装镜像中并没有提供一个分区表,否则直接 dd 一把梭就好了:(

首先使用 parted 新建分区,这里我们建立一个 GPT 分区表,并建立两个分区:

为什么我们不选择直接拷贝 Win 镜像进 EFI 分区?虽然 Win 镜像本身便是一个可启动的 EFI 分区,但是其安装文件 source/install.wim 通常大于 UEFI specs 所支持的 fat32 文件系统所支持的最大文件大小(4G),虽然部分 OEM 的 UEFI 会额外有对 exFAT 或是 NTFS 的支持,但为了兼容性考虑我们还是选择 fat32,并使用第三方软件 RUFUS 所提供的 EFI 程序

这里的 /dev/sda 为你的 U 盘设备路径,请自行辨别,需要注意的是NTFS 分区应当在第一位,EFI 分区在第二位 ,否则会导致 无法进行安装 (提示缺少驱动):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sudo parted /dev/sda                        
GNU Parted 3.6
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) mktable gpt
Warning: The existing disk label on /dev/sda will be destroyed and all data on this disk will be lost. Do you
want to continue?
Yes/No? Yes
(parted) mkpart windows-iso ntfs 2048 16777215
(parted) mkpart efi fat32 16777216 33554432
(parted) set 2 esp on
(parted) set 2 boot on
(parted) name 1 Windows
(parted) name 2 EFI
(parted) quit
Information: You may need to update /etc/fstab.

然后运行如下两条命令初始化 EFI 分区的文件系统:

需要说明的是与 NTFS 相关的操作在 Linux 下都会特别慢(至少在笔者的机器上如此,这可能和 ntfs-3g 的性能相关),建议 其实也只能 耐心等待:)

1
2
3
4
5
6
7
$ sudo mkfs.ntfs /dev/sda1
Cluster size has been automatically set to 4096 bytes.
Initializing device with zeroes: 100% - Done.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.
$ sudo mkfs.fat -F 32 /dev/sda2
mkfs.fat 4.2 (2021-01-31)

接下来将 ISO 中数据拷贝到 U 盘当中,再将 RUFUS 提供的 EFI 镜像拷贝到 EFI 分区即可

1
2
3
4
5
6
7
8
9
10
11
12
13
$ sudo mkdir /mnt/{iso,efi,win}
$ sudo mount ~/Downloads/Win11_23H2_Chinese_Simplified_x64v2.iso /mnt/iso/
mount: /mnt/iso: WARNING: source write-protected, mounted read-only.
$ sudo mount /dev/sda1 /mnt/win/
$ sudo mount /dev/sda2 /mnt/efi/
$ sudo cp -r /mnt/iso/* /mnt/win/
$ sudo umount /mnt/iso
$ sudo mount ~/Downloads/uefi-ntfs.img /mnt/iso/
$ sudo cp -r /mnt/iso/* /mnt/efi
$ sudo umount /mnt/efi
$ sudo umount /mnt/win
$ sudo umount /mnt/iso
$ sync

之后就能 原神启动 正常启动进入安装界面了,需要注意的是原装的键盘触摸板完全无法使用,因此你需要额外用扩展坞连接通用无驱键鼠

原装键鼠仅在 UEFI 启动阶段可用,目测是 Windows 官网默认的安装介质中并未带有对应的驱动

Windows,启动——

以及这个安装方式在笔者的电脑上并未成功,但是使用各种第三方的 PE 启动盘提供的第三方工具却能轻松完成, 👴只能说 Windows 官方的安装程序确实比较垃圾

0x02. 安装 Gentoo Linux

完成 Windows 安装之后接下来是安装 Gentoo Linux,在开始之前别忘了在 Windows 上进入硬盘管理中划出一块完整的空间留给 Gentoo Linux 使用,这里笔者就不截图了:)

创建安装介质

Gentoo 官网上下载镜像后 用 balenaEtcher 或是一些其他的软件或是直接 dd 往 U 盘里写都 ok,其中 Minimal Installation CD 和 Arch 一样只有命令行,而 LiveGUI USB Image 则带有一个图形环境,但是最后都是要敲命令行一步步安装 ,只是带 GUI 的会有个 KDE 桌面让你能在 Konsole 中敲,方便开浏览器和联网 :)

以及别忘了在 Surface UEFI 中将 USB 调整为第一启动项

进入桌面后只有一个 Gentoo Linux Handbook 的快捷方式,而不似其他 Linux 发行版有引导式安装程序:

需要注意的是 Surface 屏幕分辨率较高,建议调一下缩放后 logout 再重新进来

创建文件系统

网络连接笔者直接使用 KDE 组件完成了,习惯命令行的也可以尝试使用 net-setup

首先我们先使用 cfdisk 对硬盘进行分区,按惯例建立四个新分区:

  • EFI 分区(fat32,挂载在 /boot/efi ):存放 EFI 启动程序(grub)
  • 系统分区( ext4 ,挂载在 / ):存放系统基本文件
  • 数据分区( ext4 ,挂载在 /home ):存放用户数据
  • SWAP 分区(swap ):交换内存

Surface 上仅有一块 SSD ,所以硬盘路径基本上定死为 /dev/nvme0n1 ,如果你在其他有多块硬盘的机器上参照本文进行配置则注意识别自己想要安装的键盘

1
# cfdisk /dev/nvme0n1

注:这一步使用 LiveGUI CD 中的 KDE Partitioner 或是 GParted 也可以

100M 是 Windows 分区弄错了留下来的一个多余的无用空间,因为 NTFS 没法前扩所以笔者也懒得管了

接下来创建文件系统,惯例地 mkfs 一把梭,开始之前最好先 fdisk -l 再辨别一下自己想要格式化的分区:

1
2
3
4
5
# mkfs.fat -F 32 /dev/nvme0n1p4
# mkfs.ext4 /dev/nvme0n1p5
# mkswap /dev/nvme0n1p6
# swapon /dev/nvme0n1p6
# mkfs.ext4 /dev/nvme0n1p7

日志输出太长了,没法拍完屏,将就看看

最后就是挂载文件系统了:

1
2
3
4
5
6
7
# mkdir /mnt/gentoo
# mount /dev/nvme0n1p5 /mnt/gentoo
# mkdir /mnt/gentoo/boot
# mkdir /mnt/gentoo/boot/efi
# mkdir /mnt/gentoo/home
# mount /dev/nvme0n1p4 /mnt/gentoo/boot/efi
# mount /dev/nvme0n1p7 /mnt/gentoo/home

安装 Stage 3

Stage 可以简单理解为构建 Gentoo Linux 系统的各个不同阶段:

  • Stage 1 :通常仅 Gentoo 内部开发人员使用,由一个基本的 packages,build 文件生成的系统包
  • Stage 2 :通常仅 Gentoo 内部开发人员使用,从 Stage 1 编译而来的可以自举的工具链
  • Stage 3 :由 Stage 2 编译而来的文件,并包含一组 @system set 软件包
  • Stage 4 :在 Stage 3 基础上安装好的完整的 Gentoo 系统

首先我们将 Stage 3 下载到文件系统根目录下解压,笔者比较习惯 systemd 所以还是选择 systemd + desktop 版的:

1
2
3
# cd /mnt/gentoo
# wget https://distfiles.gentoo.org/releases/amd64/autobuilds/20240428T163427Z/stage3-amd64-desktop-systemd-20240428T163427Z.tar.xz
# tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner

然后是配置机器时间:

1
# chronyd -q

接下来配置编译选项,Portage 在运行时会读取一个 make.conf 配置文件,位于文件系统根目录下的 /etc/portage/make.conf 当中,Stage 3 文件中已经给我们提供好了一个空白模板,其中主要是一些编译参数与选项,我们只需要根据自身习惯进行修改即可:

一般来说只需要在 COMMON_FLAGS 中添加 -march=native 以告诉编译器选择当前的系统体系结构,此时 GCC 会自动调查 CPU 并配置合适的 flag,但若是当前机器正在为其他机器编译时则不应当启用该项

对于内存比较小的设备,则不应当启用 -pipe 编译选项,因为这使用管道而非文件来存放编译中间文件,而这将占用更多的内存,从而导致编译器可能被 kill 掉而编译失败

其他的可用选项可以参照 Gentoo wiki

1
# vim ./etc/portage/make.conf

安装基本系统

接下来复制 DNS 信息,从而确保 chroot 之后有网可用:

1
# cp --dereference /etc/resolv.conf /mnt/gentoo/etc/

接下来挂载一些必要的文件系统并 chroot 到根目录,也可以直接通过 arch-chroot /mnt/gentoo 命令完成:

1
2
3
4
5
6
7
8
9
10
# 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 /mnt/gentoo /bin/bash
# source /etc/profile
# export PS1="(chroot) ${PS1}"

接下来配置 Portage 仓库:

1
2
# mkdir --parents /etc/portage/repos.conf
# cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf

接下来安装 Gentoo ebuild 数据库快照:

1
# emerge-webrsync

(可选配置:选择镜像站)

若有需要,则可以使用 mirrorselect 这个工具来手动选择想要使用的镜像源(空格键选中后 enter,可以选多个项),本质上是往 make.conf 中写入新的 GENTOO_MIRRORS 变量:

1
2
# emerge --ask --verbose --oneshot app-portage/mirrorselect
# mirrorselect -i -o >> /etc/portage/make.conf

接下来配置系统的 profile (决定了系统的默认配置,例如 USECFLAGS 等),第一条命令用来查看可用配置,第二条则进行选择,这里笔者选择了 default/linux/amd64/23.0/desktop/plasma/systemd

1
2
# eselect profile list
# eselect profile set 28

(可选配置:添加二进制包源)

众所周知 gentoo 是个几乎任何东西都要自行编译的发行版,如果你不想在当前机器上进行编译,而想要像其他发行版那样直接拿二进制可执行文件,则可以配置一个 binary package host ,这可以是你的另一台 Gentoo 机器,也可以是官方或是其他人的源

源地址需要写在 /etc/portage/binrepos.conf/gentoobinhost.conf 文件中,这是官方给的一个例子:

1
2
3
[binhost]
priority = 9999
sync-uri = https://distfiles.gentoo.org/releases/<arch>/binpackages/<profile>/x86-64/

对于想要以获取二进制可执行文件的形式进行安装的软件包,在使用 emerge 安装软件时添加 --getbinpkg 即可,也可以通过修改 /etc/portage/make.conf 文件并添加 FEATURES 变量来完成,例如:

1
2
3
4
# Appending getbinpkg to the list of values within the FEATURES variable
FEATURES="${FEATURES} getbinpkg"
# Require signatures
FEATURES="${FEATURES} binpkg-request-signature"

若选择这种方式,则在修改后需要额外运行 getuto 命令进行配置

接下来配置 CPU_FLAGS_* 变量,编译器会在编译特定汇编代码/指令时使用,笔者是 x86/64 架构所以应当为 CPU_FLAGS_X86 ,不过工具 cpuid2cpuflags 可以帮我们完成输出:

1
2
# emerge --ask --oneshot app-portage/cpuid2cpuflags
# echo "*/* $(cpuid2cpuflags)" > /etc/portage/package.use/00cpu-flags

接下来在 /etc/portage/make.conf 中添加 VIDEO_CARDS 变量,用以恰当地配置 GPU,Surface Pro 8 只有一个 Intel 核显所以该变量应为:

1
VIDEO_CARDS="intel"

(可选配置:可接受的 License)

如果你对软件包有 License 洁癖,不是 GPL/MIT/.. 的不用,则可以配置 ACCEPT_LICENSE 变量,建议参照官方的 handbook

如果想全都接收,则在 /etc/portage/make.conf 中将该变量设为:

1
ACCEPT_LICENSE="*"

接下来配置时区,笔者用的是 systemd ,所以直接将时区文件软链接到 /etc/localtime 即可:

1
# ln -sf ../usr/share/zoneinfo/Australia/Melbourne /etc/localtime

然后是进行本地化配置,在 /etc/locale.gen 中添加对应项即可,例如:

1
2
3
4
en_US ISO-8859-1
en_US.UTF-8 UTF-8
zh_CN GBK
zh_CN.UTF-8 UTF-8

接下来运行 locale-gen 命令,其会根据 /etc/locale.gen 中项进行生成,生成结束后通过 eselect 命令进行选择,这里最好先选择 C.utf8 ,完成之后更新环境变量:

1
2
3
4
# locale-gen
# eselect locale list
# eselect locale set 2
# env-update && source /etc/profile && export PS1="(chroot) ${PS1}"

对于中文用户,你可能会需要 gentoo 中文社区的仓库:

1
2
3
# emerge --ask app-eselect/eselect-repository
# eselect repository enable gentoo-zh
# emaint sync -r gentoo-zh

编译与安装内核

(可选配置:安装固件与微码)

在开始配置内核前我们可以安装可选的微码与固件,Surface Pro 8 是 Intel CPU,所以微码应当安装 sys-firmware/intel-microcode 包,固件则都为通用的 sys-kernel/linux-firmware 包:

1
2
# emerge --ask sys-firmware/intel-microcode
# emerge --ask sys-kernel/linux-firmware

可能会遇到 all ebuilds that could satisfy * have been masked 的错误,这是因为 LICENSE 配置问题,通过如下命令进行补充即可:

1
2
# echo "sys-kernel/linux-firmware @BINARY-REDISTRIBUTABLE" | tee -a /etc/portage/package.license
# echo "sys-firmware/intel-microcode @BINARY-REDISTRIBUTABLE" | tee -a /etc/portage/package.license

虽然内核主线暂且缺少一些 Surface 驱动,但是有一个社区项目 linux-surface 提供了部分驱动,可惜的是该项目本身仅提供 Arch/Debian/Fedora 的版本,而在 Wiki 中 fork 到 Gentoo 这边对应仓库的维护者不知道什么时候已经跑路了,因此笔者只能先用默认的内核,这里我们有三种大方向上的选择:

作为 Linux kernel hacker,手工编译内核自然是第一选择,主要原因是方便更改编译选项 而且这样看起来会显得👴比较帅

不选 distribution 的原因是配置文件中可能未必默认包含笔者需要的硬件驱动,再逐条改起来有点麻烦,而 Genkernel 感觉有点上不去下不来卡在那里了

首先安装必要的工具:

其中 installkernel 是可选包,用于自动安装新的内核并更新 bootloader 配置, 如果你比较闲的话也可以手工完成

1
2
# emerge --ask sys-apps/pciutils
# emerge --ask sys-kernel/installkernel

拉取 Gentoo 官方维护的内核源码:

1
# emerge --ask sys-kernel/gentoo-sources

如果你选择用 gentoo 官方的内核配置(gentoo-kernel),可能出现提示需要检查 configure 的问题,使用如下命令修复:

1
# dispatch-conf

基本上一路 u (update) 即可

使用如下命令查看当前安装的源码:

1
# eselect kernel list

通常我们会在 Linux 系统中维护一个指向当前内核源码的符号链接 /usr/src/linux,在 Gentoo 下我们通过如下命令手动创建(序号由 eselect 命令获得):

1
# eselect kernel set 1

接下来创建配置文件 .config ,这里笔者使用 make localyesconfig 来检测硬件并决定开启的内核模块,你也可以用默认的 make defconfig ,根据自己的需求进行选择即可:

内核模块会被编译到 vmlinuz 中,如果你想让内核模块独立存在,使用 localmodconfig

1
2
# cd /usr/src/linux
# make localyesconfig

接下来用 menuconfig 手动改一些选项,其会在已有的 .config 基础上进行修改,这里我们要决定的包括 OpenRC/systemd 的选择、常用文件系统支持、额外选一些 Surface 相关的驱动等,具体参见 Gentoo handbook

在这一步,你可能会需要手动开启 iwlwifi 的编译支持,参见 Gentoo wiki - iwlwifiDevice driver wilwifi 一节

在这一步,你还可能会需要手动将网卡固件添加到配置中,参见 Gentoo wiki - iwlwifiFirmware 一节https://wiki.gentoo.org/wiki/Iwlwifi)

如果不清楚应该添加哪个固件,可以 dmesg | grep -i wifi | grep -i ucode 查看在 LiveISO 当中使用的是哪个

1
# make menuconfig

然后开始编译内核,这可能会需要一定的时间:

实际上在笔者的机器上 8 分钟左右就能完成了,笔者也没想到 1135g7 的性能这么强,可能这就是科技的进步吧 :)

1
# make -j$(nproc) && make modules_install -j$(nproc)

接下来使用 installkernel 安装内核,这里笔者选择使用 GRUB + systemd ,首先创建文件 /etc/portage/package.use/installkernel 并写入:

1
sys-kernel/installkernel grub dracut

然后运行:

1
2
# emerge --ask sys-kernel/installkernel
# make install

配置系统

首先配置 /etc/fstab ,这个文件决定了在系统启动时哪些分区该被挂载到哪些目录,为了保证挂载的一致性,通常我们会选择使用一个分区的 UUID 进行挂载,而非设备路径,因为在有着多个磁盘的环境中不同磁盘的路径在启动后未必一致

不过因为笔者的 Surface Pro 8 仅有一个盘位,所以是可以使用设备路径进行挂载的,但保险起见还是用 UUID 进行挂载

首先查看不同分区的 UUID:

1
# blkid

接下来按照分区用途编写 fstab,以笔者的配置为例:

1
2
3
4
UUID=f0e95c49-e05d-4659-a617-bfdaee35af7c none       swap  sw           0 0
UUID=8317cece-8c46-4fec-bdf6-ddab4aa23249 / ext4 defaults 0 1
UUID=5e8624e3-b40e-4e6c-be02-e72a99e94462 /home ext4 data=ordered 0 2
UUID=C215-9C27 /boot/efi vfat utf8 0 2

然后配置主机名:

1
# echo "Surface-Pro-8" > /etc/hostname

配置 DHCP:

1
2
# emerge --ask net-misc/dhcpcd
# systemctl enable dhcpcd

设置 root 密码:

1
# passwd

初始化一些配置:

1
2
3
4
# systemd-machine-id-setup
# systemd-firstboot --prompt
# systemctl preset-all --preset-mode=enable-only
# systemctl preset-all

(可选)配置文件索引

通过空间换时间的方式加快文件搜索速度:

1
# emerge --ask sys-apps/mlocate

配置 shell 自动补全,gentoo 默认使用 bash:

1
# emerge --ask app-shells/bash-completion

配置时间同步:

1
2
# emerge --ask net-misc/chrony
# systemctl enable chronyd.service

配置文件系统和磁盘相关的一些工具,笔者只用 ext4 和 fat32:

1
2
3
# emerge --ask sys-fs/e2fsprogs
# emerge --ask sys-fs/dosfstools
# emerge --ask sys-block/io-scheduler-udev-rules

安装网络相关的一些包:

1
2
# emerge --ask net-dialup/ppp
# emerge --ask net-wireless/iw net-wireless/wpa_supplicant

安装 NetworkManager:

1
# emerge --ask net-misc/networkmanager

完成后我们通过修改 /etc/portage/make.conf 中的 USE flags 添加相关软件对 NetworkManager 的支持:

添加完 USE flags 后别忘了通过如下命令进行更新:

1
# emerge --ask --changed-use --deep @world
1
USE="${USE} networkmanager"

完成安装后启用对应的 systemd service:

1
# systemctl enable NetworkManager

安装 sudo ,解注释 %wheel ALL=(ALL:ALL) ALL 所在行:

1
2
# emerge --ask app-admin/sudo
# visudo

前面我们只配置了 root 用户,所以别忘了配置一个日常用的管理员用户:

这里会报一个 Creating mailbox file: No such file or directory 的错误,可以不用管

1
2
3
# groupadd arttnba3
# useradd -g arttnba3 -m -G users,wheel,audio,cdrom,floppy,portage,usb,video -s /bin/bash arttnba3
# passwd arttnba3

安装 boot loader

按惯例直接用 GRUB 就行, 真的会有人去用 systemd-boot 🐴

1
2
3
4
# echo 'GRUB_PLATFORMS="efi-64"' >> /etc/portage/make.conf
# emerge --ask --update --newuse --verbose sys-boot/grub
# emerge --ask sys-boot/os-prober
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Gentoo

默认的 grub 主题比较难看,而且在高分辨率屏下看着属实有些难受,所以笔者这里选择安装一个 minegrub 主题,首先克隆仓库:

1
2
3
4
5
# emerge --ask dev-vcs/git
# cd ~
# git clone https://github.com/Lxtharia/minegrub-theme.git
# cd ./minegrub-theme
# cp -ruv ./minegrub /boot/grub/themes/

接下来修改 grub 配置文件 /etc/default/grub

1
GRUB_THEME=/boot/grub/themes/minegrub/theme.txt

添加自动更新背景字体的 systemd 服务:

1
2
# cp ./minegrub-update.service /etc/systemd/system
# systemctl enable minegrub-update.service

最后将 grub 配置写入 grub.cfg 中:

1
# grub-mkconfig -o /boot/grub/grub.cfg

最后重启系统,别忘了拔 u 盘:

1
2
3
4
# exit
# umount -l /mnt/gentoo/dev{/shm,/pts,}
# umount -R /mnt/gentoo
# reboot

进入系统后我们用 os-probe 完成双系统引导中对 Windows 的检测以及 grub entry 的生成(当然如果你比较闲也可以手写),这里别忘了检查 /etc/default/grub 中是否有 GRUB_DISABLE_OS_PROBER=false

1
# grub-mkconfig -o /boot/grub/grub.cfg

安装 KDE + Wayland

首先按惯例连接网络:

1
$ nmtui

然后安装 kde-plasma/plasma-metakde-apps/kde-apps-meta,不过不同于其他的滚动发行版(Arch、openSUSE Tumbleweed、Debian Sid 等)或是贴近上游的常规发行版(如 Fedora Spin),Gentoo 滚得比较慢,目前 stable 分支还停留在 KDE 5.27:

如果你不想安装其中的部分组件,可以非常轻松地通过 USE flag 进行定义,例如 USE="kde-plasma/plasma-meta -xwayland" 将不会安装 xwayland ,通过 -sddm flag 也可以将默认的 sddm 替换为 lightdm,可用的 USE flag 详见 Gentoo wiki

1
2
$ sudo emerge --ask kde-plasma/plasma-meta
$ sudo emerge --ask kde-apps/kde-apps-meta

如果你和笔者一样使用类似 Surface Pro 的性能比较低下的笔记本,那么这个编译会耗费相当长的时间(至少数个小时),正所谓 “一杯茶,一包烟,Gentoo编译一整天” (笑)

plasma-meta 包自带依赖 sddm ,直接启用:

1
$ sudo systemctl enable --now sddm.service

最后进入到大家熟悉的 KDE 桌面,非常好的是默认使用 wayland,但非常坏的是 Plasma 6 在各大发行版都铺开了的时候 Gentoo 这边还停在 5.27

需要注意的是 Linux on Surface 由于缺少相应的触摸板驱动,触摸板使用体验极其糟糕,在系统设置中也无法被检测为触摸板

安装中文字体与输入法

首先安装中文字体,毕竟大家都不喜欢看到一大片方块:

1
$ sudo emerge --ask media-fonts/arphicfonts

中文输入法按惯例选择来自 Gentoo 中文社区的 fcitx ,不过默认被 masked 了,得先 unmasked 一下:

如果没有,检查一下你的 gentoo-zh 仓库是否启用成功

1
2
3
$ sudo emerge --ask --autounmask app-i18n/fcitx-meta
$ sudo dispatch-conf # 这里直接 u 就好
$ sudo emerge --ask app-i18n/fcitx-meta app-i18n/fcitx-chinese-addons

最后按惯例在设置的 virtual keyboard 里选中 fcitx5 ,然后右键 panel 的小企鹅图标找 Pinyin 即可:

image.png

笔者不得不吐槽的一句是软件包非常老,在各大主流发行版 fcitx5 早已全面铺开的时代,Gentoo 这边刚刚上到 rc 版本,同时 cloudpinyinlibpinyin 都还停留在 fcitx4 …不过这可能也是相当多开源社区存在的问题了,维护人员越来越少+用户出走逐渐形成恶性循环,马太效应诚不我欺.jpg

安装常用软件

因为笔者没有协议洁癖所以前面设置了接受所有协议,如果你有但是又需要安装部分软件则需要参照 wiki 手动修改 /etc/portage/package.license :)

首先是 chrome,有社区从 deb 重新打的包:

1
$ sudo emerge --ask www-client/google-chrome

以及 vscode:

1
$ sudo emerge --ask app-editors/vscode

flatpak 用以补充一些 Gentoo 上没有的软件包:

1
2
$ sudo emerge --ask sys-apps/flatpak
$ flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

然后是中国大陆这边常用的微信,虽然官方 Linux 版特供 UOS、OpenKylin 等国产发行版,但有人打了一个绕过发行版检测的 flatpak 的包 ,所以直接而下载后安装即可:

flathub 上也有,不过版本稍老

1
$ flatpak install com.tencent.WeChat.flatpak

QQ Linux 版提供了 AppImage 可用,不过还需要提前安个依赖:

1
$ sudo emerge --ask app-crypt/mit-krb5

之后随便放到个目录里然后写个 shortcut 放到 ~/.local/share/applications 下就行:

1
2
3
4
5
6
7
8
9
[Desktop Entry]
Name=QQ
GenericName=Tencent QQ
Exec=/home/arttnba3/Applications/QQ/QQ_3.2.7_240422_x86_64_01.appimage
Version=3.2.7.240422
Type=Application
Categories=Network;
Terminal=false
Icon=com.qq.QQ

0x03. 遇到的一些问题

触摸板驱动问题(not solved)

主要表现:

  • 启动后点按有效,但是多指手势(如双指==右键)无效
  • 按下触摸板左右键后点按失效
  • 在 KDE 系统设置中无法检测到触摸板

基本上只能当作一个最简陋的触摸板来用,笔者最初感觉主要可能是微软触摸板缺少驱动的问题,毕竟在安装 Windows 时在没更新驱动前也没法用键盘和触摸板( 微软怎么天天搞特殊,忍不了一点,真的有必要🐴

但是,笔者在 openSUSE Tumbleweed on Surface 中可以正常使用触摸板及多指手势 ,那这就有意思了,这么看起来似乎是笔者在编译内核时并未将部分必须的驱动给编译进去,又或是没有安装部分必须的软件,笔者更倾向于前者的缘故🤔

摄像头无法使用(not solved)

应该也是经典的缺驱动问题, 这就是你 Surface Pro 的屏摄像头啊,你们有没有这样的摄像头啊,真是摄摄像像又头头啊

休眠无法正常唤醒

放个一会整个💻就睡死了,按键盘没法唤醒,最快的解决方案是把键盘拔了再重新插上, 这就是你 Surface Pro 的键盘啊,你们有没有这样的键盘啊,真是键键又盘盘啊

Surface Pen 无法使用(not solved)

应该也是经典的缺驱动问题, 不过真的有人会有在 Linux on Surface 上使用 Surface Pen 的需求🐴

触屏无法正常使用(not solved)

应该也是经典的缺驱动问题,Surface Pro 支持十点触控的高素质屏幕几乎成了摆设, 这就是你 Surface Pro 的屏幕啊,你们有没有这样的屏幕啊,真是屏屏又幕幕啊

0xFF. 写在结束之后…

Distro hopping 的狂欢之火燃尽之后,剩下的似乎总是只有一地的灰烬,在笔者看来 Gentoo Linux 在安装流程上其实和 Arch Linux 基本差不多,所以对于笔者而言还是比较轻车熟路的,但在尝试了几小时 Gentoo Linux 后,笔者最终还是选择重新装回 openSUSE Tumbleweed,触摸板一开始就是正常可用的,也没有休眠醒不来的问题,甚至触屏功能在安装了社区提供的 linux-surface 包之后也正常可用了,唯一的遗憾就是 Surface Pen 与摄像头依旧没法工作,但其他的一切就像你在 Surface 上使用 Windows 那样自然与舒适

舒舒又适适,但可惜的是电池健康在经历笔者大四一年的蹂躏之后已经只剩不到 90 了

在回到了大蜥蜴温暖的怀抱当中后,笔者不禁思考:究竟是 Surface 这一特殊设备与 Gentoo 八字不合,还是笔者与 Gentoo Linux 在相性上不符呢?笔者自然不希望答案会是后者,但当笔者尝试在另一台旧笔记本上安装 Gentoo Linux 并再次碰到各种问题(例如 Dolphin 和触摸板无法正常工作)时,笔者不得不承认或许 Gentoo 这个特殊的发行版与笔者在某种程度上有点犯冲,而这样的两段安装经历也让笔者彻底打消了将主力操作系统从 openSUSE Tumbleweed 换成 Gentoo 的念头

除此之外,Gentoo 的各种优点似乎也没有理想中的那么好,作为一个滚动发行版,Gentoo 明显是没有 Arch、openSUSE Tumbleweed、Fedora 这样紧贴上游的(当然,如果能实现所谓“调试好了再发布”,那在能确保稳定性的情况下软件包旧一点其实无所谓,但事实上他们似乎并没有能做到这一点); USE flag 等配置听起来舒服,但是大部分情况下其实并不需要这样的特性,和其他发行版的包管理器的使用体验拉不开差距(当然,大部分情况下一个包管理器又能想要多不一样的体验呢?);Gentoo wiki 以前一直都被吹嘘能和 Arch wiki 有得一拼,但真正用起来能清晰感受到在内容上前者很明显差了后者好几个档次……

但这些其实都是小问题,毕竟 Linux 用户和苹果用户一样有着非常强的自适应性,尤其是在使用 Arch/Gentoo 这样的高度自定义的发行版的时候,出现问题了大家总会第一时间自适应地认为“是不是自己什么地方没有配置好”,可惜 Gentoo 社区一直在走下坡路却是一个不争的事实,虽然 Gentoo 听起来似乎有着各式各样不同的优点,但使用的人数确乎一直在慢慢减少,也很少有新鲜血液加入,因此很多软件包也没人打,在论坛问问题也没人回复,这又导致没人愿意继续用 Gentoo ——对于 Gentoo 社区所遇到的“马太效应“的问题,笔者思考了许久,感觉似乎没有一个比较好的解决方案,而这似乎是所有规模比较小的发行版都会遇到的问题,发行版用的人少导致社区缺少人维护从而导致系统没有那么好用,系统可用性的降低又使得人员出走,最后“强者愈强,弱者愈弱”

——而对于这个不得不被正视的问题,社区除了等死以外似乎并没有什么能做的事情,但同样是支持高度定制的系统,Gentoo 和 Arch 的命运为什么差得越来越多了呢?


【DISTRO.0x02】在 Surface Pro 8 上安装 Gentoo
https://arttnba3.github.io/2024/04/30/DISTRO-0X02-SURFACE_INSTALL_GENTOO_WINDOWS/
作者
arttnba3
发布于
2024年4月30日
许可协议