[filedisk] Support hot-swapping to another file
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sat, 12 Jun 2010 23:39:51 +0000 (19:39 -0400)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sun, 13 Jun 2010 02:51:31 +0000 (22:51 -0400)
commitb5e739e19a7133145ada945535d6b7a334b150ad
treec76103d21331bdaf68e6b08751ece1d374b8d3a7
parentde7d3843d11713ce9dbb35f2af62a6b4b5073e93
[filedisk] Support hot-swapping to another file

We can currently boot from a GRUB4DOS sector-mapped disk.
GRUB4DOS has the requirement that the sector range be
contiguous (a contiguous file will do).  In a filesystem,
things like defragmentation or other physical movement of
the image file is possible, which would likely spell
disaster if we continued to simply use the range of
sectors on the backing disk.

It is therefore a good idea to use the image file as soon
as possible, rather than the disk.  This commit introduces
the ability to hot-swap to the file pretty early on.  A
file lock is then had, and the backing filesystem and the
image file are protected from being pulled out from
underneath us.

Since GRUB4DOS doesn't pass the filename used (there might
not even be one; it could honestly just be a sector range),
we improvise a means by which filenames can be associated:

  #!GRUB4DOS MENU.LST
  title Boot disk image file
    # Establish a buffer for passing filenames
    map --rd-size=2048
    map --mem (rd)+4 (0x55)
    # Establish the sector-mapped disk
    root (hd0,0)
    map /WinXP.HDD (hd0)
    # Seal the INT 0x13 hook
    map --hook
    # Pass info via the buffer
    write (0x55) #!GRUB4DOS\x00v=1\x00WinXP.HDD\x00\x80\x00
    # Mount the FS in the disk image file and boot NTLDR
    root (hd0,0)
    chainloader /ntldr

In the above, (rd) is a built-in "disk" with a base and a
size.  By default, the base is at memory address 0.  We
adjust the size to be 2048 bytes.  We then use map --mem
to establish a RAM disk (which we are simply abusing as
a buffer) by copying 4 sectors, 512 bytes each, from (rd).
map --mem RAM disks are marked-up in the INT 0x15, AX=0xE820
memory map, so should be protected against accidental
corruption.  After establishing the sector-mapped disk,
we use the write command to put our parameters in the
buffer.  We put

a signature:

  #!GRUB4DOS\x00

a version:

  v=1\x00

a filename:

  WinXP.HDD\x00

the associated drive number (hd0 == 0x80, etc.):

  \x80

the next filename is an ASCII NUL, meaning no more files:

  \x00

The signature was chosen while keeping a particular future
possibility in mind: Passing menu.lst itself as the phony
RAM disk.  All of the path and disk information is in this
file, which makes it fairly convenient.  It would mean
needing to be able to distinguish the menu choice as well
as a extensive parsing system, but it's not impossible.
src/include/filedisk.h
src/winvblock/filedisk/filedisk.c
src/winvblock/filedisk/grub4dos.c