ubuntu20.04与win7UEFI+GPT双启动修复
ubuntu20.04与win7UEFI+GPT双启动修复
  ⽼笔记本,⼀直⽤的ubuntu14.04与win7双系统。因为怕折腾,⼀直没有升级ubuntu,毕竟⾥⾯有数年常⽤的数据、软件,升级的话不折腾⼏天是搞不定的。不过
ubuntu14.04的⽀持基本到头了,趁着ubuntu20.04 LTS新鲜出炉,决定尝试⼀下。
  这⼀尝试,⾸先出现的问题就是引导挂了。只进⼊了grub shell,然后我进⼊LiveCD⽤boot-repair⼀顿操作,把win7的启动也弄挂了,这。。。只能⼿动慢慢修了。要修就得先知道UEFI是怎么⼯作的,这⾥先简单说下UEFI的启动过程。
  ⽀持UEFI的主板上都有NVRAM(Non-Volatile Ram即掉电也不丢失数据的存储空间),安装操作系统的时候,通常都会在NVRAM写⼊引导项,这个列表除了安装操作系统时写⼊的引导项,还有⼀些固定的硬件引导项,⽐如硬盘、U盘、⽹络启动)。在开机的时候,进⼊BIOS应该是能看到这个列表的,不同的主板操作不⼀样,我机⼦上的NVRAM列表看起来是这样的:
ubuntu是安装ubuntu时写⼊的引导项,IPV4、Boot From EFI File则是⼀些固定的硬件引导项。
  实现UEFI启动,硬盘上还需要有⼀个ESP分区(EFI system partition),然后安装操作系统时,会在ESP分区写⼊引导⽂件。我机⼦上的ESP分区⼤概是这样的:
~$ sudo tree /boot/efi/EFI -L 3
/boot/efi/EFI
├── Boot
│├── BOOTX64.CSV
│├── bootx64.efi
│├── grub.cfg
│├── grubx64.efi
│├── mmx64.efi
│└── shimx64.efi
├── Microsoft
│└── Boot
│├── BCD
│├── BCD.LOG
│├── BCD.LOG1
│├── BCD.LOG2
│├── bootmgfw.efi
│├── bootmgr.efi
│├── BOOTSTAT.DAT
│├── cs-CZ
│├── da-DK
│├── de-DE
│├── el-GR
│├── en-US
│├── es-ES
│├──fi-FI
│├── Fonts
│├── fr-FR
│├── hu-HU
│├── it-IT
│├── ja-JP
│├── ko-KR
│├── memtest.efi
│├── nb-NO
│├──nl-NL
│├── pl-PL
│├── pt-BR
│├── pt-PT
│├── ru-RU
│├── sv-SE
│├──tr-TR
│├── zh-CN
│├── zh-HK
│└── zh-TW
└── ubuntu
├── BOOTX64.CSV
├── grub.cfg
├── grubx64.efi
├── mmx64.efi
└── shimx64.efi
28 directories, 19 files忘记开机密码
其中,Boot⽬录是ESP分区的默认⽬录,Microsoft是win7的引导⽬录,ubuntu则是ubuntu的引导⽬录,注意,ESP分区是fat格式,这些⽬录及⽂件名不区分⼤⼩写。
  当开机时,主板加电,会从NVRAM中读取引导列表,按顺序⼀个个去尝试引导启动,如果成功,就会进⼊对应的操作系统。例如,我的机⼦在开机时选择ubuntu的话,则主板会根据NVRAM中ubuntu这个项中的信息,直接加载ESP分区中的ubuntu/shimx64.efi,然后ubuntu/shimx64.efi会启动grub,接着由grub启动ubuntu,完成ubuntu的启动。如果选择从硬盘启动(我机⼦的BIOS中没显⽰这个项,后⾯会说到),那就会在硬盘中查ESP分区(ESP分区在同⼀个硬盘可以有多个,会⼀个个去试),如果ESP分区中存
在/Boot/bootx64.efi,就运⾏这个⽂件,完成引导,所以Boot⽬录称为ESP的默认⽬录。
  回到之前的问题,我安装ubuntu后,没能引导进系统,⽽是挂在grub shell了,说明UEFI已经正确加载了ubuntu/shimx64.efi,但在grub那⼀步,grub没能成功启动ubuntu,这可能是配置错误,⽐如f错误。但我的系统是全新安装的,grub的配置不⼤可能会出问题,可能是⼀些环境变量不对,尝试⼿动加载。我的硬盘是gpt模式,ubuntu安装在第7个区分,没有使⽤独⽴的boot分区,因此boot⽬录是在ubuntu分区的boot⽬录下,即(hd0,gpt7)/boot/grub。如果不记得安装在哪个分区,可以⽤ls (hd0,gpt7)这样⼀个个去试,会打印⼀些分区信息
