[This documentation is rather crufty at the moment.]

MEMDISK is meant to allow booting legacy operating systems via PXE,
and as a workaround for BIOSes where ISOLINUX image support doesn't
work.

MEMDISK simulates a disk by claiming a chunk of high memory for the
disk and a (very small - 2K typical) chunk of low (DOS) memory for the
driver itself, then hooking the INT 13h (disk driver) and INT 15h
(memory query) BIOS interrupts.

MEMDISK allows for an OS to detect the MEMDISK instance.  (See the
"Additional technical information" section below.)

To use it, type on the Syslinux command line:

memdisk initrd=diskimg.img

... where diskimg.img is the disk image you want to boot from.

[Obviously, the memdisk binary as well as your disk image file need to
be present in the boot image directory.]

... or add to your syslinux.cfg/pxelinux.cfg/isolinux.cfg something like:

label dos
    kernel memdisk
    append initrd=dosboot.img

Note the following:

a) The disk image can be uncompressed or compressed with gzip or zip.

b) If the disk image is less than 4,194,304 bytes (4096K, 4 MB) it is
   assumed to be a floppy image and MEMDISK will try to guess its
   geometry based on the size of the file.  MEMDISK recognizes all the
   standard floppy sizes as well as common extended formats:

     163,840 bytes  (160K) c=40 h=1 s=8		5.25" SSSD
     184,320 bytes  (180K) c=40 h=1 s=9		5.25" SSSD
     327,680 bytes  (320K) c=40 h=2 s=8		5.25" DSDD
     368,640 bytes  (360K) c=40 h=2 s=9		5.25" DSDD
     655,360 bytes  (640K) c=80 h=2 s=8		3.5"  DSDD
     737,280 bytes  (720K) c=80 h=2 s=9		3.5"  DSDD
   1,222,800 bytes (1200K) c=80 h=2 s=15	5.25" DSHD
   1,474,560 bytes (1440K) c=80 h=2 s=18	3.5"  DSHD
   1,638,400 bytes (1600K) c=80 h=2 s=20	3.5"  DSHD (extended)
   1,720,320 bytes (1680K) c=80 h=2 s=21	3.5"  DSHD (extended)
   1,763,328 bytes (1722K) c=82 h=2 s=21	3.5"  DSHD (extended)
   1,784,832 bytes (1743K) c=83 h=2 s=21	3.5"  DSHD (extended)
   1,802,240 bytes (1760K) c=80 h=2 s=22	3.5"  DSHD (extended)
   1,884,160 bytes (1840K) c=80 h=2 s=23	3.5"  DSHD (extended)
   1,966,080 bytes (1920K) c=80 h=2 s=24	3.5"  DSHD (extended)
   2,949,120 bytes (2880K) c=80 h=2 s=36	3.5"  DSED
   3,194,880 bytes (3120K) c=80 h=2 s=39	3.5"  DSED (extended)
   3,276,800 bytes (3200K) c=80 h=2 s=40	3.5"  DSED (extended)
   3,604,480 bytes (3520K) c=80 h=2 s=44	3.5"  DSED (extended)
   3,932,160 bytes (3840K) c=80 h=2 s=48	3.5"  DSED (extended)

   A small perl script is included in the MEMDISK directory which can
   determine the geometry that MEMDISK would select for other sizes;
   in general MEMDISK will correctly detect most physical extended
   formats used, with 80 cylinders or slightly more.

   If the image is 4 MB or larger, it is assumed to be a hard disk
   image, and should typically have an MBR and a partition table.  It
   may optionally have a DOSEMU geometry header; in which case the
   header is used to determine the C/H/S geometry of the disk.
   Otherwise, the geometry is determined by examining the partition
   table, so the entire image should be partitioned for proper
   operation (it may be divided between multiple partitions, however.)

   You can also specify the geometry manually with the following command
   line options:

   c=#		Specify number of cylinders (max 1024[*])
   h=#		Specify number of heads (max 256[*])
   s=#		Specify number of sectors (max 63)
   floppy[=#]	The image is a floppy image[**]
   harddisk[=#]	The image is a hard disk image[**]
   iso		The image is an El Torito ISO9660 image (drive 0xE0)

   # represents a decimal number.

    [*] MS-DOS only allows max 255 heads, and only allows 255 cylinders
        on floppy disks.

   [**] Normally MEMDISK emulates the first floppy or hard disk.  This
        can be overridden by specifying an index, e.g. floppy=1 will
        simulate fd1 (B:). This may not work on all operating systems
        or BIOSes.

c) The disk is normally writable (although, of course, there is
   nothing backing it up, so it only lasts until reset.)  If you want,
   you can mimic a write-protected disk by specifying the command line
   option:

   ro		Disk is readonly

d) MEMDISK normally uses the BIOS "INT 15h mover" API to access high
   memory.  This is well-behaved with extended memory managers which load
   later.  Unfortunately it appears that the "DOS boot disk" from
   WinME/XP *deliberately* crash the system when this API is invoked.
   The following command-line options tells MEMDISK to enter protected
   mode directly, whenever possible:

   raw		Use raw access to protected mode memory.

   bigraw	Use raw access to protected mode memory, and leave the
		CPU in "big real" mode afterwards.

   int		Use plain INT 15h access to protected memory.  This assumes
   		that anything which hooks INT 15h knows what it is doing.

   safeint	Use INT 15h access to protected memory, but invoke
		INT 15h the way it was *before* MEMDISK was loaded.
		This is the default since version 3.73.

