[syslinux] unload memdisk+FreeDOS => local boot

Miguel mth at mth.com
Fri Mar 10 15:30:23 PST 2006


Sensei H. Peter Anvin,

I have successfully modified/enhanced memdisk so that one can chainload a
local operating system after running diskless FreeDOS.

I would like your advice regarding the appropriate interface for invoking
this functionality.

In addition, I would like to know what steps to take so that you feel
comfortable considering including this in the standard syslinux
distribution.

Detail
======

In searching the mailing list archives I see that there were questions
about this a couple of times over the past few years. In one of the
replies you said that parts of it would not be too difficult, but that you
hadn't had the time to get around to it.

I have spent the past few days making enhancements to memdisk that allow
one to unload diskless memdisk+FreeDOS and boot from a local boot device.

Another way to look at it is that it chain-loads from diskless FreeDOS to
a local boot device.

The phases are:

1. pxelinux -> memdisk -> FreeDOS
2. Run an arbitrary set of FreeDOS commands, optionally using UNDI
3. Boot from a local device.

I have the code up and running, and it seems to be robust.

I have tested in on VMware machines as well as actual hardware, with final
'target' operating systems of Linux (via grub), WinXP, and MS-DOS 6.22. In
addition to chain booting to the local hard drive, I have also
chain-booted to a local floppy drive.


Overall approach
================

The syslinux-3.11 distribution of memdisk.doc includes a sample mechanism
for 'disabling' memdisk. I decided to go for a slightly more radical
approach ...

As you know, DOS hooks a number of interrupt vectors. I decided to save
the first 128 interrupt vectors before DOS runs. The memdisk 'TSR' can
then restore those vectors later, along with fields from the BIOS Data
Area. This effectively restores the machine to its previous state and
allows one to boot from local media.



additions to memdisk/setup.c
----------------------------
I added 4 data fields to the patch_area struct that is set up for the
memdisk TSR.

1. the BIOS_EQUIP word from the BIOS Data Area

2. the BIOS_HD_COUNT byte from the BIOS Data Area

3. a copy of the first 128 interrupt vectors (0-7Fh)

4. a checksum on the upper 128 interrupt vectors (80h-FFh) to validate
that they are unchanged when we later execute our *restore* procedure.

The BIOS_EQUIP and BIOS_HD_COUNT values are saved because one of them is
modified as part of the memdisk installation.

My testing shows that the highest interrupt vector that is being used is
77h ... for IDE disk handling. Hence my decisios to save up through 7Fh



additions to memdisk/memdisk.asm
--------------------------------
I added code to memdisk which essentially says:
  unload-memdisk-and-boot-the-MBR-from-the-specified-drive

The temporary interface is:
 AH = 60h
 AL = drive number to boot ... AFTER memdisk is removed
 DL = memdisk drive number
 int 13h

The restore-and-boot sequence is as follows:

1. validate the checksum on the upper 128 interrupt vectors

2. read the MBR boot sector from the specified device int 0:7C00h

3. restore the lower 128 interrupt vectors

4. restore BIOS_EQUIP and BIOS_HD_COUNT

5. jump to 0:7C00h



Questions
---------

I chose 60h because Ralf Brown's interrupt list
(http://www.ctyme.com/rbrown.htm) did not indicate that it was being used
for anything else.

I also thought about overloading the 'reset' command using the extended
registers in a style similar to your MEMDISK? installation check.

Q: What kind of entry mechanism do you recommend?


Storing the lower 128 interrupt vectors requires 512 bytes. I am currently
storing that in low memory as part of the parameter table. I considered
moving it to upper memory, but that is code that I am not familiar with
... so it was easer to leave it in base memory. In addition, it was not
clear to me whether or not that would actually have any impact on memory
consumption since things get rounded to 1K boundaries.

Q: Do you think that it is OK to leave the 512 bytes in base memory?


The BIOS Boot Specification says that int18h can be used to continue the
boot process using the boot order specfied in the BIOS settings. I was
unable to get this to work after a 'restore'. Presumably something got
corrupted. For my purposes, booting from a specified device meets my
needs.


Finally, I would like for you to consider including this in the standard
syslinx distribution.

Q: What other design information would you like?

Q: What additional testing do you want done?

Q: Should I send you patches to syslinux-3.11? Or is there a later
development version? Or do you prefer another mechanism?

Q: Anything else?



Thank you very much for all of your contributions to open source software.


Miguel




More information about the Syslinux mailing list