The basic process is:
- Boot MSDOS and create a RAM disk
- PKUNZIP a stripped down NT system on the RAM disk
- Reboot from the RAM disk
Using this technique it is possible to boot Windows NT 4.0 SP3 from four
1.44MB floppy disks in about 5 minutes. The four floppy disks do not
include utilities such as regedt32, chkdsk or winfile which might be needed
to repair a system, but these can be loaded from other floppies after the
boot is complete.
The first step (boot MSDOS and create a RAM disk) is straightforward since
the RAM disk can be created with the MSDOS RAMDRIVE.SYS. The following two
lines from config.sys reserve 16MB RAM for NT and create a 24MB RAM disk:
DEVICE=HIMEM.SYS /int15=15360
DEVICE=RAMDRIVE.SYS 24576 /e
The second step (or more particularing, choosing the files to include in the
ZIP file) is perhaps the most difficult and is discussed at the end of the
article.
Booting NT from a RAM Disk
--------------------------
The first obstacle to accomplishing the third step is to reboot the PC
without zeroing memory (as normal happens when MSDOS is rebooted with
Ctrl-Alt-Del). A two byte .COM file containing the values 0xCD, 0x19
does the trick, since this causes an "int 19h" (bootstrap loader) service to
be invoked; a suitable name for this file is REBOOT.COM.
A floppy formatted by Windows NT (so that it has a Windows NT boot
block) containing at least the following files is needed:
boot.ini 1KB
ntdetect.com 26KB
ntldr 152KB
reboot.com 1KB
The remaining files needed depends upon the contents of boot.ini. Given the
file sizes of essential components under Windows NT 4.0 SP3, two approaches
are possible; if the released NT 5.0 kernel is as large as that of Beta 1
only the second approach will be able to boot that kernel.
1st approach
------------
boot.ini contains:
[boot loader]
default=multi(0)disk(0)fdisk(0)\WINNT
[operating systems]
multi(0)disk(0)fdisk(0)\WINNT="NT 4.0 from Floppy" /maxmem=16 /basevideo
floppy also includes:
\WINNT\SYSTEM32\ntoskrnl.exe 893KB
\WINNT\SYSTEM32\hal.dll 50KB
\WINNT\SYSTEM32\CONFIG\system
\WINNT\SYSTEM32\l_intl.nls 7KB
\WINNT\SYSTEM32\c_1252.nls 64KB
\WINNT\SYSTEM32\DRIVERS\fastfat.sys 137KB
\WINNT\SYSTEM32\DRIVERS\ramboot.sys 4KB
These file sizes leave about 80KB space for the SYSTEM registry
hive. Typically the size of this hive is greater than 1MB, so it must be
substantially pruned before it will fit on the floppy; furthermore the only
"start = 0" (boot start) driver should be ramboot.sys and the registry value
HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP should be set to the
same value as the ACP value (normally c_1252.nls for Latin I) so that only
one code page is loaded by ntldr.
2nd approach
------------
boot.ini contains:
[boot loader]
default=scsi(0)disk(0)fdisk(0)\WINNT
[operating systems]
scsi(0)disk(0)fdisk(0)\WINNT="NT 4.0 from Floppy" /maxmem=16 /basevideo
[debug]
scsidebug=0
floppy also includes:
ntbootdd.sys 4KB
Locating the RAM Disk
---------------------
The config.sys line "DEVICE=HIMEM.SYS /int15=15360" ensures that the RAM disk
is not located in the first 16MB of memory (1MB of low memory + 15MB of
extended memory) and if this line is immediately followed by
"DEVICE=RAMDRIVE.SYS" then (in practice) the RAM disk always starts
exactly at the 16MB boundary. The "/maxmem=16" switch in boot.ini directs NT
to only use the first 16MB of memory, leaving the RAM disk undamaged.
Ramboot.sys
-----------
Ramboot is broadly similar to the Ramdisk sample on the DDK, with 3 notable
differences:
- Ramboot does not allocate memory for the disk but just assumes that a FAT
formatted RAM disk starts at the 16MB boundary (the RAM disk size is
determined from information in the first sector of the RAM disk)
- Ramboot does not format the disk (since it has already been formatted by
MSDOS and contains useful information)
- Ramboot uses the IoAssignArcName function so that when ntldr transfers
control to ntoskrnl the RAM disk boot device can still be found
Ramboot is a very simple driver and is implemented by about 220 lines of
code.
Ntbootdd.sys
------------
Ntbootdd is technically a SCSI miniport driver, but since there is no
hardware to control, it interprets and executes the SCSI CDB itself. In
practice there are four commands which must be implemented:
- SCSIOP_INQUIRY
- SCSIOP_MODE_SENSE
- SCSIOP_READ_CAPACITY
- SCSIOP_READ
Ntbootdd is even simpler than Ramboot and is implemented by about 140 lines
of code. During development, two little problems emerged:
- The MSDOS RAMDRIVE.SYS does not format the BIOS parameter blocks in the
RAM disk in quite the same way as a floppy; it was necessary to explicitly
set the "Large Sectors" field (offset 0x20) to zero, otherwise the RAM
disk was not recognized as containing a FAT file system.
- The ntldr implementation of the ScsiPort routine ScsiPortFreeDeviceBase
does nothing and the implementation of ScsiPortGetDeviceBase can map a
maximum of 4MB and has problems mapping non-paged aligned regions that
straddle pages.
The 4MB mapping limit places an upper bound on how much data ntbootdd.sys can
load; in practice, some RAM disk sectors are read more than once whilst ntldr
is running and the current implementation of ntbootdd will multiply map the
pages containing these sectors. Should this become a problem, there are two
steps which could be taken:
- Remember which pages have been mapped and check for an existing mapping
before creating a new one; since ntbootdd is written in C++, the STL
(Standard Template Library) map container could be used. This would extend
the amount of data which could be loaded to almost exactly 4MB.
- Obtain a mapping for a single page and then directly manipulate the PFN
(Page Frame Number) in the PTE (Page Table Entry) to address the RAM disk
sectors as needed.
Ntbootdd was debugged by using the checked version of ntldr; when using the
checked version, the ScsiPort routine ScsiDebugPrint is available and the
level of output is controlled by the [debug] section in boot.ini. Setting
scsidebug=3 produces a greate deal of output, scsidebug=2 is much more
manageable. Since the debug output is only visible on the screen and scrolls
very quickly, it is often helpful to follow a ScsiDebugPrint with code like:
for (int i = 0; i < 3; i++) ScsiPortStallExecution(1000 * 1000);
Files needed in the ZIP file
----------------------------
If using the first technique, the files which are present on the boot floppy
do not need to also appear in the ZIP file (e.g. ntoskrnl.exe).
The list also assumes that the value
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit has been
set to "cmd" and that HKLM\SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDLLs
has been pruned to just those DLLs that are actually used by some process.
Files used in approximate load order Reason for loading
------------------------------------ ------------------
\WINNT\SYSTEM32\ntoskrnl.exe Boot
\WINNT\SYSTEM32\hal.dll
\WINNT\SYSTEM32\CONFIG\system
\WINNT\SYSTEM32\l_intl.nls
\WINNT\SYSTEM32\c_1252.nls
\WINNT\SYSTEM32\c_850.nls
\WINNT\SYSTEM32\DRIVERS\fastfat.sys
\WINNT\SYSTEM32\DRIVERS\ramboot.sys Start = 0 (Boot) drivers
\WINNT\SYSTEM32\ntdll.dll
\WINNT\SYSTEM32\DRIVERS\atdisk.sys Start = 1 (System) drivers
\WINNT\SYSTEM32\DRIVERS\floppy.sys
\WINNT\SYSTEM32\DRIVERS\fs_rec.sys
\WINNT\SYSTEM32\DRIVERS\i8042prt.sys
\WINNT\SYSTEM32\DRIVERS\kbdclass.sys
\WINNT\SYSTEM32\DRIVERS\ksecdd.sys
\WINNT\SYSTEM32\DRIVERS\mouclass.sys
\WINNT\SYSTEM32\DRIVERS\msfs.sys
\WINNT\SYSTEM32\DRIVERS\npfs.sys
\WINNT\SYSTEM32\DRIVERS\ntfs.sys
\WINNT\SYSTEM32\DRIVERS\null.sys
\WINNT\SYSTEM32\DRIVERS\vga.sys
\WINNT\SYSTEM32\DRIVERS\videoprt.sys
\WINNT\SYSTEM32\smss.exe Started by Ntoskrnl
\WINNT\SYSTEM32\advapi32.dll KnownDLLs
\WINNT\SYSTEM32\gdi32.dll
\WINNT\SYSTEM32\kernel32.dll
\WINNT\SYSTEM32\msvcrt.dll
\WINNT\SYSTEM32\rpcrt4.dll
\WINNT\SYSTEM32\user32.dll
\WINNT\SYSTEM32\CONFIG\sam
\WINNT\SYSTEM32\CONFIG\security
\WINNT\SYSTEM32\CONFIG\software
\WINNT\SYSTEM32\win32k.sys Kmode SubSystems
\WINNT\SYSTEM32\csrss.exe Required SubSystems
\WINNT\SYSTEM32\csrsrv.dll
\WINNT\SYSTEM32\basesrv.dll
\WINNT\SYSTEM32\winsrv.dll
\WINNT\SYSTEM32\unicode.nls
\WINNT\SYSTEM32\locale.nls
\WINNT\SYSTEM32\ctype.nls
\WINNT\SYSTEM32\sortkey.nls
\WINNT\SYSTEM32\sorttbls.nls
\WINNT\SYSTEM32\vga.dll
\WINNT\SYSTEM32\kbdus.dll
\WINNT\SYSTEM32\winlogon.exe Started by CSRSS
\WINNT\SYSTEM32\userenv.dll
\WINNT\SYSTEM32\shell32.dll
\WINNT\SYSTEM32\comctl32.dll
\WINNT\SYSTEM32\netapi32.dll
\WINNT\SYSTEM32\netrap.dll
\WINNT\SYSTEM32\samlib.dll
\WINNT\SYSTEM32\winmm.dll
\WINNT\SYSTEM32\msgina.dll
\WINNT\SYSTEM32\rpcltc1.dll
\WINNT\SYSTEM32\rpclts1.dll
\WINNT\SYSTEM32\services.exe Started by Winlogon
\WINNT\SYSTEM32\umpnpmgr.dll
\WINNT\SYSTEM32\lsass.exe Started by Winlogon
\WINNT\SYSTEM32\lsasrv.dll
\WINNT\SYSTEM32\samsrv.dll
\WINNT\SYSTEM32\msprivs.dll
\WINNT\SYSTEM32\netlogon.dll
\WINNT\SYSTEM32\msv1_0.dll
\WINNT\SYSTEM32\security.dll
\WINNT\SYSTEM32\wsock32.dll
\WINNT\SYSTEM32\ws2_32.dll
\WINNT\SYSTEM32\ws2help.dll
\WINNT\SYSTEM32\cmd.exe Started by Winlogon
\WINNT\SYSTEM32\mpr.dll (if Userinit = "cmd")
No SCSI disk or network support included in this list of files.
Miscellaneous
-------------
The registry value
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory
Management\PagingFiles
should be set to "C:\winnt\system32\temppf.sys 2 8". This will prevent
winlogon from filling the RAM disk with a temporary paging file.
No drive letters will be assigned to the hard disks. Either use windisk to
assign letters, or use a small program like:
// Usage: <progname> <drive letter> <device name>
// e.g. <progname> D: \Device\Harddisk0\Partition1
#include <windows.h>
int main(int argc, char *argv[])
{
return DefineDosDevice(DDD_RAW_TARGET_PATH, argv[1], argv[2]);
}
Source code for ramboot.sys and ntbootdd.sys can be requested from
gary.n...@cp.novartis.com
I'm missing something here, maybe the day's been too long for me. All
you need to "Boot NT from floppy" is a floppy disk with the above on
it. Installing NT just requires the 3 install diskettes and the CD.
Best Wishes
--
--------------------------------------------------------------------
| EMail ro...@ttelmah.demon.co.uk http://www.ttelmah.demon.co.uk/ |
| A beard! A beard! cried Fly Nicholas.'By God, that's a good one!'|
| (Chaucer) |