17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53f2f09c1Sdp  * Common Development and Distribution License (the "License").
63f2f09c1Sdp  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22e557d412SChristopher Kiick  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <sys/types.h>
287c478bd9Sstevel@tonic-gate #include <sys/reboot.h>
297c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
307c478bd9Sstevel@tonic-gate #include <sys/bootconf.h>
317c478bd9Sstevel@tonic-gate #include <sys/promif.h>
327c478bd9Sstevel@tonic-gate #include <sys/obpdefs.h>
337c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
347c478bd9Sstevel@tonic-gate #include <sys/systm.h>
357c478bd9Sstevel@tonic-gate #include <sys/kobj.h>
367c478bd9Sstevel@tonic-gate #include <sys/kobj_impl.h>
377c478bd9Sstevel@tonic-gate #include <util/getoptstr.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate char *kobj_kmdb_argv[11];	/* 10 arguments and trailing NULL */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * Parse the boot line to determine boot flags.
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate void
bootflags(struct bootops * ops)457c478bd9Sstevel@tonic-gate bootflags(struct bootops *ops)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	struct gos_params params;
487c478bd9Sstevel@tonic-gate 	uchar_t num_O_opt = 0;
497c478bd9Sstevel@tonic-gate 	char *cp;
507c478bd9Sstevel@tonic-gate 	int c;
513f2f09c1Sdp 	char scratch[BOOTARGS_MAX];
527c478bd9Sstevel@tonic-gate 
53986fd29aSsetje 	if (BOP_GETPROP(ops, "bootargs", kern_bootargs) == -1) {
547c478bd9Sstevel@tonic-gate 		boothowto |= RB_ASKNAME;
557c478bd9Sstevel@tonic-gate 		return;
567c478bd9Sstevel@tonic-gate 	}
577c478bd9Sstevel@tonic-gate 
5819397407SSherry Moore 	(void) BOP_GETPROP(ops, "boot-file", kern_bootfile);
5919397407SSherry Moore 
607c478bd9Sstevel@tonic-gate 	cp = kern_bootargs;
617c478bd9Sstevel@tonic-gate 
62986fd29aSsetje #if defined(_OBP)
637c478bd9Sstevel@tonic-gate 	/*
640f24ff92SPiotr Jasiukajtis 	 * Sparc only, _OBP isn't defined on x86 any more.
657c478bd9Sstevel@tonic-gate 	 */
66986fd29aSsetje 	if (cp[0] != '-') {
67986fd29aSsetje 		/* if user booted kadb or kmdb, load kmdb */
68986fd29aSsetje 		if (cp[0] == 'k' && (cp[1] == 'a' || cp[1] == 'm') &&
69986fd29aSsetje 		    cp[2] == 'd' && cp[3] == 'b' &&
70986fd29aSsetje 		    (cp[4] == ' ' || cp[4] == '	' || cp[4] == 0))
71986fd29aSsetje 			boothowto |= RB_KMDB;
72986fd29aSsetje 		SKIP_WORD(cp);		/* Skip the kernel's filename. */
73986fd29aSsetje 	}
747c478bd9Sstevel@tonic-gate #endif
757c478bd9Sstevel@tonic-gate 	SKIP_SPC(cp);
767c478bd9Sstevel@tonic-gate 
77986fd29aSsetje #if defined(_OBP)
78986fd29aSsetje 	/* skip bootblk args */
79e557d412SChristopher Kiick 	params.gos_opts = "abcdDf:F:gGHhi:km:o:O:rsvVwxZ:";
80986fd29aSsetje #else
817c478bd9Sstevel@tonic-gate 	params.gos_opts = "abcdgGhi:km:O:rsvwx";
82986fd29aSsetje #endif
837c478bd9Sstevel@tonic-gate 	params.gos_strp = cp;
847c478bd9Sstevel@tonic-gate 	getoptstr_init(&params);
857c478bd9Sstevel@tonic-gate 	while ((c = getoptstr(&params)) != -1) {
863f2f09c1Sdp 
877c478bd9Sstevel@tonic-gate 		switch (c) {
887c478bd9Sstevel@tonic-gate 		case 'a':
897c478bd9Sstevel@tonic-gate 			boothowto |= RB_ASKNAME;
907c478bd9Sstevel@tonic-gate 			break;
917c478bd9Sstevel@tonic-gate 		case 'b':
927c478bd9Sstevel@tonic-gate 			boothowto |= RB_NOBOOTRC;
937c478bd9Sstevel@tonic-gate 			break;
947c478bd9Sstevel@tonic-gate 		case 'c':
957c478bd9Sstevel@tonic-gate 			boothowto |= RB_CONFIG;
967c478bd9Sstevel@tonic-gate 			break;
977c478bd9Sstevel@tonic-gate 		case 'd':
987c478bd9Sstevel@tonic-gate 			boothowto |= RB_DEBUGENTER;
997c478bd9Sstevel@tonic-gate 			break;
100986fd29aSsetje #if defined(_OBP)
101986fd29aSsetje 		case 'D':
102986fd29aSsetje 		case 'F':
103986fd29aSsetje 			break;
104e557d412SChristopher Kiick 		case 'f':
1050f24ff92SPiotr Jasiukajtis 			(void) prom_setprop(prom_optionsnode(), "diag-level",
106e557d412SChristopher Kiick 			    (char *)params.gos_optargp,
107e557d412SChristopher Kiick 			    params.gos_optarglen + 1);
108e557d412SChristopher Kiick 			break;
109986fd29aSsetje #endif
1107c478bd9Sstevel@tonic-gate 		case 'g':
1117c478bd9Sstevel@tonic-gate 			boothowto |= RB_FORTHDEBUG;
1127c478bd9Sstevel@tonic-gate 			break;
1137c478bd9Sstevel@tonic-gate 		case 'G':
1147c478bd9Sstevel@tonic-gate 			boothowto |= RB_FORTHDEBUGDBP;
1157c478bd9Sstevel@tonic-gate 			break;
1167c478bd9Sstevel@tonic-gate 		case 'h':
1177c478bd9Sstevel@tonic-gate 			boothowto |= RB_HALT;
1187c478bd9Sstevel@tonic-gate 			break;
119986fd29aSsetje #if defined(_OBP)
120986fd29aSsetje 		case 'H':
121986fd29aSsetje 			break;
122986fd29aSsetje #endif
1237c478bd9Sstevel@tonic-gate 		case 'i':
1247c478bd9Sstevel@tonic-gate 			if (params.gos_optarglen + 1 > sizeof (initname)) {
1257c478bd9Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: initname too long.  "
1267c478bd9Sstevel@tonic-gate 				    "Ignoring.\n");
1277c478bd9Sstevel@tonic-gate 			} else {
1287c478bd9Sstevel@tonic-gate 				(void) strncpy(initname, params.gos_optargp,
1297c478bd9Sstevel@tonic-gate 				    params.gos_optarglen);
1307c478bd9Sstevel@tonic-gate 				initname[params.gos_optarglen] = '\0';
1317c478bd9Sstevel@tonic-gate 			}
1327c478bd9Sstevel@tonic-gate 			break;
1337c478bd9Sstevel@tonic-gate 		case 'k':
1347c478bd9Sstevel@tonic-gate 			boothowto |= RB_KMDB;
1357c478bd9Sstevel@tonic-gate 			break;
1367c478bd9Sstevel@tonic-gate 		case 'm':
1373f2f09c1Sdp 			if (strlen(initargs) + 3 + params.gos_optarglen + 1 >
1383f2f09c1Sdp 			    sizeof (initargs)) {
1393f2f09c1Sdp 				_kobj_printf(ops,
1403f2f09c1Sdp 				    "unix: init options too long.  "
1413f2f09c1Sdp 				    "Ignoring -m.\n");
1423f2f09c1Sdp 				break;
1437c478bd9Sstevel@tonic-gate 			}
1443f2f09c1Sdp 			/* gos_optargp is not null terminated */
1453f2f09c1Sdp 			(void) strncpy(scratch, params.gos_optargp,
1463f2f09c1Sdp 			    params.gos_optarglen);
1473f2f09c1Sdp 			scratch[params.gos_optarglen] = '\0';
1483f2f09c1Sdp 			(void) strlcat(initargs, "-m ", sizeof (initargs));
149986fd29aSsetje 			(void) strlcat(initargs, scratch,
150986fd29aSsetje 			    sizeof (initargs));
1513f2f09c1Sdp 			(void) strlcat(initargs, " ", sizeof (initargs));
1527c478bd9Sstevel@tonic-gate 			break;
153986fd29aSsetje #if defined(_OBP)
154*bf5d9f18SAndy Fiddaman 		/* Ignore legacy wanboot argument meant for standalone */
155986fd29aSsetje 		case 'o':
156986fd29aSsetje 			break;
157986fd29aSsetje #endif
1587c478bd9Sstevel@tonic-gate 		case 'O': {
1597c478bd9Sstevel@tonic-gate 			char **str = &kobj_kmdb_argv[num_O_opt];
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 			if (++num_O_opt > (sizeof (kobj_kmdb_argv) /
1627c478bd9Sstevel@tonic-gate 			    sizeof (char *)) - 1) {
1637c478bd9Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: too many kmdb "
1647c478bd9Sstevel@tonic-gate 				    "options - ignoring option #%d.\n",
1657c478bd9Sstevel@tonic-gate 				    num_O_opt);
1667c478bd9Sstevel@tonic-gate 				continue;
1677c478bd9Sstevel@tonic-gate 			}
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 			*str = kobj_alloc(params.gos_optarglen + 1, KM_TMP);
1707c478bd9Sstevel@tonic-gate 			(void) strncpy(*str, params.gos_optargp,
1717c478bd9Sstevel@tonic-gate 			    params.gos_optarglen);
1727c478bd9Sstevel@tonic-gate 			(*str)[params.gos_optarglen] = '\0';
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 		}
1757c478bd9Sstevel@tonic-gate 		case 'r':
1763f2f09c1Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
1773f2f09c1Sdp 				_kobj_printf(ops, "unix: init options too "
1783f2f09c1Sdp 				    "long.  Ignoring -r.\n");
1793f2f09c1Sdp 				break;
1803f2f09c1Sdp 			}
1817c478bd9Sstevel@tonic-gate 			boothowto |= RB_RECONFIG;
1823f2f09c1Sdp 			(void) strlcat(initargs, "-r ", sizeof (initargs));
1837c478bd9Sstevel@tonic-gate 			break;
1847c478bd9Sstevel@tonic-gate 		case 's':
1853f2f09c1Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
1863f2f09c1Sdp 				_kobj_printf(ops, "unix: init options too "
1873f2f09c1Sdp 				    "long.  Ignoring -s.\n");
1883f2f09c1Sdp 				break;
1893f2f09c1Sdp 			}
1907c478bd9Sstevel@tonic-gate 			boothowto |= RB_SINGLE;
1913f2f09c1Sdp 			(void) strlcat(initargs, "-s ", sizeof (initargs));
1927c478bd9Sstevel@tonic-gate 			break;
1937c478bd9Sstevel@tonic-gate 		case 'v':
1943f2f09c1Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
1953f2f09c1Sdp 				_kobj_printf(ops, "unix: init options too "
1963f2f09c1Sdp 				    "long.  Ignoring -v.\n");
1973f2f09c1Sdp 				break;
1983f2f09c1Sdp 			}
1997c478bd9Sstevel@tonic-gate 			boothowto |= RB_VERBOSE;
2003f2f09c1Sdp 			(void) strlcat(initargs, "-v ", sizeof (initargs));
2017c478bd9Sstevel@tonic-gate 			break;
202986fd29aSsetje #if defined(_OBP)
203986fd29aSsetje 		case 'V':
204986fd29aSsetje 			break;
205b35c6776Staylor 		case 'Z':
206b35c6776Staylor 			break;
207986fd29aSsetje #endif
2087c478bd9Sstevel@tonic-gate 		case 'w':
2097c478bd9Sstevel@tonic-gate 			boothowto |= RB_WRITABLE;
2107c478bd9Sstevel@tonic-gate 			break;
2117c478bd9Sstevel@tonic-gate 		case 'x':
2127c478bd9Sstevel@tonic-gate 			boothowto |= RB_NOBOOTCLUSTER;
2137c478bd9Sstevel@tonic-gate 			break;
2147c478bd9Sstevel@tonic-gate 		case '?':
2157c478bd9Sstevel@tonic-gate 			switch (params.gos_last_opt) {
2167c478bd9Sstevel@tonic-gate 			case 'i':
2177c478bd9Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: Required argument "
2187c478bd9Sstevel@tonic-gate 				    "for -i flag missing.  Ignoring.\n");
2197c478bd9Sstevel@tonic-gate 				break;
2207c478bd9Sstevel@tonic-gate 			default:
2217c478bd9Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: Ignoring invalid "
2227c478bd9Sstevel@tonic-gate 				    "kernel option -%c.\n",
2237c478bd9Sstevel@tonic-gate 				    params.gos_last_opt);
2247c478bd9Sstevel@tonic-gate 			}
2257c478bd9Sstevel@tonic-gate 			break;
2267c478bd9Sstevel@tonic-gate 		default:
2277c478bd9Sstevel@tonic-gate 			_kobj_printf(ops, "krtld: Ignoring unimplemented "
2287c478bd9Sstevel@tonic-gate 			    "option -%c.\n", c);
2297c478bd9Sstevel@tonic-gate 		}
2307c478bd9Sstevel@tonic-gate 	}
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) {
2337c478bd9Sstevel@tonic-gate 		_kobj_printf(ops, "krtld: -d is not valid without -k.\n");
2347c478bd9Sstevel@tonic-gate 		boothowto &= ~RB_DEBUGENTER;
2357c478bd9Sstevel@tonic-gate 	}
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	if (*params.gos_strp) {
2387c478bd9Sstevel@tonic-gate 		/* Unused arguments. */
2397c478bd9Sstevel@tonic-gate 		if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) {
2407c478bd9Sstevel@tonic-gate 			/*EMPTY*/
2417c478bd9Sstevel@tonic-gate 			/* Lousy install arguments.  Silently ignore. */
2427c478bd9Sstevel@tonic-gate 		} else {
2437c478bd9Sstevel@tonic-gate 			_kobj_printf(ops, "krtld: Unused kernel arguments: "
2447c478bd9Sstevel@tonic-gate 			    "`%s'.\n", params.gos_strp);
2457c478bd9Sstevel@tonic-gate 		}
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate }
248