xref: /onnv-gate/usr/src/uts/common/krtld/kobj_bootflags.c (revision 2267:c5d9a656170f)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2267Sdp  * Common Development and Distribution License (the "License").
6*2267Sdp  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2267Sdp  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/types.h>
290Sstevel@tonic-gate #include <sys/reboot.h>
300Sstevel@tonic-gate #include <sys/cmn_err.h>
310Sstevel@tonic-gate #include <sys/bootconf.h>
320Sstevel@tonic-gate #include <sys/promif.h>
330Sstevel@tonic-gate #include <sys/obpdefs.h>
340Sstevel@tonic-gate #include <sys/sunddi.h>
350Sstevel@tonic-gate #include <sys/systm.h>
360Sstevel@tonic-gate #include <sys/kobj.h>
370Sstevel@tonic-gate #include <sys/kobj_impl.h>
380Sstevel@tonic-gate #include <util/getoptstr.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate char *kobj_kmdb_argv[11];	/* 10 arguments and trailing NULL */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * Parse the boot line to determine boot flags.
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate void
460Sstevel@tonic-gate bootflags(struct bootops *ops)
470Sstevel@tonic-gate {
480Sstevel@tonic-gate 	struct gos_params params;
490Sstevel@tonic-gate 	uchar_t num_O_opt = 0;
500Sstevel@tonic-gate 	char *cp;
510Sstevel@tonic-gate 	int c;
52*2267Sdp 	char scratch[BOOTARGS_MAX];
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	if (BOP_GETPROP(ops, "boot-args", kern_bootargs) != 0) {
550Sstevel@tonic-gate 		boothowto |= RB_ASKNAME;
560Sstevel@tonic-gate 		return;
570Sstevel@tonic-gate 	}
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	cp = kern_bootargs;
600Sstevel@tonic-gate 
610Sstevel@tonic-gate #if !defined(__i386) && !defined(__amd64)
620Sstevel@tonic-gate 	/*
630Sstevel@tonic-gate 	 * x86: The boot scripts (i.e., /etc/bootrc) don't prepend the kernel
640Sstevel@tonic-gate 	 * name to the boot arguments.  (And beware making it do so: if the
650Sstevel@tonic-gate 	 * run-kernel command returns, it will loop, and you will end up with
660Sstevel@tonic-gate 	 * multiple copies of the kernel name.)
670Sstevel@tonic-gate 	 */
680Sstevel@tonic-gate 	SKIP_WORD(cp);		/* Skip the kernel's filename. */
690Sstevel@tonic-gate #endif
700Sstevel@tonic-gate 	SKIP_SPC(cp);
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	params.gos_opts = "abcdgGhi:km:O:rsvwx";
730Sstevel@tonic-gate 	params.gos_strp = cp;
740Sstevel@tonic-gate 	getoptstr_init(&params);
750Sstevel@tonic-gate 	while ((c = getoptstr(&params)) != -1) {
76*2267Sdp 
770Sstevel@tonic-gate 		switch (c) {
780Sstevel@tonic-gate 		case 'a':
790Sstevel@tonic-gate 			boothowto |= RB_ASKNAME;
800Sstevel@tonic-gate 			break;
810Sstevel@tonic-gate 		case 'b':
820Sstevel@tonic-gate 			boothowto |= RB_NOBOOTRC;
830Sstevel@tonic-gate 			break;
840Sstevel@tonic-gate 		case 'c':
850Sstevel@tonic-gate 			boothowto |= RB_CONFIG;
860Sstevel@tonic-gate 			break;
870Sstevel@tonic-gate 		case 'd':
880Sstevel@tonic-gate 			boothowto |= RB_DEBUGENTER;
890Sstevel@tonic-gate 			break;
900Sstevel@tonic-gate 		case 'g':
910Sstevel@tonic-gate 			boothowto |= RB_FORTHDEBUG;
920Sstevel@tonic-gate 			break;
930Sstevel@tonic-gate 		case 'G':
940Sstevel@tonic-gate 			boothowto |= RB_FORTHDEBUGDBP;
950Sstevel@tonic-gate 			break;
960Sstevel@tonic-gate 		case 'h':
970Sstevel@tonic-gate 			boothowto |= RB_HALT;
980Sstevel@tonic-gate 			break;
990Sstevel@tonic-gate 		case 'i':
1000Sstevel@tonic-gate 			if (params.gos_optarglen + 1 > sizeof (initname)) {
1010Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: initname too long.  "
1020Sstevel@tonic-gate 				    "Ignoring.\n");
1030Sstevel@tonic-gate 			} else {
1040Sstevel@tonic-gate 				(void) strncpy(initname, params.gos_optargp,
1050Sstevel@tonic-gate 				    params.gos_optarglen);
1060Sstevel@tonic-gate 				initname[params.gos_optarglen] = '\0';
1070Sstevel@tonic-gate 			}
1080Sstevel@tonic-gate 			break;
1090Sstevel@tonic-gate 		case 'k':
1100Sstevel@tonic-gate 			boothowto |= RB_KMDB;
1110Sstevel@tonic-gate 			break;
1120Sstevel@tonic-gate 		case 'm':
113*2267Sdp 			if (strlen(initargs) + 3 + params.gos_optarglen + 1 >
114*2267Sdp 			    sizeof (initargs)) {
115*2267Sdp 				_kobj_printf(ops,
116*2267Sdp 				    "unix: init options too long.  "
117*2267Sdp 				    "Ignoring -m.\n");
118*2267Sdp 				break;
1190Sstevel@tonic-gate 			}
120*2267Sdp 			/* gos_optargp is not null terminated */
121*2267Sdp 			(void) strncpy(scratch, params.gos_optargp,
122*2267Sdp 			    params.gos_optarglen);
123*2267Sdp 			scratch[params.gos_optarglen] = '\0';
124*2267Sdp 			(void) strlcat(initargs, "-m ", sizeof (initargs));
125*2267Sdp 			(void) strlcat(initargs, scratch, sizeof (initargs));
126*2267Sdp 			(void) strlcat(initargs, " ", sizeof (initargs));
1270Sstevel@tonic-gate 			break;
1280Sstevel@tonic-gate 		case 'O': {
1290Sstevel@tonic-gate 			char **str = &kobj_kmdb_argv[num_O_opt];
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 			if (++num_O_opt > (sizeof (kobj_kmdb_argv) /
1320Sstevel@tonic-gate 			    sizeof (char *)) - 1) {
1330Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: too many kmdb "
1340Sstevel@tonic-gate 				    "options - ignoring option #%d.\n",
1350Sstevel@tonic-gate 				    num_O_opt);
1360Sstevel@tonic-gate 				continue;
1370Sstevel@tonic-gate 			}
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 			*str = kobj_alloc(params.gos_optarglen + 1, KM_TMP);
1400Sstevel@tonic-gate 			(void) strncpy(*str, params.gos_optargp,
1410Sstevel@tonic-gate 			    params.gos_optarglen);
1420Sstevel@tonic-gate 			(*str)[params.gos_optarglen] = '\0';
1430Sstevel@tonic-gate 			break;
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 		case 'r':
146*2267Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
147*2267Sdp 				_kobj_printf(ops, "unix: init options too "
148*2267Sdp 				    "long.  Ignoring -r.\n");
149*2267Sdp 				break;
150*2267Sdp 			}
1510Sstevel@tonic-gate 			boothowto |= RB_RECONFIG;
152*2267Sdp 			(void) strlcat(initargs, "-r ", sizeof (initargs));
1530Sstevel@tonic-gate 			break;
1540Sstevel@tonic-gate 		case 's':
155*2267Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
156*2267Sdp 				_kobj_printf(ops, "unix: init options too "
157*2267Sdp 				    "long.  Ignoring -s.\n");
158*2267Sdp 				break;
159*2267Sdp 			}
1600Sstevel@tonic-gate 			boothowto |= RB_SINGLE;
161*2267Sdp 			(void) strlcat(initargs, "-s ", sizeof (initargs));
1620Sstevel@tonic-gate 			break;
1630Sstevel@tonic-gate 		case 'v':
164*2267Sdp 			if (strlen(initargs) + 3 + 1 > sizeof (initargs)) {
165*2267Sdp 				_kobj_printf(ops, "unix: init options too "
166*2267Sdp 				    "long.  Ignoring -v.\n");
167*2267Sdp 				break;
168*2267Sdp 			}
1690Sstevel@tonic-gate 			boothowto |= RB_VERBOSE;
170*2267Sdp 			(void) strlcat(initargs, "-v ", sizeof (initargs));
1710Sstevel@tonic-gate 			break;
1720Sstevel@tonic-gate 		case 'w':
1730Sstevel@tonic-gate 			boothowto |= RB_WRITABLE;
1740Sstevel@tonic-gate 			break;
1750Sstevel@tonic-gate 		case 'x':
1760Sstevel@tonic-gate 			boothowto |= RB_NOBOOTCLUSTER;
1770Sstevel@tonic-gate 			break;
1780Sstevel@tonic-gate 		case '?':
1790Sstevel@tonic-gate 			switch (params.gos_last_opt) {
1800Sstevel@tonic-gate 			case 'i':
1810Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: Required argument "
1820Sstevel@tonic-gate 				    "for -i flag missing.  Ignoring.\n");
1830Sstevel@tonic-gate 				break;
1840Sstevel@tonic-gate 			default:
1850Sstevel@tonic-gate 				_kobj_printf(ops, "krtld: Ignoring invalid "
1860Sstevel@tonic-gate 				    "kernel option -%c.\n",
1870Sstevel@tonic-gate 				    params.gos_last_opt);
1880Sstevel@tonic-gate 			}
1890Sstevel@tonic-gate 			break;
1900Sstevel@tonic-gate 		default:
1910Sstevel@tonic-gate 			_kobj_printf(ops, "krtld: Ignoring unimplemented "
1920Sstevel@tonic-gate 			    "option -%c.\n", c);
1930Sstevel@tonic-gate 		}
1940Sstevel@tonic-gate 	}
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) {
1970Sstevel@tonic-gate 		_kobj_printf(ops, "krtld: -d is not valid without -k.\n");
1980Sstevel@tonic-gate 		boothowto &= ~RB_DEBUGENTER;
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	if (*params.gos_strp) {
2020Sstevel@tonic-gate 		/* Unused arguments. */
2030Sstevel@tonic-gate 		if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) {
2040Sstevel@tonic-gate 			/*EMPTY*/
2050Sstevel@tonic-gate 			/* Lousy install arguments.  Silently ignore. */
2060Sstevel@tonic-gate 		} else {
2070Sstevel@tonic-gate 			_kobj_printf(ops, "krtld: Unused kernel arguments: "
2080Sstevel@tonic-gate 			    "`%s'.\n", params.gos_strp);
2090Sstevel@tonic-gate 		}
2100Sstevel@tonic-gate 	}
2110Sstevel@tonic-gate }
212