当前位置: 首页 > news >正文

【Fedora 44 GRUB 菜单每次开机都显示问题】

Fedora 44 GRUB 菜单每次开机都显示问题

  • Fedora 44 GRUB 菜单每次开机都显示问题
    • 问题现象
    • 环境信息
    • 走过的弯路
      • 弯路一:方案 B「直接隐藏」诱惑很大但要拒绝
      • 弯路二:方案 A「自动隐藏」按教程做了不生效
      • 弯路三:以为是 grub.cfg 没重新生成
    • 真正的诊断:往 grub.cfg 里注入 DEBUG
    • 根因:跨文件系统的符号链接
    • 修复:用 ext4 上的真实文件替换符号链接
    • 还有一个坑:测试时不要重启太快
    • 工作机制总结
    • 顺便:为什么 Ubuntu 没这问题?
    • 经验

Fedora 44 GRUB 菜单每次开机都显示问题

问题现象

Fedora 44,UEFI 启动,单系统单硬盘。每次开机都会出现 GRUB 启动菜单,停留 5 秒倒计时,必须等待或按回车才能进入系统。明明只装了一个系统,根本不需要选什么。

更恼火的是:我不希望直接把菜单关掉——理想行为是「正常启动时不显示,启动出问题时自动显示」。这是 Linux 发行版应该具备的健壮性。

环境信息

OS: Fedora 44 (Workstation) Kernel: 6.19.14-300.fc44.x86_64 Boot: UEFI + GRUB 2.12 + shim GRUB: grub2-efi-x64-2.12-56.fc44

分区布局(这个细节后面是关键):

/dev/nvme0n1p1 → /boot/efi (FAT32, EFI System Partition) /dev/nvme0n1p2 → /boot (ext4) /dev/nvme0n1p3 → / (btrfs)

走过的弯路

弯路一:方案 B「直接隐藏」诱惑很大但要拒绝

最简单的修复是把/etc/default/grub里的GRUB_TIMEOUT=5改成0,再加上GRUB_TIMEOUT_STYLE=hidden,重新生成 grub.cfg:

sudogrub2-mkconfig-o/boot/grub2/grub.cfg

菜单确实再也不出现了——但启动出问题时也看不到菜单了。这是隐藏问题,不是解决问题。

弯路二:方案 A「自动隐藏」按教程做了不生效

Fedora 的「自动隐藏」机制涉及三个 grubenv 变量:

sudogrub2-editenv -setmenu_auto_hide=1sudogrub2-editenv -setboot_success=1

重启后,菜单照样出现。

弯路三:以为是 grub.cfg 没重新生成

这一步确实有意义。Fedora 的 GRUB 自动隐藏依赖/etc/grub.d/12_menu_auto_hide这个脚本生成的逻辑,而你的 grub.cfg 可能是早期版本生成的、缺这段。

sudogrub2-mkconfig-o/boot/grub2/grub.cfg

验证 cfg 里确实有了相关逻辑:

sudogrep-nE'menu_hide_ok|menu_auto_hide|timeout_style'/boot/grub2/grub.cfg

输出能看到完整的12_menu_auto_hide段以及10_reset_boot_success段——逻辑齐全。

但是!重启还是显示菜单


真正的诊断:往 grub.cfg 里注入 DEBUG

到这里我已经无从猜起,只好往 GRUB 启动脚本里注入调试输出:

sudosed-i'/^### BEGIN \/etc\/grub.d\/12_menu_auto_hide ###$/a\ echo "DEBUG fts=[${feature_timeout_style}] ma=[${menu_auto_hide}] mhok=[${menu_hide_ok}] bs=[${boot_success}] bi=[${boot_indeterminate}]"\ sleep 8'/boot/grub2/grub.cfg

这会在12_menu_auto_hide块开头打印五个关键变量、停 8 秒。重启观察。

第一次 DEBUG 输出

DEBUG fts=[y] ma=[] mhok=[0] bs=[0] bi=[]

同时屏幕上还有两行报错:

error: ../../grub-core/commands/loadenv.h:read_envblk_file:51:invalid environment block. error: ../../grub-core/commands/loadenv.h:read_envblk_file:51:invalid environment block.

终于看到真相了:

  • fts=[y]— GRUB 功能正常
  • ma=[]menu_auto_hide空的
  • bi=[]boot_indeterminate也是空的

这两个本来该从 grubenv 加载的变量都是空的,加上invalid environment block报错,结论:GRUB 启动时根本读不了 grubenv

grub2-editenv list命令明明能正常列出变量啊?


根因:跨文件系统的符号链接

