Ubuntu 重装、双系统引导与 Linux 游戏排错

warning
记录已脱敏

原始对话里出现过内网地址、SSH 密码和主机指纹。本文不保存这些凭据,只使用 <目标主机>、<用户名> 等占位符。已经暴露过的密码应立即更换,远程登录优先改用 SSH 密钥。

这次不是单纯“装一个 Ubuntu”,而是一条连续的系统排障链:

远程连不上
→ 判断当前是不是 Live 环境
→ 区分 Windows、TF 卡、安装 U 盘和内部 SSD
→ 发现 Ubuntu 根分区其实没有完整安装
→ 发现安装 U 盘的 filesystem.squashfs 已损坏
→ 改为从网络安装到内部 SSD
→ 修复 initramfs、EFI、GRUB 和 Wi-Fi/SSH
→ 升级 Ubuntu
→ 排查 Steam/SMAPI 游戏读档闪退
→ 用日志和内存证据定位 OOM

1. 第一原则:先判断“现在运行的系统”

远程排查一开始不能直接假设目标机已经进入硬盘上的 Ubuntu。先检查网络和服务:

Test-Connection <目标主机> -Count 2
Test-NetConnection <目标主机> -Port 22 -InformationLevel Quiet

如果能 ping 通但 22 端口没有响应,可能是:

  • SSH 服务没有启动;
  • 防火墙拦截;
  • 当前启动的是安装 U 盘的 Live 环境;
  • 网络地址发生变化。

在目标机本地 Live 终端中,可以先安装并启动 SSH:

sudo apt install openssh-server
sudo systemctl enable --now ssh

连接时不要把密码写进脚本或聊天记录:

ssh <用户名>@<目标主机>

1.1 用根分区来源确认是否真的进了已安装系统

登录后先看根分区、内核和启动模式:

hostname
uname -a
findmnt / -o SOURCE,FSTYPE,TARGET
lsblk -o NAME,SIZE,TYPE,FSTYPE,LABEL,MODEL,MOUNTPOINTS
test -d /sys/firmware/efi && echo UEFI || echo Legacy

这一步比“SSH 能连上”更重要。SSH 能连上只说明某个 Linux 环境在运行,不代表已经从目标硬盘启动。

2. 第一次判断:不是双系统分区撞车,而是 Ubuntu 没有完整安装

第一次检查得到的结构大致是:

设备 记录中的作用 关键判断
/dev/sda Windows 所在盘 EFI 在 /dev/sda1,Windows 根分区在 /dev/sda3
/dev/sdc3 原本打算放 Ubuntu 实际内容仍像 Live/安装器残留,含 casper、ubiquity
/dev/sdc2 预留的 Ubuntu EFI 空,没有 EFI/ubuntu
/dev/sdc1 SteamLibrary 计划保留

同时还观察到:

  • EFI 启动项里没有 ubuntu;
  • Windows EFI 里只有 Microsoft;
  • /boot/grub/grub.cfg 不存在;
  • 内核启动链接不完整。

所以结论不是“Windows 和 Ubuntu 分区互相覆盖”,而是:

Windows 仍然存在
Ubuntu 目标分区也存在
但 Ubuntu 根文件系统、内核、EFI 和 GRUB 没有形成完整启动链

这解释了为什么机器只能启动 Windows 或 Live U 盘,却没有正常的 Ubuntu/Windows 双系统菜单。

3. 第一条失败路线:把 Ubuntu 放在可移动盘上

最初方案是清空 /dev/sdc3、把 Ubuntu 安装到可移动盘,并使用 /dev/sdc2 作为它自己的 EFI 分区。这个方案的边界是:

  • 只清空用户明确授权的 /dev/sdc3;
  • Windows 盘 /dev/sda 不动;
  • /dev/sdc1 的 SteamLibrary 不动。

过程中曾遇到旧的 /target 挂载占用目标分区,格式化因此被系统拒绝。这是有益的安全保护:先清理挂载,再确认设备,最后才格式化。

