See my answer on your boot-from-ISO-files question. Using that as a starting point, I ran some tests with an old hard-drive. I've previously configured Grub2 to boot a multi-ISO flash drive, so what I did was:
Create a couple of partitions on an old hard drive. This was done using a USB-to-IDE adapter, so the drive appears as /dev/sdb.
- Partition 1: FAT32, ~2GB in size
- Partition 2: unformatted
Mounted the first partition to /mnt and installed a copy of Grub from my system onto the drive:
sudo grub-install --no-floppy --root-directory=/mnt /dev/sdb
"Burned" an ISO to the second partition:
sudo dd if=avg.iso /dev/sdb2
This is an AVG virus-scanner ISO; on my multi-ISO flash drive, I use this to boot the ISO directly:
menuentry "AVG Rescue CD" {
loopback loop /iso/avg.iso
linux (loop)/isolinux/vmlinuz max_loop=255 vga=791 init=linuxrc iso-scan/filename=/iso/avg.iso
initrd (loop)/isolinux/initrd.lzm
}
In order to make this work from a hard drive partition, we need to nix the loopback command and set the root device and such. My attempts to have Grub2 discover the root device automagically all failed, so I pointed it at the partition directly. This works, but watch out for Grub's device enumeration; the drive you're trying to boot from may not be (hd0). Here's a working entry for the ISO partition:
menuentry "AVG Rescue CD" {
linux (hd0,2)/isolinux/vmlinuz max_loop=255 vga=791 init=linuxrc
initrd (hd0,2)/isolinux/initrd.lzm
}
This results in a bootable ISO-on-partition.
This works because Grub2 can read ISO9660 filesystems, because this particular ISO is loading an OS that can cope with an ISO on a partition, and because practically everything the kernel loads is in the initrd.
If you're using Grub4DOS or Grub 1, you may be able to pull a similar trick with the chainloader. Presuming that this works to boot the Win7 ISO directly (source):
title Windows 7
map (hd0,0)/win7.iso (hd32)
map --hook
chainloader (hd32)
You may have luck with this modification (assuming you "burned" the ISO to the second primary partition, (hd0,1); otherwise substitute the proper partition):
title Windows 7
map (hd0,1) (hd32)
map --hook
chainloader (hd32)
You may also get away with this:
title Windows 7
chainloader (hd0,1)
However, the ISO isn't really configured to boot from a drive, so you may run into other problems.
Since I figured this out yesterday I may as well point the answer.
To go from GRUB2 to another MBR you need to do the following
menuentry "Other Disk" {
insmod part_msdos
set root='(hd1)'
drivemap -s hd0 hd1
chainloader (hd1)+1
}
That is booting my GRUB2 into GRUB managed by OpenSUSE. hd1 could be swapped for any other drive or partition. The drivemap is needed so the other GRUB will find the partitions on hd1 it needs, since the other GRUB (1) will treat the other disk as hd0. To boot off a partition you would change (hd1) to (hd1,2) or whatever partition you want, note the drivemap would omit the partition.
GRUB2 -> GRUB2 should be the same way, though I don't have an install to test this. The config file might work for GRUB2->GRUB2, but I didn't test that either since I'm going form GRUB2 -> GRUB
Best Answer
This is with grub-pc version 1.98+20100804-5ubuntu3 (Maverick Meerkat).
The grub2 installer can install to loopback devices, but if you mount using the device mapper it will get confused and believe that you have an LVM scheme, failing mysteriously with a complaint about a missing abstraction.
Instead, you should setup the loopback device for the partition yourself, with a name that must match the pattern "/dev/loop[0-9]", i.e. without any partition designator at the end:
(Note that if you want grub-mkconfig/update-grub to operate on this volume, then the partition loopback must be connected to the disk loopback under /dev, and not directly to the image file).
Since you used fdisk to partition the image, you have an msdos-style partition table (aka label), and boot using a BIOS. In addition to putting the stage1/boot.img in the MBR, the stage1.5/core.img will be put in an embedding area in unpartitioned space (!) following right after, and there must be space for this.
The trick is now to tell the grub2 installer through a device map how your loopback setup will map to BIOS drives in the virtual machine. (In grub1 legacy this was done directly in the shell). You are probably planning to boot this image as the first disk, so I guess the appropriate mapping would be:
Here I have put the device map inside the guest disk image, so that you can generate the boot configuration file grub.cfg:
(Beware that the post-installer of the grub-pc package will run a probe that overwrites the device map(!), so you'll have to write it after installation and run grub-mkconfig/update-grub yourself).
Now run the installer from the host, pointing to the guest installation:
Finally, unmount everything set up here before starting qemu on your image: