[SKILL]从零开始的Arch Linux安装工作流程

一、前言

这是一个用于让AI自动帮你最小安装Arch Linux的工作流程,对此你只需要做下面几件事即可让AI帮你安装Arch Linux

0.除了要安装Arch的电脑外,你还需要一台电脑,或者任意可以运行agent(codex,claude code等)的设备

1.制作系统U盘

2.进入安装引导

3.在安装引导中配置好网络(无线有线皆可)

4.让你的具有工具的电脑与被安装电脑在同一局域网

5.在安装引导中获取IP地址

6.设置安装引导中root的密码

7.将下方MD文档内容复制一份到本地文档

8.告诉你熟悉的agent文档路径与你安装引导中获取到的IP地址以及root密码,等待安装完成

注意:

本次安装会清空你的磁盘,如果你需要双系统,需要对AI进行特殊说明

使用本SKILL需要一定的基础\

你需要有操作agent的经验

二、SKILL文档

bash 复制代码
# Arch Linux 从零安装到可启动的完整实战文档

本文基于一次真实的 Arch Linux 远程安装与救援过程整理,不是只讲"标准答案",而是把实际会踩到的坑、为什么会踩、怎么避免、踩了以后怎么修,都写进去。

目标是让你看完以后,能够:

- 从 Arch ISO 开始,独立完成一次 UEFI + GPT + Btrfs 的安装
- 正确理解 ESP、`/boot`、`/boot/efi`、GRUB、`systemd-boot` 之间的关系
- 知道为什么"装好了包"不等于"能启动"
- 知道远程安装时,怎样避免重启后失联
- 知道启动失败以后,应该从哪里下手修

本文使用中文,并尽量用"能直接照做"的方式写。

---

## 1. 本文适用场景

本文最适合下面这种机器和需求:

- 机器使用 UEFI 启动
- 磁盘分区表使用 GPT
- 根分区使用 Btrfs
- ESP 单独分区,挂载到 `/boot/efi`
- 你希望使用 GRUB 作为启动器
- 你可能需要通过 SSH 远程安装或远程救援
- 你是笔记本,可能需要 Wi-Fi 才能联网

本文也适合"系统已经装了一半,但启动坏了"的情况,因为后面专门有修复流程。

---

## 2. 这次真实机器的最终工作配置

先把这次实机最终跑通的配置列出来,后面很多命令都围绕它展开。

### 2.1 磁盘与文件系统

- 磁盘:`/dev/nvme0n1`
- 分区 1:`/dev/nvme0n1p1`
  - 类型:ESP
  - 大小:512 MiB
  - 文件系统:FAT32
  - 挂载点:`/boot/efi`
- 分区 2:`/dev/nvme0n1p2`
  - 类型:swap
  - 大小:8 GiB
- 分区 3:`/dev/nvme0n1p3`
  - 类型:Btrfs
  - 标签:`Arch`
  - 子卷:
    - `@` 挂载到 `/`
    - `@home` 挂载到 `/home`

### 2.2 启动方式

- 固件模式:UEFI
- 启动器:GRUB
- EFI 文件路径:
  - `\EFI\MyArch\grubx64.efi`
  - `\EFI\Boot\bootx64.efi` 作为 fallback
- UEFI 启动项:`Boot0000* MyArch`

### 2.3 系统与网络

- 主机名:`MyArch`
- 内核:`linux`
- 微码:`intel-ucode`
- 远程访问:`openssh` + `sshd`
- 无线网络:`iwd`
- IP 配置:`systemd-networkd`
- DNS:`systemd-resolved`

### 2.4 这次最关键的坑

这次真正把系统搞坏的,不是"没装内核",也不是"没写引导项",而是:

- ESP 实际挂载在 `/boot/efi`
- 内核和 initramfs 实际在根文件系统的 `/boot`
- 但原来的 `systemd-boot` 条目却写成了从 ESP 根目录找 `/vmlinuz-linux`、`/initramfs-linux.img`

结果就是:

- 文件明明存在
- `bootctl` 明明也在
- 但是启动条目实际指向了错误位置
- 最终表现为"看上去都装了,但就是起不来"

这是本文最重要的经验之一。

---

## 3. 安装前必须先想清楚的三件事

很多人安装 Arch 失败,不是命令不会敲,而是这三件事没在开工前想清楚。

### 3.1 你到底是 BIOS 还是 UEFI

先确认:

```bash
ls /sys/firmware/efi/efivars
```

如果目录存在,说明你当前是 UEFI 模式启动的。

更直接一点:

```bash
if [ -d /sys/firmware/efi/efivars ]; then
  echo UEFI
else
  echo BIOS
fi
```

为什么这一步很重要:

