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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <sys/types.h> 28 #include <sys/reboot.h> 29 #include <sys/cmn_err.h> 30 #include <sys/bootconf.h> 31 #include <sys/promif.h> 32 #include <sys/obpdefs.h> 33 #include <sys/sunddi.h> 34 #include <sys/systm.h> 35 #include <sys/kobj.h> 36 #include <sys/kobj_impl.h> 37 #include <util/getoptstr.h> 38 39 char *kobj_kmdb_argv[11]; /* 10 arguments and trailing NULL */ 40 41 /* 42 * Parse the boot line to determine boot flags. 43 */ 44 void 45 bootflags(struct bootops *ops) 46 { 47 struct gos_params params; 48 uchar_t num_O_opt = 0; 49 char *cp; 50 int c; 51 char scratch[BOOTARGS_MAX]; 52 53 if (BOP_GETPROP(ops, "bootargs", kern_bootargs) == -1) { 54 boothowto |= RB_ASKNAME; 55 return; 56 } 57 58 (void) BOP_GETPROP(ops, "boot-file", kern_bootfile); 59 60 cp = kern_bootargs; 61 62 #if defined(_OBP) 63 /* 64 * x86: The boot scripts (i.e., /etc/bootrc) don't prepend the kernel 65 * name to the boot arguments. (And beware making it do so: if the 66 * run-kernel command returns, it will loop, and you will end up with 67 * multiple copies of the kernel name.) 68 */ 69 if (cp[0] != '-') { 70 /* if user booted kadb or kmdb, load kmdb */ 71 if (cp[0] == 'k' && (cp[1] == 'a' || cp[1] == 'm') && 72 cp[2] == 'd' && cp[3] == 'b' && 73 (cp[4] == ' ' || cp[4] == ' ' || cp[4] == 0)) 74 boothowto |= RB_KMDB; 75 SKIP_WORD(cp); /* Skip the kernel's filename. */ 76 } 77 #endif 78 SKIP_SPC(cp); 79 80 #if defined(_OBP) 81 /* skip bootblk args */ 82 params.gos_opts = "abcdDf:F:gGHhi:km:o:O:rsvVwxZ:"; 83 #else 84 params.gos_opts = "abcdgGhi:km:O:rsvwx"; 85 #endif 86 params.gos_strp = cp; 87 getoptstr_init(¶ms); 88 while ((c = getoptstr(¶ms)) != -1) { 89 90 switch (c) { 91 case 'a': 92 boothowto |= RB_ASKNAME; 93 break; 94 case 'b': 95 boothowto |= RB_NOBOOTRC; 96 break; 97 case 'c': 98 boothowto |= RB_CONFIG; 99 break; 100 case 'd': 101 boothowto |= RB_DEBUGENTER; 102 break; 103 #if defined(_OBP) 104 case 'D': 105 case 'F': 106 break; 107 case 'f': 108 (void)prom_setprop(prom_optionsnode(), "diag-level", 109 (char *)params.gos_optargp, 110 params.gos_optarglen + 1); 111 break; 112 #endif 113 case 'g': 114 boothowto |= RB_FORTHDEBUG; 115 break; 116 case 'G': 117 boothowto |= RB_FORTHDEBUGDBP; 118 break; 119 case 'h': 120 boothowto |= RB_HALT; 121 break; 122 #if defined(_OBP) 123 case 'H': 124 break; 125 #endif 126 case 'i': 127 if (params.gos_optarglen + 1 > sizeof (initname)) { 128 _kobj_printf(ops, "krtld: initname too long. " 129 "Ignoring.\n"); 130 } else { 131 (void) strncpy(initname, params.gos_optargp, 132 params.gos_optarglen); 133 initname[params.gos_optarglen] = '\0'; 134 } 135 break; 136 case 'k': 137 boothowto |= RB_KMDB; 138 break; 139 case 'm': 140 if (strlen(initargs) + 3 + params.gos_optarglen + 1 > 141 sizeof (initargs)) { 142 _kobj_printf(ops, 143 "unix: init options too long. " 144 "Ignoring -m.\n"); 145 break; 146 } 147 /* gos_optargp is not null terminated */ 148 (void) strncpy(scratch, params.gos_optargp, 149 params.gos_optarglen); 150 scratch[params.gos_optarglen] = '\0'; 151 (void) strlcat(initargs, "-m ", sizeof (initargs)); 152 (void) strlcat(initargs, scratch, 153 sizeof (initargs)); 154 (void) strlcat(initargs, " ", sizeof (initargs)); 155 break; 156 #if defined(_OBP) 157 /* Ignore argument meant for wanboot standalone */ 158 case 'o': 159 break; 160 #endif 161 case 'O': { 162 char **str = &kobj_kmdb_argv[num_O_opt]; 163 164 if (++num_O_opt > (sizeof (kobj_kmdb_argv) / 165 sizeof (char *)) - 1) { 166 _kobj_printf(ops, "krtld: too many kmdb " 167 "options - ignoring option #%d.\n", 168 num_O_opt); 169 continue; 170 } 171 172 *str = kobj_alloc(params.gos_optarglen + 1, KM_TMP); 173 (void) strncpy(*str, params.gos_optargp, 174 params.gos_optarglen); 175 (*str)[params.gos_optarglen] = '\0'; 176 break; 177 } 178 case 'r': 179 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 180 _kobj_printf(ops, "unix: init options too " 181 "long. Ignoring -r.\n"); 182 break; 183 } 184 boothowto |= RB_RECONFIG; 185 (void) strlcat(initargs, "-r ", sizeof (initargs)); 186 break; 187 case 's': 188 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 189 _kobj_printf(ops, "unix: init options too " 190 "long. Ignoring -s.\n"); 191 break; 192 } 193 boothowto |= RB_SINGLE; 194 (void) strlcat(initargs, "-s ", sizeof (initargs)); 195 break; 196 case 'v': 197 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 198 _kobj_printf(ops, "unix: init options too " 199 "long. Ignoring -v.\n"); 200 break; 201 } 202 boothowto |= RB_VERBOSE; 203 (void) strlcat(initargs, "-v ", sizeof (initargs)); 204 break; 205 #if defined(_OBP) 206 case 'V': 207 break; 208 case 'Z': 209 break; 210 #endif 211 case 'w': 212 boothowto |= RB_WRITABLE; 213 break; 214 case 'x': 215 boothowto |= RB_NOBOOTCLUSTER; 216 break; 217 case '?': 218 switch (params.gos_last_opt) { 219 case 'i': 220 _kobj_printf(ops, "krtld: Required argument " 221 "for -i flag missing. Ignoring.\n"); 222 break; 223 default: 224 _kobj_printf(ops, "krtld: Ignoring invalid " 225 "kernel option -%c.\n", 226 params.gos_last_opt); 227 } 228 break; 229 default: 230 _kobj_printf(ops, "krtld: Ignoring unimplemented " 231 "option -%c.\n", c); 232 } 233 } 234 235 if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) { 236 _kobj_printf(ops, "krtld: -d is not valid without -k.\n"); 237 boothowto &= ~RB_DEBUGENTER; 238 } 239 240 if (*params.gos_strp) { 241 /* Unused arguments. */ 242 if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) { 243 /*EMPTY*/ 244 /* Lousy install arguments. Silently ignore. */ 245 } else { 246 _kobj_printf(ops, "krtld: Unused kernel arguments: " 247 "`%s'.\n", params.gos_strp); 248 } 249 } 250 } 251