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 52267Sdp * Common Development and Distribution License (the "License"). 62267Sdp * 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 /* 226659Staylor * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <sys/types.h> 280Sstevel@tonic-gate #include <sys/reboot.h> 290Sstevel@tonic-gate #include <sys/cmn_err.h> 300Sstevel@tonic-gate #include <sys/bootconf.h> 310Sstevel@tonic-gate #include <sys/promif.h> 320Sstevel@tonic-gate #include <sys/obpdefs.h> 330Sstevel@tonic-gate #include <sys/sunddi.h> 340Sstevel@tonic-gate #include <sys/systm.h> 350Sstevel@tonic-gate #include <sys/kobj.h> 360Sstevel@tonic-gate #include <sys/kobj_impl.h> 370Sstevel@tonic-gate #include <util/getoptstr.h> 380Sstevel@tonic-gate 390Sstevel@tonic-gate char *kobj_kmdb_argv[11]; /* 10 arguments and trailing NULL */ 400Sstevel@tonic-gate 410Sstevel@tonic-gate /* 420Sstevel@tonic-gate * Parse the boot line to determine boot flags. 430Sstevel@tonic-gate */ 440Sstevel@tonic-gate void 450Sstevel@tonic-gate bootflags(struct bootops *ops) 460Sstevel@tonic-gate { 470Sstevel@tonic-gate struct gos_params params; 480Sstevel@tonic-gate uchar_t num_O_opt = 0; 490Sstevel@tonic-gate char *cp; 500Sstevel@tonic-gate int c; 512267Sdp char scratch[BOOTARGS_MAX]; 520Sstevel@tonic-gate 535648Ssetje if (BOP_GETPROP(ops, "bootargs", kern_bootargs) == -1) { 540Sstevel@tonic-gate boothowto |= RB_ASKNAME; 550Sstevel@tonic-gate return; 560Sstevel@tonic-gate } 570Sstevel@tonic-gate 58*7656SSherry.Moore@Sun.COM (void) BOP_GETPROP(ops, "boot-file", kern_bootfile); 59*7656SSherry.Moore@Sun.COM 600Sstevel@tonic-gate cp = kern_bootargs; 610Sstevel@tonic-gate 625648Ssetje #if defined(_OBP) 630Sstevel@tonic-gate /* 640Sstevel@tonic-gate * x86: The boot scripts (i.e., /etc/bootrc) don't prepend the kernel 650Sstevel@tonic-gate * name to the boot arguments. (And beware making it do so: if the 660Sstevel@tonic-gate * run-kernel command returns, it will loop, and you will end up with 670Sstevel@tonic-gate * multiple copies of the kernel name.) 680Sstevel@tonic-gate */ 695648Ssetje if (cp[0] != '-') { 705648Ssetje /* if user booted kadb or kmdb, load kmdb */ 715648Ssetje if (cp[0] == 'k' && (cp[1] == 'a' || cp[1] == 'm') && 725648Ssetje cp[2] == 'd' && cp[3] == 'b' && 735648Ssetje (cp[4] == ' ' || cp[4] == ' ' || cp[4] == 0)) 745648Ssetje boothowto |= RB_KMDB; 755648Ssetje SKIP_WORD(cp); /* Skip the kernel's filename. */ 765648Ssetje } 770Sstevel@tonic-gate #endif 780Sstevel@tonic-gate SKIP_SPC(cp); 790Sstevel@tonic-gate 805648Ssetje #if defined(_OBP) 815648Ssetje /* skip bootblk args */ 826659Staylor params.gos_opts = "abcdDF:gGHhi:km:o:O:rsvVwxZ:"; 835648Ssetje #else 840Sstevel@tonic-gate params.gos_opts = "abcdgGhi:km:O:rsvwx"; 855648Ssetje #endif 860Sstevel@tonic-gate params.gos_strp = cp; 870Sstevel@tonic-gate getoptstr_init(¶ms); 880Sstevel@tonic-gate while ((c = getoptstr(¶ms)) != -1) { 892267Sdp 900Sstevel@tonic-gate switch (c) { 910Sstevel@tonic-gate case 'a': 920Sstevel@tonic-gate boothowto |= RB_ASKNAME; 930Sstevel@tonic-gate break; 940Sstevel@tonic-gate case 'b': 950Sstevel@tonic-gate boothowto |= RB_NOBOOTRC; 960Sstevel@tonic-gate break; 970Sstevel@tonic-gate case 'c': 980Sstevel@tonic-gate boothowto |= RB_CONFIG; 990Sstevel@tonic-gate break; 1000Sstevel@tonic-gate case 'd': 1010Sstevel@tonic-gate boothowto |= RB_DEBUGENTER; 1020Sstevel@tonic-gate break; 1035648Ssetje #if defined(_OBP) 1045648Ssetje case 'D': 1055648Ssetje case 'F': 1065648Ssetje break; 1075648Ssetje #endif 1080Sstevel@tonic-gate case 'g': 1090Sstevel@tonic-gate boothowto |= RB_FORTHDEBUG; 1100Sstevel@tonic-gate break; 1110Sstevel@tonic-gate case 'G': 1120Sstevel@tonic-gate boothowto |= RB_FORTHDEBUGDBP; 1130Sstevel@tonic-gate break; 1140Sstevel@tonic-gate case 'h': 1150Sstevel@tonic-gate boothowto |= RB_HALT; 1160Sstevel@tonic-gate break; 1175648Ssetje #if defined(_OBP) 1185648Ssetje case 'H': 1195648Ssetje break; 1205648Ssetje #endif 1210Sstevel@tonic-gate case 'i': 1220Sstevel@tonic-gate if (params.gos_optarglen + 1 > sizeof (initname)) { 1230Sstevel@tonic-gate _kobj_printf(ops, "krtld: initname too long. " 1240Sstevel@tonic-gate "Ignoring.\n"); 1250Sstevel@tonic-gate } else { 1260Sstevel@tonic-gate (void) strncpy(initname, params.gos_optargp, 1270Sstevel@tonic-gate params.gos_optarglen); 1280Sstevel@tonic-gate initname[params.gos_optarglen] = '\0'; 1290Sstevel@tonic-gate } 1300Sstevel@tonic-gate break; 1310Sstevel@tonic-gate case 'k': 1320Sstevel@tonic-gate boothowto |= RB_KMDB; 1330Sstevel@tonic-gate break; 1340Sstevel@tonic-gate case 'm': 1352267Sdp if (strlen(initargs) + 3 + params.gos_optarglen + 1 > 1362267Sdp sizeof (initargs)) { 1372267Sdp _kobj_printf(ops, 1382267Sdp "unix: init options too long. " 1392267Sdp "Ignoring -m.\n"); 1402267Sdp break; 1410Sstevel@tonic-gate } 1422267Sdp /* gos_optargp is not null terminated */ 1432267Sdp (void) strncpy(scratch, params.gos_optargp, 1442267Sdp params.gos_optarglen); 1452267Sdp scratch[params.gos_optarglen] = '\0'; 1462267Sdp (void) strlcat(initargs, "-m ", sizeof (initargs)); 1475648Ssetje (void) strlcat(initargs, scratch, 1485648Ssetje sizeof (initargs)); 1492267Sdp (void) strlcat(initargs, " ", sizeof (initargs)); 1500Sstevel@tonic-gate break; 1515648Ssetje #if defined(_OBP) 1525648Ssetje /* Ignore argument meant for wanboot standalone */ 1535648Ssetje case 'o': 1545648Ssetje break; 1555648Ssetje #endif 1560Sstevel@tonic-gate case 'O': { 1570Sstevel@tonic-gate char **str = &kobj_kmdb_argv[num_O_opt]; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate if (++num_O_opt > (sizeof (kobj_kmdb_argv) / 1600Sstevel@tonic-gate sizeof (char *)) - 1) { 1610Sstevel@tonic-gate _kobj_printf(ops, "krtld: too many kmdb " 1620Sstevel@tonic-gate "options - ignoring option #%d.\n", 1630Sstevel@tonic-gate num_O_opt); 1640Sstevel@tonic-gate continue; 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate *str = kobj_alloc(params.gos_optarglen + 1, KM_TMP); 1680Sstevel@tonic-gate (void) strncpy(*str, params.gos_optargp, 1690Sstevel@tonic-gate params.gos_optarglen); 1700Sstevel@tonic-gate (*str)[params.gos_optarglen] = '\0'; 1710Sstevel@tonic-gate break; 1720Sstevel@tonic-gate } 1730Sstevel@tonic-gate case 'r': 1742267Sdp if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 1752267Sdp _kobj_printf(ops, "unix: init options too " 1762267Sdp "long. Ignoring -r.\n"); 1772267Sdp break; 1782267Sdp } 1790Sstevel@tonic-gate boothowto |= RB_RECONFIG; 1802267Sdp (void) strlcat(initargs, "-r ", sizeof (initargs)); 1810Sstevel@tonic-gate break; 1820Sstevel@tonic-gate case 's': 1832267Sdp if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 1842267Sdp _kobj_printf(ops, "unix: init options too " 1852267Sdp "long. Ignoring -s.\n"); 1862267Sdp break; 1872267Sdp } 1880Sstevel@tonic-gate boothowto |= RB_SINGLE; 1892267Sdp (void) strlcat(initargs, "-s ", sizeof (initargs)); 1900Sstevel@tonic-gate break; 1910Sstevel@tonic-gate case 'v': 1922267Sdp if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { 1932267Sdp _kobj_printf(ops, "unix: init options too " 1942267Sdp "long. Ignoring -v.\n"); 1952267Sdp break; 1962267Sdp } 1970Sstevel@tonic-gate boothowto |= RB_VERBOSE; 1982267Sdp (void) strlcat(initargs, "-v ", sizeof (initargs)); 1990Sstevel@tonic-gate break; 2005648Ssetje #if defined(_OBP) 2015648Ssetje case 'V': 2025648Ssetje break; 2036659Staylor case 'Z': 2046659Staylor break; 2055648Ssetje #endif 2060Sstevel@tonic-gate case 'w': 2070Sstevel@tonic-gate boothowto |= RB_WRITABLE; 2080Sstevel@tonic-gate break; 2090Sstevel@tonic-gate case 'x': 2100Sstevel@tonic-gate boothowto |= RB_NOBOOTCLUSTER; 2110Sstevel@tonic-gate break; 2120Sstevel@tonic-gate case '?': 2130Sstevel@tonic-gate switch (params.gos_last_opt) { 2140Sstevel@tonic-gate case 'i': 2150Sstevel@tonic-gate _kobj_printf(ops, "krtld: Required argument " 2160Sstevel@tonic-gate "for -i flag missing. Ignoring.\n"); 2170Sstevel@tonic-gate break; 2180Sstevel@tonic-gate default: 2190Sstevel@tonic-gate _kobj_printf(ops, "krtld: Ignoring invalid " 2200Sstevel@tonic-gate "kernel option -%c.\n", 2210Sstevel@tonic-gate params.gos_last_opt); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate break; 2240Sstevel@tonic-gate default: 2250Sstevel@tonic-gate _kobj_printf(ops, "krtld: Ignoring unimplemented " 2260Sstevel@tonic-gate "option -%c.\n", c); 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate if ((boothowto & (RB_DEBUGENTER | RB_KMDB)) == RB_DEBUGENTER) { 2310Sstevel@tonic-gate _kobj_printf(ops, "krtld: -d is not valid without -k.\n"); 2320Sstevel@tonic-gate boothowto &= ~RB_DEBUGENTER; 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if (*params.gos_strp) { 2360Sstevel@tonic-gate /* Unused arguments. */ 2370Sstevel@tonic-gate if (params.gos_strp[0] == '-' && ISSPACE(params.gos_strp[1])) { 2380Sstevel@tonic-gate /*EMPTY*/ 2390Sstevel@tonic-gate /* Lousy install arguments. Silently ignore. */ 2400Sstevel@tonic-gate } else { 2410Sstevel@tonic-gate _kobj_printf(ops, "krtld: Unused kernel arguments: " 2420Sstevel@tonic-gate "`%s'.\n", params.gos_strp); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate } 246