但第一次安装即使把基础包、桌面和 GRUB 写完,重启后仍无法稳定从目标盘进入系统。后续核查发现,用户真正想要的是内部 SSD 上的 Ubuntu,而不是 TF 卡/可移动盘上的系统,因此这条路线停止,不继续在错误目标上修补。

4. 真正的根因:安装 U 盘的镜像文件损坏

重装失败时,不能只盯着“目标盘是不是坏了”。要同时检查安装介质、目标盘 SMART 和内核 I/O 日志:

sudo dmesg -T | grep -Ei 'error|i/o|squash|ata|reset|failed|timeout'
sudo smartctl -H -A /dev/sda
ls -lh /cdrom/casper/filesystem.squashfs

这次的关键证据是:

SQUASHFS error: zlib decompression failed, data probably corrupt
Failed to read block ... -5
filesystem.squashfs mismatch

而内部 LITEON SSD 的 SMART 为 PASSED,重映射、读错误和 CRC 都是 0。因此:

Errno 5 不是内部 SSD 已损坏的证据
本次 Errno 5 的直接来源是安装 U 盘中的 squashfs 数据损坏

这也是为什么继续用同一个 U 盘重复安装没有意义。正确处理是重新制作并校验安装介质,或者绕过损坏的 Live 镜像,从网络安装。

5. 第二条路线:网络安装到内部 SSD

在确认设备型号后,才执行破坏性操作。目标变为:

内部 SSD /dev/sda
├── /dev/sda1  EFI
└── /dev/sda2  UbuntuRoot(ext4)

TF 卡和安装 U 盘不再作为系统盘。Live 环境中补齐了网络安装需要的工具:

sudo apt update
sudo apt install debootstrap dosfstools smartmontools

核心步骤的学习版结构如下,设备名必须以现场 lsblk 结果为准,不能盲目复制:

# 仅示意:执行前必须再次核对 /dev/sda 型号和容量
sudo mkfs.fat -F32 /dev/sda1
sudo mkfs.ext4 -F /dev/sda2
sudo mount /dev/sda2 /target
sudo mkdir -p /target/boot/efi
sudo mount /dev/sda1 /target/boot/efi

sudo debootstrap --variant=minbase --arch=amd64 \
  --components=main,restricted,universe,multiverse \
  jammy /target http://mirrors.tuna.tsinghua.edu.cn/ubuntu

随后在 /target 中安装完整系统组件:

systemd-sysv linux-generic linux-firmware
network-manager sudo openssh-server
grub-efi-amd64-signed shim-signed efibootmgr
locales tzdata ubuntu-standard ca-certificates
ubuntu-desktop-minimal

5.1 安装过程中的两个坑

镜像速度和 CA 证书

原镜像速度很慢,切换清华镜像后,新系统还没有安装 CA 证书,HTTPS 校验暂时失败。处理顺序是:

先用可达的镜像完成基础安装
→ 安装 ca-certificates
→ 恢复 HTTPS 源

HTTP 只作为安装阶段的临时手段,正式系统应恢复 HTTPS 并校验软件源。

Live 环境的 /run 不能直接带进新系统

最初把 Live 环境的 /run 绑定进 chroot,导致新系统里的 Snap 状态误看到 Live 环境已有 Firefox,触发 Firefox deb/Snap 重复安装错误。

修正方法是给目标系统挂一个干净的运行时目录:

sudo mount -t tmpfs -o mode=755,nosuid,nodev tmpfs /target/run

随后改用 ubuntu-desktop-minimal --no-install-recommends 完成桌面安装,避免把 Live 环境状态污染到新系统。

6. EFI、initramfs 和 GRUB 验收

网络安装完成后,不能只看到 grub-install 没报错就重启。需要检查内核、initramfs、菜单和 EFI 文件:

sudo chroot /target grub-install \
  --target=x86_64-efi \
  --efi-directory=/boot/efi \
  --bootloader-id=ubuntu \
  --recheck