- UEFI 和 BIOS 的启动器安装方式不同
- UEFI 需要 ESP
- BIOS 通常不需要 ESP
- 你如果在 UEFI 机器上按 BIOS 思路装,或者反过来,后面很容易白干

### 3.2 你到底想把 ESP 挂在哪里

UEFI 机器上最常见的两种做法:

1. 把 ESP 挂到 `/boot`
2. 把 ESP 挂到 `/boot/efi`

这两种做法都可以,但后果不同。

#### 做法 A:ESP 挂到 `/boot`

优点:

- `systemd-boot` 用起来最顺手
- 内核、initramfs、微码直接放在 ESP 上,路径简单

缺点:

- ESP 是 FAT32,不支持 Unix 权限和很多 Linux 特性
- `/boot` 上所有东西都放到 FAT32,不是所有人都喜欢

#### 做法 B:ESP 挂到 `/boot/efi`

优点:

- `/boot` 仍然在 Linux 文件系统里
- 内核和 initramfs 不必放在 FAT32
- 和很多发行版的默认习惯更接近

缺点:

- 如果你还想用 `systemd-boot`,就必须非常清楚内核文件到底在 ESP 上还是不在
- 你不能想当然地写 `linux /vmlinuz-linux`,除非那个文件真的在 ESP 根目录

这次我们最终选择的是:

- `/boot` 在 Btrfs 根文件系统里
- ESP 挂在 `/boot/efi`
- 启动器用 GRUB

这是一个非常稳的组合。

### 3.3 你到底想用什么网络方案

大多数桌面笔记本用户有两个常见选择:

#### 方案 A:`NetworkManager`

优点:

- 最省心
- 对桌面、笔记本、Wi-Fi、图形界面最友好
- 重启后网络恢复通常比较简单

缺点:

- 对"纯手工控制"用户来说会稍重一点

#### 方案 B:`iwd + systemd-networkd + systemd-resolved`

优点:

- 纯净
- 可控
- 适合远程、服务器风格、手工管理

缺点:

- 你必须自己确保 Wi-Fi profile、networkd 配置、DNS 配置都落到目标系统里
- 少一步都可能导致"系统能启动,但重启后没网,SSH 连不上"

这次为了保证远程重启后尽量能自己回网,我们最终使用的是方案 B。

如果你只是本地安装、后续要装桌面环境,通常 `NetworkManager` 更省事。

---

## 4. 准备工作

### 4.1 你需要准备什么

- Arch Linux 启动 U 盘
- 能进入 BIOS/Boot Menu
- 明确知道目标磁盘是哪块
- 如果你要远程装机:
  - 机器必须先联网
  - 你要有另一台机器能 SSH 进去
  - 你要能在现场看屏幕,或者有人在机器旁边

### 4.2 BIOS 里建议先确认

- 启动模式是 UEFI
- Secure Boot 是否关闭
- 启动顺序里允许从 U 盘启动

如果你不确定 Secure Boot 状态,在 Arch ISO 里也可以看:

```bash
bootctl status
```

如果看到 `Secure Boot: disabled`,那就和这次实机一致。

---

## 5. 进入 Arch ISO 后的第一批检查

启动进 Arch ISO 之后,不要马上分区,先做检查。

### 5.1 确认时间同步

```bash
timedatectl set-ntp true
timedatectl status
```

时间不准会影响很多事,比如包管理、TLS、日志判断。

### 5.2 确认网络

#### 有线网络

通常插上就有,直接看:

```bash
ip -br a
ip route
ping -c 3 archlinux.org
```

#### Wi-Fi 网络

用 `iwctl`:

```bash
iwctl
device list
station wlan0 scan
station wlan0 get-networks
station wlan0 connect <你的SSID>
exit
```

然后再检查:

```bash
ip -br a
ping -c 3 archlinux.org
```

### 5.3 如果你要远程安装

先在 live 环境设置 root 密码并启动 SSH:

```bash
passwd
systemctl start sshd
ip -br a
```

然后从另一台机器登录:

```bash
ssh root@<live环境的IP>
```

这次实际操作就是先远程连进 live 环境,再继续排查和 chroot。

---

## 6. 识别磁盘,别装错盘

先看磁盘:

```bash
lsblk -f
blkid
```

重点看:

- 哪块是 U 盘
- 哪块是内置 NVMe/SSD
- 之前有没有 Windows 分区
- 有没有已经存在的 ESP
- 有没有已有的 Linux 分区

这次实机里看到的是:

- `sda`:Arch ISO U 盘
- `nvme0n1`:内部系统盘

绝对不要看到 `sda` 就直接分。很多人第一步就把安装 U 盘自己格式化了。

---

## 7. 推荐分区方案

这里给出和这次实机一致、比较稳的方案。

### 7.1 分区布局

