*BSD News Article 13779


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!saimiri.primate.wisc.edu!zaphod.mps.ohio-state.edu!uwm.edu!linac!att!att-out!rutgers!igor.rutgers.edu!geneva.rutgers.edu!hedrick
From: hedrick@geneva.rutgers.edu (Charles Hedrick)
Newsgroups: comp.os.386bsd.questions
Subject: Re: MREAD -- patch to access DOS partitions
Message-ID: <Mar.31.03.38.01.1993.4626@geneva.rutgers.edu>
Date: 31 Mar 93 08:38:07 GMT
References: <1paal2INN43f@stimpy.css.itd.umich.edu>
Organization: Rutgers Univ., New Brunswick, N.J.
Lines: 200

altitude@css.itd.umich.edu (Alexander King Tang) writes:

>Hi.  I was just wondering if it's possible to mread from my C: drive if I've
>got both a bsd and dos partition?  I know that there is another mread article
>but I can't get to the articles.  sorry. Thanx.

Mread as it comes in the distribution is configured to use /dev/rwd0d.
That's the whole disk, in raw mode.  That's more or less OK if DOS is
your first partition.  If not, you lose.

Here's a patch to wd.c to allow access to all your DOS partitions.
If the 0x40 bit is on in the minor number, the low order bits are
interpreted as a DOS partition number, rather than a BSD partition
number.  More precisesly, the minor number is 64 + N, where N is
the DOS partition number (starting from 0).  So if DOS is in your
4th partition, do

  mknod /dev/rdosC c 3 67

Then you'll have to fix up mread, mwrite, etc., to access /dev/rdosC
for c:.  That mapping is set up in devices.c.  If you can't rebuild
from source, and you're brave, you can edit the binary in emacs.  It's
not hard to find the device names.

I haven't tried building a file system in DOS partition and mounting
it, though I don't see why it wouldn't work.

This patch is extremely simple, because all the mechanism is already
present in the code.  It already reads and decodes the DOS partition
table, and it already defines the 0x40 bit has having the effect I
wanted.  It's just missing a few lines of code to acctually implement
the bit.

I use this mechanism to do backups:

  dump 0f - / | compress | mwrite - c:/unixback/dump.bsd

(My version of mwrite accepts input from primary input if you specify
- as a file name.  Unfortunately /dev/fd/0 won't work, because the
stock mwrite wants to stat the file to see how big it is.)

By the way, the following patch also includes a change to 
wdcommand to increase the timeouts.  I needed this in order to
use Bruce Evans' com patches.  You can ignore those changes if
you prefer.

-----------------------
*** wd.c.HOLD	Tue Jul 14 20:55:21 1992
--- wd.c	Tue Mar 30 04:29:58 1993
***************
*** 247,253 ****
  	}
  
  	/* have partitions and want to use them? */
