fix a minor bug in diskless, add a serial emulation into the grub shell, fix a cosmetic problem in the grub shell.

This commit is contained in:
okuji 2000-08-13 20:01:51 +00:00
parent fbd0ada4bb
commit 443bdcb325
6 changed files with 225 additions and 8 deletions

View file

@ -1,3 +1,31 @@
2000-08-13 OKUJI Yoshinori <okuji@gnu.org>
* grub/main.c (main): Move the version number inside the
parentheses, since the grub shell is merely one of the programs
included in GNU GRUB.
2000-08-13 OKUJI Yoshinori <okuji@gnu.org>
Add a serial device emulation into the grub shell.
* grub/asmstub.c: Include sys/time.h and termios.h.
(serial_fd): New variable.
(serial_device): Likewise.
(serial_getkey): New function.
(serial_checkkey): Likewise.
(serial_putchar): Likewise.
(get_termios_speed): Likewise.
(serial_init): Likewise.
(set_serial_device): Likewise.
(grub_stage2): Restore SERIAL_DEVICE and SERIAL_FD, if they were
allocated.
* stage2/serial.h [GRUB_UTIL] (set_serial_device): Declared.
2000-08-13 OKUJI Yoshinori <okuji@gnu.org>
* stage2/asm.S (codestart) [SUPPORT_DISKLESS]: Don't reset a
disk system. That is not only uncessary but also harmful.
2000-08-12 OKUJI Yoshinori <okuji@gnu.org>
Add a serial device driver (but only the driver).

View file

@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.020.
.TH GRUB "8" "August 2000" "GNU GRUB 0.5.96" FSF
.TH GRUB "8" "August 2000" "grub (GNU GRUB 0.5.96)" FSF
.SH NAME
GRUB \- the grub shell
grub \- the grub shell
.SH SYNOPSIS
.B grub
[\fIOPTION\fR]...
@ -53,13 +53,13 @@ print version information and exit
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B GRUB
.B grub
is maintained as a Texinfo manual. If the
.B info
and
.B GRUB
.B grub
programs are properly installed at your site, the command
.IP
.B info GRUB
.B info grub
.PP
should give you access to the complete manual.

View file

