Windows – learn more about how to use the GRUB `ntldr` command (module?)

grub2windows

I recently stumbled across the GRUB ntldr module.

Apparently one of the things it can be used for is as an alternative to chainloader to boot the NT >= 6.0 versions of Windows as in the example below. (Very handy if the Volume Boot Record for a Windows partition is, uh, corrupted.)

menuentry "Windows 7 (bootmgr on /dev/sda1)" --class windows --class os {
    insmod part_msdos
    insmod ntfs
    insmod ntldr
    set root='(hd0,msdos1)'
    search --no-floppy --fs-uuid --set=root 1EA0019AA0017A13
    ntldr ($root)/bootmgr
}

Where can I learn more about how this boot directive can be used? I did not see it listed when I looked in the HTML version of the GNU GRUB manual.


Replying to ckhan's answer

Thank you very much! I had pretty much decided I would have to try digging through the source code to learn more about the GRUB ntldr command/module. But you have done a much better job than I would have.

It never would have occurred to me to look at the email archives to see what design discussions the person who wrote the code might have had. That method sounds like it could be very helpful in the future. Thanks for mentioning it.

My thoughts about GRUB ntldr support

  1. While I'm not really sure how much the distinction means, ntldr is a module, not a command. Or perhaps a dynamically loaded command if you wish.

    Following your source code link and looking at lines 152 (GRUB_MOD_INIT) and 159 (GRUB_MOD_FINI) you can see the code to load and … I'm guessing … unload the module.

    GRUB apparently implements many functions which you might think are "commands" as modules. The only difference in usage that I'm aware of is that before using a module one must ensure it has been loaded with the command insmod ntldr.

    Aside: I always wondered why GRUB does not support reboot. It turns out the command exists, but it is a module. If reboot returns unknown command, then insmod reboot allows GRUB to "remember" the reboot command.

    Aside: When and why GRUB might "unload" a module, I have no idea yet. Maybe it is the result of something similar to "garbage collection"?? I have noticed that once loaded the modules seem to persist, even after a system is powered down and rebooted. Of course, you cannot depend on that, but that appears to be how it often works in practice.

  2. It is interesting that they based ntldr on chainloader. I have not looked at the chainloader.c code. I guess it probably also does a relocating load in Intel 16-bit real mode?

    I am rather glad they did not implement ntldr as an option of chainloader. I agree with Vladimir. Whatever the similarities under the covers, the usage syntax is very different. The current approach is less kludgy.

  3. It is also interesting to see the apparent lack of enthusiasm for adding this command to GRUB. Apparently the GRUB developers thought damage to the Windows Partition Boot Record (PBR) was extremely unlikely. However, I can sketch out how to do it during an ordinary enough install.

    Start by assuming a user has Windows installed on their system. They now install Ubuntu (12.04 LTS) "alongside" Windows. At one point during the Ubuntu install they can apparently decide where they want GRUB to be installed. For reasons I cannot begin to guess at, some of them decide to install GRUB into the partition Windows is installed in.

    The install completes and they can successfully start Ubuntu. However, when they try to start Windows by selecting the entry in the GRUB menu, Windows does not start. Instead attempting to start Windows with GRUB just re-displays the GRUB menu?

    Why? Well, apparently when they elected to install GRUB into the windows partition part of what actually happened was the PBR for the Windows partition was over-written with GRUB's PBR. So chainloader +1 does not chain load a Windows bootloader, but instead re-loads GRUB.

    IMO, the safest quick way to allow a user to boot Windows in that situation is to use the GRUB's new ntldr. I wonder if this would be of interest to the developers. I expect they did not anticipate this scenario.

I wonder what bootloaders other than the Windows ones, ntldr and bootmgr, the GRUB ntldr command might be able to load?

Best Answer

Researching the undocumented feature

You're right the ntldr command (it is command, not module) is not documented. So it's a great excuse for some adventures in code archaeology.

Whenever I find an undocumented feature, first thing to do is check sources.

  • The source at the Savannah git repo shows that it was merged into the main line in August 2010.

  • The source branch seems no more, but you can still see it came into existence earlier that year, in April 2010. The checkin comment, from "Vladimir 'phcoder' Serbinenko" was

    ntldr support. (based on information from nyu but no code from him)
    

It's based very closely on the chainloader command, so much so that the file name in the header comment still hasn't been updated.

Now that we have an exact checkin, and a name, we can check mailing archives. You can see where the developers had the discussing about adding this feature a year earlier on the grub-devel mailing list:

Some relevant excerpts from that thread:

Robert Millan This patch implements a loader for NTLDR boot semantics (which are the same in BootMGR, hence both are supported)

Robert Millan If we want this feature at all, I think it should be an option in the chainloader rather than a standalone command. It's almost the same as the chainloader really, the only difference is that ntldr is load after PBR by GRUB instead of by PBR itself.

Vladimir Serbinenko I don't think it's of any problem since ntldr uses this PBR only as superblock to identify the partition. As such I would rather consider this loading as a special case of passing $root, just the form of it is a bit weird

Yves Blusseau About the command, i think that it will be simpler for the user if we have only one command: chainloader (like in grub4dos) that will try to detect the type of the bootloader. This is only my personal opinion.

Vladimir Serbinenko I don't agree with this. chainloader and ntldr don't share the same syntax: chainloader expects a bootsector whereas ntldr expects an ntldr ot bootmgr file. GRUB2 is done to break with bad design decisions of GRUB1 one of them being "kernel" command. GRUB4DOS follows GRUB1 on this subject.

Robert Millan Alright. Let's make it a separate command. I think it should still share code with chainloader.c though (with some ifdefs).

Answering your question

After poring over all that, what do we know about how it can be used?

  • It's based on chainloader.

  • It takes a single argument: the file to open.

  • It avoids the partition boot record: so it can bypass corruption there. See this post detailing how they tested that.

  • It's only about 160 lines of code, you can see there's not much else there.

Hope this was useful!

Related Question