From owner-svn-src-all@FreeBSD.ORG Tue Jun 16 01:13:01 2009 Return-Path: Delivered-To: svn-src-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9EAE6106566C; Tue, 16 Jun 2009 01:13:01 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail07.syd.optusnet.com.au (mail07.syd.optusnet.com.au [211.29.132.188]) by mx1.freebsd.org (Postfix) with ESMTP id 38D678FC14; Tue, 16 Jun 2009 01:13:01 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c122-106-159-184.carlnfd1.nsw.optusnet.com.au (c122-106-159-184.carlnfd1.nsw.optusnet.com.au [122.106.159.184]) by mail07.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id n5G1CvGw021738 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 16 Jun 2009 11:12:59 +1000 Date: Tue, 16 Jun 2009 11:12:58 +1000 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Ulf Lilleengen In-Reply-To: <4A367A11.4080202@FreeBSD.org> Message-ID: <20090616100938.R25672@delplex.bde.org> References: <200906151618.n5FGIO0o094444@svn.freebsd.org> <4931048A-B398-4957-B0B2-5B8BC0810F44@mac.com> <4A367A11.4080202@FreeBSD.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, Marcel Moolenaar , src-committers@FreeBSD.org Subject: Re: svn commit: r194241 - head/lib/libdisk X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jun 2009 01:13:02 -0000 On Mon, 15 Jun 2009, Ulf Lilleengen wrote: > Marcel Moolenaar wrote: >> >> On Jun 15, 2009, at 9:18 AM, Ulf Lilleengen wrote: >> >>> Author: lulf >>> Date: Mon Jun 15 16:18:24 2009 >>> New Revision: 194241 >>> URL: http://svn.freebsd.org/changeset/base/194241 >>> >>> Log: >>> - Relax sanitazion requirements in libdisk, as a previous commit >>> enabling this >>> sanitization broke sysinstall on some disks. This was due to the >>> disks >>> reporting a geometry that was incorrectly sanitized by sysinstall. >>> This makes >>> the sanitization consistent with fdisk. >> >> *snip* >> >>> + if (disk->bios_hd > 256) >>> sane = 0; >> >> The number of heads cannot exceed 255. There are only 8-bits >> in which the number of heads is stored. This also applies to >> PC98, BTW. No, the number of heads can be 256 except in certain broken APIs and BIOSes. The broken APIs don't include fdisk tables, since the maximum number of heads isn't stored. Only the maximum head number is stored. Head numbers are 0-based, so their maximum is 1 less than the number of heads. The maximum head number of 255 fits in the 8 bits in an fdisk table. Most of the original int 0x13 BIOS interfaces are similar. E.g., AH = 8 (read drive parameters) returns the maximum for each CHS value. C and H values are 0-based, so their max is one less than their number. S values are bogusly 1-based, so their max is the same as their total. AH = 2 (read sectors) and AH = 3 (write sectors) naturally pass the (current) head number (in an 8-bit register), so they never need to represent 256 in the 8-bit register. The only broken API that I remember the int 0x41 and 0x46 pseudo-interrupts. These may be only de-facto (I can't find them in the Phoenix BIOS book copyright 1987-1991), but before about 1990 the int 0x13 AH=8 interface was often not implemented and int 0x41 and int 0x46 worked better. The IDT entry for ints 0x41 and 0x46 contains a pointer to a table with the following data (0x41 for hard disk 0 and 0x46 for hard disk 1): from the header file for Minix "wini" disk drivers: /* BIOS table layout. */ typedef char wn_biosdrive[16]; #define WN_CYLINDERS(t) (* (unsigned short *) (&(t)[0x0])) #define WN_HEADS(t) (* (unsigned char *) (&(t)[0x2])) #define WN_PRECOMP(t) (* (unsigned short *) (&(t)[0x5])) #define WN_CTLBYTE(t) (* (unsigned char *) (&(t)[0x8])) #define WN_LANDINGZONE(t) (* (unsigned short *) (&(t)[0xc])) #define WN_SECTORS(t) (* (unsigned char *) (&(t)[0xe])) Many or most 1990's BIOSes present precisely this table for you to edit in their setup. They present many possibilities for obselete (even in 1990's) disks from arrays of this table in ROM, and at least 1 modifiable table per disk in CMOS. Since the head number is for the number of heads, and the table entry for it has type unsigned char, 256 heads does't fit, it becomes 0. Non-broken software would unwrap 0 back to 0 256 and just work, but having 256 (virtual) heads is not very useful so configuring it should be avoided. Apparently, some newer BIOSes know that they are non-broken here (or maybe for cylinder numbers), and default to larger numbers. Such defaults should still be avoided in case you want to move the disk to a machine with a BIOS that doesn't support them. I once tried to standardize on the maximum possible number of heads (256), but had to switch to 255 when 256 failed on only some machines. I still use 255 on all machines. With 2000's BIOSes this requires ignoring BIOS defaults and/or selecting so-called LBA mode in BIOS configurations. FreeBSD doesn't know the BIOS defaults anyway; it gives different defaults (except in my version) which I ignore. Many 2000's BIOSes produce defaults for the number of sectors that can't possibly work in fdisk tables since they significantly exceed 63. Selecting LBA mode always avoids this for me (LBA CHS = xxx/255/63). I don't know how misconfigurations from this are usually avoided. > Aha, so I should fix fdisk too then. Thanks. Please don't break fdisk too. There must be a way to set valid but dangerous values, or theoretically invalid but practically working values, if they are representable and are needed for compatibility. Bruce