Home > Computers, Howto, Linux, Windows > Booting Ubuntu through NTLDR or Windows Boot Manager

Booting Ubuntu through NTLDR or Windows Boot Manager

You know you’re a bit of a dinosaur when you get excited and nostalgic at the prospect of using assembly language again. Assembler was the second computer language I learnt – straight after Sinclair BASIC on the ZX Spectrum, which was nearly 26 years ago. For a while I hand-assembled my programs, painstakingly writing each instruction on paper, and then converting the opcodes and operands into their hex equivalents for eventual POKEing into memory. I went on to learn x86 assembler, but haven’t used it in years. Until now!

Imagine that you have two hard drives (sda and sdb). Windows is installed and working happily(?) on sda. You have installed Ubuntu on sdb. You don’t want to mess with your Windows partition, so you’ve installed Grub to the MBR of sdb, but you do want to be able to launch Ubuntu via the Windows NTLDR boot menu. This was a problem, which recently arose on the Ubuntu forums. I’m blogging about it, because it was a lot of fun to solve, and it may help people understand a little better what goes on in the boot sequence.

Essentially, the boot sector of a disk contains a small program known as the “bootstrap”. These programs are usually written in assembly language, partly due to size limitations, and also because assembly is nearly the purest way of communicating directly with the hardware. You’re practically “on the metal”, as we used to say (for some reason).

The easiest way to get the Windows boot manager to start Ubuntu, is to extract the Grub boot sector to a file, and reference this from boot.ini.

Note – if you’re using Vista or 7, then you’ll need to use bcdedit. The process is essentially the same, though.

To extract the Grub boot sector to a file, simply boot into Linux (using a Live CD, or changing the hard drive startup order in the BIOS), and type:

sudo dd if=/dev/sdb of=./bootsect.bin bs=512 count=1

This will extract the boot sector of the second hard drive to a file named bootsect.bin. Copy this file to the root directory of your Windows installation and, if you’re using XP, then open a command prompt and type:

attrib -r -h -s \boot.ini

Then edit the boot.ini file, adding the following line at the end, beneath the [operating systems] label:

C:\bootsect.bin = "Ubuntu"

If you’re using Vista or 7, then open an administrative command prompt, by right clicking on it and choosing “Run as Administrator”, then:

Add the new entry by typing:

bcdedit /create /d “Ubuntu” /application BOOTSECTOR

Write down the ID that is returned – it will be between curly braces {}. Then type:

bcdedit /set {THE ID YOU WROTE DOWN} device boot
bcdedit /set {THE ID YOU WROTE DOWN} PATH \linux.bin
bcdedit /displayorder {THE ID YOU WROTE DOWN} /addlast
bcdedit /timeout 10

When you reboot, you will see that Ubuntu now appears as an option; however attempting to boot it will fail. Why is this?

The short answer is that Grub expects to boot Ubuntu from the booting drive. So, when you start your computer, the BIOS stores a boot drive index number, which the boot loader can then read. Since you’re starting up from your Windows drive, the Grub bootstrap program in bootsect.bin expects that Ubuntu will be on the same drive. That’s the short explanation. The long explanation is after the fix.

To fix this, and get Ubuntu booting properly, open bootsect.bin in a hex editor. I simply use the Gnome Hex Editor, but XVI32 for Windows is good too. When you’ve opened the file:

  • Go to address 0064
  • The value should read FF. Change this to 81.
  • Save the file and reboot.

The Ubuntu menu option will now work. If all you wanted to do was to get this working, you can stop reading now. If you’re interested in low-level programming and how Grub works, then keep on reading.

Remember we said earlier that, on startup, the BIOS stores the boot drive index number? This is stored in the DL processor register. It’s beyond the scope of this post to explain what a register is, but manipulating processor registers is the heart of assembly language programming. Have a look here for a general explanation of processor registers.

When the Grub bootstrap is invoked, it checks for the existence of the boot drive index number in DL, by executing the following code:

TEST DL,80

You can see this for yourself by looking at bootsect.bin in a hex editor. The hex equivalent of the above command is F6 C2 80, and it can be found at offset (address) 004D in the file. This checks to see if the boot drive index number has been stored correctly – apparently some BIOSes don’t pass the index number to DL, so if it doesn’t exist, the subsequent code corrects the situation.

