by H. Peter Anvin

[ home | wiki | SYSLINUX | PXELINUX | ISOLINUX | EXTLINUX | MEMDISK | screen shots | development ]
[ download | common problems | hardware compatibility | comboot api | changelog | contact | helping me fund my Linux habit ]

{ MEMDISK documentation }

[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

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.

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 one of the following sizes, it's assumed to be a
   floppy image:

     368,640 bytes -  360K floppy
     737,280 bytes -  720K floppy
   1,222,800 bytes - 1200K floppy
   1,474,560 bytes - 1440K floppy
   1,720,320 bytes - 1680K floppy (common extended format)
   1,763,328 bytes - 1722K floppy (common extended format)
   2,949,120 bytes - 2880K floppy
   3,932,160 bytes - 3840K floppy (extended format)

   For any other size, the image 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[**]

   # 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

   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.

   safeint	Use INT 15h access to protected memory, but invoke
		INT 15h the way it was *before* MEMDISK was loaded.

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

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:

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

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, or, for a detailed description.

The MEMDISK info structure currently contains:

	[ES:DI]		word	Total size of structure (currently 28 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

MEMDISK 3.00 and higher has the size of this structure as 27; earlier
versions had size 26 and did not include the boot loader ID.

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):

	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

	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