diff options
author | John Levon <john.levon@joyent.com> | 2020-01-20 07:39:38 -0800 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2020-01-28 06:14:07 -0800 |
commit | 2e6e9b6b9da4e0f480e434e015ff8e9b82300ed1 (patch) | |
tree | 8f350528ab0c442d6559f31cda9a667fbb487483 | |
parent | 881f4659ab3a3d7bac3274ca7320c076fcd007de (diff) | |
download | illumos-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.c | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/boot/boot_console.c | 273 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/fakebop.c | 29 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/boot_console.h | 3 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/bootconf.h | 4 |
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); |