Shortly after these checks, Grub executes the following code:

MOV AL,[7C64]
CMP AL,FF
JZ 7C85
MOV DL,AL

Effectively, this copies the value contained in 7C64 (offset 64 in the file) to the AL register. It then checks to see if the value is FF. If it is, then Grub changes nothing. It uses the boot drive index number that’s already in DL. If the value of AL is anything other than FF, then Grub moves the contents of AL into DL – changing the boot drive index number. This code starts at offset 7E, the hex equivalent is: A0 64 7C 3C FF 74 02 88 C2

So, when we change the value at offset 64 from FF to 81, Grub checks to see if the value is FF. The comparison fails, because the values are different, so the new boot drive index number is copied to DL – overwriting the existing one.

The BIOS starts numbering the drives from 80. So, 80 is the first drive, 81 the second and so on. When we alter the value to 81, it tells Grub to boot Linux from the second drive in the system, which is why this tweak works.

  1. August 5th, 2010 at 00:51 | #1

    Hi Matt,

    That certainly is an interesting exercise but I would’ve been inclined to install Grub to /dev/sda which I think would’ve side stepped the whole issue, since Grub 2 will automatically detect other installed OSes such as Windows. Just goes to show how much better Grub is than ntldr.

    Another use for hexediting the offset for a partition is if you have used ntfsclone to copy a partition to a drive with a different patitioning scheme. For instance if the source drive has a diagnostic partition and the destination drive doesn’t and you don’t want to spend time copying the whole disk (which would be incredibly slow if the source disk is failing).

    The modify NTFS boot sector section at http://www.dominok.net/en/it/en.it.clonexp.html has information on same.

    It’s certainly the only time I’ve needed to use hexedit in the last 5 years.

  2. August 5th, 2010 at 01:06 | #2

    BTW as an interesting but possibly erroneous exercise I experimented with accessing raw partitions from within VirtualBox, which, allows going from physical to virtual and vice versa with relative ease. Reactivating Windows and possibly installing/removing VirtualBox guest tools depending on which way you are going, and making sure the drivers are ok, are the only things I had to do. I devised it as a master plan to wean people off Windows. Maybe it could help you at some stage.

  3. August 5th, 2010 at 08:21 | #3

    Hi John,

    It certainly was an interesting and fun exercise. The original poster had specifically stated that he didn’t want to touch his Windows MBR at all – otherwise my immediate recommendation would have been to install Grub to /dev/sda and let Grub deal with it. You can follow the thread here, if you wish. I comment under the name lechien73.

    Grub is an interesting beast indeed, it also records the absolute sector reference for its stage.2 file. So, you can’t just take someone else’s boot sector dump and use it on your hard drive. If the stage.2 file is not where Grub expects it to be, then Grub will fail.

    As an aside, I love how all the tools you need are supplied as standard with Linux. You have powerful commands at your disposal, such as “dd”, and other useful tools, like “hexdump”.

    Matt

  4. August 5th, 2010 at 10:12 | #4

    My first reply in that thread would’ve been “why?”. Changing the boot sector is trivial, as is backing it up. I’m all for keeping people happy but talk about making it difficult.

    Grub 2, for all it’s automated wonder, can do some strange things, especially if you have it installed in multiple partitions. For instance it will not auto load menu entries if it has been chain loaded by another grub 2 which can be a pain if you have just remotely rebooted a customer server and it is sitting there waiting for someone to hit enter. A great advertisement for Serial Over LAN if you ask me but then Grub 2 doesn’t support console redirection yet, so you are stuck with Grub Legacy or Lilo in that case (I prefer Lilo cos it’s lean).

    Yes dd is great and so is ddrescue (the GNU one), testdisk and photorec. To think we used to pay for things like R-Studio!

    The fanciest way I’ve used dd is to image a hard drive, gzip it and used netcat to transmit it to another machine. Or course there is more than one way to skin that cat, but I love solutions that are on one line (well 2 lines if you count having to start netcat at the other end).

    BTW I am jpl888 on the forums, but then you will see the website address in my signature so you’ve probably already guessed that if you have read some of my posts.

    Nice to see you have posted more in 6 months than I have in 3 years, must be because you haven’t got 4 kids or are you superman?

  5. August 5th, 2010 at 14:39 | #5

    Definitely not Superman ;) but I don’t have 4 kids either – or any for that matter. I tend to be around the Ubuntu Forums for most of the day, mainly because I’m supporting 2 x Ubuntu servers running KVM that host several Windows 2003 guests. I also care for an Alpine Linux-based firewall system, an Alpine VoIP server, and an Ubuntu fax server. I have so much exposure to Linux that when I get back to a DOS command prompt these days, there’s an initial brain retrieval error when I try to remember, “is it \ or / and do I type ‘dir’ or ‘ls’???”

  6. August 6th, 2010 at 21:50 | #6

    That’s really cool. I’m glad you are getting to spend so much time out of the Windoze mono-culture these days.

    Sure, you pretty much know what I’m looking after these days. Stick an Ubuntu server in at each customer to take care of everything. Load some form of Windows in a VirtualBox VM if they need a windows only app served (sorry stopped using KVM a while back because it wouldn’t pass SMBIOS info into VM and stopped me from using OEM license that came with machine, maybe that’s changed?). I have to say I do like KVM for day to day usage though, especially if you are doing it from the command line, much easier to use than fiddly VBoxManage commands.

    I have similar DOS command prompt aversion too, except that I start typing Linux commands before I remember where I am :/

    Unfortunately I still have to look after plenty of Windows workstations. You know the drill, try to remove virus/malware, if stubborn reinstall, rinse and repeat!

  7. Mike
    October 24th, 2010 at 22:53 | #7

    Does this tutorial work as written if Ubuntu is installed not on a second physical drive, but rather on a separate partition on the same physical drive as Windows? Does the “change FF to 81″ thing need to be modified at all depending on what drive/partition is used for Ubuntu?

  8. Lee Seymour
    November 28th, 2010 at 20:38 | #8

    I am using XVI32 to edit stated value of extracted file, bootsec.bin, as per your guide, but I’ve never used a hex editor before. How do I navigate to address 0064?

    I’ve tried the search function. Am I going wrong somewhere or is every bootsec.bin file different?

  9. November 28th, 2010 at 21:19 | #9

    Hi, press CTRL+G to open the Goto box. Click on “Hexadecimal” and type in $0064 as the address. Then click OK. Hope this helps. Thanks for your comment :)

  10. Lee Seymour
    November 28th, 2010 at 21:23 | #10

    Nuked my bootloader & had to use Startup Repair!

  11. November 28th, 2010 at 23:26 | #11

    Did you create the bootsect.bin file from your Ubuntu installation? It should be impossible for this technique to affect your bootloader, because all we’re doing is editing a file – not the bootloader itself!

  12. Lee Seymour
    November 29th, 2010 at 21:46 | #12

    Yes copied & pasted

    “sudo dd if=/dev/sdb of=./bootsect.bin bs=512 count=1″

    Then copied to C drive. The PC booted & declared no bootable partition found. I used Startup Repair to recover.

    Is there a way of removing the “Ubuntu” startup entry?

  13. Lee Seymour
    December 5th, 2010 at 18:30 | #13

    Bump:

    Is there a way of removing the “Ubuntu” startup entry from 7′s boot list?

    Could of been a coincidence, in that Ubuntu updates overwrote NTLDR, as this has happened before.

  14. Lee Seymour
    December 7th, 2010 at 22:31 | #14

    EasyBCD is the answer!!!

  15. December 7th, 2010 at 23:18 | #15

    True…that would work. Sorry for not responding to your previous comments – I’m in the process of moving home at the moment, so the blog is taking a bit of a back seat! Glad you got it sorted though.

  16. fleamour
    December 9th, 2010 at 21:58 | #16

    Ah..Stressful! Hope it goes well…

    I have decided that booting Ubuntu from F11 pop out menu from secondary HDD has built in redundancy if 7′s HDD goes down. At least I’ll be able to access solutions on t’net.

    I tried installing WTL 2010 under Xubuntu last night, but no joy, even with latest WINE beta. It’s a small world! Do you know fellow tech Tony Elmer AKA: Mr. Mepis?

    http://sites.google.com/site/mrmepis/

  1. No trackbacks yet.