summaryrefslogtreecommitdiff
path: root/usr/src/grub
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/grub')
-rw-r--r--usr/src/grub/Makefile6
-rw-r--r--usr/src/grub/Makefile.grub1
-rw-r--r--usr/src/grub/grub-0.97/stage2/boot.c13
-rw-r--r--usr/src/grub/grub-0.97/stage2/builtins.c92
-rw-r--r--usr/src/grub/grub-0.97/stage2/cmdline.c23
-rw-r--r--usr/src/grub/grub-0.97/stage2/serial.c14
-rw-r--r--usr/src/grub/grub-0.97/stage2/serial.h6
7 files changed, 130 insertions, 25 deletions
diff --git a/usr/src/grub/Makefile b/usr/src/grub/Makefile
index 28c2eca2ff..c31e9a802c 100644
--- a/usr/src/grub/Makefile
+++ b/usr/src/grub/Makefile
@@ -29,6 +29,7 @@ INST_TARGETS += $(ROOT_BOOT_GRUB)/$(GRUB_MENU)
INST_TARGETS += $(ROOT_BOOT_GRUB)/$(INSTALL_MENU)
INST_TARGETS += $(ROOT_BOOT_GRUB)/$(GRUB_DEFAULT)
INST_TARGETS += $(ROOT_BOOT_GRUB)/$(CAPABILITY)
+INST_TARGETS += $(ROOT_USR_SBIN)/grub
$(ROOT_BOOT_GRUB)/$(GRUB_DEFAULT) := FILEMODE = 444
$(ROOT_BOOT_GRUB)/$(CAPABILITY) := FILEMODE = 444
@@ -45,9 +46,14 @@ $(GRUB): FRC
$(ROOT_BOOT_GRUB)/%: $(ROOT_BOOT_GRUB) %
$(INS.file)
+$(ROOT_USR_SBIN)/%: $(GRUB)/grub/grub $(ROOT_USR_SBIN)
+ $(INS.file)
+
$(ROOT_BOOT_GRUB):
$(INS.dir)
+$(ROOT_USR_SBIN):
+ $(INS.dir)
clean clobber: $(SUBDIRS)
diff --git a/usr/src/grub/Makefile.grub b/usr/src/grub/Makefile.grub
index 18354324ae..99942fa2ed 100644
--- a/usr/src/grub/Makefile.grub
+++ b/usr/src/grub/Makefile.grub
@@ -10,3 +10,4 @@ PLATFORM = i86pc
ROOT_BOOT_GRUB = $(ROOT)/boot/grub
ROOT_PLAT_GRUB = $(ROOT)/platform/$(PLATFORM)/boot/grub
ROOT_SRC = $(ROOT)/usr/share/src/grub
+ROOT_USR_SBIN = $(ROOT)/usr/sbin
diff --git a/usr/src/grub/grub-0.97/stage2/boot.c b/usr/src/grub/grub-0.97/stage2/boot.c
index cfc2336a4c..027de7709b 100644
--- a/usr/src/grub/grub-0.97/stage2/boot.c
+++ b/usr/src/grub/grub-0.97/stage2/boot.c
@@ -25,6 +25,8 @@
#include "imgact_aout.h"
#include "i386-elf.h"
+#define SAFE_LOAD_BASE 0xc800000
+
static int cur_addr;
entry_func entry_addr;
static struct mod_list mll[99];
@@ -773,6 +775,17 @@ load_module (char *module, char *arg)
{
int len;
+ /*
+ * XXX Workaround for RICHMOND-16: on some systems, the region
+ * [c700000, c800000) is corrupted by an unknown external (off-CPU) actor(s)
+ * during boot. To be on the safe side, we will simply ensure that every
+ * module is loaded above this region. Note that this means this particular
+ * boot loader supports only systems with at least 200 MB of DRAM plus the
+ * amount of space used by any modules.
+ */
+ if (cur_addr < SAFE_LOAD_BASE)
+ cur_addr = SAFE_LOAD_BASE;
+
/* if we are supposed to load on 4K boundaries */
cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
diff --git a/usr/src/grub/grub-0.97/stage2/builtins.c b/usr/src/grub/grub-0.97/stage2/builtins.c
index 9cc05dc99b..77800ff4b1 100644
--- a/usr/src/grub/grub-0.97/stage2/builtins.c
+++ b/usr/src/grub/grub-0.97/stage2/builtins.c
@@ -4057,12 +4057,20 @@ static struct builtin builtin_savedefault =
static int
serial_func (char *arg, int flags)
{
- unsigned short port = serial_hw_get_port (0);
+ int i;
+ int units[SERIAL_MAX_PORTS];
+ unsigned short ports[SERIAL_MAX_PORTS];
unsigned int speed = 9600;
int word_len = UART_8BITS_WORD;
int parity = UART_NO_PARITY;
int stop_bit_len = UART_1_STOP_BIT;
+ for (i = 0; i < SERIAL_MAX_PORTS; ++i)
+ {
+ units[i] = -1;
+ ports[i] = 0;
+ }
+
/* Process GNU-style long options.
FIXME: We should implement a getopt-like function, to avoid
duplications. */
@@ -4072,17 +4080,28 @@ serial_func (char *arg, int flags)
{
char *p = arg + sizeof ("--unit=") - 1;
int unit;
-
- if (! safe_parse_maxint (&p, &unit))
- return 1;
-
- if (unit < 0 || unit > 3)
+
+ i = 0;
+ do
{
- errnum = ERR_DEV_VALUES;
- return 1;
- }
+ if (i >= SERIAL_MAX_PORTS)
+ {
+ errnum = ERR_DEV_FORMAT;
+ return 1;
+ }
+
+ if (! safe_parse_maxint (&p, &unit))
+ return 1;
+
+ if (unit < 0 || unit > 3)
+ {
+ errnum = ERR_DEV_VALUES;
+ return 1;
+ }
- port = serial_hw_get_port (unit);
+ units[i++] = unit;
+ }
+ while (*p++ == ',');
}
else if (grub_memcmp (arg, "--speed=", sizeof ("--speed=") - 1) == 0)
{
@@ -4098,11 +4117,28 @@ serial_func (char *arg, int flags)
{
char *p = arg + sizeof ("--port=") - 1;
int num;
-
- if (! safe_parse_maxint (&p, &num))
- return 1;
- port = (unsigned short) num;
+ i = 0;
+ do
+ {
+ if (i >= SERIAL_MAX_PORTS)
+ {
+ errnum = ERR_DEV_FORMAT;
+ return 1;
+ }
+
+ if (! safe_parse_maxint (&p, &num))
+ return 1;
+
+ if (num > 0xffff || num <= 0)
+ {
+ errnum = ERR_DEV_VALUES;
+ return 1;
+ }
+
+ ports[i++] = (unsigned short) num;
+ }
+ while (*p++ == ',');
}
else if (grub_memcmp (arg, "--word=", sizeof ("--word=") - 1) == 0)
{
@@ -4178,8 +4214,21 @@ serial_func (char *arg, int flags)
arg = skip_to (0, arg);
}
- /* Initialize the serial unit. */
- if (! serial_hw_init (port, speed, word_len, parity, stop_bit_len))
+ if (units[0] == -1 && ports[0] == 0)
+ units[0] = 0;
+
+ for (i = 0; i < SERIAL_MAX_PORTS; ++i)
+ {
+ if (units[i] != -1)
+ ports[i] = serial_hw_get_port (units[i]);
+ if (ports[i] == 0)
+ continue;
+
+ if (serial_hw_init (ports[i], speed, word_len, parity, stop_bit_len))
+ break;
+ }
+
+ if (i >= SERIAL_MAX_PORTS)
{
errnum = ERR_BAD_ARGUMENT;
return 1;
@@ -4193,14 +4242,17 @@ static struct builtin builtin_serial =
"serial",
serial_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
- "serial [--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] [--parity=PARITY] [--stop=STOP] [--device=DEV]",
+ "serial [[--unit=UNIT[,UNIT...]] | [--port=PORT[,PORT...]]] [--speed=SPEED] [--word=WORD] [--parity=PARITY] [--stop=STOP] [--device=DEV]",
"Initialize a serial device. UNIT is a digit that specifies which serial"
- " device is used (e.g. 0 == COM1). If you need to specify the port number,"
- " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length,"
+ " device is used (e.g. 0 == ttya (aka COM1)). If you need to specify the port"
+ " number, set it by --port. Either but not both of --unit and --port is"
+ " permitted; --unit takes precedence. Multiple devices may be specified,"
+ " separated by commas; the first working device in the list will be used"
+ " and the rest ignored. SPEED is the DTE-DTE speed. WORD is the word length,"
" PARITY is the type of parity, which is one of `no', `odd' and `even'."
" STOP is the length of stop bit(s). The option --device can be used only"
" in the grub shell, which specifies the file name of a tty device. The"
- " default values are COM1, 9600, 8N1."
+ " default values are ttya, 9600, 8N1."
};
#endif /* SUPPORT_SERIAL */
diff --git a/usr/src/grub/grub-0.97/stage2/cmdline.c b/usr/src/grub/grub-0.97/stage2/cmdline.c
index 46c5fda027..6d5591e1de 100644
--- a/usr/src/grub/grub-0.97/stage2/cmdline.c
+++ b/usr/src/grub/grub-0.97/stage2/cmdline.c
@@ -212,8 +212,27 @@ run_script (char *script, char *heap)
intervention. */
if (fallback_entryno < 0)
{
- grub_printf ("\nPress any key to continue...");
- (void) getkey ();
+ int time1, time2 = -1;
+
+ grub_printf (
+ "\nRebooting in 2 minutes (press any key to continue)...");
+ grub_timeout = 120;
+
+ /* using RT clock now, need to initialize value */
+ while ((time1 = getrtsecs()) == 0xFF);
+
+ while (grub_timeout >= 0) {
+ if ((time1 = getrtsecs()) != time2 && time1 != 0xFF) {
+ time2 = time1;
+ grub_timeout--;
+ }
+
+ if (checkkey() >= 0)
+ break;
+ }
+
+ grub_printf ("\nresetting...");
+ grub_reboot();
}
return 1;
diff --git a/usr/src/grub/grub-0.97/stage2/serial.c b/usr/src/grub/grub-0.97/stage2/serial.c
index 4e120e000d..b9f27bc581 100644
--- a/usr/src/grub/grub-0.97/stage2/serial.c
+++ b/usr/src/grub/grub-0.97/stage2/serial.c
@@ -141,6 +141,16 @@ serial_hw_init (unsigned short port, unsigned int speed,
int i;
unsigned short div = 0;
unsigned char status = 0;
+
+ if (port == 0)
+ return 0;
+
+ /* Make sure the port actually exists. */
+ outb (port + UART_SR, UART_SR_TEST);
+ outb (port + UART_FCR, 0);
+ status = inb (port + UART_SR);
+ if (status != UART_SR_TEST)
+ return 0;
/* Turn off the interrupt. */
outb (port + UART_IER, 0);
@@ -163,7 +173,7 @@ serial_hw_init (unsigned short port, unsigned int speed,
outb (port + UART_DLH, div >> 8);
/* Set the line status. */
- status |= parity | word_len | stop_bit_len;
+ status = parity | word_len | stop_bit_len;
outb (port + UART_LCR, status);
/* Enable the FIFO. */
@@ -186,8 +196,6 @@ serial_hw_init (unsigned short port, unsigned int speed,
{
term_table[i].flags &= ~TERM_NEED_INIT;
}
-
- /* FIXME: should check if the serial terminal was found. */
return 1;
}
diff --git a/usr/src/grub/grub-0.97/stage2/serial.h b/usr/src/grub/grub-0.97/stage2/serial.h
index 76c222720d..19f7be6e63 100644
--- a/usr/src/grub/grub-0.97/stage2/serial.h
+++ b/usr/src/grub/grub-0.97/stage2/serial.h
@@ -23,6 +23,9 @@
/* Macros. */
+/* The maximum number of ports we ever try to use. */
+#define SERIAL_MAX_PORTS 4
+
/* The offsets of UART registers. */
#define UART_TX 0
#define UART_RX 0
@@ -65,6 +68,9 @@
/* Turn on DTR, RTS, and OUT2. */
#define UART_ENABLE_MODEM 0x0B
+/* Arbitrary pattern to write during existence testing. */
+#define UART_SR_TEST 0x4F
+
/* Function prototypes. */