This is yet another attempt to document the journey to success of doing something your computer isn't happy about. Hopefully the person searching for this info will find it. This comes with the usual "Your mileage may vary" disclaimer.
The problem: You have a PC with the 137 Gig, 28 bit LBA limitation. If you are installing XP and/or Linux, you likely are not looking for this information. If you are, however, wanting DOS and/or a version of Windows prior to XP, read on.
Recent operating systems use their own IDE drivers and are not limited by the 28 bit limitation. If you can see the proper size of your drive in your operating system's fdisk utility, you likely do not have a hardware issue. If Linux or XP is not recognizing the full size of the drive you may need a new IDE controller.
I purchased a new (to me) Dell C840 laptop. After finding out that 2.5" IDE drives are getting hard to find, I was happy to finally see 320 GB of new drive in my Slackware fdisk utility. I started the usual game of installing DOS, Windows and Linux. I have legacy software used to program two-way radios. Old radio programming software does not work correctly in XP. I installed DOS, Windows 2000 and XP using the Slackware fdisk along the way to hide partitions during the process. Each OS booted fine and had all the updates and drivers working when I installed Linux and configured lilo. My first boot of Windows 2000 ended in a blue screen of death. I also discovered that the Linux /boot partition needs to be below the 137GB limit.
2015 Update: This issue is not just about the motherboard. Windows 2000 also fails if the 28 bit data appears inconsistant. I had to apply the 274G limit to a newer motherboard as well to get Windows 2000 to boot.
I decided to keep the 320 Gig drive as a spare and restarted the process with a 250GB drive. All four operating systems are now booting correctly. Before getting into the dirty details, here are a couple tips for a clean start:
dd if=/dev/zero of=/dev/sda bs=512 count=10
A calculator that converts between decimal and HEX will be needed. You will also need to write HEX numbers out on paper in binary.
You will need to repeatedly boot to Linux and utilize fdisk. I used Slackware, but any distro should work. The Slackware install disk boots very quickly. An alternative would be to partition the drive and install Linux first. A minimal image like the Slackware disk boots faster than most Linux installations. If you made a mistake in partitioning, you could end up starting over from step one.
Boot your Linux disk and run fdisk.
Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
You need to write down the last cylinder (30401 in this example)
Multiply this number by the Units (16065 in this example) This is heads * sectors
Using a calculator with HEX, convert that number to HEX and write that down
Next we need to write the HEX number out in binary:
30401
488392065
1D1C4581
0001 1101 0001 1100 0100 0101 1000 0001
Here is the trick. Your BIOS only sees 28 bits.
0001 1101 0001 1100 0100 0101 1000 0001
Convert that to HEX, then use a calculator to convert to decimal:
D1C4581 = 219956609
divide by units (16065 in my case)
Round down to the integer -> 13691
13691 is the last cylinder from your BIOS' point of view. All your partition start and end boundaries must make sense to BIOS or you get the blue screen.
The upper limit for the end of the /boot partition on this drive is:
13691 * 16065 * 512 = 112 GB
Before defining your Linux partitions, you need to repeat this math to be sure the BIOS sees a logical partition order. Your start and end points for swap and / must be below 13691 (on this drive) from a 28 bit viewpoint.
We'll start with DOS. DOS needs to be first on the drive to be happy. Knowing that DOS has a 2 Gig limit, I entered '+2G' into fdisk as the ending cylinder. This failed! Enter an end cylinder of 255 or less. 255 cylinders will yield 2GB. Using '+2G' will go past 255 and cause problems with DOS. I think the 65535 cluster limit is at play here.
Tag the partition as type '6' and make it active. Write the partition table and boot your DOS disk. You should now be able to: format /s c:
and reboot on the new partition to a DOS prompt.
Reboot your Linux disk and run fdisk.
Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sda1 1 255 2048256 16 Hidden FAT16
/dev/sda2 * 263 2874 20980890 7 HPFS/NTFS
You'll notice the gap between my 1st and 2nd partitions. This was due to my original end of partition 1 was larger than 255 and I didn't want to reinstall all systems. ** If your drive has a different value for heads and sectors, you may have a different upper limit for the DOS partition. **
At this point you should reboot to your Windows 2000 disk. When you arrive at the partition screen, your target partition should be labeled as 'C:'. If not, something went wrong. If all appears well, install Windows.
Reboot your Linux disk and run fdisk.
Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sda1 1 255 2048256 16 Hidden FAT16
/dev/sda2 263 2874 20980890 17 Hidden HPFS/NTFS
/dev/sda3 * 2875 12532 77577885 7 HPFS/NTFS
Reboot your Linux disk and run fdisk.
Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x01234567
Device Boot Start End Blocks Id System
/dev/sda1 1 255 2048256 16 Hidden FAT16
/dev/sda2 * 263 2874 20980890 7 HPFS/NTFS
/dev/sda3 2875 12532 77577885 17 Hidden HPFS/NTFS
/dev/sda4 12533 30401 143532742+ 5 Extended
/dev/sda5 12533 12664 1060258+ 83 Linux
/dev/sda6 12665 13187 4200966 82 Linux swap
/dev/sda7 13188 20886 61842186 83 Linux
Now reboot to test the Windows 2000 partition.
If all seems well, boot your favorite Linux install disk and install Linux to the partitions you just created. Install the boot loader to the MBR.
Once you are finished and booted into your new Linux environment, the boot options for the other partitions need some editing. I am not familiaer with grub so you may have to adapt my lilo entries.
The key here is to toggle the active partition flag for the partition booted.
This is necessary so that the booted system's drive letter does not change from 'C:'
You will also want to edit the partition labels so you don't accidentally lose data later.
Once all is well, you will also want to write down the partition information from Linux fdisk in case your partition table gets changed. This is a real possibility if you use the recovery console later to fix a Windows issue or run fdisk from another OS.
Let's use my 320 GB drive for this. The last cylinder is 38913. Binary form of total sectors is:
10 0101 0100 0010 1101 0110 1100 0001
In order to use this as the last cylinder, the starting cylinder would have to be no higher than:
10 0101 0100 0010 1101 0110 1100 0000
I think this could work, but the first three partitions would have to fall below:
00 0101 0100 0010 1101 0110 1100 0000
because of the 28 bit issue. Converting back to decimal and multiplying by 512, we get 45 GB. We could use this, but I wanted more space for the two Windows partitions. Let's now look at this:
01 1111 1111 1111 1111 1111 1111 1111
fdisk allows this because it is smaller than the last cylinder. The 28 bit software sees it as valid because the starting cylinder is smaller. Do the math here and we get 274 GB.