hyc@math.lsa.umich.edu (Howard Chu) (11/27/88)
Enclosed are diffs to allow ST-Minix to use (just about) any floppy disk
format. (82 tracks, 11 sectors, what have you. As long as it uses 512 byte
sectors it's OK. I was going to allow arbitrary sector size at first, but
it didn't seem worthwhile...) The patches should be applied thus:
In
/usr/src/commands: mkfs.dif - Patched up to create a semi-legal bootblock,
instead of all zeros. The info I consider necessary, number of
sectors per disk, and number of sectors per track, are preserved,
while a couple other fields are twiddled for the benefit of TOS and
the tos program. (Set sectors per cluster to 0x80, -128, and TOS
will show 0 bytes available. Set reserved field so tos program will
recognize it as a minix diskette...)
/usr/src/kernel: stfloppy.dif - Allocate arrays, with one entry per drive,
to record number of tracks and sectors per track on the disk in that
drive. Initialized to 80/9, these values are updated by a new procedure
do_open (with corresponding new message type DISK_OPEN) which is
called whenever a floppy disk special device file is opened.
/usr/src/fs: device.dif, mount.dif, table.dif - Change device dispatch
table to include flop_open call, which sends a DISK_OPEN message
to the floppy task. Also make the mount system call open the special
file before reading a superblock, so the flop_open will be invoked
when mounting floppy filesystems.
One other change, which I just now remembered and forgot to include in these
diffs - in /usr/src/h/com.h, add an entry to the disk message types named
DISK_OPEN - I stuck it in as message number 2, just before DISK_READ...
I'm using this system now, and haven't had any troubles yet, so I think
it's pretty stable. Your kernel will be about 1K larger when it boots. Try
it and send me any comments...
-- Howard
#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive. Save this into a file, edit it
# and delete all lines above this comment. Then give this
# file to sh by executing the command "sh file". The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r-- 1 hyc 1094 Nov 26 19:20 device.dif
# -rw-r--r-- 1 hyc 2620 Nov 26 19:21 mkfs.dif
# -rw-r--r-- 1 hyc 493 Nov 26 19:23 mount.dif
# -rw-r--r-- 1 hyc 6705 Nov 26 19:23 stfloppy.dif
# -rw-r--r-- 1 hyc 1660 Nov 26 19:23 table.dif
#
echo 'x - device.dif'
if test -f device.dif; then echo 'shar: not overwriting device.dif'; else
sed 's/^X//' << '________This_Is_The_END________' > device.dif
X*** device.c~ Thu Nov 10 21:16:04 1988
X--- device.c Fri Nov 25 06:10:58 1988
X***************
X*** 11,16 ****
X--- 11,17 ----
X * no_call: dummy procedure (e.g., used when device need not be opened)
X * tty_open: a tty has been opened
X * tty_exit: a process with pid=pgrp has exited.
X+ * flop_open: a floppy disk has been opened
X */
X
X #include "../h/const.h"
X***************
X*** 262,265 ****
X--- 263,281 ----
X dev_mess.TTY_PGRP = 0;
X (*dmap[major].dmap_rw)(task, &dev_mess);
X return(OK);
X+ }
X+
X+ /*===========================================================================
X+ * flop_open
X+ *===========================================================================*/
X+ PUBLIC flop_open(task_nr, mess_ptr)
X+ int task_nr;
X+ message *mess_ptr;
X+ {
X+ /* Tell floppy task to read block 0 of the diskette and configure itself...*/
X+ mess_ptr->m_type = DISK_OPEN;
X+ mess_ptr->DEVICE = (mess_ptr->DEVICE >> MINOR) & BYTE;
X+ mess_ptr->PROC_NR = task_nr;
X+ (*dmap[major].dmap_rw)(task_nr, mess_ptr);
X+ if(mess_ptr->m_type == SUSPEND) suspend(task_nr);
X }
________This_Is_The_END________
if test `wc -c < device.dif` -ne 1094; then
echo 'shar: device.dif was damaged during transit (should have been 1094 bytes)'
fi
fi ; : end of overwriting check
echo 'x - mkfs.dif'
if test -f mkfs.dif; then echo 'shar: not overwriting mkfs.dif'; else
sed 's/^X//' << '________This_Is_The_END________' > mkfs.dif
X*** mkfs.c~ Thu Nov 10 21:35:38 1988
X--- mkfs.c Sat Nov 26 17:44:04 1988
X***************
X*** 69,75 ****
X--- 69,100 ----
X long lseek();
X char gwarning[] = {65,46,83,46,84,97,110,101,110,98,97,117,109,10};
X
X+ /*
X+ * Block 0 of a TOS media -- from tos.c
X+ * (media : floppy diskette or hard disk partion)
X+ * Contains media description and boot code
X+ */
X+ struct block0 {
X+ char b0_res0[8];
X+ char b0_serial[3];
X+ char b0_bps[2];
X+ char b0_spc;
X+ char b0_res[2];
X+ char b0_nfats;
X+ char b0_ndirs[2];
X+ char b0_nsects[2];
X+ char b0_media;
X+ char b0_spf[2];
X+ char b0_spt[2];
X+ char b0_nsides[2];
X+ char b0_nhid[2];
X+ char b0_code[0x1e2];
X+ };
X+ struct block0 block0;
X+ char buf[BLOCK_SIZE - sizeof(block0)];
X
X+ /* convert an 88-format short into a 68-format short */
X+ #define sh88tosh68(ch) ((short)(((ch)[1]<<8)|(ch)[0]))
X
X /*================================================================
X * mkfs - make filesystem
X***************
X*** 165,176 ****
X } /* end switch */
X } /* end while */
X
X
X-
X #ifdef UNIX
X if (!donttest) {
X static short testb[BLOCK_SIZE/sizeof(short)];
X
X /* Try writing the last block of partition or diskette. */
X ls = lseek(fd, ((long)blocks - 1L) * BLOCK_SIZE, 0);
X testb[0] = 0x3245;
X--- 190,207 ----
X } /* end switch */
X } /* end while */
X
X+ cache_init();
X+ get_block (0, &block0); /* get_block routine cheats... */
X+ get_block (0, &block0);
X
X #ifdef UNIX
X if (!donttest) {
X static short testb[BLOCK_SIZE/sizeof(short)];
X
X+ i = sh88tosh68(block0.b0_nsects) / 2;
X+ if (blocks > i)
X+ pexit("File system is too big for minor device");
X+
X /* Try writing the last block of partition or diskette. */
X ls = lseek(fd, ((long)blocks - 1L) * BLOCK_SIZE, 0);
X testb[0] = 0x3245;
X***************
X*** 192,201 ****
X }
X #endif
X
X /* make the file-system */
X
X! cache_init();
X! put_block (0, zero); /* Write a null boot block. */
X
X zone_shift = 0; /* for future use */
X zones = blocks >> zone_shift;
X--- 223,241 ----
X }
X #endif
X
X+ /* Fix the boot block up.... */
X+
X+ block0.b0_res0[0] = block0.b0_res0[1] = 0;
X+ for (i=0; i<6; i++) block0.b0_res0[i+2] = "MINIX "[i];
X+ block0.b0_spc = 0x80;
X+ block0.b0_nfats = 0;
X+ block0.b0_ndirs[0] = block0.b0_ndirs[1] = 0;
X+ block0.b0_spf[0] = block0.b0_spf[1] = 0;
X+ bzero(block0.b0_code, sizeof(block0.b0_code) + sizeof(buf));
X+
X /* make the file-system */
X
X! put_block (0, &block0); /* Write a new boot block. */
X
X zone_shift = 0; /* for future use */
X zones = blocks >> zone_shift;
________This_Is_The_END________
if test `wc -c < mkfs.dif` -ne 2620; then
echo 'shar: mkfs.dif was damaged during transit (should have been 2620 bytes)'
fi
fi ; : end of overwriting check
echo 'x - mount.dif'
if test -f mount.dif; then echo 'shar: not overwriting mount.dif'; else
sed 's/^X//' << '________This_Is_The_END________' > mount.dif
X*** mount.c~ Thu Nov 10 21:16:10 1988
X--- mount.c Fri Nov 25 07:21:42 1988
X***************
X*** 50,55 ****
X--- 50,58 ----
X if (found) return(EBUSY); /* already mounted */
X if (sp == NIL_SUPER) return(ENFILE); /* no super block available */
X
X+ /* Touch the device. Updates floppy tables in the kernel... */
X+ if ( (r = dev_open(dev, 0)) != OK) return(r);
X+
X /* Fill in the super block. */
X sp->s_dev = dev; /* rw_super() needs to know which dev */
X rw_super(sp, READING);
________This_Is_The_END________
if test `wc -c < mount.dif` -ne 493; then
echo 'shar: mount.dif was damaged during transit (should have been 493 bytes)'
fi
fi ; : end of overwriting check
echo 'x - stfloppy.dif'
if test -f stfloppy.dif; then echo 'shar: not overwriting stfloppy.dif'; else
sed 's/^X//' << '________This_Is_The_END________' > stfloppy.dif
X*** stfloppy.c~ Thu Nov 10 21:19:46 1988
X--- stfloppy.c Sat Nov 26 18:02:44 1988
X***************
X*** 11,17 ****
X * | DISK_READ | device | proc nr | bytes | offset | buf ptr |
X * |------------+---------+---------+---------+---------+---------|
X * | DISK_WRITE | device | proc nr | bytes | offset | buf ptr |
X! * ----------------------------------------------------------------
X *
X * The file contains two entry points:
X *
X--- 11,19 ----
X * | DISK_READ | device | proc nr | bytes | offset | buf ptr |
X * |------------+---------+---------+---------+---------+---------|
X * | DISK_WRITE | device | proc nr | bytes | offset | buf ptr |
X! * |------------+----------------------------------------------------
X! * | DISK_OPEN | device | proc nr | <-- this is new
X! * ----------------------------------
X *
X * The file contains two entry points:
X *
X***************
X*** 54,59 ****
X--- 56,64 ----
X #define NR_DRIVES 2 /* maximum number of drives */
X #define NR_TYPES 2 /* number of diskette/drive combinations */
X #define MAX_ERRORS 10 /* how often to try rd/wt before quitting */
X+ PRIVATE int nr_sec[NR_DRIVES];
X+ PRIVATE int nr_cyl[NR_DRIVES];
X+ PRIVATE int Nr_sec; /* convenience copy */
X
X /* return values of xfer_ok(): */
X #define X_OK 0
X***************
X*** 103,110 ****
X dmagrab(FLOPPY, fdcint);
X dmawdat(FDC_CS, IRUPT, FDC_DELAY); /* reset controller */
X dmafree(FLOPPY);
X! for (drive = 0; drive < NR_DRIVES; drive++)
X curcyl[drive] = -1; /* uncalibrated */
X while (TRUE) {
X receive(ANY, &mess);
X ASSERT(mess.m_source >= 0);
X--- 108,118 ----
X dmagrab(FLOPPY, fdcint);
X dmawdat(FDC_CS, IRUPT, FDC_DELAY); /* reset controller */
X dmafree(FLOPPY);
X! for (drive = 0; drive < NR_DRIVES; drive++) {
X curcyl[drive] = -1; /* uncalibrated */
X+ nr_sec[drive] = NR_SECTORS;
X+ nr_cyl[drive] = NR_CYLINDERS;
X+ }
X while (TRUE) {
X receive(ANY, &mess);
X ASSERT(mess.m_source >= 0);
X***************
X*** 114,119 ****
X--- 122,128 ----
X
X /* Now carry out the work. */
X switch (mess.m_type) {
X+ case DISK_OPEN: r = do_open(&mess); break;
X case DISK_READ:
X case DISK_WRITE: r = do_rdwt(&mess); break;
X default: r = EINVAL; break;
X***************
X*** 128,133 ****
X--- 137,196 ----
X }
X
X
X+ /*===========================================================================
X+ * do_open
X+ *===========================================================================*/
X+ PRIVATE int do_open(mp)
X+ register message *mp;
X+ {
X+ register d, ret;
X+ register short temp;
X+ /*
X+ * Block 0 of a TOS media -- from tos.c
X+ * (media : floppy diskette or hard disk partion)
X+ * Contains media description and boot code
X+ */
X+ struct block0 {
X+ unsigned char b0_res0[8];
X+ unsigned char b0_serial[3];
X+ unsigned char b0_bps[2];
X+ unsigned char b0_spc;
X+ unsigned char b0_res[2];
X+ unsigned char b0_nfats;
X+ unsigned char b0_ndirs[2];
X+ unsigned char b0_nsects[2];
X+ unsigned char b0_media;
X+ unsigned char b0_spf[2];
X+ unsigned char b0_spt[2];
X+ unsigned char b0_nsides[2];
X+ unsigned char b0_nhid[2];
X+ unsigned char b0_code[0x1e2];
X+ };
X+ struct block0 block0;
X+
X+ /* convert an 88-format short into a 68-format short */
X+ #define sh88tosh68(ch) ((short)(((ch)[1]<<8)|(ch)[0]))
X+
X+ mp->m_type = DISK_READ;
X+ mp->COUNT = SECTOR_SIZE;
X+ mp->POSITION = 0L;
X+ mp->ADDRESS = (char *) &block0;
X+
X+ ret = do_rdwt(mp);
X+ if (ret != SECTOR_SIZE)
X+ return(ret);
X+ d = DRIVE(mp->DEVICE);
X+ temp = sh88tosh68(block0.b0_spt);
X+ if (!temp) { /* Probably a zeroed bootblok. Should only */
X+ nr_sec[d] = NR_SECTORS; /* happen with older Minix filesystems... */
X+ nr_cyl[d] = NR_CYLINDERS;
X+ return(0);
X+ }
X+ nr_sec[d] = temp;
X+ nr_cyl[d] = sh88tosh68(block0.b0_nsects) / nr_sec[d];
X+ return(0);
X+ }
X+
X /*===========================================================================*
X * do_rdwt *
X *===========================================================================*/
X***************
X*** 137,148 ****
X register struct proc *rp;
X register struct xfer *xp;
X register nbytes;
X extern phys_bytes umap();
X
X xp = &xfer;
X xp->x_rw = mp->m_type;
X xp->x_drive = mp->DEVICE;
X! if (DRIVE(xp->x_drive) >= NR_DRIVES)
X return(EIO);
X if (DTYPE(xp->x_drive) >= NR_TYPES)
X return(EIO);
X--- 200,213 ----
X register struct proc *rp;
X register struct xfer *xp;
X register nbytes;
X+ register d;
X extern phys_bytes umap();
X
X xp = &xfer;
X xp->x_rw = mp->m_type;
X xp->x_drive = mp->DEVICE;
X! d = DRIVE(xp->x_drive);
X! if (d >= NR_DRIVES)
X return(EIO);
X if (DTYPE(xp->x_drive) >= NR_TYPES)
X return(EIO);
X***************
X*** 152,157 ****
X--- 217,223 ----
X return(EINVAL);
X if ((nbytes % SECTOR_SIZE) != 0)
X return(EINVAL);
X+ Nr_sec = nr_sec[d];
X xp->x_secnum = (int)(mp->POSITION/SECTOR_SIZE);
X rp = proc_addr(mp->PROC_NR);
X xp->x_address = umap(rp, D, (vir_bytes) mp->ADDRESS, (vir_bytes) nbytes);
X***************
X*** 186,199 ****
X xp = &xfer;
X
X d = DTYPE(xp->x_drive);
X! cylinder = xp->x_secnum / NR_SECTORS;
X head = cylinder % nr_heads[d];
X cylinder = cylinder / nr_heads[d];
X- if (cylinder >= NR_CYLINDERS)
X- return(0);
X
X d = DRIVE(xp->x_drive);
X
X hbit = 0;
X if (select(d, head) != 0)
X hbit = HBIT; /* motor on, suppress spin up sequence */
X--- 252,266 ----
X xp = &xfer;
X
X d = DTYPE(xp->x_drive);
X! cylinder = xp->x_secnum / Nr_sec;
X head = cylinder % nr_heads[d];
X cylinder = cylinder / nr_heads[d];
X
X d = DRIVE(xp->x_drive);
X
X+ if (cylinder >= nr_cyl[d])
X+ return(0);
X+
X hbit = 0;
X if (select(d, head) != 0)
X hbit = HBIT; /* motor on, suppress spin up sequence */
X***************
X*** 230,242 ****
X return(1);
X }
X
X TRACE(printf("fd%d: %s: secnum=%d,cylinder=%d,sector=%d,head=%d\n",
X xp->x_drive, xp->x_rw == DISK_READ ? "read" : "write",
X xp->x_secnum, cylinder, sector, head));
X-
X- /* The drive is now on the proper cylinder. Read or write 1 block. */
X- sector = xp->x_secnum % NR_SECTORS;
X- sector++; /* start numbering at 1 */
X
X dmawdat(FDC_SR, sector, FDC_DELAY);
X dmaaddr(xp->x_address); /* DMA address setup */
X--- 297,309 ----
X return(1);
X }
X
X+ /* The drive is now on the proper cylinder. Read or write 1 block. */
X+ sector = xp->x_secnum % Nr_sec;
X+ sector++; /* start numbering at 1 */
X+
X TRACE(printf("fd%d: %s: secnum=%d,cylinder=%d,sector=%d,head=%d\n",
X xp->x_drive, xp->x_rw == DISK_READ ? "read" : "write",
X xp->x_secnum, cylinder, sector, head));
X
X dmawdat(FDC_SR, sector, FDC_DELAY);
X dmaaddr(xp->x_address); /* DMA address setup */
________This_Is_The_END________
if test `wc -c < stfloppy.dif` -ne 6705; then
echo 'shar: stfloppy.dif was damaged during transit (should have been 6705 bytes)'
fi
fi ; : end of overwriting check
echo 'x - table.dif'
if test -f table.dif; then echo 'shar: not overwriting table.dif'; else
sed 's/^X//' << '________This_Is_The_END________' > table.dif
X*** table.c~ Thu Nov 10 21:16:20 1988
X--- table.c Sun Nov 20 21:15:28 1988
X***************
X*** 107,113 ****
X };
X
X
X! extern rw_dev(), rw_dev2(), tty_open();
X
X /* The order of the entries here determines the mapping between major device
X * numbers and tasks. The first entry (major device 0) is not used. The
X--- 107,113 ----
X };
X
X
X! extern rw_dev(), rw_dev2(), tty_open(), flop_open();
X
X /* The order of the entries here determines the mapping between major device
X * numbers and tasks. The first entry (major device 0) is not used. The
X***************
X*** 120,126 ****
X ---- ---------- ----- ------- ------ ---- */
X 0, 0, 0, 0, /* 0 = not used */
X no_call, rw_dev, no_call, MEM, /* 1 = /dev/mem */
X! no_call, rw_dev, no_call, FLOPPY, /* 2 = /dev/fd0 */
X no_call, rw_dev, no_call, WINCHESTER, /* 3 = /dev/hd0 */
X tty_open, rw_dev, no_call, TTY, /* 4 = /dev/tty0 */
X no_call, rw_dev2, no_call, TTY, /* 5 = /dev/tty */
X--- 120,126 ----
X ---- ---------- ----- ------- ------ ---- */
X 0, 0, 0, 0, /* 0 = not used */
X no_call, rw_dev, no_call, MEM, /* 1 = /dev/mem */
X! flop_open, rw_dev, no_call, FLOPPY, /* 2 = /dev/fd0 */
X no_call, rw_dev, no_call, WINCHESTER, /* 3 = /dev/hd0 */
X tty_open, rw_dev, no_call, TTY, /* 4 = /dev/tty0 */
X no_call, rw_dev2, no_call, TTY, /* 5 = /dev/tty */
________This_Is_The_END________
if test `wc -c < table.dif` -ne 1660; then
echo 'shar: table.dif was damaged during transit (should have been 1660 bytes)'
fi
fi ; : end of overwriting check
exit 0
--
/
/_ , ,_. Howard Chu
/ /(_/(__ University of Michigan
/ Computing Center College of LS&A
' Unix Project Information Systems