RIPLing Windows Millennium Edition

Original work by Micho Durdevich

Introduction
In this article we shall talk about diskless Windows workstations that remote-boot Windows Millennium Edition from OS/2 Warp Server.

Configurations we are going to present are the most complex, yet the most powerful Windows RIPLing solutions. We achieve this by combining diverse ideas presented in the previous articles, with a new structural element: Dynamical transition from real-mode to protected mode networking, during the boot process.

Our RIPL clients start as normal DOS requesters from a virtual superfloppy [A:]. During the real-mode boot phase, they create a small RAM-drive [C:] that holds Registry and some critical Windows files. These files form what we shall call the sub-nucleus (in contrast to the nucleus configurations considered previously, the sub-nucleus alone is not enough to boot GUI).

Using ideas of this article, it is possible to set up RIPL clients that have absolutely the same functionality, and the same look and feel as the standard Windows machines. In particular, we can set up a diskless workstation that runs a standard, full-blown version of Windows Millennium from OS/2 Warp Server.

More specifically, basic characteristics of our RIPL-clients are:
 * Dynamical switch from real-mode to protected mode networking during the boot process. Full 32-bit networking working.
 * Full long file-name support.
 * At least as stable as standard Windows Millennium Edition systems. Actually, we have an increased security and stability, because of the RIPL-context.
 * Ability to play video clips, advanced audio support, games :) Virtually all applications are supported.
 * The whole HTML-engine working, including the extensive help subsystem, wizards and IE.
 * High flexibility in configuring. Possibility to introduce a local HDD for swapping. A local HDD can also hold the sub-nucleus files.
 * Universality: Ideas of this article apply also to Windows 95/98/98SE. This RIPLing method works for all types of lite Windows versions, too.

Diskless Windows 95/98/98SE configurations require much less work. Various WinME-specific steps described here are not necessary, while some other steps require trivial modifications. Therefore, I decided to illustrate everything on the most challenging case-Windows Millennium.

The article is organized as follows. The next section contains a couple of simple, but important remarks, about the server setup. The main part of the article is Section 3, that describes the boot process and the design of our RIPL requesters. In particular, it contains the sub-nucleus listing for Windows Millennium. We also explain how to get dynamical networking transition working, with the help of SNAPSHOT.EXE and SNAPSHOT.VXD.

Section 4 discusses two sample configurations (that use NETBIOS and IPX as real-mode protocols, respectively). In particular, it contains PROTOCOL.INI and mini-Registry descriptions for these configurations.

In Section 5, concluding remarks and observations are made. This includes modifying original fully diskless setup, in order to include configurations that have a local hard drive. As we already mentioned, a local HDD can be very useful as a swapping media. It can also hold the subnucleus package. It is also possible to install more Windows files locally, which enables us to fine-tune the performance of network clients.

The article ends with two appendices. The first appendix (having an independent interest) describes a very elegant procedure to enable real-mode DOS support in Windows Millennium Edition. The second appendix discusses a couple of strange properties of Windows 98SE/ME. I do not see any other purpose of these "new features" except to make it exceedingly difficult to run Windows in any non-standard environment, including our RIPL context.

After all, there is something good in the fact that Windows designers decided to introduce such puzzling obstacles. One of the best ways to learn any subject is, perhaps, by solving non-trivial problems appearing in the game.

In the spirit of this, the paper features a variety of exercises. Some of them are easy, some of them are tricky. And the solution is not always unique! Anyway, I hope that solving exercises, or just thinking about possible solutions, can help you understand better a very subtle and exciting theory of RIPLing diskless Windows workstations from OS/2 Warp Server.

Notes on Servers Involved
It is important to distinguish between three different possible roles that a server system could play in a RIPL game:

The RIPL Server: Enables a diskless system to start over a network, loading a DOS kernel and initiating the 16-bit networking.

The Operating System Server: It is where Windows files are stored. This server enables the RIPL workstation to boot into a full 32-bit Windows client.

The Applications Server: It is where all application files are stored.

The simplest setup is that a single OS/2 Warp Server machine plays all these roles. In more complex networks however, it might be a better idea to designate different server machines to perform different remote-boot-related tasks. And of course, it is possible to have several server machines, within the same group (for example, a couple of RIPL servers). This could be interesting in the situations where the network is heavily loaded by RIPL requests.