- `p1`:ESP,512 MiB,FAT32
- `p2`:swap,8 GiB
- `p3`:Btrfs,占剩余全部空间

### 7.2 用 `cfdisk` 手工分区

如果你更喜欢交互式:

```bash
cfdisk /dev/nvme0n1
```

选择:

- 分区表:GPT
- 建立 512 MiB EFI System 分区
- 建立 8 GiB Linux swap 分区
- 剩余空间建立 Linux filesystem 分区

### 7.3 用 `parted` 非交互分区

如果你喜欢可复制命令:

```bash
parted /dev/nvme0n1 --script mklabel gpt
parted /dev/nvme0n1 --script mkpart ESP fat32 1MiB 513MiB
parted /dev/nvme0n1 --script set 1 esp on
parted /dev/nvme0n1 --script mkpart primary linux-swap 513MiB 8705MiB
parted /dev/nvme0n1 --script mkpart primary btrfs 8705MiB 100%
```

分完再次确认:

```bash
lsblk -f
parted /dev/nvme0n1 print
```

---

## 8. 格式化文件系统

### 8.1 格式化 ESP

```bash
mkfs.fat -F32 /dev/nvme0n1p1
```

### 8.2 初始化 swap

```bash
mkswap /dev/nvme0n1p2
swapon /dev/nvme0n1p2
```

### 8.3 格式化 Btrfs

```bash
mkfs.btrfs -L Arch /dev/nvme0n1p3
```

---

## 9. 创建 Btrfs 子卷并正确挂载

这一步非常关键。

### 9.1 先挂顶层,再创建子卷

```bash
mount /dev/nvme0n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
umount /mnt
```

### 9.2 重新按目标布局挂载

```bash
mount -o subvol=@,compress=zstd:3,ssd,discard=async /dev/nvme0n1p3 /mnt
mkdir -p /mnt/home
mkdir -p /mnt/boot/efi
mount -o subvol=@home,compress=zstd:3,ssd,discard=async /dev/nvme0n1p3 /mnt/home
mount /dev/nvme0n1p1 /mnt/boot/efi
```

### 9.3 验证挂载结果

```bash
findmnt -R /mnt
```

你希望看到的是类似:

- `/mnt` 来自 `subvol=@`
- `/mnt/home` 来自 `subvol=@home`
- `/mnt/boot/efi` 来自 ESP

### 9.4 这一步最常见的坑

#### 坑 1:以为系统已经挂了,其实 `/mnt` 是空的

这次真实排查时,一开始 `/mnt` 根本就是空的,说明目标系统压根没挂上去。

判断方式:

```bash
findmnt -R /mnt
ls -la /mnt
```

如果只看到空目录,就别急着 chroot,更别急着装引导。

#### 坑 2:把 ESP 挂到 `/mnt/boot`,后来 `fstab` 却写成 `/boot/efi`

这会直接埋雷。

你必须全程统一:

- 你决定 ESP 挂到哪里
- 就一路保持一致
- `fstab`、启动器、路径、验证命令都要用同一套逻辑

---

## 10. 安装基础系统

### 10.1 推荐安装包

如果你按本文路线走,建议安装这些包:

```bash
pacstrap -K /mnt \
  base \
  linux \
  linux-firmware \
  btrfs-progs \
  grub \
  efibootmgr \
  sudo \
  vim \
  openssh \
  iwd \
  intel-ucode
```

如果你是 AMD CPU,把 `intel-ucode` 换成 `amd-ucode`。

如果你更想走 `NetworkManager` 路线,可以额外装:

```bash
pacstrap -K /mnt networkmanager
```

### 10.2 生成 `fstab`

```bash
genfstab -U /mnt > /mnt/etc/fstab
cat /mnt/etc/fstab
```

注意这里我故意用的是 `>` 而不是 `>>`。

#### 为什么这里要强调

这次实机遇到过一个非常典型的坑:

- 同一个根分区和 home 分区被重复写进了 `fstab`
- 结果 `fstab` 里出现了两份 `/`、两份 `/home`

这种问题往往来自:

- 多次执行 `genfstab -U /mnt >> /mnt/etc/fstab`
- 每次都 append,没有先清掉旧内容

所以:

- 第一次生成时优先用 `>`
- 如果你需要重生成,先人工审查

### 10.3 推荐的 `fstab` 目标样子

如果你按本文的方案,最终应该类似:

```fstab
# /dev/nvme0n1p3 LABEL=Arch
UUID=<btrfs-uuid> / btrfs rw,relatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=/@ 0 0

# /dev/nvme0n1p3 LABEL=Arch
UUID=<btrfs-uuid> /home btrfs rw,relatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=/@home 0 0

# /dev/nvme0n1p1
UUID=<esp-uuid> /boot/efi vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2

# /dev/nvme0n1p2
UUID=<swap-uuid> none swap defaults 0 0
```

