From Syslinux Wiki
Revision as of 20:29, 28 November 2014 by Ady (talk | contribs) (Note as outdated.)

Jump to: navigation, search

This document is partially outdated. Please see MEMDISK.
The content of doc/memdisk.txt (release 3.72):

(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.

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[**]

   # 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.

   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

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

  pause        Wait for a keypress right before booting

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

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

        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