! 	if ((du->dk_flags & DKFL_BSDLABEL) != 0 && wdpart(bp->b_dev) != WDRAW) {
  
  		/*
  		 * do bounds checking, adjust transfer. if error, process.
--- 247,255 ----
  	}
  
  	/* have partitions and want to use them? */
! 	if ((du->dk_flags & DKFL_BSDLABEL) != 0 &&
! 	    wdpart(bp->b_dev) != WDRAW &&
! 	    wddospart(bp->b_dev) == 0) {
  
  		/*
  		 * do bounds checking, adjust transfer. if error, process.
***************
*** 320,325 ****
--- 322,328 ----
  	register struct disk *du;	/* disk unit for IO */
  	register struct buf *bp;
  	struct disklabel *lp;
+ 	struct dos_partition *dosp;
  	struct buf *dp;
  	register struct bt_bad *bt_ptr;
  	long	blknum, pagcnt, cylin, head, sector;
***************
*** 366,377 ****
  		du->dk_bc = bp->b_bcount;
  
  	lp = &du->dk_dd;
  	secpertrk = lp->d_nsectors;
  	secpercyl = lp->d_secpercyl;
  	cylin = blknum / secpercyl;
  	head = (blknum % secpercyl) / secpertrk;
  	sector = blknum % secpertrk;
! 	if ((du->dk_flags & DKFL_BSDLABEL) != 0 && wdpart(bp->b_dev) != WDRAW)
  		cylin += lp->d_partitions[wdpart(bp->b_dev)].p_offset
  				/ secpercyl;
  
--- 369,385 ----
  		du->dk_bc = bp->b_bcount;
  
  	lp = &du->dk_dd;
+ 	dosp = du->dk_dospartitions;
+ 	if (wddospart(bp->b_dev))
+ 		blknum += dosp[wdpart(bp->b_dev)].dp_start;
  	secpertrk = lp->d_nsectors;
  	secpercyl = lp->d_secpercyl;
  	cylin = blknum / secpercyl;
  	head = (blknum % secpercyl) / secpertrk;
  	sector = blknum % secpertrk;
! 	if ((du->dk_flags & DKFL_BSDLABEL) != 0 &&
! 	    wdpart(bp->b_dev) != WDRAW &&
! 	    wddospart(bp->b_dev) == 0)
  		cylin += lp->d_partitions[wdpart(bp->b_dev)].p_offset
  				/ secpercyl;
  
***************
*** 670,676 ****
  		du->dk_dd.d_secpercyl = 17*8;
  		du->dk_state = WANTOPEN;
  		du->dk_unit = unit;
! 		if (part == WDRAW)
  			du->dk_flags |= DKFL_QUIET;
  		else
  			du->dk_flags &= ~DKFL_QUIET;
--- 678,684 ----
  		du->dk_dd.d_secpercyl = 17*8;
  		du->dk_state = WANTOPEN;
  		du->dk_unit = unit;
! 		if (part == WDRAW && wddospart(dev) == 0)
  			du->dk_flags |= DKFL_QUIET;
  		else
  			du->dk_flags &= ~DKFL_QUIET;
***************
*** 704,710 ****
           * that overlaps another partition which is open
           * unless one is the "raw" partition (whole disk).
           */
!         if ((du->dk_openpart & mask) == 0 /*&& part != RAWPART*/ && part != WDRAW) {
  		int	start, end;
  
                  pp = &du->dk_dd.d_partitions[part];
--- 712,719 ----
           * that overlaps another partition which is open
           * unless one is the "raw" partition (whole disk).
           */
!         if ((du->dk_openpart & mask) == 0 /*&& part != RAWPART*/ &&
! 	    part != WDRAW && wddospart(dev) == 0) {
  		int	start, end;
  
                  pp = &du->dk_dd.d_partitions[part];
***************
*** 728,734 ****
                                      pp - du->dk_dd.d_partitions + 'a');
                  }
          }
!         if (part >= du->dk_dd.d_npartitions && part != WDRAW)
                  return (ENXIO);
  
  	/* insure only one open at a time */
--- 737,744 ----
                                      pp - du->dk_dd.d_partitions + 'a');
                  }
          }
!         if (part >= du->dk_dd.d_npartitions && part != WDRAW && 
! 	    wddospart(dev) == 0)
                  return (ENXIO);
  
  	/* insure only one open at a time */
***************
*** 828,834 ****
   */
  static int
  wdcommand(struct disk *du, int cmd) {
! 	int timeout = 1000000, stat, wdc;
  
  	/* controller ready for command? */
  	wdc = du->dk_port;
--- 838,844 ----
   */
  static int
  wdcommand(struct disk *du, int cmd) {
! 	int timeout = 10000000, stat, wdc;
  
  	/* controller ready for command? */
  	wdc = du->dk_port;
***************
*** 839,844 ****
--- 849,855 ----
  
  	/* send command, await results */
  	outb(wdc+wd_command, cmd);
+ 	timeout = 10000000;
  	while (((stat = inb(wdc+wd_status)) & WDCS_BUSY) && timeout > 0)
  		timeout--;
  	if (timeout <= 0)
***************
*** 847,852 ****
--- 858,864 ----
  		return (stat);
  
  	/* is controller ready to return data? */
+ 	timeout = 10000000;
  	while (((stat = inb(wdc+wd_status)) & (WDCS_ERR|WDCS_DRQ)) == 0 &&
  		timeout > 0)
  		timeout--;