/* * Get the boot arguments from the PROM and split it into filename and * options components. * * As per IEEE1275 and boot(1M), the boot arguments will have the syntax * "[filename] [-options]". If filename is specified, it is copied into the * first buffer. (Otherwise, the buffer is left alone.) The rest of the string * is copied into the second buffer. */ static void init_bootargs(char *fname_buf, int fname_buf_sz, char *bargs_buf, int bargs_buf_sz) { const char *tp = prom_bootargs(); if (!tp || *tp == '\0') { *bargs_buf = '\0'; return; } SKIP_WHITESPC(tp); /* * If we don't have an option indicator, then we * already have our filename prepended. */ if (*tp && *tp != '-') { int i; /* * Copy the filename into fname_buf. */ for (i = 0; i < fname_buf_sz && *tp && !ISSPACE(*tp); ++i) *fname_buf++ = *tp++; if (i >= fname_buf_sz) { printf("boot: boot filename too long!\n"); printf("boot halted.\n"); prom_enter_mon(); /*NOTREACHED*/ } else { *fname_buf = '\0'; } SKIP_WHITESPC(tp); } /* The rest of the line is the options. */ while (bargs_buf_sz > 1 && *tp) { *bargs_buf++ = *tp++; --bargs_buf_sz; } *bargs_buf = '\0'; if (bargs_buf_sz == 1) { printf("boot: boot arguments too long!\n"); printf("boot halted.\n"); prom_enter_mon(); /*NOTREACHED*/ } }
/* * switch input to keyboard before entering the prom, and switch to the * crafted nulldev after returning from the prom. this occurs only when * stdinpath is a USB keyboard; entering the prom is usually done only * for debugging purposes - see check_halt() and above DMA comment. */ void cb_enter_mon(void) { cb_set_idev(kbd_input); prom_enter_mon(); cb_set_idev(null_input); }
/*ARGSUSED*/ int main(void *cookie, char **argv, int argc) { /* * bpath is the boot device path buffer. * bargs is the boot arguments buffer. */ static char bpath[OBP_MAXPATHLEN], bargs[OBP_MAXPATHLEN]; boolean_t user_specified_filename; prom_init("boot", cookie); fiximp(); system_check(); dprintf("\nboot: V%d /boot interface.\n", BO_VERSION); #ifdef HALTBOOT prom_enter_mon(); #endif /* HALTBOOT */ init_memlists(); #ifdef DEBUG_LISTS dprintf("Physmem avail:\n"); if (debug) print_memlist(pfreelistp); dprintf("Virtmem avail:\n"); if (debug) print_memlist(vfreelistp); dprintf("Phys installed:\n"); if (debug) print_memlist(pinstalledp); prom_enter_mon(); #endif /* DEBUG_LISTS */ /* * Initialize the default filename (exported as "default-name" and * used by kadb). */ set_default_filename(defname); /* * Parse the arguments ASAP in case there are any flags which may * affect execution. */ /* * filename is the path to the standalone. Initialize it to the empty * string so we can tell whether the user specified it in the * arguments. */ filename[0] = '\0'; /* * Fetch the boot arguments from the PROM and split the filename off * if it's there. */ init_bootargs(filename, sizeof (filename), bargs, sizeof (bargs)); /* * kadb was delivered as a standalone, and as such, people got used to * typing `boot kadb'. kmdb isn't a standalone - it is loaded by krtld * as just another kernel module. For compatibility, though, when we * see an attempt to `boot kadb' or `boot kmdb', we'll transform that * into a `boot -k' (or equivalent). */ if (strcmp(filename, "kmdb") == 0 || strcmp(filename, "kadb") == 0) { boothowto |= RB_KMDB; *filename = '\0'; /* let boot figure out which unix to use */ } bootflags(bargs, sizeof (bargs)); user_specified_filename = (filename[0] != '\0'); /* Fetch the boot path from the PROM. */ (void) strncpy(bpath, prom_bootpath(), sizeof (bpath) - 1); bpath[sizeof (bpath) - 1] = '\0'; dprintf("arch: %s\n", is_sun4v ? "sun4v" : "sun4u"); dprintf("bootpath: 0x%p %s\n", (void *)bpath, bpath); dprintf("bootargs: 0x%p %s\n", (void *)bargs, bargs); dprintf("filename: 0x%p %s\n", (void *)filename, filename); dprintf("kernname: 0x%p %s\n", (void *)kernname, kernname); /* * *v2path will be exported to the standalone as the boot-path boot * property. */ v2path = bpath; /* * Our memory lists should be "up" by this time */ setup_bootops(); /* * If bpath is a network card, set v2path to a copy of bpath with the * options stripped off. */ mangle_os_bootpath(bpath); /* * Not necessary on sun4v as nvram is virtual * and kept by the guest manager on the SP. */ if (!is_sun4v) { retain_nvram_page(); } if (bootprog(bpath, bargs, user_specified_filename) == 0) { post_mountroot(filename, NULL); /*NOTREACHED*/ } return (0); }
void post_mountroot(char *bootfile, char *redirect) { int (*go2)(); int fd; /* Save the bootfile, just in case we need it again */ (void) strcpy(filename2, bootfile); for (;;) { if (boothowto & RB_ASKNAME) { char tmpname[MAXPATHLEN]; printf("Enter filename [%s]: ", bootfile); (void) cons_gets(tmpname, sizeof (tmpname)); if (tmpname[0] != '\0') (void) strcpy(bootfile, tmpname); } if (boothowto & RB_HALT) { printf("Boot halted.\n"); prom_enter_mon(); } if ((fd = openfile(bootfile)) == FAILURE) { /* * There are many reasons why this might've * happened .. but one of them is that we're * on the installation CD, and we need to * revector ourselves off to a different partition * of the CD. Check for the redirection file. */ if (redirect != NULL && read_redirect(redirect)) { /* restore bootfile */ (void) strcpy(bootfile, filename2); return; /*NOTREACHED*/ } printf("%s: cannot open %s\n", my_own_name, bootfile); boothowto |= RB_ASKNAME; /* restore bootfile */ (void) strcpy(bootfile, filename2); continue; } if ((go2 = readfile(fd, boothowto & RB_VERBOSE)) != (int(*)()) -1) { (void) close(fd); } else { printf("boot failed\n"); boothowto |= RB_ASKNAME; continue; } if (boothowto & RB_HALT) { printf("Boot halted before exit to 0x%p.\n", (void *)go2); prom_enter_mon(); } my_own_name = bootfile; dprintf("Calling exitto64(%p, %p)\n", (void *)go2, (void *)elfbootvecELF64); exitto64(go2, (void *)elfbootvecELF64); } }
void kmdb_prom_enter_mon(void) { prom_enter_mon(); }