Date: Sun, 16 Mar 1997 13:55:38 -0700 (MST) From: Don Yuniskis <dgy@rtd.com> To: freebsd-hackers@freefall.FreeBSD.org (FreeBSD hackers) Cc: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch), bde@zeta.org.au (Bruce Evans) Subject: wd and funky geometry (understood?) Message-ID: <199703162055.NAA23944@seagull.rtd.com>
next in thread | raw e-mail | index | archive | help
Greetings! I *think* I've located the source of the geometry foul-ups I've seen with IDE drives... [apologies that the code fragments herein are quoted from a 2.1R system -- I've just dismantled the 2.1.7R system to reprogram the system ROMs :-( The code is essentially the same. Liberal snipping employed throughout for readability...] This problem appears to have been in the system since at least Aug 94 (by my notes). The problem appears to an inconsistent use of geometry information for each drive. During IPL, the drive is INITed with parameters from the BIOS's disk parameter table. This makes sense as I can't imagine any *other* place from which to get the disk geometry (reliably). From boot() in /usr/src/sys/i386/boot/biosboot/boot.c: /////////////////////////////////////////////////////////////////// #include <machine/bootinfo.h> struct bootinfo bootinfo; /* Pick up the story from the Bios on geometry of disks */ for(ret = 0; ret < N_BIOS_GEOM; ret ++) bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80); /////////////////////////////////////////////////////////////////// [get_diskinfo() system call basically does an INT 13, AH=8 (Read Drive Parameters) -- see /usr/src/sys/i386/boot/biosboot/bios.S] Since the system ROM's have already INITed the drive, the geometry reflected in bootinfo.bi_bios_geom[] will reflect the current geometries of each of these INITed drives. However, in wdattach(), wdgetctlr() is invoked to get the drive's geometry. It does this by issuing an IDENTIFY command (i.e. READP) to the drive. The data returned by the command is interpreted as a wdparams structure: /////////////////////////////////////////////////////////////////// /* * read parameters command returns this: */ struct wdparams { /* drive info */ short wdp_config; /* general configuration */ short wdp_fixedcyl; /* number of non-removable cylinders */ short wdp_removcyl; /* number of removable cylinders */ short wdp_heads; /* number of heads */ short wdp_unfbytespertrk; /* number of unformatted bytes/track */ short wdp_unfbytes; /* number of unformatted bytes/sector */ short wdp_sectors; /* number of sectors */ short wdp_minisg; /* minimum bytes in inter-sector gap*/ short wdp_minplo; /* minimum bytes in postamble */ short wdp_vendstat; /* number of words of vendor status */ /* controller info */ char wdp_cnsn[20]; /* controller serial number */ short wdp_cntype; /* controller type */ #define WDTYPE_SINGLEPORTSECTOR 1 /* single port, single sector buffer */ #define WDTYPE_DUALPORTMULTI 2 /* dual port, multiple sector buffer */ #define WDTYPE_DUALPORTMULTICACHE 3 /* above plus track cache */ short wdp_cnsbsz; /* sector buffer size, in sectors */ short wdp_necc; /* ecc bytes appended */ char wdp_rev[8]; /* firmware revision */ char wdp_model[40]; /* model name */ short wdp_nsecperint; /* sectors per interrupt */ short wdp_usedmovsd; /* can use double word read/write? */ }; /////////////////////////////////////////////////////////////////// The drive's geometry is deduced from the wdp_fixedcyl, wdp_removcyl, wdp_heads and wdp_sectors members thereof. This information is reported in the probe (actually, the attach) on the console as the device's geometry. The drive is then reINITed with these parameters by wdsetctlr() when the device is opened or an error is detected. Herein lies the problem: these parameters reflect "the default geometry of the device" (paraphrased from the ATA specification). However, the BIOS's geometry may *NOT* agree with the drives "default geometry". For example, the probe of my IDE drives yields: wdc0 at 0x1f0-0x1f7 irq 14 on isa wdc0: unit 0 (wd0): <Maxtor 7345 AT> wd0: 329MB (675450 sectors), 790 cyls, 15 heads, 57 S/T, 512 B/S wdc0: unit 1 (wd1): <MAXTOR LXT-340A> wd1: 321MB (659232 sectors), 654 cyls, 16 heads, 63 S/T, 512 B/S However, *both* drives have a BIOS geometry of 611/16/63. (Sorry, my ancient BIOS does not support "user configurable" geometries so this was the closest geometry I could find -- hence the reason I have disassembled the 2.1.7R system to reprogram the system ROMs! The drives will automatically adapt to whatever geometry they are INITed with so it doesn't pose a problem). I haven't delved into how the geometry contained within the disklabel written to the drive factors into all this. Why is all this a problem? I don't *think* it causes any problems during IPL -- since the drive is INITed with the BIOS geometry during the boot and then switched to the "default geometry" during the attach/open. I think that the image loaded from the disk during boot is small enough that changes to the size/shape of the first track are safely ignored. (though, on second thought, I suspect this *can* screw you if your FBSD partition does not begin at the start of the disk! Comments?) However, sharing a partition might be a problem since DOS's FDISK (which you used to create the DOS partition) will talk to a disk shaped per the BIOS geometry. When FBSD takes over, the geometry of the disk is changed and track/cylinder boundaries can "move" (e.g., consider my case with a default geometry of 57 S/C vs. the BIOS's 63 S/C). And, switching to/from DOS can screw you. Consider DOS and FBSD sharing wd0. FBSD reINITs the drive to use it's default geometry. Then, you mount a DOS partition FROM THE SAME DRIVE! The layout of the DOS partition expected the BIOS geometry yet the disk is now accessed using the FBSD geometry. I suspect that LBA *could* be a redeeming grace. However, I don't know enough about the *guarantees* within the drive to determine if a particular sector address will *allways* map to the same (PHYSICALLY EQUIVALENT) sector regardless of geometry (i.e., will sector "97" in a 611/16/63 geometry correspond to the exactl same physical sector when the drive is configured for 790/15/57??) [someone who really *knows* what they are talking about could probably determine the *real* effects of all this :-( ] I was initially thinking a good hack to fix this would be to simply copy the "apparent" disk geometry from the results of the IDENTIFY command (i.e. from the shorts at parameters[54] through [56]) into the "default" disk geometry parameters (i.e., the shorts at parameters[1], [4] and [6]). That seemed easier than changing the wdparams structure to include thes other fields and then *use* those fields instead of wdp_ncylinders, wdp_heads, etc. But, I'm a bit nervous about just making that change and "hoping" it doesn't break something else :> I don't claim to know what the hell I'm talking about :> so if someone would like to enlighten me as to the errors in my analysis/assumptions, I'd be *thrilled*! :> But, right now I have to try and tweek the geometries in these system ROMs to match the geometries of my drives (and forget all these other -- more interesting -- issues! :>) Thanks! --don
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703162055.NAA23944>