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