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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <sys/types.h> 28 #include <sys/param.h> 29 #include <sys/fcntl.h> 30 #include <sys/obpdefs.h> 31 #include <sys/reboot.h> 32 #include <sys/promif.h> 33 #include <sys/stat.h> 34 #include <sys/bootvfs.h> 35 #include <sys/platnames.h> 36 #include <sys/salib.h> 37 #include <sys/elf.h> 38 #include <sys/link.h> 39 #include <sys/auxv.h> 40 #include <sys/boot_policy.h> 41 #include <sys/boot_redirect.h> 42 #include <sys/bootconf.h> 43 #include <sys/boot.h> 44 #include "boot_plat.h" 45 #include "ramdisk.h" 46 47 #define SUCCESS 0 48 #define FAILURE -1 49 50 #ifdef DEBUG 51 extern int debug = 0; 52 #else 53 static const int debug = 0; 54 #endif 55 56 #define dprintf if (debug) printf 57 58 char *def_boot_archive = "boot_archive"; 59 char *def_miniroot = "miniroot"; 60 extern char cmd_line_boot_archive[]; 61 62 extern int openfile(char *filename); 63 64 static int 65 read_and_boot_ramdisk(int fd) 66 { 67 struct stat st; 68 caddr_t virt; 69 size_t size; 70 extern ssize_t xread(int, char *, size_t); 71 72 if ((fstat(fd, &st) != 0) || 73 ((virt = create_ramdisk(RD_ROOTFS, st.st_size, NULL)) == NULL)) 74 return (-1); 75 76 dprintf("reading boot archive ...\n"); 77 if ((size = xread(fd, (char *)virt, st.st_size)) != st.st_size) { 78 (void) printf("Error reading boot archive, bytes read = %ld, " 79 "filesize = %ld\n", (long)size, (long)st.st_size); 80 destroy_ramdisk(RD_ROOTFS); 81 return (-1); 82 } 83 84 boot_ramdisk(RD_ROOTFS); 85 /* NOT REACHED */ 86 return (0); /* to make cc happy */ 87 } 88 89 90 static void 91 post_mountroot_nfs(void) 92 { 93 int fd; 94 char *fn; 95 char tmpname[MAXPATHLEN]; 96 97 for (;;) { 98 fn = NULL; 99 if (boothowto & RB_ASKNAME) { 100 char ctmpname[MAXPATHLEN]; 101 102 fn = (cmd_line_boot_archive[0] != '\0') ? 103 cmd_line_boot_archive : def_boot_archive; 104 105 /* Avoid buffer overrun */ 106 (void) strncpy(tmpname, fn, strlen(fn)+1); 107 fn = tmpname; 108 109 printf("Enter filename [%s]: ", fn); 110 (void) cons_gets(ctmpname, sizeof (ctmpname)); 111 if (ctmpname[0] != '\0') { 112 (void) strncpy(tmpname, ctmpname, 113 strlen(ctmpname)+1); 114 fn = tmpname; 115 } 116 } 117 118 if (boothowto & RB_HALT) { 119 printf("Boot halted.\n"); 120 prom_enter_mon(); 121 } 122 123 124 if (fn != NULL) { 125 fd = openfile(fn); 126 } else if (cmd_line_boot_archive[0] != '\0') { 127 (void) strncpy(tmpname, cmd_line_boot_archive, 128 strlen(cmd_line_boot_archive)+1); 129 fn = tmpname; 130 fd = openfile(fn); 131 } else { 132 (void) strncpy(tmpname, def_boot_archive, 133 strlen(def_boot_archive)+1); 134 fn = tmpname; 135 if ((fd = openfile(fn)) == FAILURE) { 136 (void) strncpy(tmpname, def_miniroot, 137 strlen(def_miniroot)+1); 138 fn = tmpname; 139 fd = openfile(fn); 140 } 141 } 142 143 if (fn != tmpname || tmpname[0] == '\0') { 144 printf("Possible buffer overrun, " 145 "entering boot prompt\n"); 146 prom_enter_mon(); 147 } 148 149 150 if (fd == FAILURE) { 151 if (strncmp(fn, def_miniroot, 152 strlen(def_miniroot)+1) != 0) 153 printf("cannot open %s\n", fn); 154 else 155 printf("cannot open neither %s nor %s\n", 156 def_boot_archive, def_miniroot); 157 } else { 158 /* 159 * this function does not return if successful. 160 */ 161 (void) read_and_boot_ramdisk(fd); 162 163 printf("boot failed\n"); 164 (void) close(fd); 165 } 166 boothowto |= RB_ASKNAME; 167 } 168 } 169 170 171 /* 172 * bpath is the boot device path buffer. 173 * bargs is the boot arguments buffer. 174 */ 175 /*ARGSUSED*/ 176 int 177 bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) 178 { 179 systype = set_fstype(v2path, bpath); 180 181 if (verbosemode) { 182 printf("device path '%s'\n", bpath); 183 if (strcmp(bpath, v2path) != 0) 184 printf("client path '%s'\n", v2path); 185 } 186 187 if (mountroot(bpath) != SUCCESS) 188 prom_panic("Could not mount filesystem."); 189 190 /* 191 * kernname (default-name) might have changed if mountroot() called 192 * boot_nfs_mountroot(), and it called set_default_filename(). 193 */ 194 if (!user_specified_filename) 195 (void) strcpy(filename, kernname); 196 197 if (verbosemode) 198 printf("standalone = `%s', args = `%s'\n", filename, bargs); 199 200 set_client_bootargs(filename, bargs); 201 202 post_mountroot_nfs(); 203 204 return (1); 205 } 206