61

I recently got a computer from school. It came with Windows 8.1 installed. I then installed another copy of Windows 8.1 (so it would use the built-in Windows Pro license) and upgraded it to Windows 10. I then installed Ubuntu alongside both Windows 8 and 10.

Note that I made a separate 255MB ext2 partition for /boot.

Now, when I boot the computer, I first see a GRUB prompt (I already un-hid the grub prompt 'cuz I like it that way) with Windows 8 and Ubuntu options. However, there is no Windows 10 option. If I select Ubuntu, the computer boots into Ubuntu. However, if I select the Windows 8 option, I then get sent to the Windows bootloader, where it then gives me options to boot either Windows 8 or Windows 10. (However, by this point, the computer has already loaded the kernel and all. Apparently Microsoft misunderstood the concept of a bootloader and decided that that meant "boot practically the entire system before actually showing the bootloader". Typical Microsoft.)

How can I disable the Windows bootloader and add a Windows 10 option to GRUB?

EDIT: Someone has answered telling me to disable the Windows bootloader. However, I still do not know how to add Windows to the GRUB OS list. Can anyone help with this?

EDIT 2: After removing Windows 10 from the Windows bootloader with EasyBCD, it seemed that, after a few reboots, it would continually unhide itself and Windows 10 would reappear. However, I then later deleted Windows 10 from the list of OSes in msconfig, and it seems to have stayed deleted.

However, I STILL have not managed to get Windows 10 to appear in GRUB. It's as if GRUB simply doesn't detect it.

Also, I'll put this in the question so that people see it - I have tried using boot-repair, however, it has NOT helped any.

singrium
  • 7,320

9 Answers9

44

Sometimes os-prober is wrong.

Look at the UUID of your Windows 10 partition, for exemple:

sudo blkid /dev/sda2

Then edit /etc/grub.d/40_custom, and at the end of the file add:

menuentry "Windows 10" --class windows --class os {
   insmod ntfs
   search --no-floppy --set=root --fs-uuid $your_uuid_here$
   ntldr /bootmgr
}

Don't forget to change the UUID.

And finally update your grub config file:

sudo update-grub

Source

Zanna
  • 72,312
noraj
  • 831
42

This solution provides a proper entry in the grub2 menu and chainloads directly into Windows 10 without reference to the BIOS. It comes from this webpage so I claim no credit. It was such a relief to find a working solution.

Briefly, edit /etc/grub.d/40_custom and add:

menuentry 'Windows 10' {
    search --fs-uuid --no-floppy --set=root CC66-4B02
    chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}

To find the UUID for the --set=root line (CC66-4B02 in the example) you use sudo fdisk -l to identify the EFI partition then sudo blkid /dev/sda1 (or whatever) to find the UUID of the EFI partition. Note it's not the Windows partition but the EFI one you need. Once you've saved the edit, run sudo update-grub to generate the /boot/grub/menu.cfg file and then restart to test.

fuenfundachtzig
  • 356
  • 3
  • 13
30

Use:

sudo update-grub
sudo grub-install /dev/[BOOT PARTITION eg. Sda6]

commands in terminal of Ubuntu, probably it will solve your problem.

By this command the system will automatically detect your Windows installations and add them to the GRUB list.

Zanna
  • 72,312
Neel Shah
  • 438
13

use this app EasyBCD for windows http://neosmart.net/EasyBCD/ download the free version and install it.

when you open it you will see an entry for windows 8 and one for windows 10.

delete the windows 8 entry and you'll be good to go.

Update after doing the steps above go back to Ubuntu,

open the terminal by pressing ctrl+alt+T

then copy past this commands to it one after another,

sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair

and by this you will install a tool called boot-repair.

open boot repair from dash and you'll get this window

enter image description here

choose the recommended repair and follow the steps.

Note you have to be connected to the Internet when using boot-repair.

5

As far as I understood your question you have two different Windows installations on one or more harddrives and you don't want the Windows loader to get in the way or managing both Windows installations. I remember that it was possible on legacy setups to directly boot the Windows kernel from Grub (I may be wrong here) but I haven't been able to do this on UEFI setups. Having two independent Windows bootloader configurations that can be called from Grub independently should be very close to what you are looking for.

It came with Windows 8.1 installed.

I'm going to assume that this is a UEFI capable computer.

  1. Please check that the computer actually is UEFI capable (I will remove my answer if it is not) and familiarize yourself with the differences between BIOS and UEFI (different boot modes, efibootmgr, different partition tables, EFI system partition (ESP), EFI loaders…).
  2. Then check that all OSes are installed in UEFI mode and check that you have a GPT partition table. You can use Windows' dism to backup and restore partitions to a new partition table layout and use the command prompt from latest Windows installation media to reinstall the bootloader, more details on this in the next point.
    • Since you have been recommended to try various other tools that don't address your issue you have to revert these changes to a pristine condition, otherwise this will get more and more confusing. Sorry about that. :(
  3. You can use my answer from How to boot Windows 8 from a legacy MBR partition in UEFI mode via GRUB?
    • This answer does install an independent Windows boot loader configuration through bcdboot in a different location where Grub will call it. For convenience I have chosen the Windows root partition. You will need to do this for every Windows installation, so that every Windows installation has its own and will only boot itself (clean the individual Windows boot menus from other entries).
    • Remember that you need to create an individual entry for each Windows installation you want to boot in /etc/grub.d/40_custom and follow the instructions and explanations about UUIDs, partitions and partition tables.
    • Probably disable every semi-smart feature that detects different OSes like OS-prober in Grub (GRUB_DISABLE_OS_PROBER) or troubleshooting boot issues with Windows or boot-repair (or manually clean up after them).

N.B.: Your request was to be able to manage all OSes with Grub, however with UEFI, the traditional "dualboot" term becomes almost a misnomer. UEFI allows coexistence of several bootloaders on the ESP and you can choose which one to boot (if they have been registered in the UEFI firmware and the manufacturers firmware doesn't do out of spec patronizing like only booting Windows). The sad thing here is that only very few people can think about installing more than one (independent) version of Windows, Linux or one release of Ubuntu onto one computer (or a harddrive that is used with several computers and boots a different installation of the same OS release on each computer). Most of this is already possible, but mechanisms in Windows and Ubuntu (Fedora,…) plainly choose to overwrite what is in their namespace under the false assumption that there can only be one.

(I do boot Windows8/10, Ubuntu, Ubuntu LTS and Fedora on one computer and have tinkered a few times with UEFI booting under different requirements.)

LiveWireBT
  • 29,597
2

You need to create a new EFI Partition for the later installed windows. Because the one first installed had its own EFI but the later one seeing another windows just added its own entry to the bootloader now creating its own EFI in /EFI/Microsoft/Boot/bootmgfw.efi so fire up CMD as admin on your Windows 10 and enter the following commands (From here on TenForums):

diskpart
list disk
select disk # Note: Select the disk where Win10 is installed
list partition
select partition # Note: Select the Win10 installation partition.
shrink desired=100
create partition efi size=100
format quick fs=fat32
assign letter=s
list partition
list volume Note: Note the volume letter where the Win10 is installed.
exit

bcdboot X:\windows /s S: Note: Replace "X" with the volume letter of the Win10 partition.

BCDBoot copies the boot files from the Windows partition to the EFI System partition and creates the BCD store in the same partition.

Now just add an entry pointing to this partition like this in /etc/grub.d/40_custom or (any custom file in /etc/grub.d/):

insmod part_gpt
insmod ntfs
set root=hd1,gpt10
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
Ahmed
  • 21
2

Just login to your Ubuntu OS, open a terminal, and type in the following:

sudo update-grub

After this, reboot your system.

Nidhan
  • 21
1

After looking for a solution for a while, and also being lazy for not trying to spend another hour finding out what and where should I edit and update (as it was futile) I eventually installed Grub Customizer. Works wonders!

1

Windows 10 will, for the most part, be added to grub boot menu by the os-prober automajically.

For my specific setup I wanted to completely hide grub menu and automatically boot windows unless a hotkey was pressed to boot Ubuntu. So in my specific case os-prober isn't an option because the most important step in hiding the grub menu, which most answers I found neglect to mention, is to set the disable os-prober flag or the menu WILL be shown until os-prober completes.

It took considerably longer than I had anticipated to get right because there are so many partial answers out there but most are version dependant and can lead you astray. I spent a lot of time trying write my own grub menu entry trying use grub commands that didn't exist like ntdlr. Another caveat is that the chainloader functions on my grub try to boot bios not efi and will not work.(Im sure I was doing something wrong?)

In the end the solution was actually simple as the scripts that make your /boot/grub/grub.cfg do most of the work for you in finding UUIDS for your boot partitions. So you can skip the fdisk and blkid steps most people mention.

So step 1 is to make sure /boot/grub/grub.cfg is current using update-grub to make .cfg file. In terminal

sudo update-grub

Step 2 is to add custom menu entries in /etc/grub.d/40_custom. Don't waste time trying to write your own simply open /boot/grub/grub.cfg search "menuentry" and copy the automatically generated entries.

The first in the list will be ubuntu mine looks like

menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-9e66eed6-e672-49ff-a07c-afdc00809148' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root  9e66eed6-e672-49ff-a07c-afdc00809148
else
  search --no-floppy --fs-uuid --set=root 9e66eed6-e672-49ff-a07c-afdc00809148
fi
linux   /boot/vmlinuz-5.4.0-39-generic root=UUID=9e66eed6-e672-49ff-a07c-afdc00809148 ro  quiet splash $vt_handoff
initrd  /boot/initrd.img-5.4.0-39-generic

}

Windows will be similar. Copy both to /etc/grub.d/40_custom. The only change I made for Ubuntu is to add the --hotkey=key flag which will make grub boot the os associated with that hotkey.

menuentry 'Ubuntu2' --class ubuntu --class gnu-linux --class gnu --class os --hotkey=u $menuentry_id_option 'gnulinux-simple-9e66eed6-e672-49ff-a07c-afdc00809148' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root  9e66eed6-e672-49ff-a07c-afdc00809148
else
  search --no-floppy --fs-uuid --set=root 9e66eed6-e672-49ff-a07c-afdc00809148
fi
linux   /boot/vmlinuz-5.4.0-39-generic root=UUID=9e66eed6-e672-49ff-a07c-afdc00809148 ro  quiet splash $vt_handoff
initrd  /boot/initrd.img-5.4.0-39-generic

}

I use --hotkey=u here to set Ubuntu boot hotkey to u.

Then I tweaked the Windows entry, replacing $menuentry_id_option withe the grub --id flag.

menuentry "Windows 10" --class windows --class os --id windows-custom {
insmod part_gpt
insmod fat
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root  0EAE-C882
else
  search --no-floppy --fs-uuid --set=root 0EAE-C882
fi
chainloader /EFI/Microsoft/Boot/bootmgfw.efi

}

I used --id windows-custom. Save chages to /etc/grub.d/40_custom.

Finally open /etc/default/grub and add

GRUB_DISABLE_OS_PROBER=true

change GRUB_DEFAULT=0 to GRUB_DEFAULT=windows-custom and change GRUB_TIMEOUT=10 to your choice of timings I use 0.5 just to give myself a little extra time to hit u to boot Ubuntu after POST.

Hopefully this saves someone a bit of headache, cheers!