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 * Sparc only, _OBP isn't defined on x86 any more. 65 */ 66 if (cp[0] != '-') { 67 /* if user booted kadb or kmdb, load kmdb */ 68 if (cp[0] == 'k' && (cp[1] == 'a' || cp[1] == 'm') && 69 cp[2] == 'd' && cp[3] == 'b' && 70 (cp[4] == ' ' || cp[4] == ' ' || cp[4] == 0)) 71 boothowto |= RB_KMDB; 72 SKIP_WORD(cp); /* Skip the kernel's filename. */ 73 } 74 #endif 75 SKIP_SPC(cp); 76 77 #if defined(_OBP) 78 /* skip bootblk args */ 79 params.gos_opts = "abcdDf:F:gGHhi:km:o:O:rsvVwxZ:"; 80 #else 81 params.gos_opts = "abcdgGhi:km:O:rsvwx"; 82 #endif 83 params.gos_strp = cp; 84 getoptstr_init(¶ms); 85 while ((c = getoptstr(¶ms)) != -1) { 86 87 switch (c) { 88 case 'a': 89 boothowto |= RB_ASKNAME; 90 break; 91 case 'b': 92 boothowto |= RB_NOBOOTRC; 93 break; 94 case 'c': 95 boothowto |= RB_CONFIG; 96 break; 97 case 'd': 98 boothowto |= RB_DEBUGENTER; 99 break; 100 #if defined(_OBP) 101 case 'D': 102 case 'F': 103 break; 104 case 'f': 105 (void) prom_setprop(prom_optionsnode(), "diag-level", 106 (char *)params.gos_optargp, 107 params.gos_optarglen + 1); 108 break; 109 #endif 110 case 'g': 111 boothowto |= RB_FORTHDEBUG; 112 break; 113 case 'G': 114 boothowto |= RB_FORTHDEBUGDBP; 115 break; 116 case 'h': 117 boothowto |= RB_HALT; 118 break; 119 #if defined(_OBP) 120 case 'H': 121 break; 122 #endif 123 case 'i': 124 if (params.gos_optarglen + 1 > sizeof (initname)) { 125 _kobj_printf(ops, "krtld: initname too long. " 126 "Ignoring.\n"); 127 } else { 128 (void) strncpy(initname, params.gos_optargp, 129 params.gos_optarglen); 130 initname[params.gos_optarglen] = '\0'; 131 } 132 break; 133 case 'k': 134 boothowto |= RB_KMDB; 135 break; 136 case 'm': 137 if (strlen(initargs) + 3 + params.gos_optarglen + 1 > 138 sizeof (initargs)) { 139 _kobj_printf(ops, 140 "unix: init options too long. " 141 "Ignoring -m.\n"); 142 break; 143 } 144 /* gos_optargp is not null terminated */ 145 (void) strncpy(scratch, params.gos_optargp, 146 params.gos_optarglen); 147 scratch[params.gos_optarglen] = '\0'; 148 (void) strlcat(initargs, "-m ", sizeof (initargs)); 149 (void) strlcat(initargs, scratch, 150 sizeof (initargs)); 151 (void) strlcat(initargs, " ", sizeof (initargs)); 152 break; 153 #if defined(_OBP) 154 /* Ignore argument meant for wanboot standalone */ 155 case 'o': 156 break; 157 #endif 158 case 'O': { 159 char **str = &kobj_kmdb_argv[num_O_opt]; 160 161 if (++num_O_opt > (sizeof (kobj_kmdb_argv) / 162 sizeof (char *)) - 1) { 163 _kobj_printf(ops, "krtld: too many kmdb " 164 "options - ignoring option #%d.\n", 165 num_O_opt); 166 continue; 167 } 168 169 *str = kobj_alloc(params.gos_optarglen + 1, KM_TMP); 170 (void) strncpy(*str, params.gos_optargp, 171 params.gos_optarglen); 172 (*str)[params.gos_optarglen] = '\0'; 173 break; 174 } 175 case 'r': 176 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 177 _kobj_printf(ops, "unix: init options too " 178 "long. Ignoring -r.\n"); 179 break; 180 } 181 boothowto |= RB_RECONFIG; 182 (void) strlcat(initargs, "-r ", sizeof (initargs)); 183 break; 184 case 's': 185 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 186 _kobj_printf(ops, "unix: init options too " 187 "long. Ignoring -s.\n"); 188 break; 189 } 190 boothowto |= RB_SINGLE; 191 (void) strlcat(initargs, "-s ", sizeof (initargs)); 192 break; 193 case 'v': 194 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 195 _kobj_printf(ops, "unix: init options too " 196 "long. Ignoring -v.\n"); 197 break; 198 } 199 boothowto |= RB_VERBOSE; 200 (void) strlcat(initargs, "-v ", sizeof (initargs)); 201 break; 202 #if defined(_OBP) 203 case 'V': 204 break; 205 case 'Z': 206 break; 207 #endif 208 case 'w': 209 boothowto |= RB_WRITABLE; 210 break; 211 case 'x': 212 boothowto |= RB_NOBOOTCLUSTER; 213 break; 214 case '?': 215 switch (params.gos_last_opt) { 216 case 'i': 217 _kobj_printf(ops, "krtld: Required argument " 218 "for -i flag missing. Ignoring.\n"); 219 break; 220 default: 221 _kobj_printf(ops, "krtld: Ignoring invalid " 222 "kernel option -%c.\n", 223 params.gos_last_opt); 224 } 225 break; 226 default: 227 _kobj_printf(ops, "krtld: Ignoring unimplemented " 228 "option -%c.\n", c); 229 } 230 } 231 232 if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) { 233 _kobj_printf(ops, "krtld: -d is not valid without -k.\n"); 234 boothowto &= ~RB_DEBUGENTER; 235 } 236 237 if (*params.gos_strp) { 238 /* Unused arguments. */ 239 if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) { 240 /*EMPTY*/ 241 /* Lousy install arguments. Silently ignore. */ 242 } else { 243 _kobj_printf(ops, "krtld: Unused kernel arguments: " 244 "`%s'.\n", params.gos_strp); 245 } 246 } 247 } 248