---

## 11. 进入 chroot,开始真正配置系统

```bash
arch-chroot /mnt
```

进去以后,按下面顺序配置。

### 11.1 时区

```bash
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
hwclock --systohc
```

### 11.2 本地化

编辑:

```bash
vim /etc/locale.gen
```

取消注释至少这两行:

```text
en_US.UTF-8 UTF-8
zh_CN.UTF-8 UTF-8
```

生成 locale:

```bash
locale-gen
```

写入:

```bash
cat > /etc/locale.conf <<'EOF'
LANG=zh_CN.UTF-8
EOF
```

### 11.3 主机名

```bash
cat > /etc/hostname <<'EOF'
MyArch
EOF
```

### 11.4 `/etc/hosts`

```bash
cat > /etc/hosts <<'EOF'
127.0.0.1 localhost
::1 localhost
127.0.1.1 MyArch.localdomain MyArch
EOF
```

### 11.5 root 密码

```bash
passwd
```

### 11.6 创建普通用户

```bash
useradd -m -G wheel -s /usr/bin/bash archuser
passwd archuser
```

### 11.7 开启 sudo

推荐方式是 `visudo`,但如果你就是想快速自动化:

```bash
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers
```

验证:

```bash
grep '^%wheel ALL=(ALL:ALL) ALL' /etc/sudoers
```

---

## 12. 选择并配置网络方案

这一节非常重要,因为"系统能启动"和"系统启动后能联网"是两回事。

---

### 12.1 方案 A:`NetworkManager`,适合大多数桌面用户

安装:

```bash
pacman -S networkmanager
systemctl enable NetworkManager
```

优点是重启后本地用 `nmtui` 或桌面网络管理器很好配。

如果你是本地装机,而且不依赖远程 SSH 回连,这是最省事的选择。

---

### 12.2 方案 B:`iwd + systemd-networkd + systemd-resolved`,适合手工控制和远程续连

这次实机最终使用的就是这一套。

#### 安装

```bash
pacman -S iwd openssh
```

#### 启用服务

```bash
systemctl enable iwd
systemctl enable systemd-networkd
systemctl enable systemd-resolved
systemctl enable sshd
```

#### `resolv.conf`

```bash
rm -f /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
```

#### `networkd` 配置

创建 `/etc/systemd/network/20-wlan.network`:

```ini
[Match]
Type=wlan

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes
MulticastDNS=yes

[DHCPv4]
RouteMetric=600

[IPv6AcceptRA]
RouteMetric=600
```

如果你还要给有线网卡准备自动 DHCP,再加 `/etc/systemd/network/20-ethernet.network`:

```ini
[Match]
Type=ether
Kind=!*

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes
MulticastDNS=yes

[DHCPv4]
RouteMetric=100

[IPv6AcceptRA]
RouteMetric=100
```

#### Wi-Fi 配置怎么持久化

如果你是本地安装,首次开机后直接用:

```bash
iwctl
station wlan0 scan
station wlan0 get-networks
station wlan0 connect <你的SSID>
```

`iwd` 会在 `/var/lib/iwd/` 里生成对应 profile。

如果你是远程安装,并且当前 live 环境已经连上了 Wi-Fi,那么最稳的办法是:

```bash
cp -f /var/lib/iwd/<你的SSID>.psk /mnt/var/lib/iwd/
chmod 600 /mnt/var/lib/iwd/<你的SSID>.psk
```

这样重启后目标系统就有现成的 Wi-Fi profile 了。

#### 不要让两套网络栈抢同一个无线网卡

如果你最终决定用 `iwd + networkd`,那就不要同时让 `NetworkManager` 启用:

```bash
systemctl disable NetworkManager
```

这次实机最终就是这么处理的。

---

## 13. 为什么这次最终选择 GRUB,而不是 systemd-boot

这一节是本文最有价值的部分之一。

### 13.1 先说结论

在这次的目录结构下:

- ESP 挂载到 `/boot/efi`
- 内核、微码、initramfs 位于根文件系统 `/boot`

最稳的选择是 GRUB。

### 13.2 `systemd-boot` 什么时候最舒服

当你满足下面任一条件时,`systemd-boot` 会比较顺手:

1. 你把 ESP 直接挂到 `/boot`
2. 你使用 UKI,并且 UKI 放在 ESP 上
3. 你明确管理好内核、微码、initramfs 到 ESP 的复制和路径

### 13.3 这次为什么原来的 `systemd-boot` 会坏

原来的状况是:

- `fstab` 写的是 ESP 挂载到 `/boot/efi`
- 但 `loader/entries/arch.conf` 里写的是:

```text
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
```

对于 `systemd-boot` 来说,这些路径是相对于 ESP 的。

