Annotation of Net2/arch/i386/boot/disk.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Ported to boot 386BSD by Julian Elischer ([email protected]) Sept 1992
                      3:  *
                      4:  * Mach Operating System
                      5:  * Copyright (c) 1992, 1991 Carnegie Mellon University
                      6:  * All Rights Reserved.
                      7:  * 
                      8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
                     13:  * 
                     14:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     15:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     16:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     17:  * 
                     18:  * Carnegie Mellon requests users of this software to return to
                     19:  * 
                     20:  *  Software Distribution Coordinator  or  [email protected]
                     21:  *  School of Computer Science
                     22:  *  Carnegie Mellon University
                     23:  *  Pittsburgh PA 15213-3890
                     24:  * 
                     25:  * any improvements or extensions that they make and grant Carnegie Mellon
                     26:  * the rights to redistribute these changes.
                     27:  */
                     28: 
                     29: /*
                     30:  * HISTORY
1.1.1.2 ! root       31:  * disk.c,v
        !            32:  * Revision 1.3  1993/07/11  12:02:23  andrew
        !            33:  * Fixes from bde, including support for loading @ any MB boundary (e.g. a
        !            34:  * kernel linked for 0xfe100000 will load at the 1MB mark) and read-ahead
        !            35:  * buffering to speed booting from floppies.  Also works with aha174x
        !            36:  * controllers in enhanced mode.
        !            37:  *
        !            38:  * Revision 1.2  1993/06/18  02:28:58  cgd
        !            39:  * make it *do* something when loading the kernel, a la sun twiddling-thing
        !            40:  *
        !            41:  * Revision 1.1  1993/03/21  18:08:36  cgd
1.1       root       42:  * after 0.2.2 "stable" patches applied
                     43:  *
                     44:  * Revision 2.2  92/04/04  11:35:49  rpd
                     45:  *     Fabricated from 3.0 bootstrap and 2.5 boot disk.c:
                     46:  *     with support for scsi
                     47:  *     [92/03/30            mg32]
                     48:  * 
                     49:  */
                     50: 
                     51: /*
                     52:  * 9/20/92
                     53:  * Peng-Toh Sim.  [email protected]
                     54:  * Added bad144 support under 386bsd for wd's
                     55:  * So, bad block remapping is done when loading the kernel.
                     56:  */
                     57: 
                     58: #include "boot.h"
                     59: #ifdef DO_BAD144
                     60: #include <sys/dkbad.h>
                     61: #endif DO_BAD144
                     62: #include <sys/disklabel.h>
                     63: 
                     64: #define        BIOS_DEV_FLOPPY 0x0
                     65: #define        BIOS_DEV_WIN    0x80
                     66: 
                     67: #define BPS            512
                     68: #define        SPT(di)         ((di)&0xff)
                     69: #define        HEADS(di)       ((((di)>>8)&0xff)+1)
                     70: 
                     71: char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0};
                     72: 
                     73: #ifdef DO_BAD144
                     74: struct dkbad dkb;
                     75: int do_bad144;
                     76: int bsize;
                     77: #endif DO_BAD144
                     78: 
                     79: int spt, spc;
                     80: 
                     81: char *iodest;
                     82: struct fs *fs;
                     83: struct inode inode;
                     84: int dosdev,  unit, part, maj, boff, poff, bnum, cnt;
                     85: 
                     86: /*#define EMBEDDED_DISKLABEL 1*/
                     87: extern struct disklabel disklabel;
                     88: /*struct       disklabel disklabel;*/
                     89: 
                     90: devopen()
                     91: {
                     92:        struct dos_partition *dptr;
                     93:        struct disklabel *dl;
                     94:        int dosdev = inode.i_dev;
                     95:        int i, sector, di;
                     96:        
                     97:        di = get_diskinfo(dosdev);
                     98:        spc = (spt = SPT(di)) * HEADS(di);
                     99:        if (dosdev == 2)
                    100:        {
                    101:                boff = 0;
                    102:                part = (spt == 15 ? 3 : 1);
                    103:        }
                    104:        else
                    105:        {
                    106: #ifdef EMBEDDED_DISKLABEL
                    107:                dl = &disklabel;
                    108: #else  EMBEDDED_DISKLABEL
                    109:                Bread(dosdev, 0);
                    110:                dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF);
                    111:                for (i = 0; i < NDOSPART; i++, dptr++)
                    112:                        if (dptr->dp_typ == DOSPTYP_386BSD)
                    113:                                break;
                    114:                sector = dptr->dp_start + LABELSECTOR;
                    115:                Bread(dosdev, sector++);
                    116:                dl=((struct disklabel *)0);
                    117:                disklabel = *dl;        /* structure copy (maybe useful later)*/
                    118: #endif EMBEDDED_DISKLABEL
                    119:                if (dl->d_magic != DISKMAGIC) {
                    120:                        printf("bad disklabel");
                    121:                        return 1;
                    122:                }
                    123:                if( (maj == 4) || (maj == 0) || (maj == 1))
                    124:                {
                    125:                        if (dl->d_type == DTYPE_SCSI)
                    126:                        {
                    127:                                maj = 4; /* use scsi as boot dev */
                    128:                        }
                    129:                        else
                    130:                        {
                    131:                                maj = 0; /* must be ESDI/IDE */
                    132:                        }
                    133:                }
                    134:                boff = dl->d_partitions[part].p_offset;
                    135: #ifdef DO_BAD144
                    136:                bsize = dl->d_partitions[part].p_size;
                    137:                do_bad144 = 0;
                    138:                if (dl->d_flags & D_BADSECT) {
                    139:                    /* this disk uses bad144 */
                    140:                    int i;
                    141:                    int dkbbnum;
                    142:                    struct dkbad *dkbptr;
                    143: 
                    144:                    /* find the first readable bad144 sector */
                    145:                    /* some of this code is copied from ufs/disk_subr.c */
                    146:                    /* read a bad sector table */
                    147:                    dkbbnum = dl->d_secperunit - dl->d_nsectors;
                    148:                    if (dl->d_secsize > DEV_BSIZE)
                    149:                      dkbbnum *= dl->d_secsize / DEV_BSIZE;
                    150:                    else
                    151:                      dkbbnum /= DEV_BSIZE / dl->d_secsize;
                    152:                    i = 0;
                    153:                    do_bad144 = 0;
                    154:                    do {
                    155:                        /* XXX: what if the "DOS sector" < 512 bytes ??? */
                    156:                        Bread(dosdev, dkbbnum + i);
                    157:                        dkbptr = (struct dkbad *) 0;
                    158: /* XXX why is this not in <sys/dkbad.h> ??? */
                    159: #define DKBAD_MAGIC 0x4321
                    160:                        if (dkbptr->bt_mbz == 0 &&
                    161:                                dkbptr->bt_flag == DKBAD_MAGIC) {
                    162:                            dkb = *dkbptr;      /* structure copy */
                    163:                            do_bad144 = 1;
                    164:                            break;
                    165:                        }
                    166:                        i += 2;
                    167:                    } while (i < 10 && i < dl->d_nsectors);
                    168:                    if (!do_bad144)
                    169:                      printf("Bad badsect table\n");
                    170:                    else
                    171:                      printf("Using bad144 bad sector at %d\n", dkbbnum+i);
                    172:                }
                    173: #endif DO_BAD144
                    174:        }
                    175:        return 0;
                    176: }
                    177: 
                    178: devread()
                    179: {
                    180:        int offset, sector = bnum;
                    181:        int dosdev = inode.i_dev;
                    182:        for (offset = 0; offset < cnt; offset += BPS)
                    183:        {
                    184:                Bread(dosdev, badsect(dosdev, sector++));
                    185:                bcopy(0, iodest+offset, BPS);
                    186:        }
                    187: }
                    188: 
