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 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 /* 64*0f24ff92SPiotr 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; 727c478bd9Sstevel@tonic-gate 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(¶ms); 857c478bd9Sstevel@tonic-gate while ((c = getoptstr(¶ms)) != -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': 105e557d412SChristopher Kiick (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) 154986fd29aSsetje /* Ignore argument meant for wanboot 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