查看 grubenv 文件:

$sudols-la/boot/grub2/grubenv lrwxrwxrwx.1root root25... /boot/grub2/grubenv ->../efi/EFI/fedora/grubenv

它是一个相对符号链接,指向 EFI 分区上的 grubenv。

回顾分区布局:

  • /boot在 ext4 分区上
  • /boot/efi是另一个分区(FAT32 EFI 分区)的挂载点

Linux 用户态有内核帮忙:跟着符号链接../efi/EFI/fedora/grubenv走,会自动跨过挂载点边界,正确读到 EFI 分区的文件。所以grub2-editenv list没问题。

但 GRUB 启动时还没有 Linux 内核:

  • GRUB 在 ext4 分区里看到/grub2/grubenv这个符号链接
  • 跟着相对路径../efi/EFI/fedora/grubenv
  • 落在 ext4 分区上的/efi/EFI/fedora/grubenv——而这个路径在 ext4 上根本不存在/efi只是个空挂载点目录)
  • GRUB 读到无效内容 → 报invalid environment block
  • 之后 GRUB 自己的save_env又往这个错误位置写,让事情更糟,进入「读坏 → 写坏 → 更坏」的循环

修复:用 ext4 上的真实文件替换符号链接

# 1. 备份 EFI 分区上的原文件(保险)sudocp/boot/efi/EFI/fedora/grubenv /boot/efi/EFI/fedora/grubenv.bak# 2. 删除符号链接sudorm/boot/grub2/grubenv# 3. 在 ext4 上直接创建标准格式的 grubenv(1024 字节)sudogrub2-editenv /boot/grub2/grubenv create# 4. 写回必要变量sudogrub2-editenv /boot/grub2/grubenvset\saved_entry=$(grub2-editenv /boot/efi/EFI/fedora/grubenv.bak list|grepsaved_entry|cut-d=-f2-)\menu_auto_hide=1\boot_success=1\boot_indeterminate=0# 5. 验证:必须不是符号链接,必须 1024 字节sudols-la/boot/grub2/grubenv# 应该是 -rw-r--r-- 不是 lrwxrwxrwxsudowc-c/boot/grub2/grubenv# 应该是 1024sudogrub2-editenv /boot/grub2/grubenv list# 6. 重新生成 grub.cfgsudogrub2-mkconfig-o/boot/grub2/grub.cfg

重启验证:

  • 没有invalid environment block报错了
  • DEBUG 输出变成ma=[1] mhok=[1] bs=[0] bi=[0](bs=0 是因为10_reset_boot_success已经把它从 1 重置成 0,正常现象)
  • 菜单不再显示,直接进系统

还有一个坑:测试时不要重启太快

修好之后我又被一个问题困扰:测试时反复重启,菜单时不时还会出现。

查看 grubenv:

$sudogrub2-editenv /boot/grub2/grubenv listsaved_entry=...menu_auto_hide=1boot_success=0# ← 又变成 0 了boot_indeterminate=0

boot_success怎么变成 0 了?查看用户级 timer:

$ systemctl--userstatus grub-boot-success.timer Active: active(waiting)since... Trigger:...;39s left

——原来grub-boot-success.timer默认在用户登录2 分钟后才把boot_success写回 1。如果你登录后不到 2 分钟就 poweroff/重启,timer 没机会跑,下次开机 GRUB 看到boot_success=0就会显示菜单。

这其实是「异常检测」的正确行为:从系统视角看,会话太短可能意味着启动后立刻崩溃。

如果觉得 2 分钟太长,可以做用户级 override:

mkdir-p~/.config/systemd/user/grub-boot-success.timer.d/cat>~/.config/systemd/user/grub-boot-success.timer.d/override.conf<<'EOF' [Timer] OnActiveSec= OnActiveSec=20s EOFsystemctl--userdaemon-reload

或者重启前手动标记成功:

grub2-set-bootflag boot_success

工作机制总结

修复完成后,整套「正常时隐藏、异常时显示」的机制:

场景grubenv 状态表现
正常启动boot_success=1→ GRUB 隐藏菜单,重置为 0菜单不显示
登录后 2 分钟+timer 触发 →boot_success=1为下次正常启动准备
启动后立即崩溃timer 没机会跑 →boot_success保持 0下次开机显示菜单
强制断电(2 分钟内)同上下次开机显示菜单
内核启动失败boot_indeterminate累加显示菜单

顺便:为什么 Ubuntu 没这问题?

我装 Ubuntu 时从没遇到过这种事。差别在三层:

1. 分区布局

  • Ubuntu 默认:ESP + 根分区,/boot在根分区里
  • Fedora 默认:ESP + 独立/boot+ 根分区

