Index: stand/common/boot.c =================================================================== --- stand/common/boot.c +++ stand/common/boot.c @@ -160,30 +160,6 @@ autoboot(-1, NULL); /* try to boot automatically */ } -int -bootenv_flags() -{ - int i, howto; - char *val; - - for (howto = 0, i = 0; howto_names[i].ev != NULL; i++) { - val = getenv(howto_names[i].ev); - if (val != NULL && strcasecmp(val, "no") != 0) - howto |= howto_names[i].mask; - } - return (howto); -} - -void -bootenv_set(int howto) -{ - int i; - - for (i = 0; howto_names[i].ev != NULL; i++) - if (howto & howto_names[i].mask) - setenv(howto_names[i].ev, "YES", 1); -} - static int autoboot(int timeout, char *prompt) { Index: stand/common/bootstrap.h =================================================================== --- stand/common/bootstrap.h +++ stand/common/bootstrap.h @@ -63,8 +63,6 @@ /* boot.c */ void autoboot_maybe(void); int getrootmount(char *rootdev); -int bootenv_flags(void); -void bootenv_set(int); /* misc.c */ char *unargv(int argc, char *argv[]); Index: stand/common/metadata.c =================================================================== --- stand/common/metadata.c +++ stand/common/metadata.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #if defined(LOADER_FDT_SUPPORT) #include @@ -96,62 +97,11 @@ static int md_getboothowto(char *kargs) { - char *cp; int howto; - int active; /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - - howto |= bootenv_flags(); + howto = boot_parse_cmdline(kargs); + howto |= boot_env_to_howto(); #if defined(__sparc64__) if (md_bootserial() != -1) howto |= RB_SERIAL; Index: stand/efi/loader/bootinfo.c =================================================================== --- stand/efi/loader/bootinfo.c +++ stand/efi/loader/bootinfo.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -59,12 +60,6 @@ extern EFI_SYSTEM_TABLE *ST; -static const char howto_switches[] = "aCdrgDmphsv"; -static int howto_masks[] = { - RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, - RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE -}; - static int bi_getboothowto(char *kargs) { @@ -73,7 +68,8 @@ char *console; int howto; - howto = bootenv_flags(); + howto = boot_parse_cmdline(kargs); + howto |= boot_env_to_howto(); console = getenv("console"); if (console != NULL) { @@ -83,21 +79,6 @@ howto |= RB_MUTE; } - /* Parse kargs */ - if (kargs == NULL) - return (howto); - - opts = strchr(kargs, '-'); - while (opts != NULL) { - while (*(++opts) != '\0') { - sw = strchr(howto_switches, *opts); - if (sw == NULL) - break; - howto |= howto_masks[sw - howto_switches]; - } - opts = strchr(opts, '-'); - } - return (howto); } Index: stand/efi/loader/main.c =================================================================== --- stand/efi/loader/main.c +++ stand/efi/loader/main.c @@ -28,11 +28,13 @@ #include __FBSDID("$FreeBSD$"); +#include + #include #include #include +#include #include -#include #include #include #include @@ -550,7 +552,7 @@ howto = parse_args(argc, argv, has_kbd); - bootenv_set(howto); + boot_howto_to_env(howto); /* * XXX we need fallback to this stuff after looking at the ConIn, ConOut and ConErr variables Index: stand/i386/libi386/bootinfo.c =================================================================== --- stand/i386/libi386/bootinfo.c +++ stand/i386/libi386/bootinfo.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "bootstrap.h" #include "libi386.h" @@ -38,63 +39,12 @@ int bi_getboothowto(char *kargs) { - char *cp; char *curpos, *next, *string; int howto; - int active; int vidconsole; - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - howto |= bootenv_flags(); + howto = boot_parse_cmdline(kargs); + howto |= boot_env_to_howto(); /* Enable selected consoles */ string = next = strdup(getenv("console")); @@ -130,7 +80,7 @@ bi_setboothowto(int howto) { - bootenv_set(howto); + boot_howto_to_env(howto); } /* Index: stand/libsa/Makefile =================================================================== --- stand/libsa/Makefile +++ stand/libsa/Makefile @@ -37,6 +37,10 @@ .PATH: ${LIBC_SRC}/stdlib SRCS+= abs.c strtol.c strtoll.c strtoul.c strtoull.c +# common boot code +.PATH: ${SYSDIR}/kern +SRCS+= subr_boot.c + .if ${MACHINE_CPUARCH} == "arm" .PATH: ${LIBC_SRC}/arm/gen Index: stand/userboot/userboot/bootinfo.c =================================================================== --- stand/userboot/userboot/bootinfo.c +++ stand/userboot/userboot/bootinfo.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "bootstrap.h" @@ -38,64 +39,12 @@ int bi_getboothowto(char *kargs) { - char *cp; char *curpos, *next, *string; int howto; - int active; int vidconsole; - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - - howto |= bootenv_flags(); + howto = boot_parse_cmdline(kargs); + howto |= boot_env_to_howto(); /* Enable selected consoles */ string = next = strdup(getenv("console")); @@ -117,7 +66,8 @@ /* * XXX: Note that until the kernel is ready to respect multiple consoles - * for the boot messages, the first named console is the primary console + * for the messages from /etc/rc, the first named console is the primary + * console */ if (!strcmp(string, "vidconsole")) howto &= ~RB_SERIAL; @@ -131,7 +81,7 @@ bi_setboothowto(int howto) { - bootenv_set(howto); + boot_howto_to_env(howto); } /* Index: sys/arm/arm/machdep_boot.c =================================================================== --- sys/arm/arm/machdep_boot.c +++ sys/arm/arm/machdep_boot.c @@ -68,6 +68,8 @@ #define debugf(fmt, args...) #endif +static char static_kenv[4096]; + extern int *end; static uint32_t board_revision; @@ -146,9 +148,8 @@ static void cmdline_set_env(char *cmdline, const char *guard) { - char *cmdline_next, *env; + char *cmdline_next; size_t size, guard_len; - int i; size = strlen(cmdline); /* Skip leading spaces. */ @@ -164,37 +165,27 @@ size -= guard_len; } - /* Skip leading spaces. */ - for (; isspace(*cmdline) && (size > 0); cmdline++) - size--; - - /* Replace ',' with '\0'. */ - /* TODO: implement escaping for ',' character. */ - cmdline_next = cmdline; - while(strsep(&cmdline_next, ",") != NULL) - ; - init_static_kenv(cmdline, 0); - /* Parse boothowto. */ - for (i = 0; howto_names[i].ev != NULL; i++) { - env = kern_getenv(howto_names[i].ev); - if (env != NULL) { - if (strtoul(env, NULL, 10) != 0) - boothowto |= howto_names[i].mask; - freeenv(env); - } - } + boothowto |= boot_parse_cmdline(); } +/* + * Called for armv6 and newer. + */ void arm_parse_fdt_bootargs(void) { #ifdef FDT if (loader_envp == NULL && fdt_get_chosen_bootargs(linux_command_line, - LBABI_MAX_COMMAND_LINE) == 0) + LBABI_MAX_COMMAND_LINE) == 0) { + init_static_kenv(static_kenv, sizeof(static_kenv)); cmdline_set_env(linux_command_line, CMDLINE_GUARD); + } #endif } +/* + * Called for armv[45]. + */ static vm_offset_t linux_parse_boot_param(struct arm_boot_params *abp) { @@ -271,6 +262,7 @@ (char *)walker - (char *)atag_list + ATAG_SIZE(walker)); lastaddr = fake_preload_metadata(abp, NULL, 0); + init_static_kenv(static_kenv, sizeof(static_kenv)); cmdline_set_env(linux_command_line, CMDLINE_GUARD); return lastaddr; } Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -3868,6 +3868,7 @@ kern/subr_acl_posix1e.c optional ufs_acl kern/subr_autoconf.c standard kern/subr_blist.c standard +kern/subr_boot.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard Index: sys/dev/ofw/ofw_subr.c =================================================================== --- sys/dev/ofw/ofw_subr.c +++ sys/dev/ofw/ofw_subr.c @@ -184,44 +184,6 @@ return (0); } -/* Parse cmd line args as env - copied from xlp_machdep. */ -/* XXX-BZ this should really be centrally provided for all (boot) code. */ -static void -_parse_bootargs(char *cmdline) -{ - char *n, *v; - - while ((v = strsep(&cmdline, " \n")) != NULL) { - if (*v == '\0') - continue; - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - /* Someone should simulate that ;-) */ - case 'C': boothowto |= RB_CDROM; break; - case 'd': boothowto |= RB_KDB; break; - case 'D': boothowto |= RB_MULTIPLE; break; - case 'm': boothowto |= RB_MUTE; break; - case 'g': boothowto |= RB_GDB; break; - case 'h': boothowto |= RB_SERIAL; break; - case 'p': boothowto |= RB_PAUSE; break; - case 'r': boothowto |= RB_DFLTROOT; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } - } -} - /* * This is intended to be called early on, right after the OF system is * initialized, so pmap may not be up yet. @@ -238,7 +200,7 @@ return (chosen); if ((err = OF_getprop(chosen, "bootargs", buf, sizeof(buf))) != -1) { - _parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); return (0); } Index: sys/kern/subr_boot.c =================================================================== --- /dev/null +++ sys/kern/subr_boot.c @@ -0,0 +1,223 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 1998 Michael Smith + * All Rights Reserved. + * Copyright (c) 1998 Robert Nordier + * All Rights Reserved. + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * Copyright (c) 2014 Roger Pau Monné + * All Rights Reserved. + * Copyright (c) 2018 Kyle Evans + * Copyright (c) 2018 Netflix + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* Note: This is compiled in both the kernel and boot loader contexts */ + +#include +#ifdef _KERNEL +#include +#else +#include +#endif +#include +#include + +#ifdef _KERNEL +#define SETENV(k, v) kern_setenv(k, v) +#define GETENV(k) kern_getenv(k) +#define FREE(v) freeenv(v) +#else /* Boot loader */ +#define SETENV(k, v) setenv(k, v, 1) +#define GETENV(k) getenv(k) +#define FREE(v) +#endif + +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + { "boot_askname", RB_ASKNAME}, + { "boot_cdrom", RB_CDROM}, + { "boot_ddb", RB_KDB}, + { "boot_dfltroot", RB_DFLTROOT}, + { "boot_gdb", RB_GDB}, + { "boot_multicons", RB_MULTIPLE}, + { "boot_mute", RB_MUTE}, + { "boot_pause", RB_PAUSE}, + { "boot_serial", RB_SERIAL}, + { "boot_single", RB_SINGLE}, + { "boot_verbose", RB_VERBOSE}, + { NULL, 0} +}; + +/* + * In the boot environment, we often parse a command line and have to throw away + * its contents. As we do so, we set environment variables that correspond to + * the flags we encounter. Later, to get a howto mask, we grovel through these + * to reconstruct it. This also allows users in their loader.conf to set them + * and have the kernel see them. + */ + +/** + * @brief convert the env vars in howto_names into a howto mask + */ +int +boot_env_to_howto(void) +{ + int i, howto; + char *val; + + for (howto = 0, i = 0; howto_names[i].ev != NULL; i++) { + val = GETENV(howto_names[i].ev); + if (val != NULL && strcasecmp(val, "no") != 0) + howto |= howto_names[i].mask; + FREE(val); + } + return (howto); +} + +/** + * @brief Set env vars from howto_names based on howto passed in + */ +void +boot_howto_to_env(int howto) +{ + int i; + + for (i = 0; howto_names[i].ev != NULL; i++) + if (howto & howto_names[i].mask) + SETENV(howto_names[i].ev, "YES"); +} + +/** + * @brief Helper routine to parse a single arg and return its mask + * + * Parse all the - options to create a mask (or a serial speed in the + * case of -S). If the arg doesn't start with '-' assume it's an env + * variable and set that instead. + */ +int +boot_parse_arg(char *v) +{ + char *n; + int howto; + +#if 0 +/* Need to see if this is better or worse than the meat of the #else */ +static const char howto_switches[] = "aCdrgDmphsv"; +static int howto_masks[] = { + RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, + RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE +}; + + opts = strchr(kargs, '-'); + while (opts != NULL) { + while (*(++opts) != '\0') { + sw = strchr(howto_switches, *opts); + if (sw == NULL) + break; + howto |= howto_masks[sw - howto_switches]; + } + opts = strchr(opts, '-'); + } +#else + howto = 0; + if (*v == '-') { + while (*v != '\0') { + v++; + switch (*v) { + case 'a': howto |= RB_ASKNAME; break; + case 'C': howto |= RB_CDROM; break; + case 'd': howto |= RB_KDB; break; + case 'D': howto |= RB_MULTIPLE; break; + case 'm': howto |= RB_MUTE; break; + case 'g': howto |= RB_GDB; break; + case 'h': howto |= RB_SERIAL; break; + case 'p': howto |= RB_PAUSE; break; + case 'P': howto |= RB_PROBE; break; + case 'r': howto |= RB_DFLTROOT; break; + case 's': howto |= RB_SINGLE; break; + case 'S': SETENV("comconsole_speed", v + 1); v += strlen(v); break; + case 'v': howto |= RB_VERBOSE; break; + } + } + } else { + n = strsep(&v, "="); + if (v == NULL) + SETENV(n, "1"); + else + SETENV(n, v); + } +#endif + return (howto); +} + +/** + * @brief breakup the command line into args, and pass to boot_parse_arg + */ +int +boot_parse_cmdline_delim(char *cmdline, const char *delim) +{ + char *v; + int howto; + + howto = 0; + while ((v = strsep(&cmdline, delim)) != NULL) { + if (*v == '\0') + continue; + howto |= boot_parse_arg(v); + } + return (howto); +} + +/** + * @brief Simplified interface for common 'space separated' args + */ +int +boot_parse_cmdline(char *cmdline) +{ + + return (boot_parse_cmdline_delim(cmdline, " \n")); +} + +/** + * @brief Pass a vector of strings to boot_parse_arg + */ +int +boot_parse_args(int argc, char *argv[]) +{ + int i, howto; + + howto = 0; + for (i = 1; i < argc; i++) + howto |= boot_parse_arg(argv[i]); + return (howto); +} Index: sys/mips/atheros/ar531x/ar5315_machdep.c =================================================================== --- sys/mips/atheros/ar531x/ar5315_machdep.c +++ sys/mips/atheros/ar531x/ar5315_machdep.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -65,39 +66,6 @@ the dynamic kenv is setup */ char boot1_env[4096]; -/* - * We get a string in from Redboot with the all the arguments together, - * "foo=bar bar=baz". Split them up and save in kenv. - */ -static void -parse_argv(char *str) -{ - char *n, *v; - - while ((v = strsep(&str, " ")) != NULL) { - if (*v == '\0') - continue; - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - case 'd': boothowto |= RB_KDB; break; - case 'g': boothowto |= RB_GDB; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } - } -} - void platform_cpu_init() { @@ -299,7 +267,7 @@ if (MIPS_IS_VALID_PTR(argv)) { for (i = 0; i < argc; i++) { printf(" %s", argv[i]); - parse_argv(argv[i]); + boothowto |= boot_parse_arg(argv[i]); } } else Index: sys/mips/atheros/ar71xx_machdep.c =================================================================== --- sys/mips/atheros/ar71xx_machdep.c +++ sys/mips/atheros/ar71xx_machdep.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -66,39 +67,6 @@ the dynamic kenv is setup */ char boot1_env[4096]; -/* - * We get a string in from Redboot with the all the arguments together, - * "foo=bar bar=baz". Split them up and save in kenv. - */ -static void -parse_argv(char *str) -{ - char *n, *v; - - while ((v = strsep(&str, " ")) != NULL) { - if (*v == '\0') - continue; - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - case 'd': boothowto |= RB_KDB; break; - case 'g': boothowto |= RB_GDB; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } - } -} - void platform_cpu_init() { @@ -428,7 +396,7 @@ if (MIPS_IS_VALID_PTR(argv)) { for (i = 0; i < argc; i++) { printf(" %s", argv[i]); - parse_argv(argv[i]); + boothowto |= boot_parse_arg(argv[i]); } } else Index: sys/mips/cavium/octeon_machdep.c =================================================================== --- sys/mips/cavium/octeon_machdep.c +++ sys/mips/cavium/octeon_machdep.c @@ -664,30 +664,6 @@ } /* impEND: This stuff should move back into the Cavium SDK */ -static void -boothowto_parse(const char *v) -{ - if ((v == NULL) || (*v != '-')) - return; - - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - case 'C': boothowto |= RB_CDROM; break; - case 'd': boothowto |= RB_KDB; break; - case 'D': boothowto |= RB_MULTIPLE; break; - case 'm': boothowto |= RB_MUTE; break; - case 'g': boothowto |= RB_GDB; break; - case 'h': boothowto |= RB_SERIAL; break; - case 'p': boothowto |= RB_PAUSE; break; - case 'r': boothowto |= RB_DFLTROOT; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } -} - /* * The boot loader command line may specify kernel environment variables or * applicable boot flags of boot(8). @@ -709,7 +685,7 @@ if (v == NULL) continue; if (*v == '-') { - boothowto_parse(v); + boothowto |= boot_parse_arg(v); continue; } n = strsep(&v, "="); Index: sys/mips/ingenic/jz4780_machdep.c =================================================================== --- sys/mips/ingenic/jz4780_machdep.c +++ sys/mips/ingenic/jz4780_machdep.c @@ -173,50 +173,7 @@ #endif } -static void -_parse_bootarg(char *v) -{ - char *n; - - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - /* Someone should simulate that ;-) */ - case 'C': boothowto |= RB_CDROM; break; - case 'd': boothowto |= RB_KDB; break; - case 'D': boothowto |= RB_MULTIPLE; break; - case 'm': boothowto |= RB_MUTE; break; - case 'g': boothowto |= RB_GDB; break; - case 'h': boothowto |= RB_SERIAL; break; - case 'p': boothowto |= RB_PAUSE; break; - case 'r': boothowto |= RB_DFLTROOT; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } -} - -static void -_parse_cmdline(int argc, char *argv[]) -{ - int i; - - for (i = 1; i < argc; i++) - _parse_bootarg(argv[i]); -} - #ifdef FDT -/* Parse cmd line args as env - copied from xlp_machdep. */ -/* XXX-BZ this should really be centrally provided for all (boot) code. */ static void _parse_bootargs(char *cmdline) { @@ -225,7 +182,7 @@ while ((v = strsep(&cmdline, " \n")) != NULL) { if (*v == '\0') continue; - _parse_bootarg(v); + boothowto |= boot_parse_arg(v); } } #endif @@ -285,12 +242,12 @@ */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) - _parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); #endif /* Parse cmdline from U-Boot */ argc = a0; argv = (char **)a1; - _parse_cmdline(argc, argv); + boothowto |= boot_parse_cmdline(argc, argv); mips_init(); } Index: sys/mips/mediatek/mtk_machdep.c =================================================================== --- sys/mips/mediatek/mtk_machdep.c +++ sys/mips/mediatek/mtk_machdep.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -196,52 +197,6 @@ #endif } -static void -_parse_bootarg(char *v) -{ - char *n; - - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - /* Someone should simulate that ;-) */ - case 'C': boothowto |= RB_CDROM; break; - case 'd': boothowto |= RB_KDB; break; - case 'D': boothowto |= RB_MULTIPLE; break; - case 'm': boothowto |= RB_MUTE; break; - case 'g': boothowto |= RB_GDB; break; - case 'h': boothowto |= RB_SERIAL; break; - case 'p': boothowto |= RB_PAUSE; break; - case 'r': boothowto |= RB_DFLTROOT; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } -} - -/* Parse cmd line args as env - copied from xlp_machdep. */ -/* XXX-BZ this should really be centrally provided for all (boot) code. */ -static void -_parse_bootargs(char *cmdline) -{ - char *v; - - while ((v = strsep(&cmdline, " \n")) != NULL) { - if (*v == '\0') - continue; - _parse_bootarg(v); - } -} - void platform_reset(void) { @@ -295,7 +250,7 @@ */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bsdbootargs", buf, sizeof(buf)) != -1) - _parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); printf("FDT DTB at: 0x%08x\n", (uint32_t)dtbp); Index: sys/mips/nlm/xlp_machdep.c =================================================================== --- sys/mips/nlm/xlp_machdep.c +++ sys/mips/nlm/xlp_machdep.c @@ -49,6 +49,7 @@ #include /* cinit() */ #include +#include #include #include #include @@ -261,36 +262,6 @@ return; } -/* Parse cmd line args as env - copied from ar71xx */ -static void -xlp_parse_bootargs(char *cmdline) -{ - char *n, *v; - - while ((v = strsep(&cmdline, " \n")) != NULL) { - if (*v == '\0') - continue; - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - case 'd': boothowto |= RB_KDB; break; - case 'g': boothowto |= RB_GDB; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } - } -} - #ifdef FDT static void xlp_bootargs_init(__register_t arg) @@ -321,7 +292,7 @@ } if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) - xlp_parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); } #else /* @@ -363,7 +334,7 @@ v = kern_getenv("bootargs"); if (v != NULL) { strlcpy(buf, v, sizeof(buf)); - xlp_parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); freeenv(v); } } Index: sys/sys/boot.h =================================================================== --- sys/sys/boot.h +++ sys/sys/boot.h @@ -1,6 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * + * Copyright (c) 2018 Netflix * Copyright (c) 2014 Roger Pau Monné * All rights reserved. * @@ -31,27 +32,11 @@ #ifndef _SYS_BOOT_H_ #define _SYS_BOOT_H_ -/* - * Return a 'boothowto' value corresponding to the kernel arguments in - * (kargs) and any relevant environment variables. - */ -static struct -{ - const char *ev; - int mask; -} howto_names[] = { - { "boot_askname", RB_ASKNAME}, - { "boot_cdrom", RB_CDROM}, - { "boot_ddb", RB_KDB}, - { "boot_dfltroot", RB_DFLTROOT}, - { "boot_gdb", RB_GDB}, - { "boot_multicons", RB_MULTIPLE}, - { "boot_mute", RB_MUTE}, - { "boot_pause", RB_PAUSE}, - { "boot_serial", RB_SERIAL}, - { "boot_single", RB_SINGLE}, - { "boot_verbose", RB_VERBOSE}, - { NULL, 0} -}; +int boot_env_to_howto(void); +void boot_howto_to_env(int howto); +int boot_parse_arg(char *v); +int boot_parse_cmdline_delim(char *cmdline, const char *delim); +int boot_parse_cmdline(char *cmdline); +int boot_parse_args(int argc, char *argv[]); #endif /* !_SYS_BOOT_H_ */ Index: sys/sys/reboot.h =================================================================== --- sys/sys/reboot.h +++ sys/sys/reboot.h @@ -63,6 +63,7 @@ #define RB_PAUSE 0x100000 /* pause after each output line during probe */ #define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */ #define RB_POWERCYCLE 0x400000 /* Power cycle if possible */ +#define RB_PROBE 0x10000000 /* Probe multiple consoles */ #define RB_MULTIPLE 0x20000000 /* use multiple consoles */ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ Index: sys/x86/xen/pv.c =================================================================== --- sys/x86/xen/pv.c +++ sys/x86/xen/pv.c @@ -305,21 +305,6 @@ init_static_kenv(cmd_line, 0); } -static void -xen_pv_set_boothowto(void) -{ - int i; - char *env; - - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) { - if ((env = kern_getenv(howto_names[i].ev)) != NULL) { - boothowto |= howto_names[i].mask; - freeenv(env); - } - } -} - #ifdef DDB /* * The way Xen loads the symtab is different from the native boot loader, @@ -418,7 +403,7 @@ } else { /* Parse the extra boot information given by Xen */ xen_pv_set_env(); - xen_pv_set_boothowto(); + boothowto |= boot_env_to_howto(); kmdp = NULL; }