grub > ls
(hd0), (hd0,gpt8),(hd0,gpt7),(hd0,gpt6),(hd0,gpt5),(hd0,gpt4),(hd0,gpt3),(hd0,gpt2),(hd0,gpt1)
grub > set root=(hd0,gpt7)
grub > set prefix=(hd0,gpt7)/boot/grub
grub > insmod normal
grub > normal
如果成功,会出现后⾯那个grub菜单,即可进⼊系统。如果失败,或者⽆法引导进⼊系统,那么说明grub已经没救了(⾄少以我的⽔平救不了了),你需要⼀个LiveCD之类的盘了。进⼊系统后,就需要修复⼀下grub了
sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
正在⽣成 grub 配置⽂件 ...
到 Linux 镜像:/boot/vmlinuz-5.4.0-26-generic
到 initrd 镜像:/boot/initrd.img-5.4.0-26-generic
Adding boot menu entry for UEFI Firmware Settings
完成
update-grub会搜索当前系统,查各种启动,然后完成修复。按我的理解,update-grub只是修复grub
引导,即对应/boot/grub⽬录下的东西,并不会修改ESP分区以及NVRAM 的东西,但Adding boot menu entry for UEFI Firmwre Settings实在让⼈困惑,这个像是往NVRAM添加引导项。
如果进⼊的是LiveCD,那么当前系统并不是你想要修复的系统,你想修复的系统还在硬盘上,那么⼿动修复就复杂多了,我没这样操作过。在LiveCD可以使⽤boot-repair来修复
sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair
boot-repair是⼀个带UI的程序,在菜单⾥到它直接按提⽰操作就好。我的机⼦修复好以后,ubuntu能进了,但是win7的导引没了。⽽且,出现了新的问题
每次启动时,都会提⽰
System BootOrder not found. Initializing defaults.
Creating boot entry "Boot0001" with label "ubuntu" for file "\EFI\ubuntu\shhimx64.efi"
⽽且这个Boot0001会依次增加为Boot0001、Boot0002、Boot0003,这样⼀直加下去,但是能正常进⼊
ubuntu系统。根据上⾯UEFI的启动过程,可以推断,提⽰这个的时候,主板还没加载任何efi⽂件,⽽是在尝试引导某个NVRAM中的启动项时失败,然后主板在ESP分区到了\EFI\ubuntu\shimx64.efi这个⽂件,并⽤这个⽂件引导ubuntu。我的直觉是NVRAM列表有问题,需要修复下。在ubuntu下,可以⽤efibootmgr来管理NVRAM列表
~$ efibootmgr
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0002
Boot0000* ubuntu
Boot0001* ubuntu
Boot0002* ubuntu
$ efibootmgr -v
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0002
Boot0000* ubuntu HD(1,GPT,2b776bfe-665b-4a9a-995f-4c74e11712a4,0x800,0x95800)/File(\EFI\ubuntu\shimx64.efi)
Boot0001* ubuntu HD(1,GPT,2b776bfe-665b-4a9a-995f-4c74e11712a4,0x800,0x95800)/File(\EFI\ubuntu\shimx64.efi)
Boot0002* ubuntu HD(1,GPT,2b776bfe-665b-4a9a-995f-4c74e11712a4,0x800,0x95800)/File(\EFI\ubuntu\shimx64.efi)
sudo efibootmgr -b 0001 -B
sudo efibootmgr -b 0002 -B
sudo efibootmgr -o 0000
sudo efibootmgr -b 0000 -a
通过efibootmgr指令可以看到主板已经给NVRAM列表添加了⼏个ubuntu,通过efibootmgr -v可以查看他们的参数(当选择NVRAM的⼀个启动项时,主板知道去哪个分区运⾏哪个efi⽂件,就是根据这些参数来的)。但是并没有看出什么问题,似乎⼀切正常。于是我把多余的删除了
sudo efibootmgr -b 0001 -B # 把启动项0001删了
sudo efibootmgr -b 0002 -B # 把0002删了
sudo efibootmgr -o 0000 # 设置0000为第⼀启动顺序
sudo efibootmgr -b 0000 -a #设置0000为活动启动项
重启,结果发现还是⼀样,主板⼜⾃动加了⼀个0001回来,参数还是⼀模⼀样。我怀疑是哪⾥操作错误,没修改到NVRAM列表,于是把它们⼜删了,还故意创建了⼀个win的引导项
~$ sudo efibootmgr -c -d /dev/sda -p 1 -L "Windows Boot Manager" -l "\EFI\microsoft\bootmgfw.efi"
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0001,0000
Boot0000* ubuntu
Boot0001* Windows Boot Manager
重启,发现NVRAM列表确实有修改到,多了Windows Boot Manager,不过问题依然存在。
⾄此,NVRAM像是没有问题的,那么我就怀疑ESP分区了。于是我直接把ESP分区给格了。然后重新安装
:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
正在⽣成 grub 配置⽂件 ...
到 Linux 镜像:/boot/vmlinuz-5.4.0-26-generic
到 initrd 镜像:/boot/initrd.img-5.4.0-26-generic
Adding boot menu entry for UEFI Firmware Settings
完成
:~$ sudo grub-install /dev/sda
正在为 x86_64-efi 平台进⾏安装。
安装完成。没有报告错误。
update-grub是修复/boot/grub的,我这⾥并没修改,其实是不需要运⾏的,不过为了保险再修复⼀次。grub-install是把当前系统的启动信息安装到ESP分区,会在ESP分区⽣成ubuntu⽬录和Boot⽬录,并且在NVRAM添加引导项。然后检测ESP分区(在ubuntu20.04⾥,已挂载到/boot/efi/EFI⽬录,ls就能看到⽂件)的各个⽂件,确认Boot和ubuntu⽬录确实存在,并且各⽂件的⽇期也是刚更新的,然后重启,问题依然存在。
  到了这⾥,我已经技穷了,实在想不出来有啥可以操作的了。甚⾄还试了下在LiveCD下修复
