i386/61890: FDisk uses incorrect calculations for disk geometry guessing and validation

Keith F. Kelly c0d3h4x0r at hotmail.com
Sun Jan 25 09:20:25 PST 2004


>Number:         61890
>Category:       i386
>Synopsis:       FDisk uses incorrect calculations for disk geometry guessing and validation
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 25 09:20:16 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Keith F. Kelly
>Release:        5.2-RELEASE
>Organization:
none
>Environment:
I can't do this at the moment, as I am in Windows XP.
>Description:
(This text is taken from an e-mail to the freebsd-questions mailing list.  The message is now archived online at http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3208799+0+archive/2004/freebsd-questions/20040125.freebsd-questions.  Although the e-mail says 5.1-RELEASE, that was a typo -- this actually occurred with 5.2-RELEASE).

I've found a bug in FDisk which is responsible for all the problems I've had trying to get FreeBSD installed.  I also found a work-around, and I'm happy to report I'm typing this message from Konquerer inside FreeBSD 5.2-RELEASE right now.

Basically, the problem is that FreeBSD's FDisk and the motherboard BIOS independently calculate a set of CHS values (Cylinders/Heads/Sectors) based on the total sector count of the disk, but they do it in different ways and thus end up with different values.

My hard drive is a Maxtor 5T040H4.  This is a 40GB ATA/100 IDE drive.  
Maxtor reports the physical geometry as 79408/16/63, which yields a total of 80043264 sectors.  With a large drive like this, the catch is that 79408 is too big to fit in the "cylinders" field in the BIOS, so to make the drive work, you have to calculate an "equivalent" set of CHS values (decrease the cylinders value,  while keeping the total sector count the same).  For anyone who doens't know, the formula is like this: cylinders x heads x sectors = total sector count.

My motherboard (MSI KT4 Ultra) BIOS calculates 19618/16/255 (80041440 total sectors).  FreeBSD's FDisk calculates 4982/255/63 (80035830 total sectors).  You'll notice that the total sector count is not the same, and you may wonder why.  It's because of rounding error and the fact that the calculations were done in reverse.  In theory, either set of CHS values should work fine, but the problem is that my BIOS picks one set and FDisk chooses another set -- and FDisk refuses to accept and use the set my BIOS calculated.

For instance, my BIOS starts with the REAL total sector count of 80043264.  It assumes a sector count of 255, and it assumes a heads count of 16.  So it calculates cylinders as 80043264/(255x16)=19618.44706, which rounds down to 19618.  My BIOS does all this calculation automatically for me because I chose "Auto" for the drive in the BIOS.

FDisk also starts with the REAL total sector count of 80043264.  But it assumes a sector count of 63, and it assumes a heads count of 255.  So it calculates cylinders as 80043264/(63x255)=4982.462745, which rounds down to 4982.

So, the problem is that FDisk makes *different* assumptions than my BIOS does about what the sectors and heads values should be.  I ran across some information on a BIOS manufacturer's site which claimed that for "LBA mode" SCSI drives (more accurately known as "LBA-Assist translation mode"), that it is safe to assume that sectors should be 63 and heads should be 255.  Given that FreeBSD's roots and developer community seems historically SCSI-centric, I can see how these assumptions would have been picked up and used in FDisk and considered acceptable.  But these assumed values are clearly not correct for how CHS gets calculated by many PC BIOSes for IDE drives.

Furthermore, I believe that the reason FDisk rejects the manually entered CHS of 19618/16/255 is because either (1) it tries to enforce those bad assumptions about heads and sectors, or (2) it gets confused by the rounding error.  In other words, in the case of rounding error, FDisk may be taking the manually-entered values, multiplying them together, and seeing that it doesn't exactly match (or come close enough to, in its humble but flawed opinion) the total sector count for the drive.  The way Fdisk's geometry validation ought to work is like this:

- Divide the total sector count of the drive by (H*S), where H and S are the user-supplied values.
- Round the result to the nearest whole number.
- Compare that result to the user-supplied value for cylinders.
- If the result matches, accept the user's input as good.

I hope that a developer somewhere can take this information and put it to good use.  I would be very happy to test a fix if someone can implement it.

In the meantime, the workaround for anyone experiencing this problem is to go into their BIOS and set the hard drive to "User" mode, and manually enter the same C/H/S settings that FDisk calculated for the drive.  Unfortunately, I think this means that if you have to repartition and reformat the entire drive, since the BIOS will now be addressing the drive using different C/H/S settings and will be unable to read any partitions that were formatting using different C/H/S addressing.  So while there is a workaround, it is far from an ideal user experience.


>How-To-Repeat:
Setup up a PC that has the following 3 components:

   - MSI KT4 Ultra motherboard, with latest available BIOS update

   - Maxtor 5T040H4 ATA/100 IDE hard drive as primary slave, set BIOS to detect the drive as "Auto"

   - LITE-ON LDW-811S IDE DVD/RW drive as primary master, set BIOS to detect the drive as "Auto"


(I know that the master/slave configuration of the drives is reversed from the ATAPI/IDE recommended standard config.  This was necessary in order to get sysinstall to even recognize that the DVD/RW drive was present and to mount it to get the installation packages.  This is a second bug that I will file an independent bug report on).

Note that the BIOS chooses the settings 19618/16/255 for C/H/S values for the Maxtor hard drive.

Boot off the DVD/RW using a FreeBSD 5.2-RELEASE Disc 1 CD.  Set installation options to pull from the CD-ROM for source media.  Then choose "standard install" and enter FDisk.  Note that FDisk bitches about the C/H/S values being invalid, and suggest the values 4982/255/63 instead.  Press "G" to manually enter disk geometry, and specify 19618/16/255 for C/H/S as the BIOS is using.  Note that FDisk claims these settings are invalid, and reverts back to 4982/255/63 again.  You are stuck.  Or, if you just proceed with installation using FDisk's suggested values, the installation claims it was successful, but when the machine reboots and tries to boot off the hard drive, it yields a "Missing operating system" error (because the BIOS is addressing the drive using the other C/H/S values).

>Fix:
FDisk should use different calculations to suggest and/or validate disk geometry settings, and/or the FreeBSD FAQ's and/or handbook and/or installation documentation should be updated to include the problem description, background, and the workaround, as I've described in the "Full Description" field of this bug report.
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-i386 mailing list