I strongly recommend that all these three principal tasks be performed by OS/2 machines (strictly speaking, you need an OS/2 server only for RIPL service, while OS/2 clients can be used to provide Windows operating system and applications). I consider OS/2 as by far the most reliable remote-boot solution.

It should be noted however, that you can easily set up things in order to use different operating systems on server machines (as Windows or UNIX).

Initial Real-Mode Boot
In this first phase, we RIPL-start a DOS requester from a virtual superfloppy of at least 8MB (the creation of such superfloppy images was described in articles 4/5).

I recommend installing two network adapters per diskless workstation, during the testing and building of the RIPL clients. The first network adapter should be dedicated to initial RIPL-processing and the second adapter should be used for M$ networking (in both real and protected modes). Once our RIPL client is working properly, we can fine-tune it and switch to a single-adapter setup easily.

The superfloppy contains the following software components:

It consists of IO.SYS, MSDOS.SYS (in the root directory) with IFSHLP.SYS (in WINDOWS folder) and VMM32.VXD=COMMAND.COM (as explained in Appendix A). Here is a possible listing of the [Paths] section of MSDOS.SYS file: WinDir=F:\WINDOWS WinBootDir=A:\WINDOWS HostWinBootDrv=F
 * Real-Mode System

It is composed from the following files: NET.EXE   NET.MSG    NETH.MSG    PROTMAN.DOS   PROTMAN.EXE   SUBST.EXE PROTOCOL.INI    SYSTEM.2    .DOS  SNAPSHOT.EXE NDISHLP.SYS Here, SYSTEM.2 is the mini-registry containing necessary information for the 16-bit networking to start. A blueprint of the mini-registry is listed in WiRIPL3. Protocol-related entries are discussed within the next section. Here, this file has a weird extension. This is because IO.SYS of WinME examines the Registry (if it finds it!) from the very beginning, and the system somehow remembers something of it. This can totally confuse the system during the GUI boot (where we switch to the full Registry). The mini-Registry is renamed to SYSTEM.DAT later, just before starting the real-mode network client.
 * Real-Mode M$ Networking

Observe also that we do not have any CONFIG.SYS file! Actually, IO.SYS of WinME is unable to load any real-mode device drivers listed in CONFIG.SYS (except IFSHLP.SYS that is loaded automatically and HIMEM.SYS that is pre-built into IO.SYS). It simply ignores the CONFIG.SYS file.

A workaround is to use the appropriate command-line utility for loading device drivers (as LDEVICE by Adlersparre & Associates, for example).

The only driver here that we would normally load from CONFIG.SYS is RAMDRIVE.SYS. The network adapter driver and NDISHLP.SYS are loaded by NET.EXE, when starting the network protocol (which by the way enables SNAPSHOT.EXE to properly capture the whole contents of the real-mode networking).

A possible solution is given by LDEVICE.EXE and RAMDRIVE.SYS!
 * Ramdrive Software

The WINDOWS folder contains all the above mentioned network & Ramdrive related files. The most important files are in subfolders SYSTEM and SYSTEM32.
 * Sub-Nucleus Files

System Subfolder CriticalFiles={kernel32.dll, user32.dll, vmm32.com, krnl386.exe, systray.exe}

Network-related={vredir.vxd, netbeui.vxd, nwlink.vxd, vnetbios.vxd}

At the protected mode level, our RIPL clients use both NETBIOS and IPX protocols, and the primary network logon is given by client for M$ networks.

KnownDLLs={nt1003.sys, advapi32.dll, netapi32.dll, msgsrv32.dll, netbios.dll, lz32.dll, lzexpand.dll, linkinfo.dll, ntdll.dll, svrapi.dll, wmi.dll, wmiexe.exe, mpr.dll, mprexe.exe, version.dll, ver.dll}

Miscellaneous={locale.nls, unicode.nls, cp_1252.nls, cp_437.nls}

System::Iosubsys={Basically, all vxd/pdr/drv files that are present in standard configurations}

System::VMM32={}

System32-subfolder={

This subfolder should contain all device drivers that are associated to the loader NTKERN.VXD, which by default is an integral part of the monolithic VMM32.COM. In particular, the corresponding 32-bit network adapter driver .SYS should be in SYSTEM32.}