e) MEMDISK by default supports EDD/EBIOS on hard disks, but not on
   floppy disks.  This can be controlled with the options:

   edd		Enable EDD/EBIOS
   noedd	Disable EDD/EBIOS

f) The following option can be used to pause to view the messages:

   pause	Wait for a keypress right before booting

g) The following option can be used to set the real-mode stack size.
   The default is 512 bytes, but if there is a failure it might be
   interesting to set it to something larger:

   stack=size   Set the stack to "size" bytes


Some interesting things to note:

If you're using MEMDISK to boot DOS from a CD-ROM (using ISOLINUX),
you might find the generic El Torito CD-ROM driver by Gary Tong and
Bart Lagerweij useful:

	http://www.nu2.nu/eltorito/


Similarly, if you're booting DOS over the network using PXELINUX, you
can use the "keeppxe" option and use the generic PXE (UNDI) NDIS
network driver, which is part of the PROBOOT.EXE distribution from
Intel:

	http://www.intel.com/support/network/adapter/1000/software.htm


Additional technical information:

Starting with version 2.08, MEMDISK now supports an installation check
API.  This works as follows:

	EAX = 454D08xxh ("ME") (08h = parameter query)
	ECX = 444Dxxxxh ("MD")
	EDX = 5349xxnnh	("IS") (nn = drive #)
	EBX = 3F4Bxxxxh ("K?")
	INT 13h

If drive nn is a MEMDISK, the registers will contain:

	EAX = 4D21xxxxh	("!M")
	ECX = 4D45xxxxh ("EM")
	EDX = 4944xxxxh ("DI")
	EBX = 4B53xxxxh ("SK")

	ES:DI -> MEMDISK info structures

The low parts of EAX/ECX/EDX/EBX have the normal return values for INT
13h, AH=08h, i.e. information of the disk geometry etc.

See Ralf Brown's interrupt list,
http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html or
http://www.ctyme.com/rbrown.htm, for a detailed description.

The MEMDISK info structure currently contains:

	[ES:DI]		word	Total size of structure (currently 30 bytes)
	[ES:DI+2]	byte	MEMDISK minor version
	[ES:DI+3]	byte	MEMDISK major version
	[ES:DI+4]	dword	Pointer to MEMDISK data in high memory
	[ES:DI+8]	dword	Size of MEMDISK data in 512-byte sectors
	[ES:DI+12]	16:16	Far pointer to command line
	[ES:DI+16]	16:16	Old INT 13h pointer
	[ES:DI+20]	16:16	Old INT 15h pointer
	[ES:DI+24]	word	Amount of DOS memory before MEMDISK loaded
	[ES:DI+26]	byte	Boot loader ID
	[ES:DI+27]	byte	Currently unused
	[ES:DI+28]	word	If nonzero, offset (vs ES) to installed DPT
				This pointer+16 contains the original INT 1Eh

Sizes of this structure:

3.71+		30 bytes	Added DPT pointer
3.00-3.70	27 bytes	Added boot loader ID
pre-3.00	26 bytes

In addition, the following fields are available at [ES:0]:

	[ES:0]		word	Offset of INT 13h routine (segment == ES)
	[ES:2]		word	Offset of INT 15h routine (segment == ES)

The program mdiskchk.c in the sample directory is an example on how
this API can be used.

The following code can be used to "disable" MEMDISK.  Note that it
does not free the handler in DOS memory, and that running this from
DOS will probably crash your machine (DOS doesn't like drives suddenly
disappearing from underneath.)  This is also not necessarily the best
method for this.

	mov eax, 454D0800h
	mov ecx, 444D0000h
	mov edx, 53490000h
	mov dl,drive_number
	mov ebx, 3F4B0000h
	int 13h

	shr eax, 16
	cmp ax, 4D21h
	jne not_memdisk
	shr ecx, 16
	cmp cx, 4D45h
	jne not_memdisk
	shr edx, 16
	cmp dx, 4944h
	jne not_memdisk
	shr ebx, 16
	cmp bx, 4B53h
	jne not_memdisk

	cli
	mov bx,[es:0]		; INT 13h handler offset
	mov eax,[es:di+16]	; Old INT 13h handler
	mov byte [es:bx], 0EAh	; FAR JMP
	mov [es:bx+1], eax

	mov bx,[es:2]		; INT 15h handler offset
	mov eax,[es:di+20]	; Old INT 15h handler
	mov byte [es:bx], 0EAh	; FAR JMP
	mov [es:bx+1], eax
	sti

MEMDISK supports the Win9x "safe hook" structure for OS detection.
(See "Safe Master Boot Record INT 13h Hook Routines," available at
http://www.osronline.com/ddkx/w98ddk/storage_5l6g.htm as of
December 7th, 2009.)  An OS driver can take a look at the INTerrupt table
and try to walk along the chain of those hooks that implement the "safe hook"
structure.  For each hook discovered, a vendor can be identified and the OS
driver can take appropriate action.  The OS driver can mark the "flags" field
of the "safe hook" to indicate that the driver has reviewed it already.  This
prevents accidental re-detection, for example.

MEMDISK adds one additional extension field to the "safe hook" structure, a
pointer to a special MEMDISK structure called the "mBFT."  The mBFT is the
"MEMDISK Boot Firmware Table" (akin to the iSCSI iBFT and the AoE aBFT).  An
OS driver looking at MEMDISK's "safe hook" should know that this field will
be present based on the fact that MEMDISK is the vendor identifier.

The mBFT is little more than an ACPI table to prefix MEMDISK's traditional
MEMDISK info structure (the "MDI").  The ACPI table's details are:

  OEM ID. . . .: MEMDSK
  OEM Table ID : Syslinux

There is a 1-byte checksum field which covers the length of the mBFT all
the way through to the end of the MEMDISK info structure.

There is also a physical pointer to the "safe hook" structure associated
with the MEMDISK instance.  An OS driver might use the following logic:

  1. Walk INT 13h "safe hook" chain as far as possible, marking hooks as
     having been reviewed.  For MEMDISK hooks, the driver then follows the
     pointer to the mBFT and gathers the RAM disk details from the included
     MDI.
  2. The OS driver scans low memory for valid mBFTs.  MEMDISK instances that
     have been "disconnected" from the INT 13h "safe hook" chain can be thus
     discovered.  Looking at their associated "safe hook" structure will
     reveal if they were indeed reviewed by the previous stage.