2. grubenv 位置策略

  • Ubuntu:/boot/grub/grubenv是普通文件,跟 grub.cfg 同分区,无跨文件系统问题
  • Fedora:/boot/grub2/grubenv是指向 EFI 分区的相对符号链接——本文的坑

3. 隐藏菜单机制

  • Ubuntu 用更简单的recordfail变量;默认GRUB_TIMEOUT_STYLE=hidden, GRUB_TIMEOUT=0,单系统机器上根本看不到菜单
  • Fedora 用menu_auto_hide+boot_success+boot_indeterminate+ 用户级 timer 这一套,更精细但活动部件多

Fedora 这套设计有它的道理(区分「快速失败」「不确定」「成功」三种状态,做异常检测),但活动部件多 = 出问题概率高,加上跨文件系统符号链接这个隐患,就容易翻车。


经验

  1. 不要轻易接受「直接关掉」。如果一个机制本来设计成「正常时隐藏、异常时显示」,那把它一刀切隐藏掉就丢了排错能力
  2. grub2-editenv list能读不代表 GRUB 能读。一个能用 Linux 内核读、不能用 GRUB 读的文件,是很容易被忽视的
  3. 诊断启动相关问题,往 grub.cfg 里加 echo + sleep 是大杀器。GRUB 脚本调试手段有限,直接打印变量值比靠猜强一万倍
  4. 跨文件系统的符号链接是个隐性陷阱。日常用户态完全感受不到,但任何不依赖 Linux 内核的工具(GRUB、initramfs 早期阶段、某些恢复工具)都可能踩坑

如果你也在 Fedora 上遇到「单系统但每次开机都显示 GRUB 菜单」的问题,先别急着改GRUB_TIMEOUT=0,先检查:

sudols-la/boot/grub2/grubenv

如果是符号链接,本文的方法可以一并解决。

http://www.jsqmd.com/news/780223/

相关文章:

  • ARM异常处理与AES加密实现深度解析
  • 基于AI与向量数据库构建个人智能知识库:从RAG原理到BookLib实践
  • 为OpenClaw构建基于时间线的知识图谱大脑:Graphiti插件实战指南
  • 回测工具差异在底层,程序员从三个维度拆给你看
  • 好用的床垫喷胶线品牌排行榜2026最新推荐
  • 泰山派3M-RK3576-系统功能-Android14-串口Debug使用
  • 为Hermes Agent配置自定义模型提供商接入Taotoken
  • 基于DeepSeek-OCR的本地化AI文字识别工具部署与应用指南
  • 基于MCP协议的棒球Statcast数据AI智能体查询与分析实战
  • 堡盟GAPI SDK内存管理陷阱:如何避免OnImage回调中的GC风暴?
  • 基于Node.js与LangChain的AI内容生成引擎:儿童教育视频自动化生产实践
  • .NET光标规则引擎:声明式光标管理库的设计与实战
  • 灭蚊灯什么牌子的效果好?市面上哪种灭蚊灯好用?热门对决灭蚊神器产品排行榜前十名
  • Pytorch入门P1周学习打卡
  • 没有“业务Sense”的CTO不是好CTO:如何用一套规则引擎支撑起千企千面的SaaS业务
  • 招聘笔试JAVA题,春招秋招软件开发工程师笔试专题。
  • 开源项目last30days:基于GitHub的周期性复盘与知识沉淀实践指南
  • 2026年静电地板十大品牌排行榜揭晓
  • JavaScript骨骼动画物理增强:wigglebone实现程序化次级运动
  • 拉坦前列腺素(Latanoprost):前列腺素F2α衍生物如何安全降眼压
  • IC设计支持体系革新:从被动响应到主动知识交付的实践
  • DSP性能优化:内存、并行与功耗的平衡艺术
  • 泰山派3M-RK3576-系统功能-Debian12-音频功能
  • NIQ研究揭示商业新规则:人工智能正开始决定消费者购买什么
  • 深入浅出 Java 反射机制,了解动态编程的原理,小白的速通指南
  • AI智能体如何重构网络运维:从自动化脚本到认知决策的实践
  • DBHub:让AI助手安全连接数据库,实现智能查询与分析
  • 2026年4月评价高的打磨生产线公司口碑推荐,数控钢筋笼绕筋机/滚焊机/数控钢筋弯曲中心,打磨生产线品牌口碑推荐 - 品牌推荐师
  • 形式化方法
  • 大气环境科研必备利器:WRF-Chem在区域污染传输与生态沉降评估中的实践全揭秘