Real-Mode Game and VMM32-Initialization
At first, we have to create the appropriate RAM-disk. For example, one solution is given by executing LDEVICE RAMDRIVE.SYS /E 10000 Next, it is necessary to copy the entire WINDOWS folder (with subfolders) into the newly created RAM-disk [C:]. Rename SYSTEM.2 into SYSTEM.DAT.

Furthermore, we execute from [C:] the following RPLTERM, SUBST A: C:\ which will terminate the connection with the virtual superfloppy, and create a new [A:]-drive, as a substitution by [C:].

Exercise: Explain reasons why do we need the SUBST step at all? What could be an alternative?

The 16-bit networking is started by the following sequence of commands: SNAPSHOT /M: net start net start workstation net use F: \\OS2Server\WinME SET path=F:\windows;F:\windows\SYSTEM where is IPX or NETBEUI and is the amount of memory in Kilobytes, that should be reserved for real-mode networking.

After establishing a network connection, we should copy the full Registry={ SYSTEM.DAT, USER.DAT, CLASSES.DAT } from a client-specific location into C:\WINDOWS.

Exercise: Explain how to take advantage of the powerful OS/2 Warp Server filtering mechanism that is built into its DOS RIPL subsystem, in order to be able to automatically transfer the appropriate requester-specific Registry files.

Before going further, let us emphasize that all Windows Millennium files/folders are stored on a redirected drive [F:]. Consequently all Registry entries should point to [F:], except the entry [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup] "WinBootDir"="A:\\WINDOWS" Technically, in preparing a diskless RIPL client, we would normally start from a "blueprint" machine equipped with a local hard disk, and install Windows in a standard way on this machine. We would then copy all Windows stuff on the server, and change configuration files, in order to point to a new drive letter (in case local Windows drive letter differs from F). In particular, we would have to export, edit and re-compile the Registry.

Exercise: What is the correct command-line syntax for creating the Registry from a text file, in the case of Windows ME?

Finally, we are ready to launch VMM32.COM from [C:], which starts a "true" Windows ME boot.

Dynamical Networking Transition
This part of the boot process is played by a small but extremely powerful static VXD driver SNAPSHOT.VXD. It is responsible for dynamical transition from real-mode to protected mode networking during the boot process, so that we end up with a clean 32-bit network client. It is loaded from the Registry, with the corresponding entry block: [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\SNAPSHOT] "Start"=hex:00 "NetClean"=hex:01 "StaticVxd"="snapshot.vxd" The driver SNAPSHOT.VXD uses the information gathered by SNAPSHOT.EXE, to transform the initial 16-bit into a 32-bit connection to [F:]. Both files SNAPSHOT.VXD/EXE are available from any Win95 distribution.

Exercise: What do you think could happen, and why, if we excluded the network files NWLINK.VXD, NETBEUI.VXD, VREDIR.VXD and .SYS from the Sub-nucleus on the local RAM-drive (but leaving them intact on the main Windows drive [F:])?

Exercise: What is the best that we could expect to happen if we eliminated SNAPSHOT.VXD from this game, leaving everything else untouched? Similarly, is it possible to get rid of SNAPSHOT.EXE?

Exercise: As we know, Windows 95/98/98SE all have the ability to process CONFIG.SYS, and thus to naturally load real-mode device drivers. Why it is not a good idea, in this context, to load the 16-bit protocol manager and the DOS adapter driver from the CONFIG.SYS file?

Protected Mode Boot Phase
This is the final part of the boot process, and there is nothing RIPL-specific here. After initializing the Configuration Manager and Windows core components such as KRNL386.EXE, KERNEL32.DLL, GDI32.EXE and USER32.DLL, a control is given to CMDNINST.EXE, which in its turn initiates M$ logon. After logon processing, the graphical interface is presented by EXPLORER.EXE.

Sample Configurations
Now, we are going to talk about two sample WinME diskless configurations: The first one is based on a single OS/2 Warp Server (Aurora) machine and the client uses NETBIOS as the main network protocol. The second one is using an auxiliary Win95 machine as an Operating System Server, while RIPL service and applications are provided by the Aurora server (much less reliable of course, but its a fun to boot WinME from Win95). The Win95 "server" machine uses IPX protocol and has peer-to-peer networking installed.