sudo chroot /target update-initramfs -c -k all
sudo chroot /target grub-mkconfig -o /boot/grub/grub.cfg

grep -E 'Windows Boot Manager|bootmgfw|menuentry' /target/boot/grub/grub.cfg
sudo efibootmgr -v
find /target/boot/efi/EFI -maxdepth 2 -type f

这次还遇到过一个容易漏掉的问题:内核文件存在,但 initrd.img 只是断开的符号链接,GRUB 因而找不到 initramfs。补生成 initramfs、再重建 GRUB 后才算完整。

最终验收证据包括:

  • /dev/sda1 是 EFI;
  • /dev/sda2 是 Ubuntu 根分区;
  • EFI 中出现 EFI/ubuntu;
  • GRUB 菜单包含 Ubuntu 和 Windows Boot Manager;
  • dpkg --audit 和 apt-get check 没有未完成包;
  • SSH、NetworkManager、图形登录管理器已启用。

重启后还要再次检查,而不是把 SSH 断开误认为成功:

findmnt / -o SOURCE,FSTYPE,TARGET
systemctl is-system-running
systemctl is-active ssh NetworkManager

7. 系统升级与 TF 卡分工

内部 SSD 上的 Ubuntu 先完成启动,再进行跨版本升级。记录中的路径是:

Ubuntu 22.04
→ 24.04.5
→ 26.04.1

每一阶段都遵循:

  1. 先完成当前版本的更新;
  2. 重启并确认根分区和 EFI 仍在 /dev/sda;
  3. 确认 SSH、Wi-Fi、apt/dpkg 正常;
  4. 再开始下一阶段升级。

升级后验证到:

  • 根分区 /dev/sda2;
  • EFI /dev/sda1;
  • 内核 7.0.0-34;
  • SSH、NetworkManager 正常;
  • apt/dpkg 无未完成项。

TF 卡后来只作为数据盘处理:清空后建立 GPT + 单个 exFAT 分区,挂载到 /mnt/tf-data。系统盘和 TF 卡的职责必须分清:

内部 SSD:Ubuntu、Steam、游戏和系统快照
TF 卡:可移动数据存储

8. 工具链与桌面环境补齐

这次还补齐了几类常用环境,重点不是记软件清单,而是理解“缺什么再补什么”:

类别 记录中的组件 验收思路
编译调试 ARM GCC、C/C++、GDB、CMake、OpenOCD、ST-Link、DFU 用最小 Cortex-M3 工程实际编译
编辑器 VS Code、C/C++、CMake Tools、Cortex-Debug、中文语言包 检查扩展安装和显示语言
远程/网络 OpenSSH、NetworkManager、FlClash 分别检查服务状态、网卡和代理进程
桌面输入 中文拼音输入组件 重新登录后用 Super + Space 切换
回滚 Timeshift 创建快照并确认快照位于内部 ext4 系统盘
游戏运行 Steam Linux Runtime、SMAPI 先验证游戏本体,再验证模组和存档

遇到 command not found 时,先判断它属于哪个软件包,再安装;不要因为一个工具缺失就误判系统或硬盘损坏。

9. Steam / SMAPI 模组安装记录

星露谷本体和存档最终确认在内部 ext4 系统盘,不在 TF 卡。安装模组前做了三层验证:

  1. 本地下载官方 SMAPI 安装包;
  2. 模组压缩包、SMAPI 压缩包做 SHA-256 比对;
  3. ZIP 完整性测试通过后,再解压到游戏目录。

记录中的结果是:

  • Stardew Valley 1.6.15;
  • SMAPI 4.5.2;
  • 约 193 个模组清单、92 个 DLL;
  • 模组统一放在 Mods/xlg,便于整体停用和回滚;
  • 重复的 TimeWatch 只保留一份;
  • 原始压缩包和存档没有被覆盖。

9.1 Linux 大小写和 Windows 依赖问题