1.1.1.2 ! root      189: #define I_ADDR         ((void *) 0)    /* XXX where all reads go */
        !           190: 
        !           191: /* Read ahead buffer large enough for one track on a 1440K floppy.  For
        !           192:  * reading from floppies, the bootstrap has to be loaded on a 64K boundary
        !           193:  * to ensure that this buffer doesn't cross a 64K DMA boundary.
        !           194:  */
        !           195: #define RA_SECTORS     18
        !           196: static char ra_buf[RA_SECTORS * BPS];
        !           197: static int ra_end;
        !           198: static int ra_first;
        !           199: 
1.1       root      200: Bread(dosdev,sector)
                    201:      int dosdev,sector;
                    202: {
1.1.1.2 ! root      203:        if (sector < ra_first || sector >= ra_end)
1.1       root      204:        {
1.1.1.2 ! root      205:                int cyl, head, sec, nsec;
        !           206: 
        !           207:                cyl = sector/spc;
        !           208:                head = (sector % spc) / spt;
        !           209:                sec = sector % spt;
        !           210:                nsec = spt - sec;
        !           211:                if (nsec > RA_SECTORS)
        !           212:                        nsec = RA_SECTORS;
        !           213:                twiddle();
        !           214:                if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
        !           215:                {
        !           216:                    nsec = 1;
        !           217:                    twiddle();
        !           218:                    while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
        !           219:                        printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
        !           220:                        twiddle();
        !           221:                    }
        !           222:                }
        !           223:                ra_first = sector;
        !           224:                ra_end = sector + nsec;
1.1       root      225:        }
1.1.1.2 ! root      226:        bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);
1.1       root      227: }
                    228: 
                    229: badsect(dosdev, sector)
                    230:      int dosdev, sector;
                    231: {
                    232:        int i;
                    233: #ifdef DO_BAD144
                    234:        if (do_bad144) {
                    235:            u_short cyl;
                    236:            u_short head;
                    237:            u_short sec;
                    238:            int newsec;
                    239:            struct disklabel *dl = &disklabel;
                    240: 
                    241:            /* XXX */
                    242:            /* from wd.c */
                    243:            /* bt_cyl = cylinder number in sorted order */
                    244:            /* bt_trksec is actually (head << 8) + sec */
                    245: 
                    246:            /* only remap sectors in the partition */
                    247:            if (sector < boff || sector >= boff + bsize) {
                    248:                goto no_remap;
                    249:            }
                    250: 
                    251:            cyl = sector / dl->d_secpercyl;
                    252:            head = (sector % dl->d_secpercyl) / dl->d_nsectors;
                    253:            sec = sector % dl->d_nsectors;
                    254:            sec = (head<<8) + sec;
                    255: 
                    256:            /* now, look in the table for a possible bad sector */
                    257:            for (i=0; i<126; i++) {
                    258:                if (dkb.bt_bad[i].bt_cyl == cyl) {
                    259:                    /* found same cylinder */
                    260:                    if (dkb.bt_bad[i].bt_trksec == sec) {
                    261:                        /* FOUND! */
                    262:                        break;
                    263:                    }
                    264:                } else if (dkb.bt_bad[i].bt_cyl > cyl) {
                    265:                    i = 126;
                    266:                    break;
                    267:                }
                    268:            }
                    269:            if (i == 126) {
                    270:                /* didn't find bad sector */
                    271:                goto no_remap;
                    272:            }
                    273:            /* otherwise find replacement sector */
                    274:            newsec = dl->d_secperunit - dl->d_nsectors - i -1;
                    275:            return newsec;
                    276:        }
                    277: #endif DO_BAD144
                    278:       no_remap:
                    279:        return sector;
                    280: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.