*BSD News Article 2628


Return to BSD News archive

Path: sserve!manuel!munnari.oz.au!mips!mips!swrinde!elroy.jpl.nasa.gov!usc!cs.utexas.edu!uunet!bonnie.concordia.ca!daily-planet.concordia.ca!davinci!steve
From: steve@concordia.ca
Newsgroups: comp.unix.bsd
Subject: Using Mtools with DOS fixed disk
Message-ID: <4621@daily-planet.concordia.ca>
Date: 28 Jul 92 03:40:02 GMT
Sender: usenet@daily-planet.concordia.ca
Organization: Concordia University, Montreal, Quebec
Lines: 102
Originator: steve@davinci


Despite all the talk about getting mtools to work with a DOS fixed
disk, none of it seemed to work.  I ended up getting things working
by taking the following approach:

1) Get a decent disk/sector editor ( I used 'DiskEdit', available
on wuarchives as /mirrors/msdos/dskutl/diskedt.zip ).  Use this
to find out what's in cylinder 0, head 0, sector 1.  The magic
offsets are 01EE, 01DE, O1CE and 01BE for the 4 possible partitions
that fdisk will report in that order.

My disk looked like this:
      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
   -------------------------------------------------
1B | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <- Unused
1C | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <- Unused
1D | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 <- DOS
                                                  ^^
1E | 01 00 06 0C B3 50 33 00 00 00 94 FF 05 00 80 00 <- 386BSD
     ^^ ^^ ^^
           || BIGDOS System Indicator (32 bit sectors)

1F | 81 51 A5 OC B3 D2 C7 FF 05 00 AE 50 01 00 55 AA
           ^^                                  ^^^^^
           386BSD System Indicator             End of MBR

Now, offset 01DE to 01ED is for my DOS partition, which is
indicated by the hex value 06 at offset 01E2.  Other valid
DOS System Indicators are 01 for DOS 12 bit FAT and 04 for
DOS 16 bit FAT (16 bit sectors).

2) Enough background. At offset 01DF the value indicates
the head(track) on which the DOS partition starts, which in
my case is track #1.  At offsets 01E0-01E1 the values are
interpreted as follows:

   01E0      01E1

 00 000001 00000000
 ^^ ^^^^^^
 |  |
 |   -> Starting sector of DOS partition = 1.
 |
 |-> Add to value at 01E1 to get 00 00000000 = 0,
     the starting cylinder # of the DOS partition.

3) Therefore we get the start of the DOS partition to be at
Cylinder # 0, Head # 1 and Sector # 1.  The same calculation
for the 386BSD partition would yield Cylinder # 593, Head # 1
and Sector #1. To turn these values into an offset usable by
the mtools device structure, we need to know a bit of the disk
geometry.  This can be obtained by looking at your disktab entry
(or by executing disklabel -r wd?).  My disktab looks like:

qlp240A|Quantum 245MB IDE (DOS in cyl. 0-592): \
	:dt=ST506:ty=winchester:se#512:nt#13:ns#51:nc#723: \
	:pa#21216:oa#393159:ta=4.2BSD:ba#4096:fa#512: \
	:pb#42432:ob#414375:tb=swap: \
	:pc#84864:oc#393159: \
	:pd#478023:od#0: \
    :ph#21216:oh#456807:th=4.2BSD:bh#4096:fh#512:

Note that the entry for partition d spans the WHOLE disk,
and partition c only spans the 386BSD portion of the disk.

You need the value for ns which is the number of sectors/head,
and nt which is the number of heads/cylinder, and se which is the
sector size in bytes.  The final calculation is:

offset = [(Cyl# * nt *ns) + (Head# * ns) + Sect# - 1] * se

which in my case yields 26112, giving the following device
description in the mtools devices.c file

#ifdef __386BSD__
struct device devices[] = {
    {'C', "/dev/rwd0d", 26112L, 16, 0, (int (O) ()) 0, 0, 0, 0},
    {'A', "/dev/rfd0a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 18}, /* 1.44m */
    {'A', "/dev/rfd0a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 15}, /* 1.2m */
    {'A', "/dev/rfd0a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 9},  /* 720k */
    {'A', "/dev/rfd0a", 0L, 12, 0, (int (*) ()) 0, 40, 2, 9},  /* 360k */
    {'A', "/dev/rfd0a", 0L, 12, 0, (int (*) ()) 0, 40, 2, 8},  /* 320k */
    {'B', "/dev/rfd1a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 18}, /* 1.44m */
    {'B', "/dev/rfd1a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 15}, /* 1.2m */
    {'B', "/dev/rfd1a", 0L, 12, 0, (int (*) ()) 0, 80, 2, 9},  /* 720k */
    {'B', "/dev/rfd1a", 0L, 12, 0, (int (*) ()) 0, 40, 2, 9},  /* 360k */
    {'B', "/dev/rfd1a", 0L, 12, 0, (int (*) ()) 0, 40, 2, 8},  /* 320k */
    {'\0', (char O) NULL, 0L, 0, 0, (int (*) ()) 0, 0, 0, 0}
};
#endif /* __386BSD__ */

It works for me.  If there is an easier way to get this information,
I don't know about it.  The closest I can get is INT 21,32 but this
doesn't seem to get me the information I want.

Hope this helps.

-- 
   Steve Biedlingmaier
   Tel.   : (514) 682-3400 ext. 284
   Fax    : (514) 686-1990
   E-mail : sbiedling@ccrit.doc.ca, steve@davinci.concordia.ca