可问题是:

- ESP 根本没有这些文件
- 这些文件实际在根文件系统里的 `/boot`

所以 `bootctl status` 直接会报类似:

- `linux: /boot//vmlinuz-linux (No such file or directory)`
- `initrd: /boot//intel-ucode.img (No such file or directory)`

这不是 `systemd-boot` 坏了,而是路径设计和挂载点逻辑错位了。

### 13.4 GRUB 为什么能解决这个问题

GRUB 能很好处理:

- UEFI ESP 只放 GRUB EFI 文件
- 内核和 initramfs 放在 Linux 根文件系统
- 根文件系统还是 Btrfs 子卷

它生成出来的条目可以直接指向:

```text
/@/boot/vmlinuz-linux
/@/boot/intel-ucode.img
/@/boot/initramfs-linux.img
```

这正是这次重启成功的关键。

---

## 14. 正确安装 GRUB 的完整步骤

进入 chroot 后:

### 14.1 先生成 initramfs

```bash
mkinitcpio -P
```

### 14.2 安装 GRUB 到 UEFI

```bash
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=MyArch --recheck
```

### 14.3 再写 fallback 路径

这一步很重要,很多人会省略。

```bash
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --no-nvram --recheck
```

它会把 EFI 文件写到:

```text
\EFI\Boot\bootx64.efi
```

有什么用:

- 某些固件不认你新建的 NVRAM 项
- 某些固件更新、清 CMOS、重置后会丢 NVRAM
- fallback 路径能兜底

### 14.4 生成 `grub.cfg`

```bash
grub-mkconfig -o /boot/grub/grub.cfg
```

### 14.5 检查语法

```bash
grub-script-check /boot/grub/grub.cfg
```

### 14.6 检查 UEFI 启动项

```bash
efibootmgr -v
```

你希望看到类似:

```text
Boot0000* MyArch HD(...) \EFI\MyArch\grubx64.efi
BootOrder: 0000,...
```

如果新建项没有被放到前面,可以自己调:

```bash
efibootmgr -o 0000,0007,0002,0003
```

这里的编号按你机器实际输出改。

---

## 15. 重启前必须做的验收

这一步非常重要。

在你敲 `reboot` 之前,至少检查以下内容。

### 15.1 挂载是否正确

```bash
findmnt / /boot/efi /home
```

### 15.2 内核与 initramfs 是否真的存在

```bash
ls -lh /boot/vmlinuz-linux /boot/intel-ucode.img /boot/initramfs-linux.img
```

### 15.3 `grub.cfg` 是否存在

```bash
ls -lh /boot/grub/grub.cfg
```

### 15.4 UEFI 文件是否存在

```bash
ls -lh /boot/efi/EFI/MyArch/grubx64.efi
ls -lh /boot/efi/EFI/Boot/bootx64.efi
```

### 15.5 SSH host key 是否存在

如果你依赖远程回连,强烈建议手动生成:

```bash
ssh-keygen -A
ls -l /etc/ssh/ssh_host_*_key
```

否则有可能发生:

- `sshd` 虽然 enabled
- 但首次开机时没把 host keys 及时准备好
- 结果 SSH 起不来

### 15.6 网络服务是否启用

如果你用的是本文的 `iwd + networkd` 路线:

```bash
systemctl is-enabled iwd
systemctl is-enabled systemd-networkd
systemctl is-enabled systemd-resolved
systemctl is-enabled sshd
```

### 15.7 `root` 密码设了,不代表 `root` 可以 SSH 登录

这是这次实机又一个非常典型的点。

这次最终表现是:

- `root` 本地密码是正确的
- 但是 SSH 用 `root` 密码登录被拒绝
- `archuser` 可以正常 SSH 登录

原因通常不是密码错,而是 SSH 策略不允许 root 密码登录。

所以远程验收时,不要只盯着 `root`,普通用户 + `sudo` 往往更稳。

---

## 16. 正确重启的方法

如果你在本机本地操作,推荐:

```bash
exit
umount -R /mnt
swapoff -a
reboot
```

如果你是远程操作,有时未必方便完全按这个顺序做,但你要知道副作用。

### 16.1 这次实机重启后的一个小后果

因为这次是在 live 环境中远程修完后直接重启,ESP 后来出现了一条警告:

```text
FAT-fs (nvme0n1p1): Volume was not properly unmounted.
```

这说明 ESP 不是完全干净卸载的。

它没有导致启动失败,但会留下 FAT dirty-bit 警告。

这类问题一般后续维护窗口再修:

```bash
fsck.vfat -a /dev/nvme0n1p1
```

所以经验是:

- 本地安装时,尽量规范卸载再重启
- 远程抢救时,功能优先,dirty-bit 警告可以后面收尾

---

## 17. 首次启动后的验收步骤

