How to Dual Boot Windows 7 and Linux using BCDEdit

(20141224 – This post has been amended to address changes in recent versions of Ubuntu, and to remove outdated instructions — iceflatline)

This post will describe how to use the Window 7 boot configuration data editor (BCDEdit) to configure a Windows 7 system that can boot to Windows 7 or a Linux distribution. The steps described in this post assume that Windows 7 and the Linux distribution will occupy the same physical hard drive. Configuring BCDEdit to recognize and boot a Linux distribution located on a second physical hard drive is beyond the scope of this post.

To help explain the steps involved, we’ll use an 320 GB SATA hard drive with Windows 7 already installed. We’ll reduce the size of the partition containing the Windows 7 operating system and re-partition the remaining unallocated disk space in order to install the Linux distribution Ubuntu. We’ll then use BCDedit to add a Windows boot menu option for Ubuntu. All steps involved assume you have a functioning CD drive (or USB drive if you’d prefer) that the system can boot from. The software versions used in this post were as follows:

  • Ubuntu v14.10 (x64)
  • Windows 7 Professional (x64)

Oh…, and while I’ve never encountered a situation where the Windows 7 Disk Management tool destroyed existing disk data, make sure you backup any critical files before you proceed.

So, let’s get started.

Reducing the Windows Partition

The first thing that we need to do is reduce the size of the existing Windows 7 partition. While you can use third-party applications like GParted, I found Windows 7’s own Disk Management tool to be the most efficient method for accomplishing this task. The Disk Management tool can be accessed by using Win+r and entering the command diskmgmt.msc.

You’ll notice that Windows 7 currently occupies all of the existing disk space using two primary partitions: one small boot partition; the other for the operating system. When finished, we’ll have five partitions in total: the two Windows 7-related partitions just mentioned, and ones for the Ubuntu operating system and Linux swap. We’ll also create a small FAT32 partition for sharing data between Windows 7 and Ubuntu. You’ll need to determine how much space you want to allocate to each of these additional partitions based on your requirements and disk size. For our 320 GB disk example, we’ll use the following partition layout:

Windows 7: ~100MB (Windows 7 boot loader)
Windows 7: ~251 GB
Ubuntu: ~31 GB
Linux-Swap: ~1 GB
FAT32: ~16 GB

Right-click on the Windows 7 volume (C:) and selected “Shrink Volume.” Then enter the amount of space (in Megabytes) that the partition should shrink (which in turn becomes the amount of space available to install our Linux distribution), which in our example is 48000 Megabytes (48 Gigabytes), then select “Shrink” (See Figure 1). When complete, exit out of the Disk Management tool and reboot the system.

Screenshot showing the Windows 7 partition reduced ~48 GB using the Windows Disk Management tool

Figure 1

Installing Ubuntu

Now it’s time to partition our 48 GB of unallocatd disk space and install Ubuntu. Download a copy of Ubuntu Desktop and burn it to a CD (or place it on a bootable USB drive). Boot the system using the Ubuntu disk. Select “Try Ubuntu…” and then double-click the “Install Ubuntu…” icon when the desktop appears. Continue through the installation process until you arrive at “Installation type” and select “Something else”, then select “Continue”. (See Figure 2).

Screenshot of the Ubuntu installation type screen

Figure 2

The screen that follows is where we’ll instruct Ubuntu how to partition the unallocated disk space. Left-click on “free space” to highlight it and then select the “+” icon to create a new partition. Make the size of this partition 31000 MB. Ensure it’s a primary partition, and located at the beginning of the free space. Select the Ext4 journaling file system and, since this partition will serve as the root partition for Ubuntu, set the mount point to / from the list of choices in the drop-down lists. Now select “OK” to accept the changes (See Figure 3).

Screenshot showing the creation of the Ubuntu root partition

Figure 3

Now let’s create a partition for use as Linux swap space. Once again, left-click on free space to highlight it and then select the + icon to create a new partition. Make the size of this partition 1000 MB. Our disk is limited to a maximum of four primary partitions, so we’ll make this a logical partition – again located at the beginning of the free space. Select “swap area” from the list of choices in the drop-down list, then select “OK” to accept the changes (See Figure 4).

Screenshot showing the creation of the swap partition

Figure 4

Using similar steps, let’s partition the remaining free space as a FAT32 file system. This too should be a logical parition, located at the beginning of the space. You may also wish to set the mount point to /media/share, or something similar. The benefit of selecting a mount point at this stage is that Ubuntu will add this partition to the file /etc/fstab so that the system automatically mounts it at boot time. No worries though, you can always select a different mount point and manually mount it and/or add it to /etc/fstab at a later time. When complete, select “OK” to accept the changes (See Figure 5).

