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