### 17.1 看系统是否真的不是 live 环境

```bash
hostnamectl
cat /etc/os-release
```

你应该看到:

- 主机名是你自己设的
- 不是 `archiso`
- 内核版本是你安装到磁盘里的系统版本

### 17.2 看 UEFI 当前到底是从哪个项目启动的

```bash
sudo efibootmgr -v
```

这次实机重启成功后的关键证据是:

```text
BootCurrent: 0000
Boot0000* MyArch ...
```

这说明固件不是"碰巧走了 fallback",而是真的从我们创建的 `MyArch` 启动项起来的。

### 17.3 看网络和 SSH

```bash
systemctl is-active iwd systemd-networkd systemd-resolved sshd
systemctl is-enabled iwd systemd-networkd systemd-resolved sshd
ip -br a
```

如果是 Wi-Fi:

```bash
iwctl station wlan0 show
```

### 17.4 看挂载

```bash
findmnt / /boot/efi /home
```

### 17.5 看有没有明显故障

```bash
systemctl --failed
journalctl -b -p warning --no-pager
```

---

## 18. 这次真实踩坑记录与经验总结

下面是这次最有代表性的坑。

### 坑 1:以为 `/mnt` 里就是已安装系统,结果其实没挂

现象:

- `arch-chroot /mnt` 进去可能是空的、错的,甚至根本进不去
- 你以为自己在改目标系统,实际上改的是 live 环境

正确做法:

```bash
findmnt -R /mnt
ls -la /mnt
```

只有确认:

- `/mnt` 真挂着目标根
- `/mnt/home` 真挂着 home 子卷
- `/mnt/boot/efi` 真挂着 ESP

后续操作才有意义。

### 坑 2:Btrfs 子卷名要先确认,别想当然

这次实际看到的是:

- `@`
- `@home`

不是所有系统都这么命名。

所以先看:

```bash
mount -o subvolid=5 /dev/nvme0n1p3 /mnt
btrfs subvolume list /mnt
umount /mnt
```

确认完再挂。

### 坑 3:`systemd-boot` 条目和真实挂载点不一致

这是本次核心问题。

错误本质:

- `fstab`:ESP 挂 `/boot/efi`
- 启动条目:假设内核在 ESP 根目录
- 实际:内核在 Linux 根文件系统的 `/boot`

这类问题最可怕的地方在于:

- 包都装了
- 文件都在
- `bootctl` 也在
- 甚至 ESP 上看起来也有 `loader/entries/arch.conf`
- 但它仍然会启动失败

经验:

- 启动器不是看"文件有没有",而是看"路径逻辑是否闭环"

### 坑 4:`fstab` 重复条目

原因通常是反复 append `genfstab`。

后果:

- 挂载行为混乱
- 排查时很容易误判

经验:

- 生成 `fstab` 时优先 `>`
- 重生成前先清楚旧内容
- 最终一定手工审一遍

### 坑 5:只装了 `sshd`,没保证重启后真能远程进

想让远程重启后还能接回来,至少要同时满足:

- `openssh` 已安装
- `sshd` 已启用
- host keys 已存在
- 网络配置已落盘
- Wi-Fi profile 已落盘
- DNS 正常

少任何一步,都可能变成:

- 系统其实启动成功了
- 但你就是连不上

### 坑 6:`root` 密码可用,不代表 root SSH 一定可用

这次实机重启后就是:

- `archuser` 可 SSH 登录
- `root` 密码 SSH 被拒绝

这说明要区分三件事:

1. root 账户是否存在
2. root 密码是否设好
3. SSH 策略是否允许 root 密码登录

不要把这三件事混成一件。

### 坑 7:远程安装时,网络栈千万别双开

如果你最后要用:

- `iwd + systemd-networkd`

那就不要再让:

- `NetworkManager`

同时接管无线网卡。

不然经常会出现:

- live 环境里明明联网
- 装好后第一次开机网络状态异常
- 接口被抢、配置混乱

### 坑 8:日志里的 `nouveau` 警告容易吓人,但它不是这次的启动主因

这次重启后的 `journalctl -b -p warning` 里有大量 `nouveau` 的 GSP 报错。

它说明的是:

- 这台带 NVIDIA 显卡的机器,开源 `nouveau` 驱动存在兼容性或功能问题

但注意:

- 这不是引导失败的原因
- 不是 GRUB 坏了
- 不是 ESP 坏了

经验:

- 启动器问题和显卡驱动问题要分开看

---

## 19. 如果启动失败,怎么救

这一节非常重要。

你如果重启后起不来,不要慌,按下面顺序来。

### 19.1 先观察失败停在哪一层

#### 情况 A:固件直接进回 BIOS / Boot Menu

优先怀疑:

