From owner-freebsd-questions@FreeBSD.ORG Sat Jan 24 02:42:26 2004 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 660DA16A4CE for ; Sat, 24 Jan 2004 02:42:26 -0800 (PST) Received: from smtp.covadmail.net (mx08.covadmail.net [63.65.120.68]) by mx1.FreeBSD.org (Postfix) with SMTP id 77BBF43D5A for ; Sat, 24 Jan 2004 02:42:09 -0800 (PST) (envelope-from strick@covad.net) Received: (covad.net 23388 invoked from network); 24 Jan 2004 10:42:04 -0000 Received: from unknown (HELO mist.nodomain) (strick@covad.net@68.164.175.73) by sun-qmail13 with SMTP; 24 Jan 2004 10:42:03 -0000 Received: from mist.nodomain (localhost [127.0.0.1]) by mist.nodomain (8.12.9p2/8.12.9) with ESMTP id i0OAg67F000635; Sat, 24 Jan 2004 02:42:06 -0800 (PST) (envelope-from dan@mist.nodomain) Received: (from dan@localhost) by mist.nodomain (8.12.9p2/8.12.9/Submit) id i0OAg6Rj000634; Sat, 24 Jan 2004 02:42:06 -0800 (PST) (envelope-from dan) Date: Sat, 24 Jan 2004 02:42:06 -0800 (PST) From: Dan Strick Message-Id: <200401241042.i0OAg6Rj000634@mist.nodomain> To: freebsd-questions@freebsd.org cc: dan@mist.nodomain Subject: a few words on BIOS/FDISK geometry X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Jan 2004 10:42:26 -0000 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