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 2008 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: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 #endif 108 case 'g': 109 boothowto |= RB_FORTHDEBUG; 110 break; 111 case 'G': 112 boothowto |= RB_FORTHDEBUGDBP; 113 break; 114 case 'h': 115 boothowto |= RB_HALT; 116 break; 117 #if defined(_OBP) 118 case 'H': 119 break; 120 #endif 121 case 'i': 122 if (params.gos_optarglen + 1 > sizeof (initname)) { 123 _kobj_printf(ops, "krtld: initname too long. " 124 "Ignoring.\n"); 125 } else { 126 (void) strncpy(initname, params.gos_optargp, 127 params.gos_optarglen); 128 initname[params.gos_optarglen] = '\0'; 129 } 130 break; 131 case 'k': 132 boothowto |= RB_KMDB; 133 break; 134 case 'm': 135 if (strlen(initargs) + 3 + params.gos_optarglen + 1 > 136 sizeof (initargs)) { 137 _kobj_printf(ops, 138 "unix: init options too long. " 139 "Ignoring -m.\n"); 140 break; 141 } 142 /* gos_optargp is not null terminated */ 143 (void) strncpy(scratch, params.gos_optargp, 144 params.gos_optarglen); 145 scratch[params.gos_optarglen] = '\0'; 146 (void) strlcat(initargs, "-m ", sizeof (initargs)); 147 (void) strlcat(initargs, scratch, 148 sizeof (initargs)); 149 (void) strlcat(initargs, " ", sizeof (initargs)); 150 break; 151 #if defined(_OBP) 152 /* Ignore argument meant for wanboot standalone */ 153 case 'o': 154 break; 155 #endif 156 case 'O': { 157 char **str = &kobj_kmdb_argv[num_O_opt]; 158 159 if (++num_O_opt > (sizeof (kobj_kmdb_argv) / 160 sizeof (char *)) - 1) { 161 _kobj_printf(ops, "krtld: too many kmdb " 162 "options - ignoring option #%d.\n", 163 num_O_opt); 164 continue; 165 } 166 167 *str = kobj_alloc(params.gos_optarglen + 1, KM_TMP); 168 (void) strncpy(*str, params.gos_optargp, 169 params.gos_optarglen); 170 (*str)[params.gos_optarglen] = '\0'; 171 break; 172 } 173 case 'r': 174 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 175 _kobj_printf(ops, "unix: init options too " 176 "long. Ignoring -r.\n"); 177 break; 178 } 179 boothowto |= RB_RECONFIG; 180 (void) strlcat(initargs, "-r ", sizeof (initargs)); 181 break; 182 case 's': 183 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 184 _kobj_printf(ops, "unix: init options too " 185 "long. Ignoring -s.\n"); 186 break; 187 } 188 boothowto |= RB_SINGLE; 189 (void) strlcat(initargs, "-s ", sizeof (initargs)); 190 break; 191 case 'v': 192 if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 193 _kobj_printf(ops, "unix: init options too " 194 "long. Ignoring -v.\n"); 195 break; 196 } 197 boothowto |= RB_VERBOSE; 198 (void) strlcat(initargs, "-v ", sizeof (initargs)); 199 break; 200 #if defined(_OBP) 201 case 'V': 202 break; 203 case 'Z': 204 break; 205 #endif 206 case 'w': 207 boothowto |= RB_WRITABLE; 208 break; 209 case 'x': 210 boothowto |= RB_NOBOOTCLUSTER; 211 break; 212 case '?': 213 switch (params.gos_last_opt) { 214 case 'i': 215 _kobj_printf(ops, "krtld: Required argument " 216 "for -i flag missing. Ignoring.\n"); 217 break; 218 default: 219 _kobj_printf(ops, "krtld: Ignoring invalid " 220 "kernel option -%c.\n", 221 params.gos_last_opt); 222 } 223 break; 224 default: 225 _kobj_printf(ops, "krtld: Ignoring unimplemented " 226 "option -%c.\n", c); 227 } 228 } 229 230 if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) { 231 _kobj_printf(ops, "krtld: -d is not valid without -k.\n"); 232 boothowto &= ~RB_DEBUGENTER; 233 } 234 235 if (*params.gos_strp) { 236 /* Unused arguments. */ 237 if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) { 238 /*EMPTY*/ 239 /* Lousy install arguments. Silently ignore. */ 240 } else { 241 _kobj_printf(ops, "krtld: Unused kernel arguments: " 242 "`%s'.\n", params.gos_strp); 243 } 244 } 245 } 246