1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/param.h> 30 #include <sys/fcntl.h> 31 #include <sys/obpdefs.h> 32 #include <sys/reboot.h> 33 #include <sys/promif.h> 34 #include <sys/stat.h> 35 #include <sys/bootvfs.h> 36 #include <sys/platnames.h> 37 #include <sys/salib.h> 38 #include <sys/elf.h> 39 #include <sys/link.h> 40 #include <sys/auxv.h> 41 #include <sys/boot_policy.h> 42 #include <sys/boot_redirect.h> 43 #include <sys/bootconf.h> 44 #include <sys/boot.h> 45 #include "boot_plat.h" 46 #include "ramdisk.h" 47 48 #define SUCCESS 0 49 #define FAILURE -1 50 51 #ifdef DEBUG 52 extern int debug = 0; 53 #else 54 static const int debug = 0; 55 #endif 56 57 #define dprintf if (debug) printf 58 59 char *def_boot_archive = "boot_archive"; 60 char *def_miniroot = "miniroot"; 61 extern char cmd_line_boot_archive[]; 62 63 extern int openfile(char *filename); 64 65 static int 66 read_and_boot_ramdisk(int fd) 67 { 68 struct stat st; 69 caddr_t virt; 70 size_t size; 71 extern ssize_t xread(int, char *, size_t); 72 73 if ((fstat(fd, &st) != 0) || 74 ((virt = create_ramdisk(RD_ROOTFS, st.st_size, NULL)) == NULL)) 75 return (-1); 76 77 dprintf("reading boot archive ...\n"); 78 if ((size = xread(fd, (char *)virt, st.st_size)) != st.st_size) { 79 (void) printf("Error reading boot archive, bytes read = %ld, " 80 "filesize = %ld\n", (long)size, (long)st.st_size); 81 destroy_ramdisk(RD_ROOTFS); 82 return (-1); 83 } 84 85 boot_ramdisk(RD_ROOTFS); 86 /* NOT REACHED */ 87 return (0); /* to make cc happy */ 88 } 89 90 91 static void 92 post_mountroot_nfs(void) 93 { 94 int fd; 95 char *fn; 96 char tmpname[MAXPATHLEN]; 97 98 for (;;) { 99 fn = NULL; 100 if (boothowto & RB_ASKNAME) { 101 fn = (cmd_line_boot_archive[0] != '\0') ? 102 cmd_line_boot_archive : def_boot_archive; 103 printf("Enter filename [%s]: ", fn); 104 (void) cons_gets(tmpname, sizeof (tmpname)); 105 if (tmpname[0] != '\0') 106 fn = tmpname; 107 } 108 109 if (boothowto & RB_HALT) { 110 printf("Boot halted.\n"); 111 prom_enter_mon(); 112 } 113 114 if (fn != NULL) 115 fd = openfile(fn); 116 else if (cmd_line_boot_archive[0] != '\0') { 117 fn = cmd_line_boot_archive; 118 fd = openfile(fn); 119 } else { 120 fn = def_boot_archive; 121 if ((fd = openfile(fn)) == FAILURE) { 122 fn = def_miniroot; 123 fd = openfile(fn); 124 } 125 } 126 127 if (fd == FAILURE) { 128 if (fn != def_miniroot) 129 printf("cannot open %s\n", fn); 130 else 131 printf("cannot open neither %s nor %s\n", 132 def_boot_archive, def_miniroot); 133 } else { 134 /* 135 * this function does not return if successful. 136 */ 137 (void) read_and_boot_ramdisk(fd); 138 139 printf("boot failed\n"); 140 (void) close(fd); 141 } 142 boothowto |= RB_ASKNAME; 143 } 144 } 145 146 147 /* 148 * bpath is the boot device path buffer. 149 * bargs is the boot arguments buffer. 150 */ 151 /*ARGSUSED*/ 152 int 153 bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) 154 { 155 systype = set_fstype(v2path, bpath); 156 157 if (verbosemode) { 158 printf("device path '%s'\n", bpath); 159 if (strcmp(bpath, v2path) != 0) 160 printf("client path '%s'\n", v2path); 161 } 162 163 if (mountroot(bpath) != SUCCESS) 164 prom_panic("Could not mount filesystem."); 165 166 /* 167 * kernname (default-name) might have changed if mountroot() called 168 * boot_nfs_mountroot(), and it called set_default_filename(). 169 */ 170 if (!user_specified_filename) 171 (void) strcpy(filename, kernname); 172 173 if (verbosemode) 174 printf("standalone = `%s', args = `%s'\n", filename, bargs); 175 176 set_client_bootargs(filename, bargs); 177 178 post_mountroot_nfs(); 179 180 return (1); 181 } 182