Followup Q to "IBM 120 G IDE -- problems"
strick at covad.net
Wed Sep 10 05:27:59 PDT 2003
On Tue, 9 Sep 2003, at 12:17:54, Mark Terribile wrote:
> Well, I've got my 120G disk up and running and
> now I'd like to understand something odd.
> I went into /stand/sysinstall to put down the
> partition and slice tables and the FS and found that
> it determined the geometry (cyl/head/sectors) as
> 15107/255/63 . Since it warned that the values must
> match the BIOS values, I set them to the 59131/16/255
> that the BIOS reports. It rejected this entry and
> went back to its own. I also tried the values
> by the ata driver on startup; these too were rejected.
> Since it's working (with about 117G -- that's
> Gi_b_abytes) it must be OK (famous last words!) but
> what's going on here? Why does it demand the values
> reported by the BIOS if it will refuse them, and why
> does the driver come up with another set of values,
> also unacceptible to the disklabel/fdisk machinery?
I expect that most people reading this are aware of some of the
limitations of "BIOS" disk addressing, including the physical disk
addresses in the disk partition table in the MBR (master bootstrap
record) of bootable PC disk drives which allocates only 10 bits for
the cylinder number, 8 bits for the head number, and 6 bits for the
sector number. There is also a Fixed Disk "Drive Parameter Table"
available through the traditional BIOS. The table format allocates
16 bits for the number of cylinders, 8 bits for the number of heads,
and 8 bits for the number of sectors per track. Since BIOS sector
numbers begin at one (not zero), the BIOS addressing limitations are
usually given as 1024 cylinders, 255 heads, and 63 sectors per track.
(Note: 1024*255*63 sectors is just under 8GB.)
The ATA/IDE specifications limit you to 65535 cylinders, 16 heads,
and 255 sectors per track (see http://www.t13.org). If you accept
both sets of limitations at once, you get a maximum of 1024 cylinders,
16 heads and 63 sectors, resulting in the infamous "528" MB hard
disk size limitation.
In an effort to work around this unacceptable limitation, your
BIOS may pretend that your disk drive has some other geometry,
typically using 255 heads and 63 sectors per track though other
fake geometries are sometimes used. When a program uses the
traditional BIOS system call to do disk I/O (machine instruction
"int 13" with a small function code < 0x16 in the AH register),
it must use the same disk geometry that is used by the BIOS for
interpreting disk addresses. Otherwise the BIOS might translate
the specified physical disk address into the wrong actual disk
(Note: there are also "Enhanced Disk Drive Services" (EDD) using
AH register function codes >=0x40 which have bigger limitations and
might support Logical Block Addresses (LBA) instead of physical disk
addresses. EDD is also described at http://www.t13.org. I don't
know which BIOS/bootstrap programs support/use EDD. Modern BIOS
presumably provides EDD services. It doesn't do you any good if
your BIOS supports EDD but your bootstrap program doesn't use it.
The FreeBSD minimal bootstrap that just boots the active partition,
/usr/src/sys/boot/i386/mbr/mbr.s, appears to use EDD services when
available. The "booteasy" program that allows you to specify a
desired partition via a function key, which may be the program
.../tools/srcs/bteasy/BOOT.ASM in your FreeBSD distribution, does
not seem to use EDD services. (I am not certain that this is the
bootstrap installed by /stand/sysinstall.) The GRUB bootstrap
program (in /usr/ports/sysutils/grub) appears to use both EDD
services and LBA when available.)
The only way to discover the geometry expected by the BIOS is to
ask the BIOS. This is no problem for bootstrap programs and some
Microsoft "operating systems" that use the BIOS disk services for
all disk I/O, but the BIOS services cannot be used by a "real"
operating system after it takes over the interrupt and virtual
memory management hardware and possibly trashes the data structures
built by the BIOS during POST (Power On Self Test). A BIOS service
routine is likely to do things unacceptable to a "real" OS, such
as screwing with system hardware configuration registers or going
into indefinite spin loops waiting for device register bits to
The FreeBSD /stand/sysinstall and fdisk programs need to use the
BIOS disk geometry when constructing MBR partition tables. It would
be nice if the kernel could get this information from the BIOS early
in the bootstrap process and stash it somewhere for further reference,
but this seems not to be a FreeBSD kernel feature. The fdisk and
/stand/sysinstall programs apparently try to guess the BIOS disk
geometry and then ask the user for the "correct" geometry. It would
only be fair if the man pages for those programs told you *how*
to determine the correct geometry.
Some BIOS self-configuration programs (what you boot when holding
down the DEL key) may tell you about some ATA/IDE drives, but I am
not sure I trust them. One BIOS gives me a choice of three or four
different geometries for each drive, some of which are suspect
because they specify more than 63 sectors per track. Keep in mind
that your BIOS may support EDD services but your bootstrap program
might not use them.
An old hack for determining BIOS disk geometry is to clear the disk
MBR (zero the first sector), boot DOS, create a new partition table
with a moderately sized DOS partition using the DOS FDISK program,
and then use the FreeBSD fdisk program to examine the result. Each
partition in the MBR partition table is described both by beginning
and ending physical disk addresses and by a 32 bit starting block
number (zero origin) and a 32 bit size in blocks. The DOS partition
should begin after the first track. Its starting block number should
be the number of sectors per track. From that and the partition size
and the physical address of the last block in the partition, you can
compute the number of heads.
You might try booting a GRUB floppy and use the "geometry" command
to display the disk geometry, but I am not sure where GRUB gets its
When I recently used the FreeBSD 5.1 /stand/sysinstall program on a
120GB serial ATA disk drive, the program program first said that the
drive had 16 heads and 255 sectors per track and some ridiculous
number of cylinders. Then the program said that this geometry was
incorrect and that it was going to use 255 heads and 63 sectors per
track. Then it strongly advised me to tell it the actual geometry
used by the BIOS. I doubt it got the initial geometry from the BIOS
(which ought to know better than to use more than 63 sectors per track).
Perhaps it got the geometry from an ATA disk controller function.
This seems more likely and it explains the geometry. I would expect
the BIOS to use 255 heads and 63 sectors per track. This is what the
GRUB geometry command reports for the drive. So I let /stand/sysinstall
use that geometry.
Since I don't boot off that drive and I don't access it using any
operating system that uses BIOS disk I/O, it won't make any difference
if the physical disk addresses are wrong. I am pretty sure that
FreeBSD uses the partition starting block numbers and sizes in the
partition table instead of the physical C/H/S disk addresses.
For an alternative discussion of BIOS geometry,
strick at covad.net
More information about the freebsd-questions