- Added support for "dual" internal/serial consoles (-D flag). If -D is set,

then all i/o from the boot blocks is to and from both the internal console
  and the serial console.  -D has no effect on the kernel (-h decides the
  kernel serial console as usual).  -D should normally be set in /boot.config.
- Get help messages from /boot.help.  You should copy boot.help from the
  biosboot directory to the root directory on the boot drive when you
  install new boot blocks.
- New, less invasive keyboard probe.  Enable keyboard probe dynamically (-P
  flag).  Should probably never be used (use -h instead).
- Fixed/improved initialization from boot.config.  It didn't interact correctly
  with the NAMEBLOCK option, and the initialization of the drive/unit/partition
  didn't stick when a non-default kernel name was entered.
- Don't reset or forget the default drive/unit/... or kernel name so often.
- Set the default kernel name to something unbootable after `?'.
- Display the defaults better.
- Removed PROBE_KEYBOARD_LOCK option (use -h instead).,
- Removed BOOT_FORCE_COMCONSOLE option (use device flag 0x20 instead).
- Removed -a (RB_HALT) flag.  This flag is only used for reboots.
Submitted by:	about 2/3 by yokota
This commit is contained in:
Bruce Evans 1997-06-09 05:10:56 +00:00
parent fb2539e946
commit de2cf96615
8 changed files with 287 additions and 249 deletions

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.55 1997/03/05 15:43:03 bde Exp $
# $Id: Makefile,v 1.56 1997/04/25 19:37:58 bde Exp $
#
PROG= boot
@ -15,21 +15,6 @@ CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
CFLAGS+= -I${.CURDIR}/../../..
CFLAGS+= ${CWARNFLAGS}
# Probe the keyboard and use the serial console if the keyboard isn't found.
.if defined(BOOT_PROBE_KEYBOARD)
CFLAGS+= -DPROBE_KEYBOARD
.endif
# Probe the keyboard lock and use the serial console if the keyboard is locked.
.if defined(BOOT_PROBE_KEYBOARD_LOCK)
CFLAGS+= -DPROBE_KEYBOARD_LOCK
.endif
# Force use of the serial console.
.if defined(BOOT_FORCE_COMCONSOLE)
CFLAGS+= -DFORCE_COMCONSOLE
.endif
# By default, if a serial port is going to be used as console, use COM1
# (aka /dev/ttyd0).
BOOT_COMCONSOLE_PORT?=0x3F8

View File

@ -2,32 +2,33 @@
SERIAL CONSOLE USAGE NOTES
Written by
Bill Paul <wpaul@ctr.columbia.edu>
Revised for 3.0-CURRENT by
Kazutaka Yokota <yokota@zodiac.mech.utsunomiya-u.ac.jp>
The FreeBSD boot block can now be used to boot FreeBSD on a system with
only a dumb terminal on a serial port (COM1) as a console. This feature
only a dumb terminal on a serial port as a console. This feature
is provided for the benefit of people who wish to install FreeBSD on
dedicated file/compute/terminal server machines that have no keyboard
(or monitor) attached, just as is possible with Sun workstations and
servers. People who don't need this extra functionality shouldn't notice
the changes at all (unless I've screwed something up horribly).
Note that 'options COMCONSOLE' can still be used to force the kernel to
boot in 'serial console' mode regardless of what boot options you use.
To boot FreeBSD in serial console mode, you must do the following:
- UNPLUG YOUR KEYBOARD. Most PC systems probe for the keyboard during the
Power-On Self-Test (POST) and will generate an error if the keyboard
isn't detected. Additionally, many machines will pause the boot process
and wait for you to reattach the keyboard and press a key before
proceeding any further. If your computer complains about the lack of a
keyboard but boots anyway, then you don't have to do anything special.
(One machine with a PHOENIX BIOS that I have here merely says 'Keyboard
failed' then continues to boot normally.) If your machine complains
loudly about the lack of a keyboard and won't continue to boot until you
plug it back in, you'll have to go into your CMOS configuration menu and
change the 'Keyboard' setting to 'Not installed' in order to bypass the
keyboard probe.
isn't detected. Some BIOSes may be set to ignore this error. Many other
machines will pause the boot process and wait for you to reattach the
keyboard and press a key before proceeding any further. Consult the manual
of your motherboard to see how it responds to the error and how to
set the BIOS to ignore the error. If your computer complains about
the lack of a keyboard but boots anyway, then you don't have to do
anything special. (One machine with a PHOENIX BIOS that I have here
merely says 'Keyboard failed' then continues to boot normally.) If your
machine complains loudly about the lack of a keyboard and won't continue
to boot until you plug it back in, you'll have to go into your CMOS
configuration menu and change the 'Keyboard' setting to 'Not installed'
in order to bypass the keyboard probe.
NOTE #1:
Setting the keyboard to 'Not installed' in the CMOS configuration
@ -51,8 +52,8 @@ To boot FreeBSD in serial console mode, you must do the following:
- PLUG A DUMB TERMINAL INTO COM1. If you don't have a dumb terminal, you
can use an old PC/XT with a modem program, or the serial port on
another UNIX box. If you don't have a COM1, get one. At this time,
there is no way to select a port other than COM1 without recompiling
both the kernel and the boot blocks. If you're already using COM1 for
there is no way to select a port other than COM1 for the boot blocks
without recompiling the boot blocks. If you're already using COM1 for
another device, you'll have to temporarily remove that device and
install a new boot block and kernel once you get FreeBSD up and running.
(It is assumed that COM1 will be available on a file/compute/terminal
@ -62,7 +63,18 @@ To boot FreeBSD in serial console mode, you must do the following:
NOTE #1:
The serial port settings are hardcoded to 9600 baud, 8 bits, no parity,
1 stop bit.
1 stop bit, by default. If you wish to change the speed, you need to
recompile at least the boot blocks. Add the following line to
/etc/make.conf and compile new boot blocks:
BOOT_COMCONSOLE_SPEED=115200
If the serial console is configured in some other way than by booting with
-h, or if the serial console used by the kernel is different from the one
used by the boot blocks, then you must also add the following option to the
kernel configuration file and compile a new kernel:
options CONSPEED=115200
NOTE #2:
In addition to a serial cable, you will need a null modem adapter
@ -78,44 +90,70 @@ To boot FreeBSD in serial console mode, you must do the following:
options BREAK_TO_DEBUGGER
options DDB
- BOOT THE MACHINE. The boot block will probe for a keyboard on your
system. If it fails to find one, you'll see a prompt appear on the
terminal that looks something like this:
No keyboard found.
- MAKE SURE THE CONFIGURATION FILE OF YOUR KERNEL HAS APPROPRIATE FLAGS
SET FOR COM1.
>> FreeBSD BOOT @ 0x10000: 640/7168 k of memory
Usage: [[[0:][fd](0,a)]/kernel][-abcCdhrsv]
Use 1:sd(0,a)kernel to boot sd0 if it is BIOS drive 1
Use ? for file list or press Enter for defaults
Boot:
Relevant `flags' are:
0x10 enable console support for this unit. The other console flags
are ignored unless this is set. Currently, at most one unit can
have console support; the first one (in config file order) with
this flag set is preferred. This option alone will not make
the serial port the console. Set the following flag or use the -h
option described below, together with this flag.
0x20 force this unit to be the console (unless there is another
higher priority console). This replaces the COMCONSOLE option.
Example:
device sio0 at isa? port "IO_COM1" tty flags 0x10 irq 4 vector siointr
If the flags were not set, you need to run UserConfig (on a different
console) or recompile the kernel.
- CREATE THE FILE "boot.config" IN THE ROOT DIRECTORY of the `a' partition
on the boot drive. Put the kernel name and options in one line. The
kernel name is optional. Options are subset of those described in boot(8):
-h toggle internal and serial consoles. You can use this to switch
console devices. For instance, if you boot from the VGA console,
you can use -h to force the kernel to use the serial port as its
console device. Alternatively, if you boot from the serial port,
you can use the -h to force the kernel to use the VGA display
as the console instead. (Can you say 'toggle' boys and girls?
I knew you could. :)
-D toggle single and dual console configurations. In the single
configuraion the console will be either the VGA display (internal
console) or the serial port, depending on the state of the -h option
above. In the dual console configuration, both the VGA display
and the serial port will become the console at the same time,
regardless of the state of the -h option.
However, the dual console configuration takes effect only during
the boot prompt. Once the kernel is loaded, the console specified
by the -h option becomes the only console.
-P probe the keyboard. If no keyboard is found, the -D and -h options
are automatically set.
Use either the -P option to select the console automatically, or the -h
option to force the serial console.
- BOOT THE MACHINE. You'll see a prompt appear on the terminal that looks
something like this:
No keyboard found
>> FreeBSD BOOT @ 0x10000: 640/7168 k of memory, serial console
Boot default: 0:wd(0,a)kernel
boot:
This is identical to the prompt that normally appears on the VGA console,
except for the 'No keyboard found' message that indicates a keyboard
couldn't be detected. (If a keyboard is detected, the boot prompt will
appear on the VGA display as usual.)
couldn't be detected, if the -P option is in `boot.conf'.
From here you can boot the system (or let it autoboot by itself) just
like you can from the VGA console and the kernel will automatically
use COM1 as the console device. No recompilation or 'options COMCONSOLE'
is required. This is done by passing a special flag to the kernel in
the 'boothowto' word. (The curious can refer to <sys/reboot.h> and the
sio driver sources for details.)
- You will notice that there's a new boot flag: -h. You can use this to
force the kernel to switch console devices. For instance, if you boot
from the VGA console, you can use -h to force the kernel to use the
serial port as its console device. Alternatively, if you boot from
the serial port, you can use the -h to force the kernel to use the VGA
display as the console instead. (Can you say 'toggle' boys and girls?
I knew you could. :)
Should you wish to force booting off a serial console no matter if
there's a keyboard connected or not, you can also uncomment the line
with the ``FORCE_COMCONSOLE'' definition in the Makefile. Remake and
reinstall your bootblocks, and finally relabel your disk (disklabel -B)
to pick up those boot blocks.
use COM1 as the console device. This is done by passing a special flag
to the kernel in the 'boothowto' word. (The curious can refer to
<sys/reboot.h> and the sio driver sources for details.)
CAVEATS:
@ -138,27 +176,21 @@ CAVEATS:
you'll never need to do this. But if you feel you must change the console
to a different port, here's how:
o Get the kerndist kernel source package.
o Edit /sys/i386/boot/biosboot/Makefile and set COMCONSOLE to the
o Get the kernel source package.
o Edit /etc/make.conf and set BOOT_COMCONSOLE_PORT to the
address of the port you want to use (0x3F8, 0x2F8, 0x3E8 or
0x2E8). Only COM1 through COM4 can be used; multiport serial
cards will not work. No interrupt setting is needed.
o Create a custom kernel configuration file and add the following
lines:
o Create a custom kernel configuration file and add appropriate
`flags' for the serial port you want to use. For example, if you
want to make COM2 the console:
options "CONADDR=0x3F8"
options "CONUNIT=0"
device sio1 at isa? port "IO_COM2" tty flags 0x10 irq 3 vector siointr
Set CONADDR to the same address that you selected for COMCONSOLE
in the bootbios Makefile. Set CONUNIT to the unit number of the
serial port that this address corresponds to (0 = sio0, 1 = sio1,
etc). This implies that the serial port you want to use must be
configured into the kernel in the normal way first. I'm not
going to list all the possible combinations here; just use your
head and you should be okay.
The console flags for the other serial ports should not be set.
o Recompile both the boot blocks and the kernel.
o Install the boot blocks with the disklabel command and boot
from the new kernel.
$Id$
$Id: README.serial,v 1.7 1997/02/22 09:30:03 peter Exp $

View File

@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, [92/04/03 16:51:14 rvb]
* $Id: boot.c,v 1.64 1997/03/12 18:48:31 bde Exp $
* $Id: boot.c,v 1.65 1997/05/27 16:26:38 bde Exp $
*/
@ -56,20 +56,20 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <a.out.h>
#include <sys/reboot.h>
#include <machine/bootinfo.h>
#ifdef PROBE_KEYBOARD_LOCK
#include <machine/cpufunc.h>
#endif
#define ouraddr (BOOTSEG << 4) /* XXX */
#define BOOT_CONFIG_SIZE 512
#define NAMEBUF_LEN (8*1024)
#define BOOT_HELP_SIZE (2 * 1024)
#define NAMEBUF_LEN (4 * 1024)
static char boot_config[BOOT_CONFIG_SIZE];
static char boot_help[BOOT_HELP_SIZE];
#ifdef NAMEBLOCK
char *dflt_name;
#endif
char *name;
static char linebuf[NAMEBUF_LEN];
static char namebuf[NAMEBUF_LEN];
static struct bootinfo bootinfo;
int loadflags;
@ -84,28 +84,6 @@ boot(int drive)
{
int ret;
#ifdef PROBE_KEYBOARD
if (probe_keyboard()) {
init_serial();
loadflags |= RB_SERIAL;
printf("\nNo keyboard found.");
}
#endif
#ifdef PROBE_KEYBOARD_LOCK
if (!(inb(0x64) & 0x10)) {
init_serial();
loadflags |= RB_SERIAL;
printf("\nKeyboard locked.");
}
#endif
#ifdef FORCE_COMCONSOLE
init_serial();
loadflags |= RB_SERIAL;
printf("\nSerial console forced.");
#endif
/* Pick up the story from the Bios on geometry of disks */
for(ret = 0; ret < N_BIOS_GEOM; ret ++)
@ -143,6 +121,8 @@ boot(int drive)
}
#endif
}
readfile("boot.config", boot_config, BOOT_CONFIG_SIZE);
readfile("boot.help", boot_help, BOOT_HELP_SIZE);
#ifdef NAMEBLOCK
/*
* XXX
@ -154,37 +134,46 @@ boot(int drive)
name = dflt_name;
} else
#endif /*NAMEBLOCK*/
readfile("boot.config", boot_config, BOOT_CONFIG_SIZE);
if (namebuf[0] != '\0')
name = "kernel";
if (boot_config[0] != '\0') {
printf("boot.config: %s", boot_config);
name = "kernel";
getbootdev(boot_config, &loadflags);
/*
* XXX parsing of `name' is in openrd(), so the defaults aren't
* updated to match the config (if any) before printing the prompt.
*/
getbootdev(boot_config, &loadflags);
if (openrd() != 0)
name = "kernel";
}
loadstart:
/* print this all each time.. (saves space to do so) */
/* If we have looped, use the previous entries as defaults */
printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory\n"
"Usage: [[[%d:][%s](%d,a)]%s][-abcCdghrsv]\n"
"Use 1:sd(0,a)kernel to boot sd0 if it is BIOS drive 1\n"
"Use ? for file list or press Enter for defaults\n\nBoot: ",
printf("\r \n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory, %s%s console\n"
"Boot default: %d:%s(%d,%c)%s\n"
"%s\n"
"boot: ",
ouraddr, bootinfo.bi_basemem, bootinfo.bi_extmem,
dosdev & 0x7f, devs[maj], unit, name);
(loadflags & RB_SERIAL) ? "serial" : "internal",
(loadflags & RB_DUAL) ? "/dual" : "",
dosdev & 0x7f, devs[maj], unit, 'a' + part,
name ? name : "*specify_a_kernel_name*",
boot_help);
loadflags &= RB_SERIAL; /* clear all, but leave serial console */
/*
* Ignore flags from previous attempted boot, if any.
* XXX this is now too strict. Settings given in boot.config should
* not be changed.
*/
loadflags &= (RB_DUAL | RB_SERIAL);
/*
* Be paranoid and make doubly sure that the input buffer is empty.
*/
if (loadflags & RB_SERIAL)
if (loadflags & (RB_DUAL | RB_SERIAL))
init_serial();
if (!gets(namebuf))
if (!gets(linebuf))
putchar('\n');
else
getbootdev(namebuf, &loadflags);
getbootdev(linebuf, &loadflags);
if (name == NULL)
goto loadstart;
ret = openrd();
if (ret != 0) {
if (ret > 0)
@ -352,8 +341,14 @@ static void
getbootdev(char *ptr, int *howto)
{
char c;
int f;
char *p;
while ((c = *ptr) != '\0') {
/* Copy the flags to save some bytes. */
f = *howto;
c = *ptr;
for (;;) {
nextarg:
while (c == ' ' || c == '\n')
c = *++ptr;
@ -361,39 +356,46 @@ nextarg:
while ((c = *++ptr) != '\0') {
if (c == ' ' || c == '\n')
goto nextarg;
if (c == 'C')
*howto |= RB_CDROM;
if (c == 'a')
*howto |= RB_ASKNAME;
if (c == 'b')
*howto |= RB_HALT;
f |= RB_ASKNAME;
if (c == 'C')
f |= RB_CDROM;
if (c == 'c')
*howto |= RB_CONFIG;
f |= RB_CONFIG;
if (c == 'D')
f ^= RB_DUAL;
if (c == 'd')
*howto |= RB_KDB;
if (c == 'h') {
*howto ^= RB_SERIAL;
if (*howto & RB_SERIAL)
init_serial();
continue;
}
f |= RB_KDB;
if (c == 'g')
*howto |= RB_GDB;
f |= RB_GDB;
if (c == 'h')
f ^= RB_SERIAL;
if (c == 'P')
f |= RB_PROBEKBD;
if (c == 'r')
*howto |= RB_DFLTROOT;
f |= RB_DFLTROOT;
if (c == 's')
*howto |= RB_SINGLE;
f |= RB_SINGLE;
if (c == 'v')
*howto |= RB_VERBOSE;
f |= RB_VERBOSE;
}
if (c == '\0')
return;
name = ptr;
while (*++ptr != '\0') {
if (*ptr == ' ' || *ptr == '\n') {
*ptr++ = '\0';
break;
}
break;
p = name = namebuf;
while (c != '\0' && c != ' ' && c != '\n') {
*p++ = c;
c = *++ptr;
}
*p = '\0';
}
if (f & RB_PROBEKBD) {
if (probe_keyboard()) {
f |= RB_DUAL | RB_SERIAL;
printf("No keyboard found\n");
} else
printf("Keyboard found\n");
}
if (f & (RB_DUAL | RB_SERIAL))
init_serial();
*howto = f;
}

View File

@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:03 rpd
* $Id: boot.h,v 1.17 1997/02/22 09:30:07 peter Exp $
* $Id: boot.h,v 1.18 1997/05/27 16:26:39 bde Exp $
*/
#include <sys/param.h>
@ -35,6 +35,9 @@
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#define RB_DUAL 0x40000 /* XXX */
#define RB_PROBEKBD 0x80000 /* XXX */
extern char *devs[];
extern char *name;
extern struct fs *fs;

View File

@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
* $Id: io.c,v 1.21 1997/02/22 09:30:10 peter Exp $
* $Id: io.c,v 1.22 1997/05/27 16:26:39 bde Exp $
*/
#include "boot.h"
@ -123,13 +123,12 @@ printf(const char *format, ...)
void
putchar(int c)
{
if (c == '\n') {
if (loadflags & RB_SERIAL)
serial_putc('\r');
else
putc('\r');
}
if (loadflags & RB_SERIAL)
if (c == '\n')
putchar('\r');
if (loadflags & RB_DUAL) {
putc(c);
serial_putc(c);
} else if (loadflags & RB_SERIAL)
serial_putc(c);
else
putc(c);
@ -141,7 +140,18 @@ getchar(int in_buf)
int c;
loop:
if ((c = ((loadflags & RB_SERIAL) ? serial_getc() : getc())) == '\r')
if (loadflags & RB_DUAL) {
if (ischar())
c = getc();
else if (serial_ischar())
c = serial_getc();
else
goto loop;
} else if (loadflags & RB_SERIAL)
c = serial_getc();
else
c = getc();
if (c == '\r')
c = '\n';
if (c == '\b') {
if (in_buf != 0) {
@ -155,7 +165,6 @@ loop:
return(c);
}
#ifdef PROBE_KEYBOARD
/*
* This routine uses an inb to an unused port, the time to execute that
* inb is approximately 1.25uS. This value is pretty constant across
@ -173,7 +182,6 @@ delay1ms(void)
while (--i >= 0)
(void)inb(0x84);
}
#endif /* PROBE_KEYBOARD */
static __inline int
isch(void)
@ -187,10 +195,12 @@ isch(void)
*/
isc = ischar();
if (!(loadflags & RB_SERIAL))
if (loadflags & RB_DUAL) {
if (isc != 0)
return (isc);
} else if (!(loadflags & RB_SERIAL))
return (isc);
return (serial_ischar());
}
static __inline unsigned

View File

@ -1,32 +1,20 @@
/*-
* Copyright (c) 1992-1995 Søren Schmidt
* Copyright (c) 1990 The Regents of the University of California.
* Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz and Don Ahn.
*
* 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.
* notice, this list of conditions and the following disclaimer.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* 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 REGENTS OR CONTRIBUTORS BE LIABLE
* 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)
@ -35,88 +23,92 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This is a modified version of the keyboard reset code used in syscons.
* If the keyboard reset fails, we assume that the keyboard has been
* unplugged and we use a serial port (COM1) as the console instead.
* Returns 1 on failure (no keyboard), 0 on success (keyboard attached).
*
* This grody hack brought to you by Bill Paul (wpaul@ctr.columbia.edu)
*
* $Id$
* $Id:$
*/
#ifdef PROBE_KEYBOARD
#include <sys/types.h>
#include <machine/console.h>
#include <machine/cpufunc.h>
#include <i386/isa/kbdio.h>
#include <i386/isa/isa.h>
#include <i386/isa/kbdio.h>
#include "boot.h"
#define PROBE_MAXRETRY 5
#define PROBE_MAXWAIT 400
#define IO_DUMMY 0x84
/* 7 microsec delay necessary for some keyboard controllers */
static void
delay7(void)
{
/*
* I know this is broken, but no timer is avaiable yet at this stage...
* See also comments in `delay1ms()' in `io.c'.
*/
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
}
/*
* Perform a simple test on the keyboard; issue the ECHO command and see
* if the right answer is returned. We don't do anything as drastic as
* full keyboard reset; it will be too troublesome and take too much time.
*/
int
probe_keyboard(void)
{
int i, retries = 5;
unsigned char val;
int retry = PROBE_MAXRETRY;
int wait;
int i;
/* flush any noise in the buffer */
while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
delay1ms();
(void) inb(IO_KBD + KBD_DATA_PORT);
while (--retry >= 0) {
/* flush any noise */
while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
delay1ms();
}
/* Try to reset keyboard hardware */
again:
while (--retries) {
#ifdef DEBUG
printf("%d ", retries);
#endif
while ((inb(IO_KBD + KBD_STATUS_PORT) & KBDS_INPUT_BUFFER_FULL)
== KBDS_INPUT_BUFFER_FULL)
delay1ms();
outb(IO_KBD + KBD_DATA_PORT, KBDC_RESET_KBD);
for (i=0; i<1000; i++) {
delay1ms();
val = inb(IO_KBD + KBD_DATA_PORT);
if (val == KBD_ACK || val == KBD_ECHO)
goto gotack;
if (val == KBD_RESEND)
break;
}
/* wait until the controller can accept a command */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (((i = inb(IO_KBD + KBD_STATUS_PORT))
& (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
break;
if (i & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
}
delay1ms();
}
gotres:
#ifdef DEBUG
printf("gotres\n");
#endif
if (!retries) {
#ifdef DEBUG
printf("gave up\n");
#endif
return(1);
if (wait <= 0)
continue;
/* send the ECHO command */
outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
/* wait for a response */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
break;
delay1ms();
}
gotack:
delay1ms();
while ((inb(IO_KBD + KBD_STATUS_PORT) & KBDS_KBD_BUFFER_FULL) == 0)
delay1ms();
delay1ms();
#ifdef DEBUG
printf("ACK ");
if (wait <= 0)
continue;
delay7();
i = inb(IO_KBD + KBD_DATA_PORT);
#ifdef PROBE_KBD_BEBUG
printf("probe_keyboard: got 0x%x.\n", i);
#endif
val = inb(IO_KBD + KBD_DATA_PORT);
if (val == KBD_ACK)
goto gotack;
if (val == KBD_RESEND)
goto again;
if (val != KBD_RESET_DONE) {
#ifdef DEBUG
printf("stray val %d\n", val);
#endif
return(0);
if (i == KBD_ECHO) {
/* got the right answer */
return (0);
}
#ifdef DEBUG
printf("ok\n");
#endif
return(0);
}
return (1);
}
#endif /* PROBE_KEYBOARD */

View File

@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $Id: serial.S,v 1.6 1997/02/22 09:30:11 peter Exp $
* $Id: serial.S,v 1.7 1997/05/16 10:40:00 bde Exp $
*/
/*
@ -94,8 +94,12 @@ ENTRY(serial_putc)
push %ebp
mov %esp, %ebp
movl $10000, %ecx # timeout
mov $COMCONSOLE + 5, %edx # line status reg
1: inb %dx, %al
1:
decl %ecx
je 2f
inb %dx, %al
test $0x20, %al
jz 1b # TX buffer not empty
@ -104,6 +108,7 @@ ENTRY(serial_putc)
sub $5, %edx # TX output reg
outb %al, %dx # send this one
2:
pop %ebp
ret
@ -169,7 +174,11 @@ ENTRY(init_serial)
movb %ah, %al
outb %al, %dx
add $2, %edx # line control reg
incl %edx # fifo control register (if any)
xorl %eax,%eax
outb %al, %dx # disable fifo to reduce worst-case busy-wait
incl %edx # line control reg
movb $0x13, %al
outb %al, %dx # 8 bit, no parity, 1 stop bit

View File

@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
* $Id: sys.c,v 1.19 1997/03/15 16:49:51 bde Exp $
* $Id: sys.c,v 1.20 1997/05/27 16:26:39 bde Exp $
*/
#include "boot.h"
@ -279,8 +279,11 @@ openrd(void)
return 1;
}
dosdev = dosdev_copy;
#if 0
/* XXX this is useful, but misplaced. */
printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
dosdev_copy, biosdrive, unit, maj);
#endif
/***********************************************\
* Now we know the disk unit and part, *
@ -298,12 +301,14 @@ openrd(void)
* Find the actual FILE on the mounted device *
\***********************************************/
ret = find(cp);
name = cp;
if (ret == 0)
return 1;
if (ret < 0)
if (ret < 0) {
name = NULL;
return -1;
}
poff = 0;
name = cp;
#endif /* RAWBOOT */
return 0;
}