We assume here that the RIPL client is using a Fast EtherLink 905X adapter. At the 32-bit level, the client machine has both IPX and NETBIOS installed.

In my lab, I constructed both these configurations using various types of machines. In particular, the following hardware gives one solution: RIPL clients are IBM Netvista (Network Station 2800) with 128MB of RAM. The built-in IBM EtherJet adapter was used during boot-block processing. A second network adapter (3Com Fast Etherlink 905C) was used for the main network connections (M$ 16-bit and 32-bit networking).

As server systems, I used two IBM ThinkPads 765D (P166MMX with 32MB) running Aurora and Win95 respectively. I also worked with two more powerful OS/2 servers (running both OS/2 Warp Server Advanced 4 and Aurora). The first one is AMD K6-II 300Mhz with 256MB of RAM, 6GB Maxtor EIDE HDD, Tyan/Via Apollo. The file system used is HPFS386. The second server is Athlon 700Mhz, AOpen/Via Apollo, 256MB RAM and 6GB Maxtor EIDE HDD. The file systems used are HPFS for the main operating systems and JFS for the RIPL stuff. Both servers use 3Com Fast EtherLink 905C-TX adapters.

NETBIOS Configuration
The network starts by invoking NET START NETBEUI and the Real Mode Network Registry section looks like [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Network\Real Mode Net] "transport"="ndishlp.sys,*netbeui" "netcard"="el90x.dos" "LoadRMDrivers"=hex:00,00,00,00 "PreferredRedir"="VREDIR" "Transition"=hex:01 "StaticDrive"="F"

IPX Configuration
The network starts by NET START IPX and the corresponding mini-Registry section is: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Network\Real Mode Net] "transport"="ndishlp.sys,*nwlink" "netcard"="el90x.dos" "LoadRMDrivers"=hex:00,00,00,00 "PreferredRedir"="VREDIR" "Transition"=hex:01 "StaticDrive"="F" Here are the listings of PROTOCOL.INI for both configurations: [protman$]                                [protman$] DriverName=protman$              DriverName=protman$ priority=NDISHLP$                  priority=NDISHLP$

[ndishlp$]                                [ndishlp$] DriverName=ndishlp$              DriverName=ndishlp$ Bindings=EL90X$                      Bindings=EL90X$

[Data]                                        [Data] netcards=EL90X$                      netcards=EL90X$ [netbeui$]                                 [nwlink$] DriverName=netbeui$               DriverName=nwlink$ Lanabase=0                              Frame_Type=4 sessions=10                              cachesize=0 ncbs=12 Bindings=EL90X$                      Bindings=EL90X$

[EL90X$]                                    [EL90X$] DriverName=EL90X$                  DriverName=EL90X$ Exercise: Explain why it might be easier to set up RIPL clients using two network adapters for different boot tasks? Discuss problems that could occur if we straightforwardly used a single adapter in building a RIPL client? Discuss additional technical steps that are recommendable in case of single-adapter clients?

Concluding Remarks and Observations
In this study, we have focused ourselves to diskless WinME systems. However, there is nothing in our considerations that is incompatible with the existence of a local HDD. A local swapping media can be very useful, decreasing the network load. In adition, a local HDD can be used to hold the subnucleus package, thus avoiding the transfering the whole subnucleus over network, each time the client boots.

For security reasons, it is better to use RIPL as the boot method, instead of booting directly from a HDD (which should not be bootable). The system Registry should be almost always stored on a server, so that it is transferred into the appropriate RAM-drive before VMM32.COM starts. Initialization scripts should be modified accordingly.

Of course, if security is not an issue, we can further simplify our configurations and have a local bootable HDD, installing the subnucleus and full Registry locally.

Another simple variation is to use a standard floppy to boot the workstation.

Exercise: Explain in detail all the steps/changes necessary to perform in order to:
 * Start a diskless workstation from a real bootable floppy;
 * Start the system from a bootable local HDD, and optionally have the Registry transferred from a server.

In both cases we do not need any RIPL server.

All diskless systems should be configured to start with Active Desktop turned off (Active Desktop works fine, and can be turned on after the system has booted).

