Difference between revisions of "Doc/memdisk"

From Syslinux Wiki
Jump to: navigation, search
(The content of doc/memdisk.txt (release 3.72):)
 
m (Wiki formatting.)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Release Documentation]][[Category:MEMDISK]]
+
[[Category:Release Documentation]]
''The content of doc/memdisk.txt (release 3.72):''
+
[[Category:MEMDISK]]
 +
'''This document is partially outdated. Please see [[MEMDISK]].'''<br />
 +
''The content of doc/memdisk.txt (<!--release -->6.04-pre1, with minor modifications):''
  
  
 
''(This documentation is rather crufty at the moment.)''
 
''(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 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 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&nbsp;13h (disk driver) and INT&nbsp;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:
 
To use it, type on the SYSLINUX command line:
<pre>
 
memdisk initrd=diskimg.img
 
</pre>
 
... where <tt>diskimg.img</tt> 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.)
+
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 <tt>syslinux.cfg/pxelinux.cfg/isolinux.cfg</tt> something like:
 
... or add to your <tt>syslinux.cfg/pxelinux.cfg/isolinux.cfg</tt> something like:
<pre>
 
label dos
 
    kernel memdisk
 
    append initrd=dosboot.img
 
</pre>
 
  
 +
label dos
 +
  kernel memdisk
 +
  append initrd=dosboot.img
 +
 +
<br />
 +
===== <span style="visibility: hidden; ">Notes</span> =====
 
Note the following:
 
Note the following:
  
