Return to BSD News archive
Newsgroups: comp.os.386bsd.misc Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!constellation!convex!hermes.oc.com!news.kei.com!uhog.mit.edu!europa.eng.gtefsd.com!library.ucla.edu!agate!tfs.com!julian From: julian@tfs.com (Julian Elischer) Subject: YES.. this time it works! (mounting DOS) Message-ID: <Cv0zFo.8Iq@tfs.com> Organization: TRW Financial Systems Date: Wed, 24 Aug 1994 06:02:12 GMT Lines: 321 Thanks to the several people who helped me debug this.. I eventually found a machine I could test on.. and found the silly bugs.. here is a version that I have seen working with my own eyes... This will make a 'virtual' disklabel if none is found.. BIOS style partitions are found and set into partitions e,f,g and h. As well, if a 386bsd partition is found but no disklabel, then partitions a and c are set up correctly as well. (it should be possible to put a Filesystem on a raw 386bsd partition using this). Whether it then allows you to update the partitions without rebooting is a whole different question. There is work going on in several places to supersede this patch, but this should keep the wolves from the door in the mean-while. julian -------------------cut here-------------------- *** ufs_disksubr.c.orig Mon Jun 6 18:21:39 1994 --- ufs_disksubr.c Tue Aug 23 22:53:30 1994 *************** *** 177,190 **** struct disklabel *dlp; char *msg = NULL; int cyl, dospartoff, i; /* minimal requirements for archtypal disk label */ if (lp->d_secperunit == 0) lp->d_secperunit = 0x1fffffff; ! lp->d_npartitions = 1; ! if (lp->d_partitions[0].p_size == 0) ! lp->d_partitions[0].p_size = 0x1fffffff; lp->d_partitions[0].p_offset = 0; /* obtain buffer to probe drive with */ bp = geteblk((int)lp->d_secsize); --- 177,198 ---- struct disklabel *dlp; char *msg = NULL; int cyl, dospartoff, i; + int pseudopart = 4; /* we fill in pseudoparts from e through h*/ + int seenBSD = 0; /* minimal requirements for archtypal disk label */ if (lp->d_secperunit == 0) lp->d_secperunit = 0x1fffffff; ! lp->d_npartitions = 4; ! lp->d_partitions[0].p_size = 0; lp->d_partitions[0].p_offset = 0; + lp->d_partitions[1].p_size = 0; + lp->d_partitions[1].p_offset = 0; + lp->d_partitions[2].p_size = 0; + lp->d_partitions[2].p_offset = 0; + if(lp->d_partitions[3].p_size == 0) + lp->d_partitions[3].p_size = DOSBBSECTOR + 1; /* start low */ + lp->d_partitions[3].p_offset = 0; /* obtain buffer to probe drive with */ bp = geteblk((int)lp->d_secsize); *************** *** 205,246 **** bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl; (*strat)(bp); ! /* if successful, wander through dos partition table */ if (biowait(bp)) { msg = "dos partition I/O error"; goto done; ! } else { ! /* XXX how do we check veracity/bounds of this? */ ! bcopy(bp->b_un.b_addr + DOSPARTOFF, dp, ! NDOSPART * sizeof(*dp)); ! for (i = 0; i < NDOSPART; i++, dp++) ! /* is this ours? */ ! if (dp->dp_size && ! dp->dp_typ == DOSPTYP_386BSD ! && dospartoff == 0) { ! ! /* need sector address for SCSI/IDE, ! cylinder for ESDI/ST506/RLL */ ! dospartoff = dp->dp_start; ! cyl = DPCYL(dp->dp_scyl, dp->dp_ssect); ! ! /* update disklabel with details */ ! lp->d_partitions[0].p_size = ! dp->dp_size; ! lp->d_partitions[0].p_offset = ! dp->dp_start; ! lp->d_ntracks = dp->dp_ehd + 1; ! lp->d_nsectors = DPSECT(dp->dp_esect); ! lp->d_subtype |= (lp->d_subtype & 3) ! + i | DSTYPE_INDOSPART; ! lp->d_secpercyl = lp->d_ntracks * ! lp->d_nsectors; ! } } } ! /* next, dig out disk label */ bp->b_blkno = dospartoff + LABELSECTOR; bp->b_cylin = cyl; bp->b_bcount = lp->d_secsize; --- 213,356 ---- bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl; (*strat)(bp); ! /* ! * if we failed in the read, give up. ! */ if (biowait(bp)) { msg = "dos partition I/O error"; goto done; ! } ! /* ! * If there seems to be BIOS bootblock and partition table ! * in that block, then try interpret it, otherwise ! * give up and use whatever we have synthesised so far ! */ ! if ((*(bp->b_un.b_addr + 510) != (char) 0x55) ! ||(*(bp->b_un.b_addr + 511) != (char) 0xaa)) { ! msg = "Disk has no Fdisk partitions"; ! goto done; } + + /* XXX how do we check veracity/bounds of this? */ + bcopy(bp->b_un.b_addr + DOSPARTOFF, dp, + NDOSPART * sizeof(*dp)); + /* + * We set up the last 4 partitions in the + * disklabel to reflect the DOS partitions + * In case we never find a disklabel, in which + * case this information will be all we have + * but it might be all we need to access a DOS + * partition. + */ + for (i = 0; i < NDOSPART; i++, dp++,pseudopart++) { + + /* + * Set this DOS part into the disklabel + */ + lp->d_partitions[pseudopart].p_size = + dp->dp_size; + lp->d_partitions[pseudopart].p_offset = + dp->dp_start; + + /* + * make sure the D part can hold it all + */ + if((dp->dp_start + dp->dp_size) + > lp->d_partitions[3].p_size) { + lp->d_partitions[3].p_size + = (dp->dp_start + dp->dp_size); + } + /* + * If we haven't seen a *BSD partition then + * check if this is a valid part.. + * if it is it may be the best we are going to + * to see, so take note of it to deduce a + * geometry in case we never find a disklabel. + */ + if (dp->dp_size) { + switch(dp->dp_typ) { + case DOSPTYP_386BSD: + /* + * at a pinch we could throw + * a FFS on here + */ + lp->d_partitions[pseudopart].p_fstype + = FS_BSDFFS; + /* + * Only get a disklabel from the + * first one we see.. + */ + if (seenBSD == 0) { + /* + * If it IS our part, then we + * need sector address for + * SCSI/IDE, cylinder for + * ESDI/ST506/RLL + */ + dospartoff = dp->dp_start; + seenBSD = 1; + cyl = DPCYL(dp->dp_scyl, + dp->dp_ssect); + + /* + * update disklabel with + * details for reading the REAL + * disklabel it it exists + */ + lp->d_partitions[0].p_size = + dp->dp_size; + lp->d_partitions[0].p_offset = + dp->dp_start; + lp->d_partitions[2].p_size = + dp->dp_size; + lp->d_partitions[2].p_offset = + dp->dp_start; + } + break; + case 0xB7: /* BSDI (?)*//* doubtful */ + lp->d_partitions[pseudopart].p_fstype + = FS_BSDFFS; + break; + case 1: + case 4: + case 6: + case 0xF2: + lp->d_partitions[pseudopart].p_fstype + = FS_MSDOS; + break; + } + + /* + * Try deduce the geometry, working + * on the principle that this + * partition PROBABLY ends on a + * cylinder boundary. + * This is really a kludge, but we are + * forced into it by the PC's design. + * If we've seen a 386bsd part, + * believe it and check no further. + */ + if (seenBSD) continue; + lp->d_ntracks = dp->dp_ehd + 1; + lp->d_nsectors = DPSECT(dp->dp_esect); + lp->d_subtype |= (lp->d_subtype & 3) + + i | DSTYPE_INDOSPART; + lp->d_secpercyl = lp->d_ntracks * + lp->d_nsectors; + } + } + lp->d_npartitions = 8; } ! /* ! * If we haven't seen a BSD partition, give up, use the dos version ! */ ! if(!seenBSD) goto done; ! ! /* ! * next, dig out disk label ! */ bp->b_blkno = dospartoff + LABELSECTOR; bp->b_cylin = cyl; bp->b_bcount = lp->d_secsize; *************** *** 249,274 **** /* if successful, locate disk label within block and validate */ if (biowait(bp)) { ! msg = "disk label I/O error"; goto done; ! } else for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! if (msg == NULL) ! msg = "no disk label"; ! } else if (dlp->d_npartitions > MAXPARTITIONS || ! dkcksum(dlp) != 0) ! msg = "disk label corrupted"; ! else { ! *lp = *dlp; ! msg = NULL; ! break; } } ! ! if (msg) goto done; /* obtain bad sector table if requested and present */ if (bdp && (lp->d_flags & D_BADSECT)) { --- 359,388 ---- /* if successful, locate disk label within block and validate */ if (biowait(bp)) { ! printf("disk label I/O error\n"); goto done; ! /* leave us at least with the dos partitions */ ! } ! for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! continue; ! } ! if (dlp->d_npartitions > MAXPARTITIONS || ! dkcksum(dlp) != 0) { ! printf("disk label corrupted\n"); ! goto done; ! /* leave us at least with the dos partitions */ } + *lp = *dlp; + msg = NULL; + break; } ! if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! printf("No disklabel found\n"); goto done; + } /* obtain bad sector table if requested and present */ if (bdp && (lp->d_flags & D_BADSECT)) { -------------------end patch------------------- +----------------------------------+ ______ _ __ | __--_|\ Julian Elischer | \ U \/ / On assignment | / \ julian@tfs.com +------>x USA \ in a very strange | ( OZ ) 300 lakeside Dr. oakland CA. \___ ___ | country ! +- X_.---._/ USA+(510) 645-3137(wk) \_/ \\ v