【Fedora 44 GRUB 菜单每次开机都显示问题】
Fedora 44 GRUB 菜单每次开机都显示问题Fedora 44 GRUB 菜单每次开机都显示问题问题现象环境信息走过的弯路弯路一方案 B「直接隐藏」诱惑很大但要拒绝弯路二方案 A「自动隐藏」按教程做了不生效弯路三以为是 grub.cfg 没重新生成真正的诊断往 grub.cfg 里注入 DEBUG根因跨文件系统的符号链接修复用 ext4 上的真实文件替换符号链接还有一个坑测试时不要重启太快工作机制总结顺便为什么 Ubuntu 没这问题经验Fedora 44 GRUB 菜单每次开机都显示问题问题现象Fedora 44UEFI 启动单系统单硬盘。每次开机都会出现 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_TIMEOUT5改成0再加上GRUB_TIMEOUT_STYLEhidden重新生成 grub.cfgsudogrub2-mkconfig-o/boot/grub2/grub.cfg菜单确实再也不出现了——但启动出问题时也看不到菜单了。这是隐藏问题不是解决问题。弯路二方案 A「自动隐藏」按教程做了不生效Fedora 的「自动隐藏」机制涉及三个 grubenv 变量sudogrub2-editenv -setmenu_auto_hide1sudogrub2-editenv -setboot_success1重启后菜单照样出现。弯路三以为是 grub.cfg 没重新生成这一步确实有意义。Fedora 的 GRUB 自动隐藏依赖/etc/grub.d/12_menu_auto_hide这个脚本生成的逻辑而你的 grub.cfg 可能是早期版本生成的、缺这段。sudogrub2-mkconfig-o/boot/grub2/grub.cfg验证 cfg 里确实有了相关逻辑sudogrep-nEmenu_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 上直接创建标准格式的 grubenv1024 字节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_hide1\boot_success1\boot_indeterminate0# 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]bs0 是因为10_reset_boot_success已经把它从 1 重置成 0正常现象菜单不再显示直接进系统还有一个坑测试时不要重启太快修好之后我又被一个问题困扰测试时反复重启菜单时不时还会出现。查看 grubenv$sudogrub2-editenv /boot/grub2/grubenv listsaved_entry...menu_auto_hide1boot_success0# ← 又变成 0 了boot_indeterminate0boot_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_success0就会显示菜单。这其实是「异常检测」的正确行为从系统视角看会话太短可能意味着启动后立刻崩溃。如果觉得 2 分钟太长可以做用户级 overridemkdir-p~/.config/systemd/user/grub-boot-success.timer.d/cat~/.config/systemd/user/grub-boot-success.timer.d/override.confEOF [Timer] OnActiveSec OnActiveSec20s EOFsystemctl--userdaemon-reload或者重启前手动标记成功grub2-set-bootflag boot_success工作机制总结修复完成后整套「正常时隐藏、异常时显示」的机制场景grubenv 状态表现正常启动boot_success1→ GRUB 隐藏菜单重置为 0菜单不显示登录后 2 分钟timer 触发 →boot_success1为下次正常启动准备启动后立即崩溃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_STYLEhidden, GRUB_TIMEOUT0单系统机器上根本看不到菜单Fedora 用menu_auto_hideboot_successboot_indeterminate 用户级 timer 这一套更精细但活动部件多Fedora 这套设计有它的道理区分「快速失败」「不确定」「成功」三种状态做异常检测但活动部件多 出问题概率高加上跨文件系统符号链接这个隐患就容易翻车。经验不要轻易接受「直接关掉」。如果一个机制本来设计成「正常时隐藏、异常时显示」那把它一刀切隐藏掉就丢了排错能力grub2-editenv list能读不代表 GRUB 能读。一个能用 Linux 内核读、不能用 GRUB 读的文件是很容易被忽视的诊断启动相关问题往 grub.cfg 里加 echo sleep 是大杀器。GRUB 脚本调试手段有限直接打印变量值比靠猜强一万倍跨文件系统的符号链接是个隐性陷阱。日常用户态完全感受不到但任何不依赖 Linux 内核的工具GRUB、initramfs 早期阶段、某些恢复工具都可能踩坑如果你也在 Fedora 上遇到「单系统但每次开机都显示 GRUB 菜单」的问题先别急着改GRUB_TIMEOUT0先检查sudols-la/boot/grub2/grubenv如果是符号链接本文的方法可以一并解决。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2596510.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!