Page MenuHomeFreeBSD

D16205.id45247.diff
No OneTemporary

D16205.id45247.diff

Index: head/stand/libsa/Makefile
===================================================================
--- head/stand/libsa/Makefile
+++ head/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: head/sys/arm/arm/machdep_boot.c
===================================================================
--- head/sys/arm/arm/machdep_boot.c
+++ head/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: head/sys/conf/files
===================================================================
--- head/sys/conf/files
+++ head/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: head/sys/kern/subr_boot.c
===================================================================
--- head/sys/kern/subr_boot.c
+++ head/sys/kern/subr_boot.c
@@ -0,0 +1,223 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * All Rights Reserved.
+ * Copyright (c) 1998 Robert Nordier
+ * All Rights Reserved.
+ * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
+ * All rights reserved.
+ * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
+ * All Rights Reserved.
+ * Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* Note: This is compiled in both the kernel and boot loader contexts */
+
+#include <sys/param.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <stand.h>
+#endif
+#include <sys/reboot.h>
+#include <sys/boot.h>
+
+#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: head/sys/sys/boot.h
===================================================================
--- head/sys/sys/boot.h
+++ head/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é <roger.pau@citrix.com>
* 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: head/sys/sys/reboot.h
===================================================================
--- head/sys/sys/reboot.h
+++ head/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: head/sys/x86/xen/pv.c
===================================================================
--- head/sys/x86/xen/pv.c
+++ head/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;
}

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 11, 10:29 PM (7 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28661483
Default Alt Text
D16205.id45247.diff (11 KB)

Event Timeline