|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.