Appendix A: Enabling Real-Mode DOS Support in Windows Millennium Edition
We shall describe here a very simple and elegant method of enabling real-mode DOS in WinME. It requires changing only one byte of the standard command interpreter COMMAND.COM. Alternatively, it is possible to incorporate non-standard command interpreters in this procedure.

The problem is that for some strange reasons WinME designers decided to completely disable real-mode DOS. The kernel IO.SYS of WinME was rewritten following this idea.

According to Microsoft, the elimination of the real mode support substantially improved the system stability and decreased the system boot time.

Roughly speaking, the boot process of WinME looks like as follows:

After reading the boot sector of the WinME partition, the system loads the DOS-kernel IO.SYS. The kernel IO.SYS reads the file MSDOS.SYS (located in the root directory) in order to figure out where is the main Windows folder. The kernel loads its internal HIMEM.SYS and also VFAT support driver IFSHLP.SYS (located in the main Windows folder). Furthermore, IO.SYS gives control to VMM32.VXD (which is located in the SYSTEM subfolder of the main Windows folder). The monolithic VMM32.VXD creates virtual machines, loads all static VxDs, and switches the processor to protected mode. Finally, protected mode components are loaded, including critical files such as KERNEL32.DLL, KRNL386.EXE, GDI32.DLL and USER32.DLL.

In particular, WinME does not need any command interpreter to boot. Moreover, its default incarnation does not need the file WIN.COM!

Our main idea is to replace the file VMM32.VXD by the appropriate command interpreter. The simplest solution would be to use the standard COMMAND.COM. However, a slight technical problem appears here, because of a funny mistake in the standard command interpreter COMMAND.COM. Fortunately, this error is only one-byte long...

The original Windows loader VMM32.VXD can be started from the command line, which would then initiate the protected-mode boot, as usual.

More precisely:

At the hexadecimal offset 00006510, replace 75 by EB :) This will correct the above mentioned error. More precisely, we are here replacing a conditional jump instruction (75 10) with an unconditional jump (EB 10). I recommend error-correcting both copies of COMMAND.COM (in the root of the boot drive and in the main Windows folder, however Windows will work fine without both of these copies). I assume you are using release 4.90.3000 of WinME (English version).
 * Step 1: Binary Editing of COMMAND.COM

Rename the file VMM32.VXD into VMM32.COM. Copy the improved COMMAND.COM into the SYSTEM subfolder, as a new "loader" file VMM32.VXD.
 * Step 2: Adjusting The Loader

Rename the file WIN.COM into WINME.COM!
 * Step 3: Getting rid of WIN.COM

Now, when we start WinME it will stop at the command prompt, displaying an error message that it can not find WIN.COM. At this point, we have WinME running in real DOS-mode :)

This error message is harmless. Optionally, it gives us a nice opportunity to replace it by another, personalized message. Simply binary-edit the file COMMAND.COM (but of course, replace the message-do not change the size of the file!)...
 * Step 4: Final adjustments

Loading WinME Graphical Interface
To load full GUI, simply launch VMM32.COM from the command prompt!

Interesting Variations
Instead of using the error-corrected COMMAND.COM, we can put another program in place of VMM32.VXD. For example, we can use another command interpreter, or custom-build a nice DOS-program, giving us something like a startup meny, and so on.

For example, we can use a simple (and very old!) Unix-like command shell csh4 (by Kent Williams). The package includes the full source code. In this case, we have to copy the shell program SHELL.COM over VMM32.VXD.

Another illustrative example is to use 4DOS from JP Software: After installing the files into a separate directory (say C:\4DOS) all we have to do is to copy 4DOS.COM over VMM32.VXD and create the appropriate 4DOS.INI file (which should stay in the SYSTEM subfolder). Note that this solution does not depend of COMMAND.COM and in particular it is not necessary to binary-edit anything.

As a third example - it possible to use Orchard House (very nice and compact DOS shell, by Gleason Pace). The package consists of a single executable OH.EXE and a configuration file (managed within the program). In this case, we copy OH.EXE over VMM32.VXD.

Since the full WinME is loaded by VMM32.COM, we do not need the file WIN.COM, as we already mentioned. The same trick is applicable with earlier versions of Windows, however assuming that we use IO.SYS from Windows Millennium. Interestingly, in all my experiments non-ME DOS kernels were causing Win95/98-based VMM32.COM to crash. Anyway, it looks like that Win95/98 workstations run a little smoother with a WinME kernel IO.SYS. In order to make a standard DOS command Window fully usable (for launching various Windows programs for example), it is also necessary to replace CONAGENT.EXE and files in COMMAND subfolder, with their WinME counterparts...