Screenshot showing the creation of a FAT32 partition

Figure 5

The final step is critical. We need to tell the Ubuntu installer where to install the system bootloader (GRUB 2). We DO NOT want to install the bootloader on /dev/sda, as that would overwrite our disk’s master boot record, nor do we want to install it on /dev/sda1 or /dev/sda2, as that would overwrite the Windows 7 bootmanager files and boot configuration data, or the operating system itself. Instead, let’s have Ubuntu install its bootloader on the partition that will contain the Ubuntu operating system – in our case /dev/sda3. To do this, click on the drop down list under “Device for boot loader installation” and select /dev/sda3 (See Figure 6).

Screenshot showing the correct partition for the ubuntu bootloader installation

Figure 6

Select “Install Now” and Ubuntu will begin the installation. When it completes you’ll be asked whether you’d like to reboot or “continue testing”. You should select continue testing as the following steps require access to a terminal.

Configure Windows for Dual Boot

Now that we have our disk partitioned and Ubuntu installed, let’s set up our system to boot Windows 7 or Ubuntu. This will involve copying the boot record of our Ubuntu partition to Windows 7, and using BCDEdit to create a new entry in the BCD store that will point to that file. This way Windows 7 will display a menu at boot time that will give you a choice between Windows 7 and Ubuntu.

First, let’s make a mount point for the FAT32 partition we created. Open a terminal and enter the following:

Next, let’s mount the correct device to this directory. Recall from the partitioning steps above that the FAT32 partition is located at device /dev/sda6:

Write the first 512 bytes of our Ubuntu partition to a file and copy that file to our FAT32 partition:

Note: using the FAT32 partition in the aforementioned steps is optional. You may chose to use another device such as a USB drive to copy the *.bin file to.

Exit out of the Ubuntu live system and reboot to Windows 7. Along the way, you may see Windows perform a disk check (don’t worry, that’s normal, and should only occur once as a result of these procedures). Log into Windows 7 and open the FAT32 volume you created and you should see the ubuntu.bin file. Copy that file to the root of the Windows 7 volume (e.g., C:).

Now we’ll use BCDEdit to add an entry to Windows 7’s BCD store. Administrative privileges are required to use BCDEdit, so use Win+r, type cmd, and then press CTRL+SHIFT+ENTER. Let’s start by creating an entry for our Linux distribution. Note here that you are free to choose another entry name if desired:

BCDEdit will return an alphanumeric identifier for this entry that I will refer to as {ID} in the remaining steps. You’ll need to replace {ID} by the actual returned identifier. An example of {ID} is {d7294d4e-9837-11de-99ac-f3f3a79e3e93}. Next, let’s specify which partition hosts a copy of the linux.bin file:

The path to our ubuntu.bin file:

An entry to the displayed menu at boot time:

and finally, let’s specify how long the menu choices will be displayed:

That’s it! Now reboot and you will be presented with menu where you can choose to boot to Windows 7 or Ubuntu. When you choose Ubuntu, you’ll be taken to the it bootloader menu where you can choose to continue booting Ubuntu.

On a final note, if at any time you want to eliminate the Ubuntu menu option simply delete the BCD store entry you created using the following command:

Conclusion

With a minimal amount time and a little Windows command line foo, you can easily set up a system that can dual boot Windows 7 and your choice of Linux distributions.

References

http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx

