Alpine Linux + EFISTUB + BTRFS

2024-07-20

制作启动镜像

这里使用 alpine-extended 镜像。

因为 standard 镜像中的磁盘分区工具只有 busybox 的 fdisk 和 sfdisk , 制作 gpt 分区表比较麻烦。 extended 镜像中有 util-linux-misc 中的 fdisk 和 cfdisk 可以用来制作 gpt 分区表。

如果你只需要 mbr 分区表,有其他制作 gpt 分区的方式,standard 镜像也是可以的。

安装系统

这里以下面的分区格式为例

挂载点 分区 文件系统类型 文件系统额外挂载参数
/boot /dev/nvme0n1p1 vfat
/ /dev/nvme0n1p3 btrfs subvol=/root
/home /dev/nvme0n1p3 btrfs subvol=/home
/dev/nvme0n1p2 swapfs

制作磁盘分区表

  apk add cfdisk # 安装 cfdisk
  cfdisk /dev/nvme0n1  # 使用 cfdisk tui 配置分区

  # 如果分区 /dev 中不存在分区设备节点,需要重启一下 mdev
  ls /dev/nvme0n1p* || /etc/init.d/mdev restart

初始化文件系统

格式化各个磁盘分区:

apk add btrfs-progs dosfstools # 安装分区工具

# 格式化分区
mkfs.vfat /dev/nvme0n1p1
mkswap /dev/nvme0n1p2
mkfs.btrfs /dev/nvme0n1p3

制作相关 btrfs 子卷:

mount /dev/nvme0n1p3 /mnt
btrfs subvol create /mnt/home
btrfs subvol create /mnt/root

umount /mnt

将各个分区按照结构,依次挂载到 /mnt 目录下:

mount /dev/nvme0n1p3 /mnt -osubvol=/root
mkdir /mnt/boot /mnt/home
mount /dev/nvme0n1p3 /mnt/home -osubvol=/home
mount /dev/nvme0n1p1 /mnt/boot
swapon /dev/nvme0n1p2

安装系统

env BOOTLOADER=none DISKOPTS=/mnt setup-alpine

相比默认的 setup-alpine sys 模式安装,最后会多两个步骤:

  • Enter where to store configs: 设置 lbu 备份路径,如果需要与 sys 模式保持一致,填 none
  • Enter apk cache directory: apk 缓存路径,如果需要与 sys 模式保持一致,也填 none

添加 swap 分区表

这种方式安装的 alpine 不会在 /etc/fstab 文件中添加交换分区记录,需要手动添加。 vi 直接编辑 /mnt/etc/fstab 文件添加类似下面的内容:

# UUID=xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx    swap   swap    defaults    0 0

或者执行

apk add blkid

cat >> /mnt/etc/fstab << EOF
UUID=$(blkid --match-tag=UUID --output value /dev/nvme0n1p2)    swap   swap    defaults    0 0
EOF

安装微码

apk add --root /mnt amd-ucode # 以 amd cpu 为例
# 或者
# apk add --root /mnt intel-ucode # intel cpu

配置 EFI Boot

运行下面的脚本

#!/usr/bin/env sh
# 可通过 wget https://p.koi.moe/efistub 获取

set -e
apk add efibootmgr blkid

UUID=$(blkid --match-tag=UUID --output value /dev/nvme0n1p3)
UCODEIMG=$(ls /mnt/boot/*-ucode.img|head -n1)

# 如果为 intel cpu ,下面的 amd-ucode.img 改为 intel-ucode.img
params="root=UUID=$UUID rootfstype=btrfs rootflags=subvol=/root rw modules=sd-mod,usb-storage,btrfs,nvme\
  initrd=\amd-ucode.img \
  initrd=\initramfs-lts"

efibootmgr --create --label "Alpine Linux" \
  --disk /dev/nvme0n1 --part 1 \
  --loader /vmlinuz-lts \
  --unicode "${params}" \
  --verbose

重启进入系统

umount /mnt && reboot