- 没有正确 EFI 文件
- UEFI 启动项没写进去
- BootOrder 不对

检查:

- BIOS 里是否能看到 `MyArch`
- 有没有 fallback 路径

#### 情况 B:能进 GRUB,但选内核后失败

优先怀疑:

- `grub.cfg` 条目路径不对
- 根 UUID 不对
- `rootflags=subvol=@` 不对
- initramfs 缺失

#### 情况 C:内核起来了,但卡在挂载根文件系统

优先怀疑:

- `fstab` 错
- Btrfs 子卷名错
- UUID 错

#### 情况 D:系统其实启动成功,但你远程连不上

优先怀疑:

- Wi-Fi profile 没落盘
- `iwd` / `networkd` / `resolved` / `sshd` 没 enable
- SSH host keys 没生成

### 19.2 通用修复流程

重新用 Arch ISO 启动,联网后:

```bash
mount -o subvol=@ /dev/nvme0n1p3 /mnt
mkdir -p /mnt/home /mnt/boot/efi
mount -o subvol=@home /dev/nvme0n1p3 /mnt/home
mount /dev/nvme0n1p1 /mnt/boot/efi
swapon /dev/nvme0n1p2
arch-chroot /mnt
```

### 19.3 修 `fstab`

```bash
cat /etc/fstab
```

确认:

- `/` 是 `subvol=/@`
- `/home` 是 `subvol=/@home`
- ESP 是 `/boot/efi`
- 没有重复条目

### 19.4 重新生成 initramfs

```bash
mkinitcpio -P
```

### 19.5 重装 GRUB

```bash
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=MyArch --recheck
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --no-nvram --recheck
grub-mkconfig -o /boot/grub/grub.cfg
grub-script-check /boot/grub/grub.cfg
efibootmgr -v
```

### 19.6 修 ESP 的 FAT dirty-bit

如果日志里提示 ESP 没有正常卸载:

先在 live 环境卸载它,然后:

```bash
fsck.vfat -a /dev/nvme0n1p1
```

### 19.7 修远程网络

如果系统启动了但连不回去:

```bash
pacman -S openssh iwd
systemctl enable sshd
systemctl enable iwd
systemctl enable systemd-networkd
systemctl enable systemd-resolved
ssh-keygen -A
```

确认:

```bash
ls -l /var/lib/iwd
ls -l /etc/systemd/network
ls -l /etc/ssh/ssh_host_*_key
```

---

## 20. 推荐的最小可行安装命令清单

如果你只想看一版能直接复制的最小流程,这里给一份浓缩版,但你最好结合前文理解它。

### 20.1 live 环境

```bash
timedatectl set-ntp true
```

联网后分区、格式化、挂载:

```bash
mkfs.fat -F32 /dev/nvme0n1p1
mkswap /dev/nvme0n1p2
swapon /dev/nvme0n1p2
mkfs.btrfs -L Arch /dev/nvme0n1p3

mount /dev/nvme0n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
umount /mnt

mount -o subvol=@,compress=zstd:3,ssd,discard=async /dev/nvme0n1p3 /mnt
mkdir -p /mnt/home /mnt/boot/efi
mount -o subvol=@home,compress=zstd:3,ssd,discard=async /dev/nvme0n1p3 /mnt/home
mount /dev/nvme0n1p1 /mnt/boot/efi

pacstrap -K /mnt base linux linux-firmware btrfs-progs grub efibootmgr sudo vim openssh iwd intel-ucode
genfstab -U /mnt > /mnt/etc/fstab
arch-chroot /mnt
```

### 20.2 chroot 内

```bash
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
hwclock --systohc

sed -i 's/^#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
sed -i 's/^#zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
echo 'LANG=zh_CN.UTF-8' > /etc/locale.conf

echo 'MyArch' > /etc/hostname
cat > /etc/hosts <<'EOF'
127.0.0.1 localhost
::1 localhost
127.0.1.1 MyArch.localdomain MyArch
EOF

passwd
useradd -m -G wheel -s /usr/bin/bash archuser
passwd archuser
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers

pacman -S iwd
systemctl enable iwd
systemctl enable systemd-networkd
systemctl enable systemd-resolved
systemctl enable sshd
rm -f /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

mkinitcpio -P
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=MyArch --recheck
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --no-nvram --recheck
grub-mkconfig -o /boot/grub/grub.cfg
grub-script-check /boot/grub/grub.cfg
ssh-keygen -A
exit
```

### 20.3 重启前

```bash
findmnt -R /mnt
cat /mnt/etc/fstab
ls -lh /mnt/boot/vmlinuz-linux /mnt/boot/intel-ucode.img /mnt/boot/initramfs-linux.img
ls -lh /mnt/boot/efi/EFI/MyArch/grubx64.efi /mnt/boot/efi/EFI/Boot/bootx64.efi
efibootmgr -v
```