首次读档闪退前,日志先暴露了两个确定的兼容性问题:

  • InputMethodFix 依赖 Windows 的 SDL2.dll,在 Ubuntu 上无法加载;
  • 5 个动物音效路径只在大小写上不同,Windows 能容忍,Linux 区分大小写后找不到文件。

处理方式是:

  • 把失效模组移出启用目录,保留可恢复性;
  • 在修改路径前做备份;
  • 按实际目录逐个修正大小写链接;
  • 用 test -r 和 ls -l 验证目标文件可读。

存档备份位置记录为:

~/.cache/stardew-valley-repair-20261002/Saves-before-mod-fix.tar.gz

备份通过归档列表检查,存档本身没有被改动。

10. 读档闪退的真正原因:内存压力和 OOM

移除确定损坏的模组后,游戏仍在读档阶段退出。此时不能继续盲目删模组,要同时看应用日志、进程和内核/用户会话内存证据:

grep -nEi 'Find Save Games|Load_ReadSave|SaveLoaded|DayStarted|fatal|unhandled' \
  ~/.config/StardewValley/ErrorLogs/SMAPI-latest.txt
free -h
swapon --show
cat /proc/pressure/memory
cat /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/memory.events

这次观察到:

  • 日志停在 Find Save Games / Load_ReadSave 附近;
  • 用户会话累计出现 2 次 OOM kill;
  • 原本约 2GB swap 几乎用满;
  • 游戏读档时持续读取大量地图和模组资源,进程并非完全卡死。

因此先做一个可撤销的验证:只在当前开机临时增加 swap,不写入 fstab:

sudo fallocate -l 6G /swapfile-stardew-temp
sudo chmod 600 /swapfile-stardew-temp
sudo mkswap /swapfile-stardew-temp
sudo swapon /swapfile-stardew-temp

随后又临时增加了第二个 4GB swap 文件,总 swap 约 12GB。重点是:

  • 这是验证内存压力的临时措施;
  • 不应把 swap 当成增加真实内存;
  • 未写入 fstab,重启后不会自动启用;
  • 临时文件仍会占磁盘,确认不再需要后应安全关闭并删除。

扩大临时 swap 后,SMAPI 日志终于出现:

DayStarted

游戏进程仍在运行,农场可以进入并操作。这个结果把“模组读档闪退”的主要矛头指向了内存峰值,而不是存档损坏或 TF 卡读写问题。

11. 最终状态与验收清单

这次记录的最终结果是:

  • Ubuntu 已安装在内部 SSD /dev/sda,不在 TF 卡;
  • EFI 和根分区分别为 /dev/sda1、/dev/sda2;
  • 系统已升级到记录中的 Ubuntu 26.04.1,内核 7.0.0-34;
  • TF 卡只作为 exFAT 数据盘;
  • SSH、Wi-Fi、桌面和嵌入式工具链可用;
  • SMAPI 和模组已安装到内部盘;
  • 存档有备份,未被修复过程直接改写;
  • 增大临时 swap 后,星露谷存档可以进入并游玩。

以后遇到类似问题,按下面顺序验收:

1. ping / SSH:确认机器在线,但不要把它当成系统安装成功
2. findmnt / + lsblk:确认根分区到底来自哪块盘
3. SMART + dmesg:区分 SSD 故障、U 盘损坏和文件系统问题
4. EFI + initramfs + GRUB:确认启动链完整
5. 重启后再次验证根盘、版本、SSH 和网络
6. 游戏闪退时先备份存档,再分离模组兼容性、文件大小写和 OOM
7. 临时修复成功后,清理临时文件并决定是否需要持久化配置

一句话复习

这次最重要的不是“重装成功”,而是学会用设备来源、SMART、SQUASHFS、EFI、initramfs、GRUB、日志和 OOM 证据逐层缩小问题:先确认运行环境,再确认安装介质和目标盘,最后才执行高风险写入;游戏排错同样先备份、看日志、分离确定错误,再用可撤销的资源调整验证假设。