@ -39,6 +39,8 @@ int grub_stage2 (void);
#include <string.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/time.h>
#include <termios.h>
#ifdef __linux__
# include <sys/ioctl.h> /* ioctl */
@ -58,6 +60,7 @@ int grub_stage2 (void);
#define WITHOUT_LIBC_STUBS 1
#include <shared.h>
#include <device.h>
#include <serial.h>
/* Simulated memory sizes. */
#define EXTENDED_MEMSIZE (3 * 1024 * 1024) /* 3MB */
@ -80,6 +83,12 @@ char **device_map = 0;
/* The jump buffer for exiting correctly. */
static jmp_buf env_for_exit;
/* The file descriptor for a serial device. */
static int serial_fd = -1;
/* The file name of a serial device. */
static char *serial_device = 0;
/* The main entry point into this mess. */
int
grub_stage2 (void)
@ -183,6 +192,9 @@ grub_stage2 (void)
close (disks[i].flags);
}
if (serial_fd >= 0)
close (serial_fd);
/* Release memory. */
restore_device_map (device_map);
device_map = 0;
@ -191,6 +203,10 @@ grub_stage2 (void)
free (scratch);
grub_scratch_mem = 0;
if (serial_device)
free (serial_device);
serial_device = 0;
/* Ahh... at last we're ready to return to caller. */
return status;
}
@ -802,3 +818,170 @@ stop_floppy (void)
{
/* NOTUSED */
}
/* The serial version of getkey. */
int
serial_getkey (void)
{
char c;
if (nread (serial_fd, &c, 1) != 1)
stop ();
return c;
}
/* The serial version of checkkey. */
int
serial_checkkey (void)
{
fd_set fds;
struct timeval timeout;
/* Wait only for the serial device. */
FD_ZERO (&fds);
FD_SET (serial_fd, &fds);
/* Set the timeout to 100ms. */
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
return select (serial_fd + 1, &fds, 0, 0, 0) > 0 ? : -1;
}
/* The serial version of grub_putchar. */
void
serial_putchar (int c)
{
char ch = (char) c;
if (nwrite (serial_fd, &ch, 1) != 1)
stop ();
}
static speed_t
get_termios_speed (int speed)
{
switch (speed)
{
case 2400: return B2400;
case 4800: return B4800;
case 9600: return B9600;
case 19200: return B19200;
case 38400: return B38400;
#ifdef B57600
case 57600: return B57600;
#endif
#ifdef B115200
case 115200: return B115200;
#endif
}
return B0;
}
/* Initialize a serial device. In the grub shell, PORT is unused. */
int
serial_init (unsigned short port, unsigned int speed,
int word_len, int parity, int stop_bit_len)
{
struct termios termios;
speed_t termios_speed;
/* Check if the file name is specified. */
if (! serial_device)
return 0;
/* Open the device file. */
serial_fd = open (serial_device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);
if (serial_fd < 0)
return 0;
/* Get the termios parameters. */
if (tcgetattr (serial_fd, &termios))
goto fail;
/* Raw mode. */
cfmakeraw (&termios);
/* Set the speed. */
termios_speed = get_termios_speed (speed);
if (termios_speed == B0)
goto fail;
cfsetispeed (&termios, termios_speed);
cfsetospeed (&termios, termios_speed);
/* Set the word length. */
termios.c_cflag &= ~CSIZE;
switch (word_len)
{
case UART_5BITS_WORD:
termios.c_cflag |= CS5;
break;
case UART_6BITS_WORD:
termios.c_cflag |= CS6;
break;
case UART_7BITS_WORD:
termios.c_cflag |= CS7;
break;
case UART_8BITS_WORD:
termios.c_cflag |= CS8;
break;
default:
goto fail;
}
/* Set the parity. */
switch (parity)
{
case UART_NO_PARITY:
termios.c_cflag &= ~PARENB;
break;
case UART_ODD_PARITY:
termios.c_cflag |= PARENB;
termios.c_cflag |= PARODD;
break;
case UART_EVEN_PARITY:
termios.c_cflag |= PARENB;
termios.c_cflag &= ~PARODD;
break;
default:
goto fail;
}
/* Set the length of stop bit. */
switch (stop_bit_len)
{
case UART_1_STOP_BIT:
termios.c_cflag &= ~CSTOPB;
break;
case UART_2_STOP_BITS:
termios.c_cflag |= CSTOPB;
break;
default:
goto fail;
}
/* Set the parameters. */
if (tcsetattr (serial_fd, TCSANOW, &termios))
goto fail;
return 1;
fail:
close (serial_fd);
serial_fd = -1;
return 0;
}
/* Set the file name of a serial device (or a pty device). This is a
function specific to the grub shell. */
void
set_serial_device (const char *device)
{
if (serial_device)
free (serial_device);
serial_device = strdup (device);
}

View file

@ -148,7 +148,7 @@ main (int argc, char **argv)
break;
case OPT_VERSION:
printf ("GNU GRUB " VERSION "\n");
printf ("grub (GNU GRUB " VERSION ")\n");
exit (0);
break;

View file

@ -110,10 +110,10 @@ codestart:
#ifndef SUPPORT_DISKLESS
/* save boot drive reference */
ADDR32 movb %dl, EXT_C(boot_drive)
#endif
/* reset disk system (%ah = 0) */
int $0x13
#endif
/* transition to protected mode */
DATA32 call EXT_C(real_to_prot)

View file

@ -84,4 +84,10 @@ unsigned short serial_get_port (int unit);
int serial_init (unsigned short port, unsigned int speed,
int word_len, int parity, int stop_bit_len);
#ifdef GRUB_UTIL
/* Set the file name of a serial device (or a pty device). This is a
function specific to the grub shell. */
void set_serial_device (const char *device);
#endif /* GRUB_UTIL */
#endif /* ! GRUB_SERIAL_HEADER */