mkdir /mnt/sda7
mount /dev/sda7 /mnt/sda7
grub-install --boot-directory=/mnt/sda7 /dev/sda
# 由于LiveCD不是要修复的系统,需要把要修复的系统mount到当前系统
# 然后修复的时候指定启动⽬录为需要修复的系统⽬录
然⽽并没有什么区别。疯狂地google "System BootOrder not found"这些关键字,发现有不少例⼦,都没能说明⽩啥原因造成,不过我也尝试了他们的⼀些做法:
1. 在BIOS设置中把ubuntu放到第⼀项,但是我的BIOS没有这个选项,尝试失败
2. 尝试创建⼀个启动项,⼿动指定到ESP分区的/ubuntu/shimx64.efi。我机⼦的BIOS确实有⼀个Customized Boot,不过不管我输⼊啥,在NVRAM列表中都不会出现这个选项,只能放弃了
3. 直接使⽤Boot From EFI File从ESP分区的/boot/bootx6
4.efi启动,能进⼊系统,但问题依旧
4. 直接从NVRAM中选择ubuntu进⼊,问题解决,但我机⼦的BIOS⽆法设置ubuntu为第⼀启动项,所以
这个不是办法
5. 接使⽤Boot From EFI File从ESP分区的/ubuntu/shimx64.efi启动,问题解决,但是这个只能⼿动启动
6. 把ESP分区⾥的/ubuntu/shimx64.efi覆盖/Boot/bootx64.efi,问题依然
7. 把ESP分区Boot⽬录⾥的⽂件全删了,复制ubuntu⽬录中的所有⽂件到Boot⽬录,然后把shimx64.efi改名bootx64.efi,问题解决
  现在,"System BootOrder not found"这个问题是如何出现的,没法知道原因。google得到的结果⾥,多数也归为BIOS固件和UEFI的兼容问题,并且不少都提到hp笔记本的固件,我的刚好就是hp笔记本。没办法解决这个问题,只能绕过它。从结果上看,这有⼏个问题。第⼀,grub-install在ESP分区⽣成的Boot/bootx64.efi,在我的笔记本上⽆法正常引导ubuntu;第⼆,hp的BIOS没有按UEFI标准来引导系统,NVRAM列表上⼀直有ubuntu,但是没有硬盘的选项,⽽启动的时候,却直接从硬盘启动,然后执
⾏/Boot/bootx64.efi,正常应该是先尝试NVRAM中设定的选项;第三,hp这个BIOS很坑,不仅不能像别的那样设定NVRAM的启动顺序,它⼀直有⼀个OS Boot Manager,这个OS Boot Manager⽤efibootmgr看不到,改不了,选中的时候主是从硬盘启动,我怀疑直接从硬盘启动就是这个隐藏选项的问题
  ubuntu的启动问题总算解决了,下⼀步,就是要修复win7的启动。windows系统启动时,加载ESP分区的EFI/Microsoft/bootmgfw.efi⽂件,bootmgfw.efi读取⽬录下的BCD ⽂件(boot configuration data),BCD保存了win的启动信息,⽐如在哪个分区。如果是多个win系统,也是在这⾥配置。根据BCD,加载对应分区
的“\windows\system32\winload.efi”,之后winload.efi加载windows内核,启动完成。
  win也提供了启动修复⼯具:。进⼊PE,确保win系统分区和ESP分区已挂载,我这⾥刚好是C和H盘,和bcdboot的帮助⽂档⼀致
