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