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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/reboot.h> 31 #include <sys/cmn_err.h> 32 #include <sys/bootconf.h> 33 #include <sys/promif.h> 34 #include <sys/obpdefs.h> 35 #include <sys/sunddi.h> 36 #include <sys/systm.h> 37 #include <sys/kobj.h> 38 #include <sys/kobj_impl.h> 39 #include <util/getoptstr.h> 40 41 char *kobj_kmdb_argv[11]; /* 10 arguments and trailing NULL */ 42 43 /* 44 * Parse the boot line to determine boot flags. 45 */ 46 void 47 bootflags(struct bootops *ops) 48 { 49 struct gos_params params; 50 uchar_t num_O_opt = 0; 51 char *cp; 52 int c; 53 54 55 if (BOP_GETPROP(ops, "boot-args", kern_bootargs) != 0) { 56 boothowto |= RB_ASKNAME; 57 return; 58 } 59 60 cp = kern_bootargs; 61 62 #if !defined(__i386) && !defined(__amd64) 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 SKIP_WORD(cp); /* Skip the kernel's filename. */ 70 #endif 71 SKIP_SPC(cp); 72 73 params.gos_opts = "abcdgGhi:km:O:rsvwx"; 74 params.gos_strp = cp; 75 getoptstr_init(¶ms); 76 while ((c = getoptstr(¶ms)) != -1) { 77 switch (c) { 78 case 'a': 79 boothowto |= RB_ASKNAME; 80 break; 81 case 'b': 82 boothowto |= RB_NOBOOTRC; 83 break; 84 case 'c': 85 boothowto |= RB_CONFIG; 86 break; 87 case 'd': 88 boothowto |= RB_DEBUGENTER; 89 break; 90 case 'g': 91 boothowto |= RB_FORTHDEBUG; 92 break; 93 case 'G': 94 boothowto |= RB_FORTHDEBUGDBP; 95 break; 96 case 'h': 97 boothowto |= RB_HALT; 98 break; 99 case 'i': 100 if (params.gos_optarglen + 1 > sizeof (initname)) { 101 _kobj_printf(ops, "krtld: initname too long. " 102 "Ignoring.\n"); 103 } else { 104 (void) strncpy(initname, params.gos_optargp, 105 params.gos_optarglen); 106 initname[params.gos_optarglen] = '\0'; 107 } 108 break; 109 case 'k': 110 boothowto |= RB_KMDB; 111 break; 112 case 'm': 113 if (2 + params.gos_optarglen + 1 > sizeof (initargs)) 114 printf( 115 "unix: -m argument too long. Ignoring.\n"); 116 else { 117 (void) strcpy(initargs, "-m"); 118 (void) strncat(initargs, params.gos_optargp, 119 params.gos_optarglen); 120 initargs[sizeof ("-m") - 1 + 121 params.gos_optarglen] = '\0'; 122 } 123 break; 124 case 'O': { 125 char **str = &kobj_kmdb_argv[num_O_opt]; 126 127 if (++num_O_opt > (sizeof (kobj_kmdb_argv) / 128 sizeof (char *)) - 1) { 129 _kobj_printf(ops, "krtld: too many kmdb " 130 "options - ignoring option #%d.\n", 131 num_O_opt); 132 continue; 133 } 134 135 *str = kobj_alloc(params.gos_optarglen + 1, KM_TMP); 136 (void) strncpy(*str, params.gos_optargp, 137 params.gos_optarglen); 138 (*str)[params.gos_optarglen] = '\0'; 139 break; 140 } 141 case 'r': 142 boothowto |= RB_RECONFIG; 143 break; 144 case 's': 145 boothowto |= RB_SINGLE; 146 break; 147 case 'v': 148 boothowto |= RB_VERBOSE; 149 break; 150 case 'w': 151 boothowto |= RB_WRITABLE; 152 break; 153 case 'x': 154 boothowto |= RB_NOBOOTCLUSTER; 155 break; 156 case '?': 157 switch (params.gos_last_opt) { 158 case 'i': 159 _kobj_printf(ops, "krtld: Required argument " 160 "for -i flag missing. Ignoring.\n"); 161 break; 162 default: 163 _kobj_printf(ops, "krtld: Ignoring invalid " 164 "kernel option -%c.\n", 165 params.gos_last_opt); 166 } 167 break; 168 default: 169 _kobj_printf(ops, "krtld: Ignoring unimplemented " 170 "option -%c.\n", c); 171 } 172 } 173 174 if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) { 175 _kobj_printf(ops, "krtld: -d is not valid without -k.\n"); 176 boothowto &= ~RB_DEBUGENTER; 177 } 178 179 if (*params.gos_strp) { 180 /* Unused arguments. */ 181 if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) { 182 /*EMPTY*/ 183 /* Lousy install arguments. Silently ignore. */ 184 } else { 185 _kobj_printf(ops, "krtld: Unused kernel arguments: " 186 "`%s'.\n", params.gos_strp); 187 } 188 } 189 } 190