Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Jan 2004 02:42:06 -0800 (PST)
From:      Dan Strick <strick@covad.net>
To:        freebsd-questions@freebsd.org
Cc:        dan@mist.nodomain
Subject:   a few words on BIOS/FDISK geometry
Message-ID:  <200401241042.i0OAg6Rj000634@mist.nodomain>

next in thread | raw e-mail | index | archive | help
I find most of the BIOS/MBR/FDISK disk geometry gospel that has recently
appeared in freebsd-questions to be confusing if not actually incorrect.
In the interest of world peace of mind, I feel compelled to offer my own
model of reality.  It really isn't that complicated.

There are two common ways in which disk sector addresses are expressed.
These are the LBA (Logical Block Address) number and the C/H/S (Cylinder/
Head/Sector) numbers.  As pretty much everyone knows, the LBA and C/H/S
values are related by an expression similar to:

	LBA = (C*NH + H)*NS + S

where NH is the number of heads and NS is the number of sectors/track.
C/H/S used to be the most common address representation but LBA has since
gained popularity because it is conceptually simpler (is only one number)
and because C/H/S numbers are typically limited to inconveniently small
values.  The physical significance of the NH and NS values has been
largely eroded by the advancement of technology.  We now only use these
values when converting between sector address representations.

The system BIOS provides a basic disk access facility sometimes called
"int13".  There are different int13 "functions" for things like reading,
writing and obtaining disk parameters such as geometry.  The original
"basic" int13 functions, implemented by essentially all versions of PC
BIOS, expect sector addresses to be in C/H/S format.  There is also a set
of "extended" int13 functions, implemented by newer BIOS, that expect
sector addresses to be in 64 bit LBA format.

The disk geometry assumed by the basic int13 functions is what we mean
by the term "BIOS geometry".  The BIOS may describe different geometries
for a single disk drive in different contexts.  We only care about the
geometry the BIOS uses to interpret the disk addresses used with the
basic int13 functions.  Note that the BIOS geometry may not be related
to any physical or logical geometry used by the disk itself.

The common FreeBSD master bootstrap program may be installed and
configured with the "boot0cfg" command.  It uses the basic int13
functions by default but may be configured to use the extended functions
(the "packet" option).  When a FreeBSD partition is booted, the boot0
program boots the boot1 program in the second sector of the partition.
The boot1 program in turn boots the boot2 program.  I don't know if
these programs use basic or extended int13 functions or at what point
in the bootstrap sequence the bootstrap programs stop using the BIOS.

The MBR (Master Bootstrap Record) partition table (aka FreeBSD slice
table) which is stored in the first sector of most PC disk drives
contains the starting address of each partition in both C/H/S and LBA
format.  There are 10 bits in the cylinder field, 8 bits in the head
field, 6 bits in the sector field and 32 bits for the LBA field.
By (MS?) convention cylinder and head numbers begin at 0 but the first
sector number is 1.  There is allegedly some important program (unknown
to me) which limits the number of heads to 255.  Programs that use the
basic BIOS int13 functions to access partitions defined in an MBR can
address at most 1024 cylinders, 255 heads and 63 sectors (somewhat less
than 8 GB).

(An explanation of the many disk sizes to which PC systems are sometimes
limited is tempting but way beyond the scope of this posting.)

The FreeBSD fdisk program needs to know the disk geometry only when
filling in the C/H/S fields in the MBR partition table.  If it gets the
geometry wrong, bootstrap programs that use the basic int13 functions
may fail.  (Programs that use the extended int13 functions will not
be affected!)

The FreeBSD fdisk program sometimes gets the BIOS geometry wrong and we
have to correct it.  How can we determine the correct BIOS geometry of a
disk drive in this case?  BIOS configuration user interfaces can be
confusing and the disk drive geometries they report may not always be
those used by the basic int13 functions.  The only (usually) reliable way
to get a BIOS disk geometry may be to ask the BIOS via one of the int13
functions or to read it out of one of the data structures left behind by
the BIOS POST (power on self test).

Sometimes if we boot a FreeBSD kernel with the "-v" option it will tell
us the BIOS geometries during the autoconfiguration monologue.  I am not
sure that I trust it.  Sometimes software will report disk controller
interface geometry instead.  (Hint: if a geometry specifies more than
255 heads or 63 sectors/track, you know it is not the BIOS geometry.)
I sometimes boot grub (see /usr/ports/sysutils/grub) off a floppy and ask
it about a disk drive with the "geometry" command.  As far as I know,
this will reliably report the BIOS geometry.

Modern BIOS geometry most frequently uses 255 heads and 63 sectors/track
because that maximizes the addressable part of the disk drive using the
basic int13 functions.  Cylinder numbers greater than 1023 don't really
matter because whatever you put in the MBR will be wrong.  I typically
manually set them to 1023.  Remember that you can only boot partitions
beyond cylinder 1023 if all bootstrap programs use the extended int13
functions.

Dan Strick
strick@covad.net



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200401241042.i0OAg6Rj000634>