执⾏
bcdboot c:\windows /s h: /f UEFI /l zh-cn
:: 表⽰c:\windows为系统⽬录
:: h为ESP分区
:: 启动⽅式为UEFI
:: 启动语⾔为中⽂简体
执⾏完后,检查ESP分区,正确创建了Microsoft⽬录。PS:看⽹上有些⼈说bcdboot修复会覆盖ESP分区⾥的Boot⽬录,我试了下,在我机⼦并不会出现这种情况,如果出现了
再⽤ubuntu的启动⽂件重新覆盖⼀次。
  重启,我发现在BIOS⾥并没有windows的引导项。但是,我⽤efibootmgr来检查,win7引导项是有在NVRAM列表中的,⽽我的ubuntu反⽽不见了。。。也不知道是bcdboot
给清了,还是主板BIOS的问题,不过反正ubuntu那个引导项从来不会排在第⼀启动项,所以我也不纠结这个,直接默认从硬盘启动就好。
:~$ efibootmgr -v
BootCurrent: 0000
Timeout: 0 seconds
No BootOrder is set; firmware will attempt recovery
Boot0000* Notebook Hard Drive BBS(HD,,0x0).......................................................................
Boot0001* SD Card BBS(7,,0xa0).......................................................................
Boot0002* Windows Boot Manager HD(1,GPT,2b776bfe-665b-4a9a-995f-4c74e11712a4,0x800,0x95800)/File(\EFI\Microsoft\Boot\bootmgfw.B.C.D.O.B.J.E.C.T.=.{.a.8.-.5.c.d.d.-.4.e.7.0.-.1.-.f.3.2.b.3.4.4.d.
在UEFI模式下,Linux + Win双系统引导只有两种⽅式,⼀是由BIOS引导,在NVRAM列表⾥直接选择启动哪个系统,不过我这⾥在BIOS⾥没有出现win的引导项,⽽且没法设
置默认ubuntu启动,所以不考虑;⼆是由Linux的grub来引导win系统。不存在win引导linux的选项,因为到⽬前为⽌,⼀旦加载ESP分区的/Microsoft/Boot/bootmgfw.efi。它就会
读取BCD中的配置,如果有多个系统,就会出现⼀个选择菜单,如果这⾥加了⼀个linux系统,它是不认linux系统的数据,引导不成功的,所以它可以引导多个windows,但不能
引导linux系统。
  进⼊ubuntu,⽤update-grub来更新grub配置
~$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
正在⽣成 grub 配置⽂件 ...
到 Linux 镜像:/boot/vmlinuz-5.4.0-26-generic
到 initrd 镜像:/boot/initrd.img-5.4.0-26-generic
到 Windows Boot Manager 位于 /dev/sda1@/EFI/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for UEFI Firmware Settings
完成
如果win的启动配置正确,update-grub应该是能够分析到win的引导并加⼊到grub中,如果不⾏,那得⼿动编辑/boot/grub/grub.cfg来⼿动添加⼊⼝。由于grub配置和ESP分区⽆
关,因此不需要grub-install,重启,应该能在grub选择菜单中看到win7了。
  关于SecureBoot,安全启动,是说在整个启动过程中,所调⽤的⽂件都是经过签名的。⽐如启动⽤的shimx64.efi,还有系统启动时⼀些驱动等。ubuntu官⽅的⽂件是有签名
的,因此⽀持安全启动,但是有⼀些驱动是私有的,⽐如AMD、NVIDIA的显卡驱动,是没有经过签名的,如果有⽤这类的驱动,就得关闭安全启动。
  关于UEFI CSM(Compatibility Support Module),UEFI的兼容模块,允许操作系统以旧的BIOS-MBR模式启动。win7必须得开启CSM才能正常启动,部分⼈以为是win7需要
MBR模式引导,这个是错误的。关闭CSM,⽤UEFI + GPT的⽅式win7⼀样能引导,只是卡在启动中,⼀般是在windows那个图标的位置就花屏了。UEFI不仅仅是从NVRAM读
取引导项,去ESP分区加载引导程序这么简单的,这只是它⼀⼩部分的功能。它的另⼀个功能,是定义了UEFI下的⼀些显⽰规则,所以UEFI的主板,启动过程可以做得很炫
酷。UEFI引导win7是没问题的,但是win7的驱动不⽀持UEFI的显⽰,因此完成引导后,就跑不下去了。有传闻说,只要愿意启动过程⿊屏,win7也是可以纯UEFI启动的(我没
试过,尝试的话后果⾃负)
设置启动过程⿊屏
< /store S:\efi\Microsoft\boot\bcd /set {default} novesa on
然后删掉vga.sys
C:\Windows\System32\drivers,把vga.sys
⽽ubuntu20.04是两者都⽀持的,但在CSM模式下,明显驱动没写好,OEM logo被拉伸了,正常情况下,hp这个应该是圆的

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。