From a00a259113386508d26882780ad746fbc558a235 Mon Sep 17 00:00:00 2001 From: Ian Dowse Date: Thu, 18 Aug 2005 00:42:45 +0000 Subject: [PATCH] Add the ability to specify the boot2 serial console speed in /boot.config or on the "boot:" prompt line via a "-S" flag, e.g. "-h -S19200". This adds about 50 bytes to the size of boot2 and required a few other small changes to limit the size impact. This changes only affects boot2; there are further loader changes to follow. --- sbin/reboot/boot_i386.8 | 26 +++++++++++++++++---- sys/boot/i386/boot2/boot2.c | 41 ++++++++++++++++++++++----------- sys/boot/i386/boot2/lib.h | 2 +- sys/boot/i386/boot2/sio.S | 7 +++--- sys/boot/i386/gptboot/gptboot.c | 41 ++++++++++++++++++++++----------- 5 files changed, 81 insertions(+), 36 deletions(-) diff --git a/sbin/reboot/boot_i386.8 b/sbin/reboot/boot_i386.8 index a6d4c3ce867e..5e59eecdb9af 100644 --- a/sbin/reboot/boot_i386.8 +++ b/sbin/reboot/boot_i386.8 @@ -36,7 +36,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 30, 2004 +.Dd August 18, 2005 .Dt BOOT 8 i386 .Os .Sh NAME @@ -126,9 +126,12 @@ the listing will be of the relevant subdirectory.) .It Xo .Sm off .Ar bios_drive : interface ( unit , Oo Ar slice , Oc Ar part ) -.Sm on .Ar filename +.Sm on .Op Fl aCcDdghmnPprsv +.Sm off +.Op Fl S Ar speed +.Sm on .Xc Specify boot file and flags. .Bl -tag -width indent @@ -186,9 +189,13 @@ slice) is booted from. The pathname of the file to boot (relative to the root directory on the specified partition). Defaults to -.Pa /kernel . +.Pa /boot/kernel/kernel . Symbolic links are not supported (hard links are). -.It Fl aCcDdghmnPprsv +.It Xo Op Fl aCcDdghmnPprsv +.Sm off +.Op Fl S Ar speed +.Sm on +.Xc Boot flags: .Pp .Bl -tag -width "-CXX" -compact @@ -263,6 +270,17 @@ boot into single-user mode; if the console is marked as (see .Xr ttys 5 ) , the root password must be entered. +.It Xo Sm off +.Fl S Ar speed +.Sm on +.Xc +set the speed of the serial console to +.Ar speed . +The default is 9600 unless it has been overridden by setting +.Va BOOT_COMCONSOLE_SPEED +in +.Pa /etc/make.conf +and recompiling the boot blocks. .It Fl v be verbose during device probing (and later). .El diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c index d12ae4709080..0a4d0568e3c2 100644 --- a/sys/boot/i386/boot2/boot2.c +++ b/sys/boot/i386/boot2/boot2.c @@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$"); #define RBX_NOINTR 0x1c /* -n */ /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */ #define RBX_DUAL 0x1d /* -D */ -#define RBX_PROBEKBD 0x1e /* -P */ /* 0x1f is reserved for log2(RB_BOOTINFO). */ /* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */ @@ -91,7 +90,7 @@ __FBSDID("$FreeBSD$"); extern uint32_t _end; -static const char optstr[NOPT] = "DhaCgmnPprsv"; +static const char optstr[NOPT] = "DhaCgmnprsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { RBX_DUAL, RBX_SERIAL, @@ -100,7 +99,6 @@ static const unsigned char flags[NOPT] = { RBX_GDB, RBX_MUTE, RBX_NOINTR, - RBX_PROBEKBD, RBX_PAUSE, RBX_DFLTROOT, RBX_SINGLE, @@ -122,6 +120,7 @@ static struct dsk { static char cmd[512]; static char kname[1024]; static uint32_t opts; +static int comspeed = SIOSPD; static struct bootinfo bootinfo; static uint8_t ioctrl = IO_KEYBOARD; @@ -390,34 +389,48 @@ static int parse() { char *arg = cmd; - char *p, *q; + char *ep, *p, *q; + const char *cp; unsigned int drv; - int c, i; + int c, i, j; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') continue; for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; if (*p) *p++ = 0; if (c == '-') { while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* Fall through to error below ('S' not in optstr[]). */ + } for (i = 0; c != optstr[i]; i++) if (i == NOPT - 1) return -1; opts ^= 1 << flags[i]; } - if (opts & 1 << RBX_PROBEKBD) { - i = *(uint8_t *)PTOV(0x496) & 0x10; - printf("Keyboard: %s\n", i ? "yes" : "no"); - if (!i) - opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; - opts &= ~(1 << RBX_PROBEKBD); - } ioctrl = opts & 1 << RBX_DUAL ? (IO_SERIAL|IO_KEYBOARD) : opts & 1 << RBX_SERIAL ? IO_SERIAL : IO_KEYBOARD; if (ioctrl & IO_SERIAL) - sio_init(); + sio_init(115200 / comspeed); } else { for (q = arg--; *q && *q != '('; q++); if (*q) { @@ -459,7 +472,7 @@ parse() ? DRV_HARD : 0) + drv; dsk_meta = 0; } - if ((i = p - arg - !*(p - 1))) { + if ((i = ep - arg)) { if ((size_t)i >= sizeof(kname)) return -1; memcpy(kname, arg, i + 1); diff --git a/sys/boot/i386/boot2/lib.h b/sys/boot/i386/boot2/lib.h index 4bb93cfe9d3e..0459bc20e2f8 100644 --- a/sys/boot/i386/boot2/lib.h +++ b/sys/boot/i386/boot2/lib.h @@ -17,7 +17,7 @@ * $FreeBSD$ */ -void sio_init(void); +void sio_init(int); void sio_flush(void); void sio_putc(int); int sio_getc(void); diff --git a/sys/boot/i386/boot2/sio.S b/sys/boot/i386/boot2/sio.S index 3fc2963997e9..7b8e9eb13b05 100644 --- a/sys/boot/i386/boot2/sio.S +++ b/sys/boot/i386/boot2/sio.S @@ -17,7 +17,6 @@ .set SIO_PRT,SIOPRT # Base port .set SIO_FMT,SIOFMT # 8N1 - .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD .globl sio_init .globl sio_flush @@ -25,14 +24,14 @@ .globl sio_getc .globl sio_ischar -/* void sio_init(void) */ +/* void sio_init(int div) */ sio_init: movw $SIO_PRT+0x3,%dx # Data format reg movb $SIO_FMT|0x80,%al # Set format outb %al,(%dx) # and DLAB pushl %edx # Save subb $0x3,%dl # Divisor latch reg - movw $SIO_DIV,%ax # Set + movl 0x8(%esp),%eax # Set outw %ax,(%dx) # BPS popl %edx # Restore movb $SIO_FMT,%al # Clear @@ -41,6 +40,8 @@ sio_init: movw $SIO_PRT+0x3,%dx # Data format reg movb $0x3,%al # Set RTS, outb %al,(%dx) # DTR incl %edx # Line status reg + call sio_flush + ret $0x4 /* void sio_flush(void) */ diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c index d12ae4709080..0a4d0568e3c2 100644 --- a/sys/boot/i386/gptboot/gptboot.c +++ b/sys/boot/i386/gptboot/gptboot.c @@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$"); #define RBX_NOINTR 0x1c /* -n */ /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */ #define RBX_DUAL 0x1d /* -D */ -#define RBX_PROBEKBD 0x1e /* -P */ /* 0x1f is reserved for log2(RB_BOOTINFO). */ /* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */ @@ -91,7 +90,7 @@ __FBSDID("$FreeBSD$"); extern uint32_t _end; -static const char optstr[NOPT] = "DhaCgmnPprsv"; +static const char optstr[NOPT] = "DhaCgmnprsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { RBX_DUAL, RBX_SERIAL, @@ -100,7 +99,6 @@ static const unsigned char flags[NOPT] = { RBX_GDB, RBX_MUTE, RBX_NOINTR, - RBX_PROBEKBD, RBX_PAUSE, RBX_DFLTROOT, RBX_SINGLE, @@ -122,6 +120,7 @@ static struct dsk { static char cmd[512]; static char kname[1024]; static uint32_t opts; +static int comspeed = SIOSPD; static struct bootinfo bootinfo; static uint8_t ioctrl = IO_KEYBOARD; @@ -390,34 +389,48 @@ static int parse() { char *arg = cmd; - char *p, *q; + char *ep, *p, *q; + const char *cp; unsigned int drv; - int c, i; + int c, i, j; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') continue; for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; if (*p) *p++ = 0; if (c == '-') { while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* Fall through to error below ('S' not in optstr[]). */ + } for (i = 0; c != optstr[i]; i++) if (i == NOPT - 1) return -1; opts ^= 1 << flags[i]; } - if (opts & 1 << RBX_PROBEKBD) { - i = *(uint8_t *)PTOV(0x496) & 0x10; - printf("Keyboard: %s\n", i ? "yes" : "no"); - if (!i) - opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; - opts &= ~(1 << RBX_PROBEKBD); - } ioctrl = opts & 1 << RBX_DUAL ? (IO_SERIAL|IO_KEYBOARD) : opts & 1 << RBX_SERIAL ? IO_SERIAL : IO_KEYBOARD; if (ioctrl & IO_SERIAL) - sio_init(); + sio_init(115200 / comspeed); } else { for (q = arg--; *q && *q != '('; q++); if (*q) { @@ -459,7 +472,7 @@ parse() ? DRV_HARD : 0) + drv; dsk_meta = 0; } - if ((i = p - arg - !*(p - 1))) { + if ((i = ep - arg)) { if ((size_t)i >= sizeof(kname)) return -1; memcpy(kname, arg, i + 1);