A more conservative method of booting WinME from DOS is to binary-edit WINME.COM (the renamed WIN.COM) and change it so it will load VMM32.COM instead of VMM32.VXD. Of course, in this case Windows starts by invoking WINME at the command prompt.

We can use the above ideas to create a bootable WinME floppy, using the same kernel IO.SYS as for the hard disk boot. Unfortunately, it seems that SYS.COM supplied with WinME is unable to transfer the system files to a floppy (by default, Windows Millennium is using a special DOS kernel IO.SYS to boot from a floppy). Perhaps the cleanest method would be to start from a blank floppy, overwriting the boot sector by the appropriate code (the boot sector is the same as for a Win95/98 bootable floppy, the fourth article contains a boot sector explanation/listing). Next, we have to copy IO.SYS and IFSHLP.SYS to the root directory of the floppy. Finally, we have to create SYSTEM subfolder and copy the standard COMMAND.COM as VMM32.VXD in SYSTEM.

Interestingly, in the case of such bootable floppies, the file COMMAND.COM works fine and it is not necessary to perform any error-corrections. The same property applies for virtual floppies and superfloppies used for RIPLing diskless workstations from OS/2 Warp Server.

Problems with big RAM-drives
This problem affects both Win98SE and WinME. It seems that the system gets confused by real-mode RAM-drives that are bigger than 10MB. Trying to load such a real-mode RAM-drive results in a dramatically increased instability. In addition, such a RAM-disk would not support long filenames(?!?)

The file that is responsible for this hostile behavior is the Input-Output Supervisor IOS.VXD. Normally, it is an integral part of VMM32.COM.

On the other hand, Windows 95 works fine with all sorts of RAM-drives, of any sizes.

Unflexibility with locations of device drivers
It seems that all drivers that are loaded by NTKERN.VXD must stay in one of the subfolders {SYSTEM32, SYSTEM, SYSTEM32\DRIVERS} of the folder pointed by winbootdir from MSDOS.SYS.

In our case, winbootdir=C:\WINDOWS and this means that all NTKERN-related drivers must be a part of the subnucleus and stay on the RAM-drive [C:].

Together with the IOS-related obstacle, this gives us a very interesting problem: To see which NTKERN drivers are really used (Windows installation puts a lot of files into SYSTEM32\DRIVERS, only a fraction of them are really needed) in order to make the subnucleus fit into 10MB limitation.

In case there are too many NTKERN drivers, there are several possible workarounds:
 * Use a local media to store the subnucleus, as discussed in Section 5.
 * Change the system Registry so that some drivers are not loaded by NTKERN :)
 * Use a compressed RAM-drive [C:], in a way similar to our nucleus configurations of WiRIPL4.

Exercise: Explain in detail the steps/changes necessary to perform in order to: [1] Avoid loading selected drivers via NTKERN; [2] Get compressed RAM-drive [C:] configurations working.

Inability to process CONFIG.SYS
This is related with so-called "removal" of real-mode DOS support from Windows Millennium. As explained in the previous appendix, in reality there is no any DOS removal, just the kernel IO.SYS was redesigned in order to start loading Windows immediately, and to ignore CONFIG.SYS.

With very little efforts, it is possible to incorporate into IO.SYS the ability to present something like a menu at start-up, with different options (this can be done very easily by writing a customized VMM32.VXD).

IO.SYS-Registry Coupling
The real-mode kernel IO.SYS examines the system Registry, before it gives control to VMM32.VXD. This can cause all sorts of weird phenomena if we change the registry during the real-mode boot. As explained, the solution is to start with a renamed mini-Registry.

Strange Instructions Built Into COMMAND.COM
If you copy any normal DOS executable over VMM32.VXD, it should start without problems, as a part of WinME "boot". The only ME-runnable program I know that does not start properly is the command interpreter COMMAND.COM (?!?) As explained in Appendix A, there is a hostile conditional jump instruction that prevents us from loading COMMAND.COM as VMM32.VXD, in the case of a normal HDD boot.