Comments

  1. Ingvar, not that I am aware of. All that’s really going on here is that you are adding another entry to the Windows BCD data store; that entry simply points to location containing of the MBR of Linux partition. Of course it has been awhile since I wrote this post so perhaps something has changed.

  2. Is it possible to use /dev/sda instead of in my case /dev/sda5?
    Of course I would have to reinstall with grub on /dev/sda.
    What would be the command to bcdedit?
    Still need the linux.bin?
    Thanks

  3. If I recall correctly, you indicated that you boot Windows from this device, /dev/sda? If so then, then yes, you can install GRUB to /dev/sda but know that it will most likely over write the Windows boot loader. Usually this isn’t a problem as GRUB is sophisticated enough now to recognize the presence of a bootable Windows partition and give the option of adding it to its menu. However, if it doesn’t, you’ll need to add it to the GRUB configuration manually. Until GRUB knows where Windows is, you won’t be able to boot it.

    The reason I wrote this article was to give those wishing to dual boot the option of using the Windows boot loader instead of GRUB.

  4. Seem this doesn’t work with BitLocker’d Win10 / Elementary.

    With above mods in place… Win10 still boots but Linux GRUB will not load, just gives error 0xc000007b which appears to be 32bit Vs. 64bit incompatibility.

  5. rulzz, perhaps it’s the application you’re running as a service with srvany that’s consuming CPU time? What happens if you shut down the service and just run the application normally?

  6. Hi, I had Centos running on my desktop and I installed windows 10. Now I cant boot into Centos. The other problem being that the steps given to copy the 512 bytes are not possible as I dont have access to the Linux OS.

    Any suggestions?

  7. Moiz R, it appears the CentOS boot loader was overwritten when you installed Windows. You’ll need to reinstall the CentOS bootloader, which I believe is GRUB. A quick web search suggests there are quite a few instructions for how to reinstall GRUB. The Rescatux program might also be a place to start.

  8. hi, i did not find if this been covered before, but after recent updates in openSUSE tumbleweed this boot setup broke (boot on / or /boot on primary or logical partition, same problem). don’t now exactly what is cause, but solution seems to be create new linux.bin since first 512b of partition were probably changed(otherwise new linux.bin should not help).

    link to forum thread, i made
    https://forums.opensuse.org/showthread.php/526787-quot-GRUB-_-quot-hang?p=2836091#post2836091

  9. I have browsed this helpful article and comments in my search for a solution to my dual-boot problem. I have a second-hand Lenovo T430 laptop. It has Win7 installed. I want to install Linux Mint 17.x or 18.x (which use Grub2) in dual boot, without overwriting the Win7 bootloader.

    I have done this successfully on other computers using EasyBCD, so I understand about partitioning and about putting the Grub on to the Linux Mint’s root (/) partition. But in this case EasyBCD does not do the job.

    The curious thing about this Lenovo laptop is that (in its original state with only Win7 installed) on initial bootup the Windows boot menu appears fleetingly, showing two options – the default is “Boot To Windows”, the other option is “Restore Original Windows Image” (with a warning that this will wipe the hard drive). After a mere 2 seconds, the default is to boot into Win7. I have never encountered this boot-menu on any other computer.

    I went through the whole process of installing Mint on appropriate partitions, and putting Grub on Mint’s root (/) partition, then rebooting into Win7 and adding Linux Mint to the EasyBCD menu.

    But when rebooting, instead of getting the Windows boot menu with Linux Mint also listed, I still got, again, only the Windows boot menu with the “Boot Windows” or “Restore Image” options. No sign of Mint.

    Two little clues. As well as a System Reserved partition and the Win7 partition, there was, and is, also a Recovery partition (only visible in GParted) on the drive. And when I was going through the install options for Mint, the installer said that there were “multiple OSs” already on the drive. I presumed that this was something to do with the Recovery partition (does it contain an image which Linux thinks is another OS?). And has the Linux Rescue and Recovery tool on the laptop not only created that Recovery partition but also modified the Windows bootloader to cause that screen with the Restore option to appear? If so, is that preventing EasyBCD from modifying the Windows bootloader?

    If any of that is on-target, then what can I do to discover the existing contents of the Windows bootloader/BCD? And if EasyBCD can’t enable booting into Linux Mint, can I use bcdedit to modify the bootloading process to add Linux Mint (or rather its Grub) without messing up the Recovery partition and/or the Restore-image option which already appears to be in place?

  10. br1anst0rm, hmmm, it’s been awhile since I’ve dealt with this issue. A couple of thoughts though. I think that the second boot option may be the Lenovo feature that allows you to reinstall the OS to the state is was in when it left the factory.

    I’ve owned many Lenovo laptops but I have never seen that feature offered as a boot option. Usually you have to enter the recovery option by pushing a button during boot, where your offered the ability to reinstall the OS. And yes, it does wipe the drive.

    I suspect one of the two partitions you’re seeing via GParted is this recovery partition, the other is likely the Windows boot partition, where windows keeps its BCD settings.

    The steps described in the post should allow you to add the Linux boot option using BCDedit as well as how long the options are displayed.

    Before you do anything though you might want to consider cloning the entire drive to another (of equal or greater size) while you’re experimenting.

    By the way, if you’re not interested in this factory recovery partition you should be able to delete it and recover its space using Windows 7’s disk management tool. You should consult the Internet though, as I’ve not done that before.

  11. Hello iceflatline and thanks for responding to my recent post.

    I have been casting around for advice and guidance – including the EasyBCD support forum and the Linux Lite and Linux Mint forums (as I use these Linux OSs and use EasyBCD to set up dual boots on my other non-Lenovo computers).

    It has been like putting together a jigsaw puzzle. I feel like Sherlock Holmes trying to follow clues and make deductions. But I think I have figured out the explanation, even if I haven’t found a solution. The main elements are these:

    – it is certain that – as you say – the laptop has not only a System Reserved (Windows Boot) partition, but also a Recovery Partition which is part of the Lenovo OEM setup;

    – it seems almost certain that either as OEM or when Win7 was (re)installed, Lenovo modified the BCD so that in the initial stages of booting, the Windows Boot Manager/Loader offered up the Restore System Image option that appears as the first screen.

    – The BCD (which I have been able to look at via the EasyBCD GUI) includes a line beginning “device” which is a custom entry which I presume is what brings up the screen offering the option to Restore System Image (which is on the Recovery partition);

    – this “device locate” custom entry is so configured that once it gets to the file concerned, it stops. That’s a crude summary of the detailed explanation at this site: http://www.mistyrebootfiles.altervista.org/documents/BCDEdit/files/device_locate.htm.

    – so even though for my dual boot I installed Linux Mint on to a separate partition with its Grub, and used EasyBCD to add this to the BCD entries, the boot process – which goes to the Windows bootloader first – does not proceed to the stage where the link to Grub and the Linux OS is offered.

    – it follows that in order to set up dual boot while keeping the Win7 Bootloader and adding the Linux OS and its Grub, the BCD has to be edited either manually or using EasyBCD….. but that in doing so, the custom configuration that Lenovo has put in place, and its recovery partition, have to be changed or removed. That’s pretty radical surgery, and even if I take a backup or clone the drive, I’m not sure it’s something i want to attempt.

    Which leaves me with the choice of abandoning dual boot ambitions for this computer and leaving it with Win7 only, or deleting Windows – and the Recovery partition – entirely and installing only one or more Linux OSs.

    If you are interested in more background on the efforts to figure all this out, and links to some other helpful websites, the posts in this thread on the Linux Lite forum (which are too long to copy-and-paste here) have screenshots of my BCD entries and other details: https://www.linuxliteos.com/forums/installing-linux-lite/dual-boot-with-win7-problem-with-boot-menus-on-lenovo-laptop/msg46058/#msg46058.

  12. br1anst0rm, that is indeed a tough choice. I won’t offer any counsel though as it is ultimately up to you to decide. But do let me know which way you go. And by the way, really appreciate all the information provided in your comment. I’m sure it will be of help to others who may come across this post.

  13. Hi iceflatline,

    I have been using these same steps with great success on my PC (Arch+Win10)

    Initially I was getting fed up with windows updates causing me issues due to syslinux being sat in MBR and this just solved it for me.

    I didn’t comment when I first discovered your article but though that as it has served me well for so long (2017 I found this article and implemented it) I thought I had better come give well deserved props.
    Must admit I followed a slightly different path but what I did was based on the info here

    Thank you.

  14. t0m5k1, thank you for your kind words. You made my day! I’m glad the post was helpful to you.

  15. Hm. I am using Windows 8.1 with UEFI with Bitlocker and Secure Boot disabled. I have this minor assembly program for testing purposes that I want as a boot option. I followed the instructions to the T – I created a new partition with the assembly .bin file on there and pointed bcdedit towards it with bcdedit /set {(ID)} device partition=O: and bcdedit /set {(ID)} path \assemblyTest.bin and the option to boot to this file DOES pop up alongside my Windows 8.1 boot option. The problem is that when I try to run it, Windows throws an error along the lines of “Windows is missing an important file.” (I am on mobile right now – writing this off of the top of my head – will post full error message and screenshot tomorrow.) The odd thing is that the assembly program does in fact boot from USB when using Rufus, but I would seriously prefer not booting from USB all the time and would like to have a nice and clean partition for my program to boot from. I do not understand what the problem is. Help?

  16. theguydude, that’s a tough one. Perhaps try moving the *.bin file you created to c:\ and then use partition=c:? Maybe the BCDEdit thinks it needs to be there.

    On the other hand, you mentioned an assembly program. Perhaps Windows has a way to boot such a program independent of the steps described in the post. Might be worth researching.

  17. I did the whole process manually and had to tune the process to target specifically i386-pc and to disable os-prober. The configuration seems fragile and running update-grub may put the boot sector copy out of sync.

    # ls -l /dev/disk/by-label
    yhteensä 0
    lrwxrwxrwx 1 root root 10 syys 1 18:47 BOOT -> ../../sda1
    lrwxrwxrwx 1 root root 10 syys 1 18:47 OS -> ../../sda2
    lrwxrwxrwx 1 root root 10 syys 1 18:47 Ubuntu -> ../../sda3

    /# mount /dev/sda3 mnt
    /# sudo mount –bind /dev /mnt/dev &&
    > sudo mount –bind /dev/pts /mnt/dev/pts &&
    > sudo mount –bind /proc /mnt/proc &&
    > sudo mount –bind /sys /mnt/sys
    /# sudo chroot /mnt
    /# chmod a-x /usr/bin/os-prober
    /# grub-install –target=i386-pc –force /dev/sda3
    Installing for i386-pc platform.
    grub-install: warning: File system ext2' doesn't support embedding.
    grub-install: warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
    Installation finished. No error reported.
    /# grub-install --target=i386-pc --recheck /dev/sda3
    Installing for i386-pc platform.
    grub-install: warning: File system
    ext2′ doesn’t support embedding.
    grub-install: warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
    grub-install: error: will not proceed with blocklists.
    /# update-grub
    Sourcing file /etc/default/grub'
    Sourcing file
    /etc/default/grub.d/init-select.cfg’
    Generating grub configuration file …
    Found linux image: /boot/vmlinuz-5.0.0-25-generic
    Found initrd image: /boot/initrd.img-5.0.0-25-generic
    Found linux image: /boot/vmlinuz-5.0.0-13-generic
    Found initrd image: /boot/initrd.img-5.0.0-13-generic
    done
    /# exit
    /# umount /mnt/sys
    /# umount /mnt/proc
    /# umount /mnt/dev/pts
    /# umount /mnt/dev

    /# mount /dev/sda2 /mnt
    /# dd if=/dev/sda3 of=/mnt/linuxbootsector.bin bs=512 count=1
    1+0 records in
    1+0 records out
    512 bytes copied, 0.000535549 s, 956 kB/s
    /# umount /mnt

    /# bcdedit /create /d “Ubuntu” /application bootsector
    /# bcdedit /set {ID} device partition=c:
    /# bcdedit /set {ID} path \linuxbootsector.bin
    /# bcdedit /displayorder {ID} /addlast
    /# bcdedit /timeout 5
    /# bcdedit /default {ID}

  18. Ah, oh, I also commented out the efi partition from fstab.

    UUID=e2bc4a8c-9dc5-4ef0-9751-71e3eae5c868 / ext4 errors=remount-ro 0 1
    # /boot/efi was on /dev/sda1 during installation
    #UUID=2C0A-1FA9 /boot/efi vfat umask=0077 0 1
    /swapfile none swap sw 0 0

  19. This is a great resource for Linux users, and it definitely got me started on setting up my dual-boot computer. Now, after considerable additional study, I may be in a position to make a contribution. Take the situation where Linux is installed on the second disk, with the grub loader occupying the boot sector of a FAT partition of that second disk. As has been pointed out, extracting the boot sector into a file, placing it on the FAT partition, and calling it with BCD from the first disk will not work. This appears to be due to the unusual arrangement of the BIOS booting the computer from the first disk, but trying to load an operating system on the second disk. Normally, to boot an OS on the second disk, the BIOS would be configured to boot from the second disk to start with. In that case, the BIOS would perform a swap, designating the second disk hd0. The grub loader relies on this designation, as it reads the rest of Grub into memory. If the grub loader is called by BCD from the first disk, however, no swap has been performed, and the grub loader will look for the rest of Grub and Linux on the first disk, hd0. After studying the source code for the grub boot loader, I noticed that it is specifically designed to accept a one-byte alteration to solve this problem. There is a byte value of 0xFF which can be changed to a value of 0x81. This byte is located between the initial jump instruction and the actual beginning of the grub code. In my bootsector, it is at offset 0x64. By the way, the 0x81 value originates from arguments for the system call to load disk sectors into memory. See the Wikipedia article on INT 13h, values for register DL. So just change the one byte in a hex editor, and the boot loader on the second disk should work with BCD on the first disk.

  20. Sam, thanks so very much for contributing to this post. This looks like an elegant approach, indeed!

Leave a Reply

Your email address will not be published. Required fields are marked *

iceflatline