home *** CD-ROM | disk | FTP | other *** search
- /* TODO
- * Do not allow any changes to unit 0 if HD rooted.
- * if tried, give message stating that unit 0 is READONLY if HD rooted.
- */
-
- /*
- ** Disk Configuration utility for Microport Unix V/AT
- **
- ** THIS PROGRAM IS NOT COMPLETE
- **
- ** It WILL NOT work (or compile) AS-IS.
- **
- ** Replaces fdisk, divvy, and showbad
- ** Adds "addbad" and "printconfiguration" utilities
- **
- ** Author: John Plocher April 1988
- **
- ** Last modified by $Author: plocher$ on $Date: 88/04/12 04:29:04 $
- **
- ** Locked by $Locker: plocher$
- ** $Revision: 1.0 $
- **
- ** Source is found in $Source$
- **
- **
- ** Modification Log
- ** ----------------
- ** $Log$
- */
-
- #ifndef lint
- static char rcsid[] =
- "$Header$";
- #endif
-
- #include <stdio.h>
-
- #include "localdisk.h"
-
- #include "mbb.h"
- #include "pbb.h"
- #include "per.h"
- #include "btt.h"
-
- #define NEEDED 0x00 /* Status states for various buffers */
- #define INCORE 0x01
- #define INVALID 0x02
- #define BADGEO 0x04
- #define DIRTY 0x08
-
- /* NEEDED - needs to be read in */
- /* INCORE - we have a copy - See INVALID bit for "goodness" */
- /* INCORE + BADGEO means that the geometry info in this thing */
- /* is out of date and needs to be updated to match */
- /* the PER geometry */
- /* INCORE + INVALID - bad copy on disk - need to regenerate */
- /* INCORE + DIRTY - need to update disk copy */
-
- #define CYL(x) x /* For clarification of code */
- #define HEAD(x) x
- #define SECTOR(x) x
-
-
- int HDRooted; /* "true" if booted off of hard disk */
-
- mbb_t mbb; /* structure to contain the Master boot Block */
- pbb_t pbb; /* Partition Boot Block */
- per_t per; /* Partition End Record */
- btt_t btt; /* Bad Track Table */
-
- int GEOstatus = NEEDED;
- /* NEEDED = not found yet */
- /* DIRTY = PBB and PER is out of date */
- /* BADGEO = out of bounds for HD Driver */
- int MBBstatus = NEEDED;
- /* INVALID= No MBB found on disk */
- /* depends on /etc/master.bblock, and PT */
- int PTstatus = NEEDED;
- /* DIRTY = PT changed */
- /* INVALID= bad numbers in it */
- int PBBstatus = NEEDED;
- /* DIRTY = needs to be written to disk */
- /* INVALID= No PBB found on disk */
- /* depends on GEO and /etc/boot.hd */
- int PERstatus = NEEDED;
- /* DIRTY = needs to be written to disk */
- /* INVALID= no PER found on disk */
- /* depends on GEO & SLICE */
- int SLICEstatus = NEEDED;
- /* DIRTY = modified */
- int BTTstatus = NEEDED;
- /* DIRTY = in core copy differs from disk copy */
- /* INVALID= blocks conflict with MBB/PBB/PER/BTT */
- int CMOSstatus= NEEDED;
- /* DIRTY = in core copy differs from CMOS RAM */
- /* INVALID= Bad Checksum - MUST RUN SETUP */
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
-
- int unit = 0;
- int pbbcyl, pbbhead, pbbsec;
- int percyl, perhead, persec;
- partition_t *activepartition;
-
- /*
- * For each of MBB PBB PER try reading and validating before assuming
- * it is invalid. This allows the user to screw up the partition table,
- * restore it, and not lose too much sleep (or info).
- */
-
- /*
- We look in the MBB, the PBB, the CMOS, and lastly in the user's brain
- for the drive geometry. When we find it, we will put it into the PBB
- if it is new/changed. NOTE that this will not work with PRE 2.3
- systems that expect the drive info to be found in the MBB! We do
- NOT write the geometry to the MBB because other OSs may be using
- the space... (not mentioning names, but some DOS programs are really
- not very well behaved!)
- */
-
- CMOSstatus = getCMOS( &cmos );
- if (CMOSstatus != INCORE || !CMOSdriveEnabled( unit, &cmos )) {
- fprintf(stderr,
- "Error: You must use the setup program to tell the machine that you have\n");
- fprintf(stderr,
- "a hard disk drive attached. If you don't have a ROM type which matches\n");
- fprintf(stderr,
- "your drive exactly, pick a type with the same number of heads and the\n");
- fprintf(stderr,
- "closest number of cylinders. If in doubt, be generous with the cylinders.\n");
- exit( -1 );
- }
-
- while (1) {
- if (MBBstatus == NEEDED) {
- if ((MBBstatus = getMBB(unit, &mbb)) == INCORE) {
- if ((GEOstatus & INCORE) != INCORE) {
- ! if (MBBGeometryIsValid( &mbb )) {
- ! GEOstatus = MBBgeoToPERgeo(mbb.geometry, geometry);
- }
- }
- }
- }
-
- if ((MBBstatus & INCORE) == INCORE)
- ! activepartition = GetActive( &mbb );
- else activepartition = NULL;
-
- if (activepartition == NULL) {
- PTstatus = INCORE + INVALID;
- } else {
-
- pbbcyl = CYL_BOOT( activepartition );
- pbbhead= HEAD_BOOT(activepartition );
- pbbsec = SEC_BOOT( activepartition );
-
- if (PBBstatus == NEEDED) {
- if ((PBBstatus= getPBB(unit, pbbcyl, pbbhead, pbbsec, &pbb))
- == INCORE) {
-
- /* Try reading a 2.3+ geometry specification */
-
- if ((GEOstatus & INCORE) != INCORE) {
- /* by definition - if a PBB is valid, it */
- /* has a valid geometry table */
- ! GEOstatus = PBBgeoToPERgeo(pbb.geometry, geometry);
- }
- }
- }
-
- /*
- At this point, if we don't have valid drive geometry info,
- we need to grab it from the CMOS ...
- */
-
- if ((GEOstatus & INCORE) != INCORE) {
- ! GEOstatus=CMOSgeoToPERgeo(&cmos,unit,geometry);
- if ((GEOstatus & INCORE) != INCORE) {
- reinitialize drive
- }
- }
-
- /* now snarf up the PER ... */
-
- percyl = CYL_END( activepartition );
- perhead= HEAD_END(activepartition );
- persec = SEC_END( activepartition );
-
- if (PERstatus == NEEDED)
- PERstatus=read_sector(unit,&per,percyl,perhead,persec);
-
- SLICEstatus = ValidSliceTable( unit, &per );
-
- if (BTTstatus == NEEDED)
- BTTstatus=read_sector(unit,&btt,percyl,perhead,persec - 1);
- }
-
- DISPLAY
- GEO, if any are NEEDED or INVALID, label as such, else
- PT, show contents on the screen
- PER,
- BTT, and
- SLICE (also note if valid superblock found there)
-
- Select one of GEO PT BTT SLICE to modify
- /* GEO */
- if ((GEOstatus & INCORE) != INCORE) { /* virgin disk! */
- ! while ((GEOstatus = GetGEOfromUser(geometry)) != INCORE)
- ; /* wait till the user gets it right */
- GEOstatus |= DIRTY;
- }
- if changed GEO, reinit drive & set MBB,PBB,PER,&BTT to NEEDED
-
- if changed PT, re-read PBB, PER, and BTT & set MBB |= DIRTY
- if not valid, mark on screen and dont allow update till fixed
-
- if changed BTT - check for conflicts with the MBB, PBB, BTT, and PER
- if conflicts, complain and allow user to modify PT to bypass these
-
- if changed SLICE, set SLICEstatus |= DIRTY
- /* at this point check over the NEEDED/INVALID bits */
- /* if any of PT, GEO, BTT, or SLICE are still set, tell what */
- /* is needed and go back to the loop */
- /* if all is kosher, quit... (OK if MBB, PBB, or PER invalid) */
- }
- /* ... to here where we must figure out what needs updating */
- /* if MBB is INVALID then read in boot code */
- /* if PBB is INVALID then read in boot code */
- /* if CMOS is BADGEO then need to update with GEO */
- /* if GEO dirty, need to update PBB, PER & set dirty, unset GEO dirty */
- /* if PT dirty, update & set MBB dirty, unset PT dirty */
- /* if SLICE dirty, update & set PER dirty */
-
- /* if MBB dirty, write & unset */
- /* if PBB dirty ... */
- /* if PER dirty ... */
- /* if BTT dirty ... */
-
- /* if SLICE dirty then need to do smartMKFSing remembering that */
- /* changes to 0s0 if HD rooted are not allowed */
- }
-
- getMBB( unit, mbbp )
- int unit;
- mbb_t *mbbp;
- {
- int cc;
-
- if ( read_sector( unit, mbbp, CYL(0), HEAD(0), SECTOR(1)) == ERROR ) {
- fprintf(stderr, "Error reading MBB from HD unit %d",unit);
- return INVALID;
- }
- if ( mbbp->signature == PT_SIG )
- return INCORE;
- else
- return INVALID;
- }
-
-
- getPBB( unit, pbbcyl, pbbhead, pbbsec, pbbp )
- int unit;
- int pbbcyl, pbbhead, pbbsec;
- pbb_t *pbbp;
- {
- int cc;
-
- if ( read_sector( unit, pbbp, pbbcyl, pbbhead, pbbsec) == ERROR ) {
- fprintf(stderr, "Error reading PBB from HD unit %d",unit);
- return INVALID;
- }
- if ( VALID_PBB( pbbp ) )
- return INCORE;
- else
- return INVALID;
- }
-
- /* forcibly update CMOS */
- CMOSstatus = PERgeoToCMOSgeo(&cmos, unit, geometry);
- if ((CMOSstatus & DIRTY) == DIRTY) {
- writeCMOS( &cmos );
- CMOSstatus &= ~DIRTY;
- }
-