Annotation of lucent/sys/src/boot/pc/main.c, revision 1.1.1.1

1.1       root        1: #include "u.h"
                      2: #include "lib.h"
                      3: #include "mem.h"
                      4: #include "dat.h"
                      5: #include "fns.h"
                      6: #include "io.h"
                      7: 
                      8: #include "dosfs.h"
                      9: 
                     10: typedef struct Type Type;
                     11: typedef struct Medium Medium;
                     12: typedef struct Mode Mode;
                     13: 
                     14: enum {
                     15:        Maxdev          = 7,
                     16:        Dany            = -1,
                     17:        Nmedia          = 16,
                     18: };
                     19: 
                     20: enum {                                 /* type */
                     21:        Tfloppy         = 0x00,
                     22:        Thard           = 0x01,
                     23:        Tscsi           = 0x02,
                     24:        Tether          = 0x03,
                     25:        NType           = 0x04,
                     26: 
                     27:        Tany            = -1,
                     28: };
                     29: 
                     30: enum {                                 /* flag and name */
                     31:        Fnone           = 0x00,
                     32: 
                     33:        Fdos            = 0x01,
                     34:        Ndos            = 0x00,
                     35:        Fboot           = 0x02,
                     36:        Nboot           = 0x01,
                     37:        Fbootp          = 0x04,
                     38:        Nbootp          = 0x02,
                     39:        NName           = 0x03,
                     40: 
                     41:        Fany            = Fbootp|Fboot|Fdos,
                     42: 
                     43:        Fini            = 0x10,
                     44:        Freverse        = 0x20,
                     45:        Fprobe          = 0x80,
                     46: };
                     47: 
                     48: enum {                                 /* mode */
                     49:        Mauto           = 0x00,
                     50:        Mlocal          = 0x01,
                     51:        Manual          = 0x02,
                     52:        NMode           = 0x03,
                     53: };
                     54: 
                     55: typedef struct Type {
                     56:        int     type;
                     57:        int     flag;
                     58:        int     (*init)(void);
                     59:        long    (*read)(int, void*, long);
                     60:        long    (*seek)(int, long);
                     61:        Partition* (*setpart)(int, char*);
                     62:        char*   name[NName];
                     63: 
                     64:        int     mask;
                     65:        Medium* media;
                     66: } Type;
                     67: 
                     68: typedef struct Medium {
                     69:        Type*   type;
                     70:        int     flag;
                     71:        Partition* partition;
                     72:        Dos;
                     73: 
                     74:        Medium* next;
                     75: } Medium;
                     76: 
                     77: typedef struct Mode {
                     78:        char*   name;
                     79:        int     mode;
                     80: } Mode;
                     81: 
                     82: static Type types[NType] = {
                     83:        {       Tfloppy,
                     84:                Fini|Fdos,
                     85:                floppyinit, floppyread, floppyseek, 0,
                     86:                { "fd", }
                     87:        },
                     88:        {       Tether,
                     89:                Fbootp,
                     90:                etherinit, 0, 0, 0,
                     91:                { 0, 0, "e", },
                     92:        },
                     93:        {       Thard,
                     94:                Fini|Fboot|Fdos,
                     95:                hardinit, hardread, hardseek, sethardpart,
                     96:                { "hd", "h", },
                     97:        },
                     98:        {       Tscsi,
                     99:                Fini|Fboot|Fdos,
                    100:                scsiinit, scsiread, scsiseek, setscsipart,
                    101:                { "sd", "s", },
                    102:        },
                    103: };
                    104: 
                    105: static Medium media[Nmedia];
                    106: static Medium *curmedium = media;
                    107: 
                    108: static Mode modes[NMode+1] = {
                    109:        [Mauto]         { "auto",   Mauto,  },
                    110:        [Mlocal]        { "local",  Mlocal, },
                    111:        [Manual]        { "manual", Manual, },
                    112: };
                    113: 
                    114: static char *inis[] = {
                    115:        "plan9/plan9.ini",
                    116:        "plan9.ini",
                    117:        0,
                    118: };
                    119: char **ini;
                    120: 
                    121: static int
                    122: parse(char *line, int *type, int *flag, int *dev, char *file)
                    123: {
                    124:        Type *tp;
                    125:        char buf[2*NAMELEN], *v[4], *p;
                    126:        int i;
                    127: 
                    128:        strcpy(buf, line);
                    129:        switch(getfields(buf, v, 4, '!')){
                    130: 
                    131:        case 3:
                    132:                break;
                    133: 
                    134:        case 2:
                    135:                v[2] = "";
                    136:                break;
                    137: 
                    138:        default:
                    139:                return 0;
                    140:        }
                    141: 
                    142:        *flag = 0;
                    143:        for(tp = types; tp < &types[NType]; tp++){
                    144:                for(i = 0; i < NName; i++){
                    145: 
                    146:                        if(tp->name[i] == 0 || strcmp(v[0], tp->name[i]))
                    147:                                continue;
                    148:                        *type = tp->type;
                    149:                        *flag |= 1<<i;
                    150: 
                    151:                        if((*dev = strtoul(v[1], &p, 0)) == 0 && p == v[1])
                    152:                                return 0;
                    153:                
                    154:                        strcpy(file, v[2]);
                    155:                
                    156:                        return 1;
                    157:                }
                    158:        }
                    159: 
                    160:        return 0;
                    161: 
                    162: }
                    163: 
                    164: static int
                    165: boot(Medium *mp, int flag, char *file)
                    166: {
                    167:        Dosfile df;
                    168:        char ixdos[128], *p;
                    169: 
                    170:        if(flag & Fbootp){
                    171:                sprint(BOOTLINE, "%s!%d", mp->type->name[Nbootp], mp->dev);
                    172:                return bootp(mp->dev, file);
                    173:        }
                    174: 
                    175:        if(flag & Fboot){
                    176:                if(mp->flag & Fini){
                    177:                        (*mp->type->setpart)(mp->dev, "disk");
                    178:                        plan9ini(mp);
                    179:                }
                    180:                if(file == 0 || *file == 0)
                    181:                        file = mp->partition->name;
                    182:                (*mp->type->setpart)(mp->dev, file);
                    183:                sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Nboot], mp->dev, file);
                    184:                return plan9boot(mp->dev, mp->seek, mp->read);
                    185:        }
                    186: 
                    187:        if(flag & Fdos){
                    188:                if(mp->type->setpart)
                    189:                        (*mp->type->setpart)(mp->dev, "disk");
                    190:                if(mp->flag & Fini)
                    191:                        plan9ini(mp);
                    192:                if(file == 0 || *file == 0){
                    193:                        strcpy(ixdos, *ini);
                    194:                        if(p = strrchr(ixdos, '/'))
                    195:                                p++;
                    196:                        else
                    197:                                p = ixdos;
                    198:                        strcpy(p, "9dos");
                    199:                        if(dosstat(mp, ixdos, &df) <= 0)
                    200:                                return -1;
                    201:                }
                    202:                else
                    203:                        strcpy(ixdos, file);
                    204:                sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Ndos], mp->dev, ixdos);
                    205:                return dosboot(mp, ixdos);
                    206:        }
                    207: 
                    208:        return -1;
                    209: }
                    210: 
                    211: static Medium*
                    212: allocm(Type *tp)
                    213: {
                    214:        Medium **l;
                    215: 
                    216:        if(curmedium >= &media[Nmedia])
                    217:                return 0;
                    218: 
                    219:        for(l = &tp->media; *l; l = &(*l)->next)
                    220:                ;
                    221:        *l = curmedium++;
                    222:        return *l;
                    223: }
                    224: 
                    225: Medium*
                    226: probe(int type, int flag, int dev)
                    227: {
                    228:        Type *tp;
                    229:        int d, i, m;
                    230:        Medium *mp;
                    231:        Dosfile df;
                    232: 
                    233:        for(tp = types; tp < &types[NType]; tp++){
                    234:                if(type != Tany && type != tp->type)
                    235:                        continue;
                    236: 
                    237:                if(flag != Fnone){
                    238:                        for(mp = tp->media; mp; mp = mp->next){
                    239:                                if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
                    240:                                        return mp;
                    241:                        }
                    242:                }
                    243: 
                    244:                if((tp->flag & Fprobe) == 0){
                    245:                        tp->flag |= Fprobe;
                    246:                        tp->mask = (*tp->init)();
                    247:                }
                    248: 
                    249:                for(i = 0; tp->mask; i++){
                    250:                        if(tp->flag & Freverse){
                    251:                                m = 1<<(Maxdev-i);
                    252:                                d = (Maxdev-i);
                    253:                        }
                    254:                        else{
                    255:                                m = 1<<i;
                    256:                                d = i;
                    257:                        }
                    258:                        if((tp->mask & m) == 0)
                    259:                                continue;
                    260:                        tp->mask &= ~m;
                    261: 
                    262:                        if((mp = allocm(tp)) == 0)
                    263:                                continue;
                    264: 
                    265:                        mp->dev = d;
                    266:                        mp->flag = tp->flag;
                    267:                        mp->seek = tp->seek;
                    268:                        mp->read = tp->read;
                    269:                        mp->type = tp;
                    270: 
                    271:                        if(mp->flag & Fboot){
                    272:                                if((mp->partition = (*tp->setpart)(d, "boot")) == 0)
                    273:                                        mp->flag &= ~Fboot;
                    274:                                (*tp->setpart)(d, "disk");
                    275:                        }
                    276: 
                    277:                        if((mp->flag & Fdos) && (dosinit(mp) < 0))
                    278:                                mp->flag &= ~(Fini|Fdos);
                    279: 
                    280:                        if(mp->flag & Fini){
                    281:                                mp->flag &= ~Fini;
                    282:                                for(ini = inis; *ini; ini++){
                    283:                                        if(dosstat(mp, *ini, &df) <= 0)
                    284:                                                continue;
                    285:                                        mp->flag |= Fini;
                    286:                                        break;
                    287:                                }
                    288:                        }
                    289: 
                    290:                        if((flag & mp->flag) && (dev == Dany || dev == d))
                    291:                                return mp;
                    292:                }
                    293:        }
                    294: 
                    295:        return 0;
                    296: }
                    297: 
                    298: void
                    299: main(void)
                    300: {
                    301:        Medium *mp;
                    302:        int dev, flag, i, mode, tried, type;
                    303:        char def[2*NAMELEN], file[2*NAMELEN], line[80], *p;
                    304:        Type *tp;
                    305: 
                    306:        i8042a20();
                    307:        memset(m, 0, sizeof(Mach));
                    308:        trapinit();
                    309:        clockinit();
                    310:        alarminit();
                    311:        spllo();
                    312: 
                    313:        if((ulong)&end > (KZERO|(640*1024)))
                    314:                panic("b.com too big\n");
                    315: 
                    316:        for(tp = types; tp < &types[NType]; tp++){
                    317:                if(tp->type == Tether)
                    318:                        continue;
                    319:                if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
                    320:                        plan9ini(mp);
                    321:                        break;
                    322:                }
                    323:        }
                    324: 
                    325:        consinit();
                    326: 
                    327:        /*
                    328:         * If there were any arguments, MS-DOS leaves a character
                    329:         * count followed by the arguments in the runtime header.
                    330:         * Step over the leading space.
                    331:         */
                    332:        p = (char*)0x80080080;
                    333:        if(p[0]){
                    334:                p[p[0]+1] = 0;
                    335:                p += 2;
                    336:        }
                    337:        else
                    338:                p = 0;
                    339: 
                    340:        tried = 0;
                    341:        mode = Mauto;
                    342:        if(p == 0)
                    343:                p = getconf("bootfile");
                    344: 
                    345:        if(p != 0) {
                    346:                mode = Manual;
                    347:                for(i = 0; i < NMode; i++){
                    348:                        if(strcmp(p, modes[i].name) == 0){
                    349:                                mode = modes[i].mode;
                    350:                                goto done;
                    351:                        }
                    352:                }
                    353:                if(parse(p, &type, &flag, &dev, file) == 0) {
                    354:                        print("Bad bootfile syntax: %s\n", p);
                    355:                        goto done;
                    356:                }
                    357:                mp = probe(type, flag, dev);
                    358:                if(mp == 0) {
                    359:                        print("Cannot access device: %s\n", p);
                    360:                        goto done;
                    361:                }
                    362:                tried = boot(mp, flag, file);
                    363:        }
                    364: done:
                    365:        if(tried == 0 && mode != Manual){
                    366:                flag = Fany;
                    367:                if(mode == Mlocal)
                    368:                        flag &= ~Fbootp;
                    369:                if((mp = probe(Tany, flag, Dany)) && mp->type->type != Tfloppy)
                    370:                        boot(mp, flag & mp->flag, 0);
                    371:        }
                    372: 
                    373:        def[0] = 0;
                    374:        probe(Tany, Fnone, Dany);
                    375:        if(mode != Manual && (mp = probe(Tfloppy, Fdos, Dany)))
                    376:                sprint(def, "%s!%d!9dos", mp->type->name[Ndos], mp->dev);
                    377: 
                    378:        flag = 0;
                    379:        for(tp = types; tp < &types[NType]; tp++){
                    380:                for(mp = tp->media; mp; mp = mp->next){
                    381:                        if(flag == 0){
                    382:                                flag = 1;
                    383:                                print("Boot devices:");
                    384:                        }
                    385:        
                    386:                        if(mp->flag & Fbootp)
                    387:                                print(" %s!%d", mp->type->name[Nbootp], mp->dev);
                    388:                        if(mp->flag & Fdos)
                    389:                                print(" %s!%d", mp->type->name[Ndos], mp->dev);
                    390:                        if(mp->flag & Fboot)
                    391:                                print(" %s!%d", mp->type->name[Nboot], mp->dev);
                    392:                }
                    393:        }
                    394:        if(flag)
                    395:                print("\n");
                    396: 
                    397:        for(;;){
                    398:                if(getstr("boot from", line, sizeof(line), def, def[0]!=0) >= 0){
                    399:                        if(parse(line, &type, &flag, &dev, file)){
                    400:                                if(mp = probe(type, flag, dev))
                    401:                                        boot(mp, flag, file);
                    402:                        }
                    403:                }
                    404:                def[0] = 0;
                    405:        }
                    406: }
                    407: 
                    408: int
                    409: getfields(char *lp, char **fields, int n, char sep)
                    410: {
                    411:        int i;
                    412: 
                    413:        for(i=0; lp && *lp && i<n; i++){
                    414:                while(*lp == sep)
                    415:                        *lp++=0;
                    416:                if(*lp == 0)
                    417:                        break;
                    418:                fields[i]=lp;
                    419:                while(*lp && *lp != sep)
                    420:                        lp++;
                    421:        }
                    422:        return i;
                    423: }
                    424: 
                    425: void*
                    426: ialloc(ulong n, int align)
                    427: {
                    428: 
                    429:        static struct {
                    430:                ulong   addr;
                    431:        } palloc;
                    432:        ulong p;
                    433: 
                    434:        if(palloc.addr == 0)
                    435:                palloc.addr = ((ulong)&end)&~KZERO;
                    436:        if(align)
                    437:                palloc.addr = PGROUND(palloc.addr);
                    438:        if((palloc.addr <= 640*1024) && (palloc.addr + n > 640*1024))
                    439:                palloc.addr = 2*1024*1024;
                    440: 
                    441:        memset((void*)(palloc.addr|KZERO), 0, n);
                    442:        p = palloc.addr;
                    443:        palloc.addr += n;
                    444:        if(align)
                    445:                palloc.addr = PGROUND(palloc.addr);
                    446: 
                    447:        return (void*)(p|KZERO);
                    448: }
                    449: 
                    450: enum {
                    451:        Paddr=          0x70,   /* address port */
                    452:        Pdata=          0x71,   /* data port */
                    453: };
                    454: 
                    455: uchar
                    456: nvramread(int offset)
                    457: {
                    458:        outb(Paddr, offset);
                    459:        return inb(Pdata);
                    460: }

unix.superglobalmegacorp.com

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