summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2020-01-20 07:39:38 -0800
committerJohn Levon <john.levon@joyent.com>2020-01-28 06:14:07 -0800
commit2e6e9b6b9da4e0f480e434e015ff8e9b82300ed1 (patch)
tree8f350528ab0c442d6559f31cda9a667fbb487483
parent881f4659ab3a3d7bac3274ca7320c076fcd007de (diff)
downloadillumos-joyent-2e6e9b6b9da4e0f480e434e015ff8e9b82300ed1.tar.gz
12220 loader multi-console shouldn't override bootenv.rc
Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/uts/common/krtld/kobj.c4
-rw-r--r--usr/src/uts/i86pc/boot/boot_console.c273
-rw-r--r--usr/src/uts/i86pc/os/fakebop.c29
-rw-r--r--usr/src/uts/i86pc/sys/boot_console.h3
-rw-r--r--usr/src/uts/intel/sys/bootconf.h4
5 files changed, 154 insertions, 159 deletions
diff --git a/usr/src/uts/common/krtld/kobj.c b/usr/src/uts/common/krtld/kobj.c
index b7fee8b36b..3ed867f0bf 100644
--- a/usr/src/uts/common/krtld/kobj.c
+++ b/usr/src/uts/common/krtld/kobj.c
@@ -25,7 +25,7 @@
/*
* Copyright 2011 Bayard G. Bell <buffer.g.overflow@gmail.com>.
* All rights reserved. Use is subject to license terms.
- * Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
*/
/*
@@ -423,7 +423,7 @@ kobj_init(
* Now that the ramdisk is mounted, finish boot property
* initialization.
*/
- boot_prop_finish();
+ read_bootenvrc();
}
#if !defined(_UNIX_KRTLD)
diff --git a/usr/src/uts/i86pc/boot/boot_console.c b/usr/src/uts/i86pc/boot/boot_console.c
index be4fe7f5dc..f23baf2f8b 100644
--- a/usr/src/uts/i86pc/boot/boot_console.c
+++ b/usr/src/uts/i86pc/boot/boot_console.c
@@ -20,11 +20,17 @@
*/
/*
* Copyright (c) 2012 Gary Mills
+ * Copyright 2020 Joyent, Inc.
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Boot console support. Most of the file is shared between dboot, and the
+ * early kernel / fakebop.
+ */
+
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/archsystm.h>
@@ -101,9 +107,10 @@ static int serial_getchar(void);
static void serial_putchar(int);
static void serial_adjust_prop(void);
+static void defcons_putchar(int);
+
#if !defined(_BOOT)
-/* Set if the console or mode are expressed in the boot line */
-static int console_set, console_mode_set;
+static boolean_t bootprop_set_tty_mode;
#endif
#if defined(__xpv)
@@ -410,12 +417,12 @@ serial_adjust_prop(void)
(void) strcpy(propname, "ttyX-mode");
propname[3] = 'a' + tty_num;
propval = get_mode_value(propname);
- if (propval == NULL)
- propval = "9600,8,n,1,-";
#if !defined(_BOOT)
- else
- console_mode_set = 1;
+ if (propval != NULL)
+ bootprop_set_tty_mode = B_TRUE;
#endif
+ if (propval == NULL)
+ propval = "9600,8,n,1,-";
/* property is of the form: "9600,8,n,1,-" */
p = propval;
@@ -680,15 +687,14 @@ bcons_init_fb(void)
}
/*
- * Go through the console_devices array trying to match the string
- * we were given. The string on the command line must end with
- * a comma or white space.
+ * Go through the known console device names trying to match the string we were
+ * given. The string on the command line must end with a comma or white space.
*
- * This function does set tty_num as an side effect, this does imply that
- * only one of the main console and the diag-device can be using serial.
+ * For convenience, we provide the caller with an integer index for the CONS_TTY
+ * case.
*/
static int
-lookup_console_devices(const char *cons_str)
+lookup_console_device(const char *cons_str, int *indexp)
{
int n, cons;
size_t len, cons_len;
@@ -707,7 +713,7 @@ lookup_console_devices(const char *cons_str)
(strncmp(cons_str, consolep->name, len) == 0)) {
cons = consolep->value;
if (cons == CONS_TTY)
- tty_num = n;
+ *indexp = n;
break;
}
}
@@ -748,7 +754,7 @@ bcons_init(struct xboot_info *xbi)
*/
cons_str = find_boot_prop("diag-device");
if (cons_str != NULL)
- diag = lookup_console_devices(cons_str);
+ diag = lookup_console_device(cons_str, &tty_num);
cons_str = find_boot_prop("console");
if (cons_str == NULL)
@@ -760,7 +766,7 @@ bcons_init(struct xboot_info *xbi)
#endif
if (cons_str != NULL)
- console = lookup_console_devices(cons_str);
+ console = lookup_console_device(cons_str, &tty_num);
#if defined(__xpv)
/*
@@ -773,16 +779,8 @@ bcons_init(struct xboot_info *xbi)
}
#endif /* __xpv */
- /*
- * If no console device specified, default to text.
- * Remember what was specified for second phase.
- */
if (console == CONS_INVALID)
console = CONS_SCREEN_TEXT;
-#if !defined(_BOOT)
- else
- console_set = 1;
-#endif
#if defined(__xpv)
if (DOMAIN_IS_INITDOMAIN(xen_info)) {
@@ -867,130 +865,6 @@ bcons_init(struct xboot_info *xbi)
}
}
-#if !defined(_BOOT)
-/*
- * 2nd part of console initialization.
- * In the kernel (ie. fakebop), this can be used only to switch to
- * using a serial port instead of screen based on the contents
- * of the bootenv.rc file.
- */
-/*ARGSUSED*/
-void
-bcons_init2(char *inputdev, char *outputdev, char *consoledev)
-{
- int cons = CONS_INVALID;
- int ttyn;
- char *devnames[] = { consoledev, outputdev, inputdev, NULL };
- console_value_t *consolep;
- int i;
- extern int post_fastreboot;
-
- if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
- console = CONS_SCREEN_TEXT;
-
- if (console != CONS_USBSER && console != CONS_SCREEN_GRAPHICS) {
- if (console_set) {
- /*
- * If the console was set on the command line,
- * but the ttyX-mode was not, we only need to
- * check bootenv.rc for that setting.
- */
- if ((!console_mode_set) && (console == CONS_TTY))
- serial_init();
- return;
- }
-
- for (i = 0; devnames[i] != NULL; i++) {
- int n;
-
- for (n = 0; console_devices[n].name != NULL; n++) {
- consolep = &console_devices[n];
- if (strcmp(devnames[i], consolep->name) == 0) {
- cons = consolep->value;
- if (cons == CONS_TTY)
- ttyn = n;
- }
- }
- if (cons != CONS_INVALID)
- break;
- }
-
-#if defined(__xpv)
- /*
- * if the hypervisor is using the currently selected console
- * device then default to using the hypervisor as the console
- * device.
- */
- if (cons == console_hypervisor_device) {
- cons = CONS_HYPERVISOR;
- console_hypervisor_redirect = B_TRUE;
- }
-#endif /* __xpv */
-
- if ((cons == CONS_INVALID) || (cons == console)) {
- /*
- * we're sticking with whatever the current setting is
- */
- return;
- }
-
- console = cons;
- if (cons == CONS_TTY) {
- tty_num = ttyn;
- serial_init();
- return;
- }
- } else {
- /*
- * USB serial and GRAPHICS console
- * we just collect data into a buffer
- */
- extern void *defcons_init(size_t);
- defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
- }
-}
-
-#if defined(__xpv)
-boolean_t
-bcons_hypervisor_redirect(void)
-{
- return (console_hypervisor_redirect);
-}
-
-void
-bcons_device_change(int new_console)
-{
- if (new_console < CONS_MIN || new_console > CONS_MAX)
- return;
-
- /*
- * If we are asked to switch the console to the hypervisor, that
- * really means to switch the console to whichever device the
- * hypervisor is/was using.
- */
- if (new_console == CONS_HYPERVISOR)
- new_console = console_hypervisor_device;
-
- console = new_console;
-
- if (new_console == CONS_TTY) {
- tty_num = console_hypervisor_tty_num;
- serial_init();
- }
-}
-#endif /* __xpv */
-
-static void
-defcons_putchar(int c)
-{
- if (defcons_buf != NULL &&
- defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
- *defcons_cur++ = c;
- *defcons_cur = 0;
- }
-}
-#endif /* _BOOT */
-
static void
serial_putchar(int c)
{
@@ -1273,6 +1147,9 @@ bcons_getchar(void)
}
}
+/*
+ * Nothing below is used by dboot.
+ */
#if !defined(_BOOT)
int
@@ -1315,4 +1192,106 @@ bcons_ischar(void)
return (c);
}
+/*
+ * 2nd part of console initialization: we've now processed bootenv.rc; update
+ * console settings as appropriate. This only really processes serial console
+ * modifications.
+ */
+void
+bcons_post_bootenvrc(char *inputdev, char *outputdev, char *consoledev)
+{
+ int cons = CONS_INVALID;
+ int ttyn;
+ char *devnames[] = { consoledev, outputdev, inputdev, NULL };
+ console_value_t *consolep;
+ int i;
+ extern int post_fastreboot;
+
+ if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
+ console = CONS_SCREEN_TEXT;
+
+ /*
+ * USB serial and GRAPHICS console: we just collect data into a buffer.
+ */
+ if (console == CONS_USBSER || console == CONS_SCREEN_GRAPHICS) {
+ extern void *defcons_init(size_t);
+ defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
+ return;
+ }
+
+ for (i = 0; devnames[i] != NULL; i++) {
+ cons = lookup_console_device(devnames[i], &ttyn);
+ if (cons != CONS_INVALID)
+ break;
+ }
+
+ if (cons == CONS_INVALID) {
+ /*
+ * No console change, but let's see if bootenv.rc had a mode
+ * setting we should apply.
+ */
+ if (console == CONS_TTY && !bootprop_set_tty_mode)
+ serial_init();
+ return;
+ }
+
+#if defined(__xpv)
+ /*
+ * if the hypervisor is using the currently selected console device then
+ * default to using the hypervisor as the console device.
+ */
+ if (cons == console_hypervisor_device) {
+ cons = CONS_HYPERVISOR;
+ console_hypervisor_redirect = B_TRUE;
+ }
+#endif /* __xpv */
+
+ console = cons;
+
+ if (console == CONS_TTY) {
+ tty_num = ttyn;
+ serial_init();
+ }
+}
+
+#if defined(__xpv)
+boolean_t
+bcons_hypervisor_redirect(void)
+{
+ return (console_hypervisor_redirect);
+}
+
+void
+bcons_device_change(int new_console)
+{
+ if (new_console < CONS_MIN || new_console > CONS_MAX)
+ return;
+
+ /*
+ * If we are asked to switch the console to the hypervisor, that
+ * really means to switch the console to whichever device the
+ * hypervisor is/was using.
+ */
+ if (new_console == CONS_HYPERVISOR)
+ new_console = console_hypervisor_device;
+
+ console = new_console;
+
+ if (new_console == CONS_TTY) {
+ tty_num = console_hypervisor_tty_num;
+ serial_init();
+ }
+}
+#endif /* __xpv */
+
+static void
+defcons_putchar(int c)
+{
+ if (defcons_buf != NULL &&
+ defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
+ *defcons_cur++ = c;
+ *defcons_cur = 0;
+ }
+}
+
#endif /* _BOOT */
diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c
index 02fbeb1814..f2c25c1402 100644
--- a/usr/src/uts/i86pc/os/fakebop.c
+++ b/usr/src/uts/i86pc/os/fakebop.c
@@ -101,7 +101,7 @@ struct bsys_mem bm;
/*
* Boot info from "glue" code in low memory. xbootp is used by:
- * do_bop_phys_alloc(), do_bsys_alloc() and boot_prop_finish().
+ * do_bop_phys_alloc(), do_bsys_alloc() and read_bootenvrc().
*/
static struct xboot_info *xbootp;
static uintptr_t next_virt; /* next available virtual address */
@@ -670,7 +670,7 @@ boot_prop_display(char *buffer)
* we do single character I/O since this is really just looking at memory
*/
void
-boot_prop_finish(void)
+read_bootenvrc(void)
{
int fd;
char *line;
@@ -778,17 +778,32 @@ boot_prop_finish(void)
/*
* If a property was explicitly set on the command line
- * it will override a setting in bootenv.rc
+ * it will override a setting in bootenv.rc. We make an
+ * exception for a property from the bootloader such as:
+ *
+ * console="text,ttya,ttyb,ttyc,ttyd"
+ *
+ * In such a case, picking the first value here (as
+ * lookup_console_devices() does) is at best a guess; if
+ * bootenv.rc has a value, it's probably better.
*/
- if (do_bsys_getproplen(NULL, name) >= 0)
+ if (strcmp(name, "console") == 0) {
+ char propval[BP_MAX_STRLEN] = "";
+
+ if (do_bsys_getprop(NULL, name, propval) == -1 ||
+ strchr(propval, ',') != NULL)
+ bsetprops(name, value);
continue;
+ }
- bsetprops(name, value);
+ if (do_bsys_getproplen(NULL, name) == -1)
+ bsetprops(name, value);
}
done:
if (fd >= 0)
(void) BRD_CLOSE(bfs_ops, fd);
+
/*
* Check if we have to limit the boot time allocator
*/
@@ -843,7 +858,7 @@ done:
v_len = 0;
}
consoledev[v_len] = 0;
- bcons_init2(inputdev, outputdev, consoledev);
+ bcons_post_bootenvrc(inputdev, outputdev, consoledev);
} else {
/*
* Ensure console property exists
@@ -853,7 +868,7 @@ done:
if (v_len < 0)
bsetprops("console", "hypervisor");
inputdev = outputdev = consoledev = "hypervisor";
- bcons_init2(inputdev, outputdev, consoledev);
+ bcons_post_bootenvrc(inputdev, outputdev, consoledev);
}
if (find_boot_prop("prom_debug") || kbm_debug)
diff --git a/usr/src/uts/i86pc/sys/boot_console.h b/usr/src/uts/i86pc/sys/boot_console.h
index 4b6a6ba251..49c9e76344 100644
--- a/usr/src/uts/i86pc/sys/boot_console.h
+++ b/usr/src/uts/i86pc/sys/boot_console.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2012 Gary Mills
+ * Copyright 2020 Joyent, Inc.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -68,7 +69,7 @@ extern int bcons_ischar(void);
extern int bcons_gets(char *, int);
#if !defined(_BOOT)
-extern void bcons_init2(char *, char *, char *);
+extern void bcons_post_bootenvrc(char *, char *, char *);
extern boolean_t bcons_hypervisor_redirect(void);
extern void bcons_device_change(int);
#endif /* !_BOOT */
diff --git a/usr/src/uts/intel/sys/bootconf.h b/usr/src/uts/intel/sys/bootconf.h
index f0ade9d94d..311fd40e6f 100644
--- a/usr/src/uts/intel/sys/bootconf.h
+++ b/usr/src/uts/intel/sys/bootconf.h
@@ -23,7 +23,7 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2016 Nexenta Systems, Inc.
- * Copyright 2019, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
*/
#ifndef _SYS_BOOTCONF_H
@@ -243,7 +243,7 @@ extern void bop_panic(const char *, ...)
__KPRINTFLIKE(1) __NORETURN;
#pragma rarely_called(bop_panic)
-extern void boot_prop_finish(void);
+extern void read_bootenvrc(void);
extern int bootprop_getval(const char *, u_longlong_t *);
extern int bootprop_getstr(const char *, char *, size_t);