### 20.4 重启

```bash
umount -R /mnt
swapoff -a
reboot
```

---

## 21. 这次真实安装给出的最终建议

如果你想减少踩坑,我的建议很明确:

### 21.1 如果你用 `/boot/efi`,优先选 GRUB

原因不是"GRUB 更高级",而是它和这种布局天然更契合。

### 21.2 如果你想用 `systemd-boot`,那就先把路径逻辑想清楚

至少得满足下面之一:

- ESP 挂 `/boot`
- 内核和 initramfs 真放在 ESP 上
- 或者你用 UKI

否则你会重现这次的故障。

### 21.3 远程安装的重点不是"装完",而是"重启后还能连回来"

所以要额外保证:

- 网络配置已经持久化
- Wi-Fi profile 已持久化
- SSH host keys 已生成
- SSH 服务已启用
- 最好有一个普通用户可 SSH + `sudo`

### 21.4 重启前一定做静态验收

不要相信"我感觉差不多了"。

真正应该相信的是:

- `findmnt`
- `fstab`
- `ls /boot`
- `ls /boot/efi/EFI/...`
- `efibootmgr -v`
- `grub-script-check`

### 21.5 日志里的所有 warning 不等于引导失败

像这次的:

- `nouveau` GSP 报错
- ACPI 警告
- ESP dirty-bit 警告

都不是这次启动链路真正的致命点。

要先抓住主因,不要被噪音带偏。

---

## 22. 后续建议

这次系统已经成功启动,但如果你继续打磨,建议后面再做这些事:

### 22.1 处理 NVIDIA 驱动

如果你这台机器有 NVIDIA 独显,建议后续安装合适的官方驱动,而不是长期用 `nouveau`。

### 22.2 决定是否允许 root SSH

默认更安全的做法是:

- `root` 只本地登录
- 远程用普通用户 + `sudo`

如果你明确要开 root SSH,再改:

```bash
sudo vim /etc/ssh/sshd_config
sudo systemctl restart sshd
```

但一定知道这是安全面更大的选择。

### 22.3 维护窗口里修 ESP 的 FAT 警告

```bash
sudo fsck.vfat -a /dev/nvme0n1p1
```

### 22.4 补充你自己的子卷策略

比如:

- `@snapshots`
- `@var_log`
- `@pkg`

但那是进阶设计,不是"先把系统装起来"的前提。

---

## 23. 最后的经验总结

这次最核心的经验,不是某条命令,而是一套判断方法:

1. 先判断启动模式,而不是先装引导
2. 先确认挂载结构,而不是先 chroot
3. 先确认路径闭环,而不是只看文件有没有
4. 先做静态验证,再决定重启
5. 远程安装时,把"网络能不能回来"当成引导问题的一部分

如果把这五点记住,你安装 Arch Linux 的成功率会高很多。

---

## 24. 附:这次真实故障的一句话复盘

一句话概括这次真实问题:

> 系统不是没装好,而是 ESP 挂在 `/boot/efi`、内核在根文件系统 `/boot`,但原有 `systemd-boot` 条目却按"内核在 ESP 上"的逻辑写,导致引导路径断裂;改为和挂载结构一致的 GRUB 后,系统成功启动。

这句话如果你能彻底理解,UEFI 下很多"怎么都起不来"的问题你都会看得更清楚。
相关推荐
Elnaij1 小时前
Linux系统与系统编程(8)——环境变量、进程控制与进程替换
linux
薛定猫AI1 小时前
【深度解析】Qwen 3.6 vs Gemma 4:本地大模型时代,如何选对“日常开发模型”
人工智能·状态模式
Galsk1 小时前
Linux零拷贝
java·linux·服务器·面试
陈天伟教授1 小时前
人生的力量来源何处?
人工智能·学习
闵孚龙1 小时前
Claude Code 缓存优化模式全解析:AI Agent 上下文工程、Prompt Cache、工具 Schema 缓存、Token 成本优化
人工智能·缓存·prompt
AI周红伟3 小时前
All in Token, 移动,电信,联通,阿里,百度,华为,字节,Token石油战争,Token经济,百度要“重写”AI价值度量
大数据·人工智能·机器学习·百度·copilot·openclaw
AI周红伟3 小时前
Token经济学:AI时代的新货币战争,All in Token, 新时代的石油战争,华为,阿里,百度,字节的石油战争
大数据·人工智能·机器学习·百度·华为·copilot·openclaw
XM_jhxx7 小时前
±0.03mm的精度怎么保证?翌东塑胶用AI赋能质量管控升级
人工智能
阿正的梦工坊7 小时前
深入理解 PyTorch 中的 unsqueeze 操作
人工智能·pytorch·python