home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- *
- * Read/Write routines to access the basic block info needed:
- * The Master Boot Block
- * The Partition Boot Block
- * The Bad Track Table
- * The Partition End Record Block
- * and The contents of the CMOS RAM chip
- *
- ***************************************************************
- *
- * Revision Control Information
- *
- * By: $Author: root $
- * $Revision: 1.2 $
- * Last modified: $Date: 87/09/16 02:12:24 $
- * $Source: /u/src/microport/newfdisk/test/RCS/getput.c,v $
- *
- * Release state: $State: Exp $
- *
- ***************************************************************
- *
- * Modification Log
- * ----------------
- * $Log: getput.c,v $
- * Revision 1.2 87/09/16 02:12:24 root
- * maintenance update
- *
- * Revision 1.1 88/04/07 23:11:20 root
- * Initial revision
- *
- *
- ***************************************************************
- */
-
- #ifndef lint
- static char rcsid[] =
- "$Header: getput.c,v 1.2 87/09/16 02:12:24 root Exp $";
- #endif
-
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/param.h>
- #include <sys/types.h>
- #include <malloc.h>
- #include "cmos.h" /* cmos layout */
- #include "mbb.h" /* master boot block */
- #include "pbb.h" /* partition boot block */
- #include "btt.h" /* bad track table */
- #include "per.h" /* partition end record */
-
- #include "fdisk.h"
-
- static int fds[2] = { -1, -1 }; /* fds for both hard disk drives */
-
- static char *unitname[] = { /* entire disk... */
- "/dev/rdsk/0s10",
- "/dev/rdsk/1s10"
- };
-
- /*
- ** Open a file which corrosponds to the entire disk.
- ** All other operations require that this be done before they call
- ** any disk I/O routines!
- */
-
- int openunit( unit )
- int unit;
- {
- char dummyblock[512];
-
- if (unit < 0 || unit > 1)
- return ERROR;
-
- if ( fds[unit] != -1 )
- closeunit( unit );
-
- if ((fds[unit] = open(unitname[unit], O_RDWR)) == -1) {
- fprintf(stderr, "Can't open %s, errno=%d\n", unitname[unit], errno);
- exit(errno);
- }
-
- /*
- ** WHY is this needed???
- */
-
- read(fds[unit],dummyblock,512); /* dummy read to force wnsweep */
- return OK;
- }
-
- closeunit( unit )
- int unit;
- {
- close( fds[unit] );
- fds[unit] = -1;
- return OK;
- }
-
- /*
- ** Read the Master Boot Block (MBB) from the hard disk
- */
-
- get_MBB( unit, mbbp )
- int unit;
- mbb_t *mbbp;
- {
- if (read_sector(fds[unit],mbbp,0,0,1 )) {
- fprintf(stderr, "read error: %s (c0,h0,s1), errno=%d\n",
- unitname[unit], errno);
- exit(errno);
- }
- }
-
- /*
- ** Write the Master Boot Block (MBB) to the hard disk
- */
-
- put_MBB( unit, mbbp )
- int unit;
- mbb_t *mbbp;
- {
- if (write_sector(fds[unit],mbbp,0,0,1 )) {
- fprintf(stderr, "write error: %s (c0,h0,s1), errno=%d\n",
- unitname[unit], errno);
- exit(errno);
- }
- }
-
- #define BOOTDRTBLOFF 0x1ee
-
- int get_PBB( unit, mbbp, pbbp ); /* Return OK if a valid PBB, */
- int unit; /* FAIL if not a uport PBB */
- mbb_t *mbbp;
- pbb_t *pbbp;
- {
- int dptdbg = 0;
-
- partition_t *pn;
- unsigned char beginsec;
- unsigned int begincyl;
-
- /*
- * Get the active unix partition boot sector where a ROM compatible
- * drive parameter entry (and Unix boot code) may be written
- */
-
- pn = (partition_t *) (mbbp + PTOFFSET);
- for (i=0; i < 4; ++i, ++pn) /* find active paratition */
- if (pn->part_boot == 0x80 &&
- ( pn->part_sys == 5 || pn->part_sys == 0x52 ) /* types 5 and 52 */
- ) /* are System5 */
- break;
- if (i < 4) { /* we found the active Microport Unix partition */
- begincyl = ((pn->part_start_s & 0xC0) << 2) | pn->part_start_c;
- beginsec = pn->part_start_s & 0x3F; /* why is this here? */
-
- read_sector(fds[unit],pbbp,begincyl,
- pn->part_start_h,
- pn->part_start_s & 0x1f);
- if (VALID_PBB(pbbp))
- return OK;
- }
- return FAIL; /* indicate not uport boot sector */
- }
-
- init_PBB( unit, mbbp, pbbp, driveinfo );
- int unit; /* unit to write drive table on */
- mbb_t *mbbp; /* this holds current partition table */
- pbb_t *pbbp; /* 512 byte work space */
- i1010drtab *driveinfo; /* and this the disk geometry */
- {
- int bsfd;
- if ((bsfd=open("/etc/boot.hd", 0)) < 0) {
- fprintf(stderr,"Can't open /etc/boot.hd\n");
- fprintf(stderr,"System5 partition on Hard Disk %d isn't bootable\n",
- unit);
- return;
- }
- if (dptdbg)
- fprintf(stderr, "Reading /etc/boot.hd\n");
- read(bsfd, pbbp, 512);
- close(bsfds[unit]);
-
- R_CYLS( ROMTABLE(pbbp) ) = driveinfo->dr_ncyl;
- R_HEADS( ROMTABLE(pbbp) ) = driveinfo->dr_nfhead;
- if (driveinfo->dr_nfhead > 8)
- R_HDFLAG( ROMTABLE(pbbp) ) = MORETHAN8HEADS;
- else
- R_HDFLAG( ROMTABLE(pbbp) ) = LESSTHAN8HEADS;
- R_PRECOMP( ROMTABLE(pbbp) ) = driveinfo->dr_precomp;
- R_LZ( ROMTABLE(pbbp) ) = driveinfo->dr_lzone;
- R_SPT( ROMTABLE(pbbp) ) = driveinfo->dr_nsec;
-
- VALIDATE_PBB( pbbp );
-
- return OK;
- }
-
- write_PBB( unit, mbbp, pbbp );
- int unit; /* unit to write drive table on */
- mbb_t *mbbp; /* this holds current partition table */
- pbb_t *pbbp; /* filled in and valid pbb */
- {
- partition_t *pn; /* partition table entry */
- unsigned char beginsec;
- unsigned int begincyl;
-
- /*
- * Find the Active Microport partition in the MBB and write the
- * Partition Boot Record to the beginning of it.
- */
-
- pn = (partition_t *) (mbbp + PTOFFSET); /* partition table */
-
- for (i=0; i < 4; ++i, ++pn) /* find active paratition */
- if (pn->part_boot == 0x80 &&
- ( pn->part_sys == 5 || pn->part_sys == 0x52 )
- )
- break;
- if (i < 4) { /* we found the active Microport Unix partition */
- begincyl = ((pn->part_start_s & 0xC0) << 2) | pn->part_start_c;
- beginsec = pn->part_start_s & 0x3F; /* why is this here? */
-
- if (dptdbg)
- fprintf(stderr,"Update PBB at C %u, H %d, S %d for unit %d\n",
- begincyl, pt->part_start_h & 0xff, pt->part_start_s & 0x1f, unit);
-
- write_sector(fds[unit],pbbp,begincyl, pn->part_start_h,
- pn->part_start_s & 0x1F);
- }
- }
-
-
- get_CMOS( cmosp )
- struct cmos *cmosp;
- {
- int cmosfd;
-
- if ((cmosfd = open(CMOSDEV, 0)) == -1) {
- perror("Opening cmos device");
- exit(1);
- }
- if ( sizeof(struct cmos) != read(cmosfd, cmosp, sizeof(struct cmos))) {
- perror("Reading cmos device");
- exit(1);
- }
- close(cmosfd);
- }
-
- put_CMOS( cmosp )
- struct cmos *cmosp;
- {
- unsigned int cksum, i;
- unsigned char *c;
- int cmosfds[unit];
-
- /* calculate new checksum */
- c = (unsigned char *) &cmos;
- cksum = 0;
- for(i=0x10; i<0x21; i++)
- cksum += *(c+i);
- /* Set new checksum */
- *(c + 0x2e ) = cksum >> 8; /* this is also known as cmos.cksum */
- *(c + 0x2f ) = cksum ;
-
- if ((cmosfd = open(CMOSDEV, 1)) == -1) {
- perror("Opening cmos device");
- exit(1);
- }
- if ( sizeof(struct cmos) != write(cmosfd, cmosp, sizeof(struct cmos))) {
- perror("writing cmos device");
- exit(1);
- }
- close(cmosfd);
- }
-
- /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! YET TO DO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ** read end-of-partition record, if any.
- ** get drtabs, slice table, and pointer to first bad-track sector
- **
- ** fds[unit] = fd of open /dev/rdsk/0x?0
- ** er = pointer to buffer to read the stuff into
- ** cyl, head, and sect are place on disk to read from
- */
-
- read_PER( unit, perp, cyl, head, sector)
- int unit;
- char *perp;
- int cyl, head, sector;
- {
- read_sector (fds[unit],perp,cyl,head,sector & 0x1f);
- }
-
- /* write updated partition end record back to disk */
-
- write_PER()
- {
- if (er) {
- /* move drive table to buffer */
- memcpy (er, (byte *) &drvtab, sizeof(struct i1010drtab));
- write_sector (fds[unit],er,endcyl,pt->ehead,pt->esect & 0x1f );
- }
- }
-
-
- /* read bad track table from disk */
-
- read_BT()
- {
- read_sector (fds[unit],bad,endcyl,pt->ehead, (pt->esect&0x1f)-1);
- }
-
- /* write updated bad track table back to disk */
-
- write_BT()
- {
- if (bad)
- write_sector (fds[unit],bad,endcyl,pt->ehead, (pt->esect&0x1f)-1);
- }
-
-