7

I'm in the process of restoring an old Compaq LTE Elite 4/75 laptop, which was missing its hard drive, so I thought I'd try booting using an SD-to-IDE adapter.

On my main workstation I created an emulated image of MS-DOS 6.22 (with Windows 3.11), as well as an image of Windows 95. I then dd'd these images to SD cards.

The SD card with MS-DOS boots up perfectly, and everything works, including Windows 3.11 and all the other software I loaded onto it.

However, when booting from the SD card with Windows 95, it just hangs at the very start, before even getting to the "Starting Windows 95..." message. (It doesn't say "missing operating system", but just hangs on a blank screen.)

The two SD cards are identical in size (2 GB), and each has just a single partition. Although I have also tried this with smaller SD cards, down to 256 MB. It certainly feels like some kind of CHS↔LBA mismatch, or the BIOS detecting the drive incorrectly, but then why would the DOS drive work, and the Win95 drive not?

More data:

  • The filesystem is FAT16.

  • This was partitioned and formatted within the emulator.

  • I'm using 2GB SD cards, but flashing them with a 500 MB disk image. In the emulator the drive was created as 1015/16/63, and from within the target laptop the drive is auto-detected as 3807/16/63.

  • Here is the partition table:

    00000180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00000190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    000001A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    000001B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01  ..............€.
    000001C0  01 00 06 0F FF F6 3F 00 00 00 51 9C 0F 00 00 00  ....ÿö?...Qœ....
    000001D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    000001E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    000001F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA  ..............Uª
    

    Single bootable partition, type ID 6 (FAT16B, CHS), first sector (0, 1, 1), final sector (1014, 15, 63), LBA offset 63, 1023057 sectors long. (Implied geometry: 16 heads, 63 sectors per track.)

  • Not sure whether the BIOS supports int13 extensions.

7
  • This won’t answer your question, but you could try replicating your DOS card on the card you intend for Windows 95, copy the 95 setup files to it, and then install 95 from DOS, to see if the result works any better. Oct 15 at 21:27
  • 2
    DOS uses the BIOS for disk access; Windows 95 probably does not. Perhaps there's some difference that Windows 95 disk drivers do not cope with. Oct 15 at 22:28
  • @another-dave I am pretty sure the part of Windows 95 that loads IO.SYS does use BIOS for disk access. Oct 16 at 14:38
  • 1
    What geometry does the IDE-SD adapter show to the BIOS? Did you use the same geometry in the disk image you created? And there is difference what geometry the IDE drive has, and if the BIOS does a logical geometry translation to access up to 8 Gbytes via BIOS, as cylinders are limited to 1024 while heads up to 255 is supported.
    – Justme
    Oct 16 at 16:15
  • So far physical–logical geometry mismatch seems consistent with the symptoms. Where did you get that 3807/16 geometry from? What geometry is reported by, say, RPM? (Ran on the laptop, of course.) Oct 16 at 19:51
9

The problem is in the geometry. Not in the physical disk geometry, but rather in the translation how the BIOS must translate the geometry for DOS when using disks larger than 1024 cylinders.

The laptop, or very close model of it, was sold with an 800 MB drive, so we have to assume that the laptop properly supports disks larger than 504 MiB, i.e. disks with hardware geometry which has more cylinders than the limit of 1024 cylinders, 16 heads, and 63 sectors per cylinder.

As you said, the SD card with the IDE adapter has geometry of 3807 cylinders, 16 heads and 63 sectors per cylinder as detected by BIOS, which is about 1873 MiB. But DOS can't access such geometry, as maximum standard BIOS interface has a limit of 1024 cylinders.

To use these larger hard drives with more than 1024 cylinders, BIOS has to perform geometry translation from the actual unusable physical geometry to usable logical geometry. In this case, the cylinder count is most likely divided by four, and head count is respectively multiplied by four, so via BIOS, the DOS would most likely see a geometry of 951 cylinders, 64 heads, and 63 sectors per track. The resulting usable size would be slightly less, about 1872 MiB.

If you made a roughly 500 MB image with logical and physical geometry of 1014/16/63 and used dd to write it to card, then when you plug that to a DOS computer, DOS will understand that the SD card is a disk that has a 1014/16/63 logical geometry, while BIOS is actually presenting the disk a 951/64/63 logical geometry, and thus chaos and corruption will ensue. After the last logical head what DOS thinks it has, DOS increments the cylinder, but then logically, heads 17-64 presented by BIOS are skipped, and another problem is that DOS thinks it can use cylinders up to 1014 but physically there is only 951 heads so near the end of the disk DOS will try to access beyond the end of the SD card. It could work if the image is small enough to fit into 951/16/63 geometry, however due to the geometry translation, it will use the whole 2GB card sparsely, and it will only work in that system.

This may explain that even using the wrong geometry, anything stored within the first 16 cylinders (about 500 kilobytes) will work, but after that the reads and writes skip the next 48 logical heads.

So even an image much smaller than the whole SD card, you must create it in a virtual machine by using an identical logical geometry which the SD card is presented via the IDE adapter and BIOS in the target system. It might be 951/64/63, but it might also be something different depending on the target system BIOS.

For best results, zero out the SD card by using dd, plug it in the target system, and by using a DOS or Windows boot floppy, partition the drive and format the partition in the target system, so it will end up being partitioned and formatted with the correct logical geometry and correct size for that specific geometry translation of the BIOS. It even accounts for other quirks of the BIOS does, like reducing the cylinder count by some amount to allow for a landing zone or something similar.

As a side note which relates to older systems, as the BIOS detects the hard drive, it is possible that it can read and print out the physical geometry reported by the drive correctly as having more than 1024 cylinders, but it may not be able to perform physical to logical geometry translation and thus only work with old physical limitations of 1024/16/63 giving you approximately a 504 MiB drive, or in the worst case, 735/16/63 if the 3807 is simply used as a 10-bit value.

5
  • This is absolutely the answer (see my last comment below the question; the Compaq diagnostic tools were reporting 16 heads, but it turns out that a third-party partitioning tool reports 64 heads). But out of curiosity -- why, then, does the whole thing work once the initial boot files are within the first cylinder's worth of sectors? I am, after all, now able to run Windows 95 (and all the software, basically up to the 500MB size of the disk) from the SD card without any other modifications. Oct 16 at 20:39
  • It only has to work via the standard BIOS interface up to the point where some clever enough driver is loaded to access the drive via extended disk BIOS or directly via IDE interface and thus the driver is able to access the drive directly without automatically forced BIOS translation.
    – Justme
    Oct 16 at 20:48
  • 2
    I was about to submit pretty much exactly this answer. What gave me a pause is that 16 heads × 63 sectors per track × 512 bytes per sector doesn’t even cover a full 512 KiB (which seems barely enough to cover the post-MBR gap, two FATs, root directory area and IO.SYS/MSDOS.SYS contents), so I would expect more data corruption symptoms to show up, even on MS-DOS 6, and even if it ostensibly boots fine. Oct 16 at 20:58
  • Thank you both! To wrap this all up, would it be reasonable to restate the guidance to say, "In the case of MS-DOS 6 or Windows 9x, as long as IO.SYS/MSDOS.SYS are within the first cylinder on the target machine, then the rest of the disk geometry is basically irrelevant"? Oct 16 at 21:18
  • No, that restatement would not be true. It would be better to say that if you formatted the drive and copied files to it in a VM that does not use the same logical geometry as the physical machine, every file with data beyond first 16 heads of first cylinder would be corrupted for sure at least in DOS.
    – Justme
    Oct 16 at 21:32
6

Whew, I've got it solved!

I took one of the disk images with Windows 95 installed on it, and examined it with a hex editor. I noticed that when the Windows installer program initially sets up the system files on the C: drive, it puts IO.SYS rather "far" into the filesystem, actually more than 100 MB inward.

What I tried then was to perform a clean format of the disk, and boot from a Windows 95 startup floppy disk. After booting the startup disk, I simply ran sys c: to transfer the bare essential system files to the C drive. This ensured that IO.SYS is close to the beginning of the filesystem. This booted successfully to a bare Windows 95 C: prompt!

Then I went back and manually copied over all the other files under the C:\WINDOWS and Program Files directories, since these don't require any particular placement in the filesystem.

And when this was done, lo and behold, the whole thing boots up without issues!

The answer: It appears that this BIOS (or something else in the boot loader) doesn't like a very far jump to get from the boot sector to IO.SYS.

3
  • The Windows 9x boot sector should have been able to load IO.SYS from anywhere on the disk, as long as the first three sectors are contiguous (and I believe it has to be the first entry in the root directory for a FAT16 file system). So this looks like a geometry mismatch indeed. Did you partition and format the CF card while it’s plugged into the laptop it’s supposed to boot? Oct 16 at 8:19
  • Interesting. So are you saying "a Win9x image can be created in DOSBox, then moved to a laptop, iff you first prep your media by running "SYS C:" on the actual laptop, then file copying all the files from emulator image to media"...
    – Brian H
    Oct 16 at 14:26
  • 1
    @BrianH I did all of the setup in the emulator, even the sys c: step. The crucial thing seems to be to put IO.SYS near the beginning of the filesystem, although I'm still not sure "why" this works. If it had to do with a mismatch of drive geometry, then I'm guessing it would fail to boot for a whole mess of other reasons, but it boots just fine now. Oct 16 at 16:36
1

This is a logical–physical geometry mismatch.

Like @Justme’s answer explains, the ‘logical’ geometry used by the BIOS disk interrupt services, and the ‘physical’ geometry reported by the disk controller are not necessarily the same. This is because the BIOS interrupt call interface and the hardware interface of the ATA controller establish different limits on the maximum possible coordinate values. Because DOS and boot sector code use BIOS services to access storage, disk partitioning ought to be performed with the logical geometry, while the asker performed partitioning and formatting with the physical geometry as reported by the Compaq diagnostic tool. Coordinates based on the wrong geometry have been written into the partition table and the file system boot sector.

The good news is that this mismatched geometry is used primarily for booting. After the DOS kernel is loaded into memory, it performs partition discovery and queries the BIOS for the geometry of each hard disk, thus obtaining the actual logical geometry. Internally, DOS uses linear block addressing and only transforms LBA sector numbers into CHS when interfacing with the BIOS. Luckily enough, the sectors-per-track value agrees between physical and logical geometries, which means that data fitting within the first cylinder (of both geometries) is going to be read correctly. This agrees with the symptoms disappearing when the contents of IO.SYS are placed earlier on the disk: as long as the coordinates of the boot sector and IO.SYS data agree, the problem is not going to be noticeable.

All this means that a fix can be performed non-destructively, simply by writing logical CHS coordinates into the MBR, and the logical geometry values into the partition’s BIOS Parameter Block. I don’t know of a tool which can do it automatically, though; myself, I would use a hex editor.

0

You didn't specify what you are using for an emulated environment to create images, but I'll assume it is DOSBox.

I routinely use DOSBox to create DOS disk images on my modern Linux machine and transfer those images (using 'dd') to various, diverse, MS-DOS compatible computers. This works fine as there are no real differences in virgin/vanilla MS-DOS installations between the various hardware.

Windows 9x is different. It utilizes "sophisticated" hardware detection during the installation and installs drivers that are specific to the detected hardware to enough of a degree that installations are different between different hardware. These images are not readily transferable between machines or from emulator to real hardware.

What I do myself for Windows 9x is, after installing MS-DOS, just copy all the Win9x installer files over to a directory on my media. Then, I run the Windows 9x SETUP on the actual hardware where I intend to use the media. This gives me the correct driver configuration to boot Windows 9x, and also allows continued boot into DOS through a custom startup menu.

2
  • 1
    That's a good idea, and I just tried it, but the result is the same. The Windows 95 setup program works just fine from within DOS, but when installation is complete and it reboots, it hangs. (before any kind of message or prompt) Oct 15 at 23:55
  • 1
    Windows 9x does perform some hardware detection, but it’s unlikely to matter this early in the boot process. The question mentions that not even the ‘Starting Windows 95’ message appears, so the boot process hangs somewhere between loading the boot sector and transferring control to IO.SYS. That boot code is always the same, and depends only on what kind of file system is in use. It seems this is either a disk geometry mismatch or failing (or absent) disk interrupt extensions. Oct 16 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.