First, the easiest way
There is a tool called os-prober, many distros ship it (I know for sure Arch does). Grub2 can automatically take advantage of this, during the generation of the config file, if you have it installed, so the easiest and least error prone way of doing this, is:
- Install os-prober
- Mount your windows partitions somewhere (both the EFI, and the data partition), it doesn't matter where
- Run grub-mkconfig -o /boot/grub/grub.cfg
It will detect the Windows installation and automatically generate the corresponding entry for it.
If you can't/don't want to use os-prober, or are looking for a manual solution read on.
Common, but all wrong solutions you can find while googling
The following things are all wrong:
- Mount the windows partition and regenerate the config, so it gets picked up automatically (does not work with UEFI)
- Add a
menuentry
withsetroot (hd0,msdos1)
(does not work with GPT partitioning) - Add a
menuentry
withchainloader +1
(does not work with UEFI) - Run
bootrec.exe /fixmbr
from the windows recovery shell (works, but bombs the grub2 loader)
The actually working solution
Put this in your /etc/grub.d/40_custom
file:
menuentry 'Windows 10' { search --fs-uuid --no-floppy --set=root D464-A236 chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi }
Where D464-A236
is the UUID of your windows UEFI partiton. You can find this by doing fdisk -l
, and looking for a partition called "EFI System", but also make sure you are looking at the correct drive, you might have 2 or more EFI partitions, if you have multiple OSes. You want the one that is on the same device as the "Windows recovery environment". After you have the device, you can query the UUID with blkid
, eg. blkid /dev/sda2
.
Leave the chainloader line as it is, grub will evaluate the (${root})
part. If you want to make extra sure, you can mount the aforementioned EFI partition, and verify that the path to bootmgfw.efi
is correct. Don't forget to run grub-mkconfig -o /boot/grub.cfg
after making the modification.