xref: /illumos-gate/usr/src/uts/common/krtld/kobj_bootflags.c (revision 60a3f738d56f92ae8b80e4b62a2331c6e1f2311f)
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 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/reboot.h>
30 #include <sys/cmn_err.h>
31 #include <sys/bootconf.h>
32 #include <sys/promif.h>
33 #include <sys/obpdefs.h>
34 #include <sys/sunddi.h>
35 #include <sys/systm.h>
36 #include <sys/kobj.h>
37 #include <sys/kobj_impl.h>
38 #include <util/getoptstr.h>
39 
40 char *kobj_kmdb_argv[11];	/* 10 arguments and trailing NULL */
41 
42 /*
43  * Parse the boot line to determine boot flags.
44  */
45 void
46 bootflags(struct bootops *ops)
47 {
48 	struct gos_params params;
49 	uchar_t num_O_opt = 0;
50 	char *cp;
51 	int c;
52 	char scratch[BOOTARGS_MAX];
53 
54 	if (BOP_GETPROP(ops, "boot-args", kern_bootargs) != 0) {
55 		boothowto |= RB_ASKNAME;
56 		return;
57 	}
58 
59 	cp = kern_bootargs;
60 
61 #if !defined(__i386) && !defined(__amd64)
62 	/*
63 	 * x86: The boot scripts (i.e., /etc/bootrc) don't prepend the kernel
64 	 * name to the boot arguments.  (And beware making it do so: if the
65 	 * run-kernel command returns, it will loop, and you will end up with
66 	 * multiple copies of the kernel name.)
67 	 */
68 	SKIP_WORD(cp);		/* Skip the kernel's filename. */
69 #endif
70 	SKIP_SPC(cp);
71 
72 	params.gos_opts = "abcdgGhi:km:O:rsvwx";
73 	params.gos_strp = cp;
74 	getoptstr_init(&params);
75 	while ((c = getoptstr(&params)) != -1) {
76 
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 (strlen(initargs) + 3 + params.gos_optarglen + 1 >
114 			    sizeof (initargs)) {
115 				_kobj_printf(ops,
116 				    "unix: init options too long.  "
117 				    "Ignoring -m.\n");
118 				break;
119 			}
120 			/* gos_optargp is not null terminated */
121 			(void) strncpy(scratch, params.gos_optargp,
122 			    params.gos_optarglen);
123 			scratch[params.gos_optarglen] = '\0';
124 			(void) strlcat(initargs, "-m ", sizeof (initargs));
125 			(void) strlcat(initargs, scratch, sizeof (initargs));
126 			(void) strlcat(initargs, " ", sizeof (initargs));
127 			break;
128 		case 'O': {
129 			char **str = &kobj_kmdb_argv[num_O_opt];
130 
131 			if (++num_O_opt > (sizeof (kobj_kmdb_argv) /
132 			    sizeof (char *)) - 1) {
133 				_kobj_printf(ops, "krtld: too many kmdb "
134 				    "options - ignoring option #%d.\n",
135 				    num_O_opt);
136 				continue;
137 			}
138 
139 			*str = kobj_alloc(params.gos_optarglen + 1, KM_TMP);
140 			(void) strncpy(*str, params.gos_optargp,
141 			    params.gos_optarglen);
142 			(*str)[params.gos_optarglen] = '\0';
143 			break;
144 		}
145 		case 'r':
146 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
147 				_kobj_printf(ops, "unix: init options too "
148 				    "long.  Ignoring -r.\n");
149 				break;
150 			}
151 			boothowto |= RB_RECONFIG;
152 			(void) strlcat(initargs, "-r ", sizeof (initargs));
153 			break;
154 		case 's':
155 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
156 				_kobj_printf(ops, "unix: init options too "
157 				    "long.  Ignoring -s.\n");
158 				break;
159 			}
160 			boothowto |= RB_SINGLE;
161 			(void) strlcat(initargs, "-s ", sizeof (initargs));
162 			break;
163 		case 'v':
164 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
165 				_kobj_printf(ops, "unix: init options too "
166 				    "long.  Ignoring -v.\n");
167 				break;
168 			}
169 			boothowto |= RB_VERBOSE;
170 			(void) strlcat(initargs, "-v ", sizeof (initargs));
171 			break;
172 		case 'w':
173 			boothowto |= RB_WRITABLE;
174 			break;
175 		case 'x':
176 			boothowto |= RB_NOBOOTCLUSTER;
177 			break;
178 		case '?':
179 			switch (params.gos_last_opt) {
180 			case 'i':
181 				_kobj_printf(ops, "krtld: Required argument "
182 				    "for -i flag missing.  Ignoring.\n");
183 				break;
184 			default:
185 				_kobj_printf(ops, "krtld: Ignoring invalid "
186 				    "kernel option -%c.\n",
187 				    params.gos_last_opt);
188 			}
189 			break;
190 		default:
191 			_kobj_printf(ops, "krtld: Ignoring unimplemented "
192 			    "option -%c.\n", c);
193 		}
194 	}
195 
196 	if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) {
197 		_kobj_printf(ops, "krtld: -d is not valid without -k.\n");
198 		boothowto &= ~RB_DEBUGENTER;
199 	}
200 
201 	if (*params.gos_strp) {
202 		/* Unused arguments. */
203 		if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) {
204 			/*EMPTY*/
205 			/* Lousy install arguments.  Silently ignore. */
206 		} else {
207 			_kobj_printf(ops, "krtld: Unused kernel arguments: "
208 			    "`%s'.\n", params.gos_strp);
209 		}
210 	}
211 }
212