static void bootpath_build(void) { const char *cp; char *pp; struct bootpath *bp; int fl; /* * Grab boot path from PROM and split into `bootpath' components. */ memset(bootpath, 0, sizeof(bootpath)); bp = bootpath; cp = prom_getbootpath(); switch (prom_version()) { case PROM_OLDMON: case PROM_OBP_V0: /* * Build fake bootpath. */ if (cp != NULL) bootpath_fake(bp, cp); break; case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: while (cp != NULL && *cp == '/') { /* Step over '/' */ ++cp; /* Extract name */ pp = bp->name; while (*cp != '@' && *cp != '/' && *cp != '\0') *pp++ = *cp++; *pp = '\0'; #if defined(SUN4M) /* * JS1/OF does not have iommu node in the device * tree, so bootpath will start with the sbus entry. * Add entry for iommu to match attachment. See also * mainbus_attach and iommu_attach. */ if (CPU_ISSUN4M && bp == bootpath && strcmp(bp->name, "sbus") == 0) { printf("bootpath_build: inserting iommu entry\n"); strcpy(bootpath[0].name, "iommu"); bootpath[0].val[0] = 0; bootpath[0].val[1] = 0x10000000; bootpath[0].val[2] = 0; ++nbootpath; strcpy(bootpath[1].name, "sbus"); if (*cp == '/') { /* complete sbus entry */ bootpath[1].val[0] = 0; bootpath[1].val[1] = 0x10001000; bootpath[1].val[2] = 0; ++nbootpath; bp = &bootpath[2]; continue; } else bp = &bootpath[1]; } #endif /* SUN4M */ if (*cp == '@') { cp = str2hex(++cp, &bp->val[0]); if (*cp == ',') cp = str2hex(++cp, &bp->val[1]); if (*cp == ':') { /* XXX - we handle just one char */ /* skip remainder of paths */ /* like "ledma@f,400010:tpe" */ bp->val[2] = *++cp - 'a'; while (*++cp != '/' && *cp != '\0') /*void*/; } } else { bp->val[0] = -1; /* no #'s: assume unit 0, no sbus offset/address */ } ++bp; ++nbootpath; } bp->name[0] = 0; break; } bootpath_print(bootpath); /* Setup pointer to boot flags */ cp = prom_getbootargs(); if (cp == NULL) return; /* Skip any whitespace */ while (*cp != '-') if (*cp++ == '\0') return; for (;*++cp;) { fl = 0; BOOT_FLAG(*cp, fl); if (!fl) { printf("unknown option `%c'\n", *cp); continue; } boothowto |= fl; /* specialties */ if (*cp == 'd') { #if defined(KGDB) kgdb_debug_panic = 1; kgdb_connect(1); #elif defined(DDB) Debugger(); #else printf("kernel has no debugger\n"); #endif } } }
void main(void *ofw) { int boothowto, i = 0, isfloppy, kboothowto; char kernel[PROM_MAX_PATH]; char bootline[PROM_MAX_PATH]; /* Initialize OpenFirmware */ romp = ofw; prom_init(); printf("\r>> %s, Revision %s\n", bootprog_name, bootprog_rev); /* Figure boot arguments */ strncpy(bootdev, prom_getbootpath(), sizeof(bootdev) - 1); kboothowto = boothowto = bootoptions(prom_getbootargs(), bootdev, kernel, bootline); isfloppy = bootdev_isfloppy(bootdev); for (;; *kernel = '\0') { if (boothowto & RB_ASKNAME) { char cmdline[PROM_MAX_PATH]; printf("Boot: "); kgets(cmdline, sizeof(cmdline)); if (!strcmp(cmdline,"exit") || !strcmp(cmdline,"halt")) { prom_halt(); } else if (!strcmp(cmdline, "?") || !strcmp(cmdline, "help")) { help(); continue; } boothowto = bootoptions(cmdline, bootdev, kernel, bootline); boothowto |= RB_ASKNAME; i = 0; } if (*kernel == '\0') { if (kernelnames[i] == NULL) { boothowto |= RB_ASKNAME; continue; } strncpy(kernel, kernelnames[i++], PROM_MAX_PATH); } else if (i == 0) { /* * Kernel name was passed via command line -- ask user * again if requested image fails to boot. */ boothowto |= RB_ASKNAME; } check_boot_config(); start_kernel(kernel, bootline, ofw, isfloppy, kboothowto); /* * Try next name from kernel name list if not in askname mode, * enter askname on reaching list's end. */ if ((boothowto & RB_ASKNAME) == 0 && (kernelnames[i] != NULL)) { printf(": trying %s...\n", kernelnames[i]); } else { printf("\n"); boothowto |= RB_ASKNAME; } } (void)printf("Boot failed! Exiting to the Firmware.\n"); prom_halt(); }
int main(void) { int error, i; char kernel[MAX_PROM_PATH]; const char *k; u_long marks[MARK_MAX], bootinfo; struct btinfo_symtab bi_sym; struct btinfo_boothowto bi_howto; void *arg; #ifdef HEAP_VARIABLE { extern char end[]; setheap((void *)ALIGN(end), (void *)0xffffffff); } #endif prom_init(); mmu_init(); printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); /* massage machine prom */ prom_patch(); /* * get default kernel. */ k = prom_getbootfile(); if (k != NULL && *k != '\0') { i = -1; /* not using the kernels */ strcpy(kernel, k); } else { i = 0; strcpy(kernel, kernels[i]); } k = prom_getbootpath(); if (k && *k) strcpy(prom_bootdevice, k); boothowto = bootoptions(prom_getbootargs()); for (;;) { /* * ask for a kernel first .. */ if (boothowto & RB_ASKNAME) { printf("device[%s] (\"halt\" to halt): ", prom_bootdevice); gets(dbuf); if (strcmp(dbuf, "halt") == 0) _rtt(); if (dbuf[0]) strcpy(prom_bootdevice, dbuf); printf("boot (press RETURN to try default list): "); gets(fbuf); if (fbuf[0]) strcpy(kernel, fbuf); else { boothowto &= ~RB_ASKNAME; i = 0; strcpy(kernel, kernels[i]); } } printf("Booting %s\n", kernel); if ((error = loadk(kernel, marks)) == 0) break; if (error != ENOENT) { printf("Cannot load %s: error=%d\n", kernel, error); boothowto |= RB_ASKNAME; } /* * if we have are not in askname mode, and we aren't using the * prom bootfile, try the next one (if it exits). otherwise, * go into askname mode. */ if ((boothowto & RB_ASKNAME) == 0 && i != -1 && kernels[++i]) { strcpy(kernel, kernels[i]); printf(": trying %s...\n", kernel); } else { printf("\n"); boothowto |= RB_ASKNAME; } } marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(u_long) - 1)) & (-sizeof(u_long)); arg = (prom_version() == PROM_OLDMON) ? (void *)PROM_LOADADDR : romp; /* Setup boot info structure at the end of the kernel image */ bootinfo = bi_init(marks[MARK_END] & loadaddrmask); /* Add kernel symbols to bootinfo */ bi_sym.nsym = marks[MARK_NSYM] & loadaddrmask; bi_sym.ssym = marks[MARK_SYM] & loadaddrmask; bi_sym.esym = marks[MARK_END] & loadaddrmask; bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym)); /* Add boothowto */ bi_howto.boothowto = boothowto; bi_add(&bi_howto, BTINFO_BOOTHOWTO, sizeof(bi_howto)); /* Add kernel path to bootinfo */ i = sizeof(struct btinfo_common) + strlen(kernel) + 1; /* Impose limit (somewhat arbitrary) */ if (i < BOOTINFO_SIZE / 2) { union { struct btinfo_kernelfile bi_file; char x[i]; } U; strcpy(U.bi_file.name, kernel); bi_add(&U.bi_file, BTINFO_KERNELFILE, i); } (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, bootinfo, DDB_MAGIC2); _rtt(); }