'''a)''' The disk image can be uncompressed or compressed with gzip or zip.
+
====== <span style="visibility: hidden; ">Note a</span> ======
 +
{{H6|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:
+
====== <span style="visibility: hidden; ">Note b</span> ======
 +
{{H6|b) }}
 +
If the disk image is less than 4,194,304 bytes (4096K, 4 MiB) 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
+
  163,840 bytes  (160K) c=40 h=1 s=8   5.25" SSSD
    368,640 bytes  (360K) c=40 h=2 s=9         5.25" DSDD
+
  184,320 bytes  (180K) c=40 h=1 s=9   5.25" SSSD
    655,360 bytes  (640K) c=80 h=2 s=8         3.5"  DSDD
+
  327,680 bytes  (320K) c=40 h=2 s=8   5.25" DSDD
    737,280 bytes  (720K) c=80 h=2 s=9         3.5"  DSDD
+
  368,640 bytes  (360K) c=40 h=2 s=9   5.25" DSDD
  1,222,800 bytes (1200K) c=80 h=2 s=15       5.25" DSHD
+
  655,360 bytes  (640K) c=80 h=2 s=8   3.5"  DSDD
  1,474,560 bytes (1440K) c=80 h=2 s=18       3.5"  DSHD
+
  737,280 bytes  (720K) c=80 h=2 s=9   3.5"  DSDD
  1,638,400 bytes (1600K) c=80 h=2 s=20       3.5"  DSHD (extended)
+
1,222,800 bytes (1200K) c=80 h=2 s=15   5.25" DSHD
  1,720,320 bytes (1680K) c=80 h=2 s=21       3.5"  DSHD (extended)
+
1,474,560 bytes (1440K) c=80 h=2 s=18   3.5"  DSHD
  1,763,328 bytes (1722K) c=82 h=2 s=21       3.5"  DSHD (extended)
+
1,638,400 bytes (1600K) c=80 h=2 s=20   3.5"  DSHD (extended)
  1,784,832 bytes (1743K) c=83 h=2 s=21       3.5"  DSHD (extended)
+
1,720,320 bytes (1680K) c=80 h=2 s=21   3.5"  DSHD (extended)
  1,802,240 bytes (1760K) c=80 h=2 s=22       3.5"  DSHD (extended)
+
1,763,328 bytes (1722K) c=82 h=2 s=21   3.5"  DSHD (extended)
  1,884,160 bytes (1840K) c=80 h=2 s=23       3.5"  DSHD (extended)
+
1,784,832 bytes (1743K) c=83 h=2 s=21   3.5"  DSHD (extended)
  1,966,080 bytes (1920K) c=80 h=2 s=24       3.5"  DSHD (extended)
+
1,802,240 bytes (1760K) c=80 h=2 s=22   3.5"  DSHD (extended)
  2,949,120 bytes (2880K) c=80 h=2 s=36       3.5"  DSED
+
1,884,160 bytes (1840K) c=80 h=2 s=23   3.5"  DSHD (extended)
  3,194,880 bytes (3120K) c=80 h=2 s=39       3.5"  DSED (extended)
+
1,966,080 bytes (1920K) c=80 h=2 s=24   3.5"  DSHD (extended)
  3,276,800 bytes (3200K) c=80 h=2 s=40       3.5"  DSED (extended)
+
2,949,120 bytes (2880K) c=80 h=2 s=36   3.5"  DSED
  3,604,480 bytes (3520K) c=80 h=2 s=44       3.5"  DSED (extended)
+
3,194,880 bytes (3120K) c=80 h=2 s=39   3.5"  DSED (extended)
  3,932,160 bytes (3840K) c=80 h=2 s=48       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.
+
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.)
+
If the image is 4 MiB 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 {{nowrap|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:
+
You can also specify the geometry manually with the following command  
<pre>
+
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.
+
{|
</pre>
+
|
(*) MS-DOS only allows max 255 heads, and only allows 255 cylinders on floppy disks.<br/>
+
c=#          Specify number of cylinders (max 1024[*])
(**) Normally MEMDISK emulates the first floppy or hard disk.  This can be overridden by specifying an index, e.g. <tt>floppy=1</tt> will simulate fd1 (B:). This may not work on all operating systems or BIOSes.
+
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. <tt>floppy=1</tt> 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
+
====== <span style="visibility: hidden; ">Note c</span> ======
 +
{{H6|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:
  
'''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 <u>''deliberately''</u> crash the system when this API is invoked. The following command-line options tells MEMDISK to enter protected mode directly, whenever possible:
+
  ro          Disk is readonly
<pre>
+
  raw          Use raw access to protected mode memory.
+
  
  bigraw      Use raw access to protected mode memory, and leave the
+
====== <span style="visibility: hidden; ">Note d</span> ======
                CPU in "big real" mode afterwards.
+
{{H6|d) }}
 +
MEMDISK normally uses the BIOS "INT&nbsp;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 <u>''deliberately''</u> crash the system when this API is invoked.  
 +
The following command-line options tells MEMDISK to enter protected
 +
mode directly, whenever possible:
  
  safeint      Use INT 15h access to protected memory, but invoke
+
{|
                INT 15h the way it was *before* MEMDISK was loaded.
+
|
</pre>
+
raw          Use raw access to protected mode memory.
'''e)''' MEMDISK by default supports EDD/EBIOS on hard disks, but not on floppy disks.  This can be controlled with the options:
+
 +
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.
 +
|}
  
  edd          Enable EDD/EBIOS
+
====== <span style="visibility: hidden; ">Note e</span> ======
  noedd        Disable EDD/EBIOS
+
{{H6|e) }}
 +
MEMDISK by default supports EDD/EBIOS on hard disks, but not on
 +
floppy disks.  This can be controlled with the options:
  
'''f)''' The following option can be used to pause to view the messages:
+
edd          Enable EDD/EBIOS
 +
noedd        Disable EDD/EBIOS
  
  pause       Wait for a keypress right before booting
+
====== <span style="visibility: hidden; ">Note f</span> ======
 +
{{H6|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:=
+
====== <span style="visibility: hidden; ">Note g</span> ======
 +
{{H6|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:
  
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:
+
{|
 +
|
 +
stack=''size''  Set the stack to "''size''" bytes
 +
|}
  
http://www.nu2.nu/eltorito/
+
====== <span style="visibility: hidden; ">Note h</span> ======
 +
{{H6|h) }}
 +
Some systems without a floppy drive have been known to have
 +
problems with floppy images. To avoid those problems, first
 +
of all make sure you don't have a floppy drive configured on the
 +
BIOS screen. If there is no option to configure that, or that
 +
doesn't work, you can use the option:
  
 +
{|
 +
|
 +
nopass      Hide all real drives of the same type (floppy or hard disk)
 +
nopassany    Hide all real drives (floppy and hard disk)
 +
|}
  
Similarly, if you're booting DOS over the network using PXELINUX, you can use the "<tt>keeppxe</tt>" option and use the generic PXE (UNDI) NDIS network driver, which is part of the PROBOOT.EXE distribution from Intel:
+
====== <span style="visibility: hidden; ">Note i</span> ======
 +
{{H6|i) }}
 +
The following standard Linux option will mark memory as reserved.
 +
Please note that the Syslinux core already loads MEMDISK and its
 +
initrd below this point:
  
http://www.intel.com/support/network/adapter/1000/software.htm
+
{|
 +
|
 +
mem=''size''    Mark available memory above this point as Reserved.
 +
|}
  
 +
<br />
 +
===== <span style="visibility: hidden; ">Some interesting things to note</span> =====
 +
<div style="color: black; background: none; margin: 0; padding-top: .5em; padding-bottom: .17em; border-bottom: none; font-weight: bold; font-size: 100%; ">Some interesting things to note:</div>
  
=Additional technical information:=
+
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
 +
<sup><small><small>&nbsp;[https://web.archive.org/web/20151105192131/http://www.nu2.nu/eltorito/]&nbsp;</small></small></sup>. 
 +
It is now included with the Syslinux
 +
distribution, in the dosutil directory.  See the file
 +
{{nowrap|<tt>dosutil/eltorito.txt</tt>}} for more information.
  
Starting with version 2.08, MEMDISK now supports an installation check API. This works as follows:
+
Similarly, if you're booting DOS over the network using PXELINUX, you
 +
can use the "<tt>keeppxe</tt>" option and use the generic PXE (UNDI) NDIS
 +
network driver, which is part of the PROBOOT.EXE<sup><small>&nbsp;[BootUtil]&nbsp;</small></sup> distribution from
 +
Intel:
  
        EAX = 454D08xxh ("ME") (08h = parameter query)
+
[https://www.intel.com/content/www/us/en/support/articles/000005790/software/manageability-products.html http://www.intel.com/support/network/adapter/1000/software.htm]
        ECX = 444Dxxxxh ("MD")
+
        EDX = 5349xxnnh ("IS") (nn = drive #)
+
        EBX = 3F4Bxxxxh ("K?")
+
        INT 13h
+
  
If drive nn is a MEMDISK, the registers will contain:
+
<br />
<pre>
+
===== <span style="visibility: hidden; ">Additional technical information</span> =====
        EAX = 4D21xxxxh ("!M")
+
<div style="color: black; background: none; margin: 0; padding-top: .5em; padding-bottom: .17em; border-bottom: none; font-weight: bold; font-size: 100%; ">Additional technical information:</div>
        ECX = 4D45xxxxh ("EM")
+
        EDX = 4944xxxxh ("DI")
+
        EBX = 4B53xxxxh ("SK")
+
  
        ES:DI -> MEMDISK info structures
+
Starting with version 2.08, MEMDISK now supports an installation check
</pre>
+
API. This works as follows:
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.
+
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 {{nowrap|EAX/ECX/EDX/EBX}} have the normal return values for {{nowrap|1=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 http://www.ctyme.com/rbrown.htm], for a detailed description.
  
 
The MEMDISK info structure currently contains:
 
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]     word    Total size of structure (currently 30 bytes)
        [ES:DI+4]       dword  Pointer to MEMDISK data in high memory
+
[ES:DI+2]   byte    MEMDISK minor version
        [ES:DI+8]       dword  Size of MEMDISK data in 512-byte sectors
+
[ES:DI+3]   byte    MEMDISK major version
        [ES:DI+12]     16:16  Far pointer to command line
+
[ES:DI+4]   dword  Pointer to MEMDISK data in high memory
        [ES:DI+16]     16:16  Old INT 13h pointer
+
[ES:DI+8]   dword  Size of MEMDISK data in sectors
        [ES:DI+20]     16:16  Old INT 15h pointer
+
[ES:DI+12]   16:16  Far pointer to command line
        [ES:DI+24]     word    Amount of DOS memory before MEMDISK loaded
+
[ES:DI+16]   16:16  Old INT 13h pointer
        [ES:DI+26]     byte    Boot loader ID
+
[ES:DI+20]   16:16  Old INT 15h pointer
        [ES:DI+27]     byte    Currently unused
+
[ES:DI+24]   word    Amount of DOS memory before MEMDISK loaded
        [ES:DI+28]     word    If nonzero, offset (vs ES) to installed DPT
+
[ES:DI+26]   byte    Boot loader ID
                                This pointer+16 contains the original INT 1Eh
+
[ES:DI+27]   byte    Sector size as a power of 2
 +
                      (If zero, assume 512-byte sectors)
 +
[ES:DI+28]   word    If nonzero, offset (vs ES) to installed DPT
 +
                      This pointer+16 contains the original INT 1Eh
 +
|}
  
 
Sizes of this structure:
 
Sizes of this structure:
<pre>
 
3.71+          30 bytes        Added DPT pointer
 
3.00-3.70      27 bytes        Added boot loader ID
 
pre-3.00        26 bytes
 
</pre>
 
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)
+
|
 +
3.71+        30 bytes  Added DPT pointer
 +
3.00-3.70   27 bytes  Added boot loader ID
 +
pre-3.00    26 bytes
 +
|}
  
The program mdiskchk.c in the sample directory is an example on how this API can be used.
+
In addition, the following fields are available at {{nowrap|1=<tt>[ES:0]</tt>:}}
  
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.
+
{|
 +
|
 +
[ES:0]      word    Offset of INT 13h routine (segment == ES)
 +
[ES:2]      word    Offset of INT 15h routine (segment == ES)
 +
|}
 +
 
 +
The program <tt>mdiskchk.c</tt> in the <s><del><small>sample</small></del></s> <tt>dosutil</tt> directory is an example of 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.
 +
 
 +
{|
 +
|
 
<pre>
 
<pre>
        mov eax, 454D0800h
+
mov eax, 454D0800h
        mov ecx, 444D0000h
+
mov ecx, 444D0000h
        mov edx, 53490000h
+
mov edx, 53490000h
        mov dl,drive_number
+
mov dl,drive_number
        mov ebx, 3F4B0000h
+
mov ebx, 3F4B0000h
        int 13h
+
int 13h
  
        shr eax, 16
+
shr eax, 16
        cmp ax, 4D21h
+
cmp ax, 4D21h
        jne not_memdisk
+
jne not_memdisk
        shr ecx, 16
+
shr ecx, 16
        cmp cx, 4D45h
+
cmp cx, 4D45h
        jne not_memdisk
+
jne not_memdisk
        shr edx, 16
+
shr edx, 16
        cmp dx, 4944h
+
cmp dx, 4944h
        jne not_memdisk
+
jne not_memdisk
        shr ebx, 16
+
shr ebx, 16
        cmp bx, 4B53h
+
cmp bx, 4B53h
        jne not_memdisk
+
jne not_memdisk
  
        cli
+
cli
        mov bx,[es:0]          ; INT 13h handler offset
+
mov bx,[es:0]          ; INT 13h handler offset
        mov eax,[es:di+16]      ; Old INT 13h handler
+
mov eax,[es:di+16]      ; Old INT 13h handler
        mov byte [es:bx], 0EAh  ; FAR JMP
+
mov byte [es:bx], 0EAh  ; FAR JMP
        mov [es:bx+1], eax
+
mov [es:bx+1], eax
  
        mov bx,[es:2]          ; INT 15h handler offset
+
mov bx,[es:2]          ; INT 15h handler offset
        mov eax,[es:di+20]      ; Old INT 15h handler
+
mov eax,[es:di+20]      ; Old INT 15h handler
        mov byte [es:bx], 0EAh  ; FAR JMP
+
mov byte [es:bx], 0EAh  ; FAR JMP
        mov [es:bx+1], eax
+
mov [es:bx+1], eax
        sti
+
sti
 
</pre>
 
</pre>
 +
|}
 +
 +
MEMDISK supports the Win9x "safe hook" structure for OS detection
 +
(see "''Safe Master Boot Record INT&nbsp;13h Hook Routines''", <small>available at
 +
[https://web.archive.org/web/20130720040748/http://www.osronline.com/ddkx/w98ddk/storage_5l6g.htm] as of
 +
December 7th, 2009</small>).  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&nbsp;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&nbsp;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.

Latest revision as of 07:04, 29 June 2019

This document is partially outdated. Please see MEMDISK.
The content of doc/memdisk.txt (6.04-pre1, with minor modifications):


(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


Notes

Note the following:

Note a
a)

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

Note b
b)

If the disk image is less than 4,194,304 bytes (4096K, 4 MiB) 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 MiB 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.


Note c
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
Note d
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.
Note e
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
Note f
f)

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

pause        Wait for a keypress right before booting
Note g
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
Note h
h)

Some systems without a floppy drive have been known to have problems with floppy images. To avoid those problems, first of all make sure you don't have a floppy drive configured on the BIOS screen. If there is no option to configure that, or that doesn't work, you can use the option:

nopass       Hide all real drives of the same type (floppy or hard disk)
nopassany    Hide all real drives (floppy and hard disk)
Note i
i)

The following standard Linux option will mark memory as reserved. Please note that the Syslinux core already loads MEMDISK and its initrd below this point:

mem=size     Mark available memory above this point as Reserved.


Some interesting things to note
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  [1] . It is now included with the Syslinux distribution, in the dosutil directory. See the file dosutil/eltorito.txt for more information.

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 [BootUtil]  distribution from Intel:

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


Additional technical information
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 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    Sector size as a power of 2
                     (If zero, assume 512-byte sectors)
[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 dosutil directory is an example of 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 [2] 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.