好久没有用 Linux 的桌面环境了,这回打算给 Surface Pro 8 装个 Arch (with ZFS on LUKS) 看看。目前看起来使用 linux surface kernel 之后除了摄像头和 Hibernate 以外都可以得到支持。

准备工作

首先需要在 Windows 上给将要安装的系统分出一定的空间,这可以直接用 Windows 自带的 Create and format hard disk partitions 来完成。接下来需要准备一个启动盘,可以直接用现成的 Arch LiveCD,也可以自己按照文档做一个。

准备好启动盘和分配好空闲的硬盘空间之后关机,插入启动盘然后开机进 BIOS,松开开机键之后立即按住音量上键,等微软的图标闪了一下之后就可以进入 Surface UEFI 界面。在此关闭安全启动,然后选择同 USB 设备启动,就可以进入安装环境了。

安装系统

安装的过程基本上按照 Arch Wiki 的操作来就行了1

准备分区和挂载对应目录

这里准备两个 zpool,分别是不加密的挂载到 /bootbpool2,和在 LUKS 上的 rpool。如下所示,此处新增加的两个分区是 /dev/nvme0n1p5/dev/nvme0n1p6

nvme0n1     259:0    0 953.9G  0 disk
├─nvme0n1p1 259:12   0   260M  0 part
├─nvme0n1p2 259:13   0    16M  0 part
├─nvme0n1p3 259:14   0 698.6G  0 part
├─nvme0n1p4 259:15   0     1G  0 part
├─nvme0n1p5 259:16   0     8G  0 part
└─nvme0n1p6 259:17   0   244G  0 part

接下来创建 LUKS 设备3

cryptsetup luksFormat --sector-size=4096 /dev/nvme0n1p6
cryptsetup open /dev/nvme0n1p6 root_crypt

然后创建 zpool:

zpool create \
    -o ashift=12 \
    -o autotrim=on \
    -o compatibility=grub2 \
    -o cachefile=/etc/zfs/zpool.cache \
    -O devices=off \
    -O acltype=posixacl -O xattr=sa \
    -O compression=lz4 \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/boot -R /mnt \
    bpool /dev/nvme0n1p5

zpool create \
    -o ashift=12 \
    -o autotrim=on \
    -O acltype=posixacl -O xattr=sa -O dnodesize=auto \
    -O compression=zstd \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/ -R /mnt \
    rpool /dev/mapper/root_crypt

zpool export bpool
zpool export rpool
zpool import bpool -R /mnt -d /dev/disk/by-id
zpool import rpool -R /mnt -d /dev/disk/by-id

接下来创建 zfs datasets:

zfs create -o canmount=off    -o mountpoint=none rpool/archlinux
zfs create -o canmount=off    -o mountpoint=none bpool/archlinux

zfs create -o canmount=noauto -o mountpoint=/    rpool/archlinux/root
zfs mount rpool/archlinux/root

# /boot
zfs create -o mountpoint=/boot bpool/archlinux/root

# /home and /root
zfs create -o mountpoint=/home rpool/home
zfs create -o mountpoint=/root rpool/home/root
chmod 700 /mnt/root

# /var
zfs create -o canmount=off     rpool/var
zfs create -o canmount=off     rpool/var/lib
zfs create                     rpool/var/lib/log
zfs create                     rpool/var/lib/libvirt

安装 Arch

接下来在 /mnt 安装必要的包并 chroot

pacstrap -K /mnt base base-devel linux-firmware
arch-chroot /mnt

然后将 ArchZFSLinuxSurface 的仓库加入 /etc/pacman.conf 并且加入相关 key,并且安装相关的包:

pacman -Sy
pacman -S linux-surface linux-surface-headers iptsd intel-ucode
pacman -S zfs-dkms zfs-utils

修改 /etc/mkinitcpio.conf,分别在 MODULES 和 HOOK 加入 zfs, luks 还有 surface 键盘相关模块,其中 surface 相关模块是为了在解密 LUKS 的时候可以用 Type Cover 键盘输入密码4

MODULES=(zfs surface_aggregator surface_aggregator_registry surface_aggregator_hub surface_hid_core 8250_dw surface_hid surface_kbd intel_lpss intel_lpss_pci pinctrl_tigerlake)
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt zfs filesystems fsck)

修改完成后使用 mkinitcpio -P 重新生成 initramfs,并且启用下列服务:

zpool set cachefile=/etc/zfs/zpool.cache rpool
zpool set cachefile=/etc/zfs/zpool.cache bpool
systemctl enable zfs.target
systemctl enable zfs-import.target
systemctl enable zfs-import-cache.service
systemctl enable zfs-mount.service

安装引导

下面安装 Grub:

pacman -S grub efibootmgr

因为 Grub 可能无法自动识别根目录对应的 zpool,所以需要手动修改指定(这在每次更新 Grub 后都需要进行):

sed -i 's/rpool=/rpool="rpool" #/' /etc/grub.d/10_linux

接下来修改 /etc/default/grub 中的内核参数,指定启动时需要解密的 LUKS 设备:

GRUB_CMDLINE_LINUX="cryptdevice=UUID=<uuid of your LUKS partition>:root_crypt:allow-discards zfs_import_dir=/dev/disk/by-id/"

之后创建 /boot/efi 并且暂时退出 chroot 环境挂载 EFI 分区,然后再回到 chroot 安装 Grub:

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
grub-mkconfig -o /boot/grub/grub.cfg

安装系统剩余部分

剩下的事情就是安装图形界面和创建账户了,这就和普通的安装过程没有区别了。

Secure Boot

目前安装的系统是不支持 Secure Boot 的,如果需要启用 Secure Boot,需要进行额外的一些操作5。例如使用 shim-signed。但是我暂时没有成功。

参考资料