Installing a large drive into an older computer

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.

Brief summary

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:

A calculator that converts between decimal and HEX will be needed. You will also need to write HEX numbers out on paper in binary.

Getting started

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.

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.

Step Two

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.

Step Three

Reboot your Linux disk and run fdisk.

Your partition table should now resemble this:

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.

Step Four

Reboot your Linux disk and run fdisk.

Your partition table should now resemble:

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 to your Windows XP 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.

Step Five

Reboot your Linux disk and run fdisk.


Your partition table should now resemble:

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.

A closer look at things

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.