I'm not the one that did these, but since you asked... ;-)
The source RPM is available on:
ftp://ftp.caldera.com/pub/eDesktop/Packages/SRPMS/grub-0.5.94-5.src.rpm
and the relevant patches from that are attached.
initrd1G - places the initrd below 1G so large mem machines will boot.
nomeminfo - tries to help some broken BIOSes with mem detection
splash - graphical menu (splash) screen, CD ioctl, etc.
--
Tim Riker - http://rikers.org/ - short SIGs! <g>
All I need to know I could have learned in Kindergarten
... if I'd just been paying attention.
--- grub-0.5.94/stage2/boot.c.orig Thu Feb 10 10:25:16 2000
+++ grub-0.5.94/stage2/boot.c Thu Feb 10 14:49:49 2000
@@ -544,7 +544,7 @@
return 0;
}
- moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000;
+ moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0x3ffff000;
memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
if (cls_hook_seg)
--- grub-0.5.94/stage2/boot.c Thu Feb 10 18:12:26 2000
+++ grub-0.5.94.new/stage2/boot.c Thu Feb 10 16:05:52 2000
@@ -261,17 +261,26 @@
/* copy command-line plus memory hack to staging area */
{
char *src = arg;
- char *dest = (char *) (CL_MY_LOCATION + 4);
-
- memmove ((char *) CL_MY_LOCATION, "mem=", 4);
-
- *((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR;
- *((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC;
-
- dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
- *(dest++) = 'K';
- *(dest++) = ' ';
+ char *dest = (char *) (CL_MY_LOCATION);
+ *((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR;
+ *((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC;
+
+ /* Help Linux to find memory only if more than 64MB are present.
+ * Up to that amount it is fairly capable to find by itself,
+ * and at least newer Phoenix BIOSes are known to put a
+ * 10k hole just before 64MB, but report a proper total.
+ */
+ if (mbi.mem_upper > 65535) /* might subtract 1MB lower mem here */
+ {
+ memmove ((char *) CL_MY_LOCATION, "mem=", 4);
+ dest = (char *) (CL_MY_LOCATION + 4);
+
+ dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
+ *(dest++) = 'K';
+ *(dest++) = ' ';
+ }
+
while (*src && *src != ' ')
src++;
diff -ur grub-0.5.94.orig/grub/asmstub.c grub-0.5.94/grub/asmstub.c
--- grub-0.5.94.orig/grub/asmstub.c Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/grub/asmstub.c Wed Jan 19 15:38:06 2000
@@ -43,6 +43,8 @@
#ifdef __linux__
# include <sys/ioctl.h> /* ioctl */
# include <linux/hdreg.h> /* HDIO_GETGEO */
+# include <linux/cdrom.h> /* CDROM_GET_CAPABILITY to identify CDs */
+# define SOME_CDROM_IOCTL CDROM_GET_CAPABILITY
# if __GLIBC__ < 2
/* Maybe libc doesn't have large file support. */
# include <linux/unistd.h> /* _llseek */
@@ -56,6 +58,8 @@
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h>
+# include <sys/cdio.h> /* CDIOCCLRDEBUG to identify CDs */
+# define SOME_CDROM_IOCTL CDIOCCLRDEBUG
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
#ifdef HAVE_OPENDISK
@@ -83,6 +87,9 @@
unsigned long boot_drive = 0;
char version_string[] = VERSION;
char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */
+char splashscreen_file[128];
+
+unsigned short cls_hook_seg;
/* Emulation requirements. */
char *grub_scratch_mem = 0;
@@ -538,6 +545,11 @@
fclose (fp);
return 0;
}
+
+ /* Make sure CD-ROMs don't get assigned a BIOS disk number
+ before SCSI disks ! */
+ if (ioctl(fileno(fp), SOME_CDROM_IOCTL, 0) >= 0)
+ return 0;
fclose (fp);
return 1;
diff -ur grub-0.5.94.orig/stage2/asm.S grub-0.5.94/stage2/asm.S
--- grub-0.5.94.orig/stage2/asm.S Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/stage2/asm.S Wed Jan 19 15:38:06 2000
@@ -1345,7 +1345,7 @@
movb %bl, %al
movb $0xe, %ah
- movw $1, %bx
+ movw $0x8f, %bx /* invert all planes */
int $0x10
DATA32 call EXT_C(real_to_prot)
@@ -1688,24 +1688,45 @@
ENTRY(cls)
- push %ebp
- push %eax
- push %ebx /* save EBX */
+ pusha
call EXT_C(prot_to_real)
.code16
+ movw EXT_C(cls_hook_seg), %ax
+ cmpw $0, %ax
+ je cls_self
+
+
+ mov %ds,%ax
+ push %ax
+
+ mov %es,%ax
+ push %ax
+
+ lcall (cls_hook)
+
+ pop %ax
+ mov %ax,%es
+
+ pop %ax
+ mov %ax,%ds
+
+ jmp cls_ret
+
+cls_self:
+
movb $0xf, %ah
int $0x10 /* Get Current Video mode */
xorb %ah, %ah
+ movw $0x0003, %ax /* hardcode 80x25 color XXX */
int $0x10 /* Set Video mode (clears screen) */
+cls_ret:
DATA32 call EXT_C(real_to_prot)
.code32
- pop %ebx
- pop %eax
- pop %ebp
+ popa
ret
@@ -1861,10 +1882,19 @@
call EXT_C(prot_to_real)
.code16
+ movw EXT_C(cls_hook_seg),%ax
+ cmpw $0, %ax
+ je sa_text
+
+ movb $0xDB, %al
+ movw $0x8f, %bx /* invert all planes */
+ jmp sa_common
+sa_text:
movb $0x8, %ah
int $0x10
- movb $0x9, %ah
movb %cl, %bl
+sa_common:
+ movb $0x9, %ah
movw $1, %cx
int $0x10
@@ -2068,6 +2098,14 @@
protstack:
.long PROTSTACKINIT
+
+cls_hook:
+ .word 0 /* offset -- hard-wired for now */
+VARIABLE(cls_hook_seg)
+ .word 0
+
+VARIABLE(splashscreen_file)
+ .string "\0/boot/grub/splashscreenXXXXXXXXXXXXXXXXXX"
VARIABLE(boot_drive)
.long 0
diff -ur grub-0.5.94.orig/stage2/boot.c grub-0.5.94/stage2/boot.c
--- grub-0.5.94.orig/stage2/boot.c Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/stage2/boot.c Wed Jan 19 15:54:39 2000
@@ -209,8 +209,9 @@
return KERNEL_TYPE_NONE;
}
- printf (" [Linux-%s, setup=0x%x, size=0x%x]\n",
- (big_linux ? "bzImage" : "zImage"), data_len, text_len);
+ if (!cls_hook_seg)
+ printf (" [Linux-%s, setup=0x%x, size=0x%x]\n",
+ (big_linux ? "bzImage" : "zImage"), data_len, text_len);
if (mbi.mem_lower >= 608)
{
@@ -546,7 +547,8 @@
moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000;
memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
- printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
+ if (!cls_hook_seg)
+ printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
ramdisk = (unsigned long *) (LINUX_SETUP + LINUX_SETUP_INITRD);
ramdisk[0] = RAW_ADDR (moveto);
diff -ur grub-0.5.94.orig/stage2/builtins.c grub-0.5.94/stage2/builtins.c
--- grub-0.5.94.orig/stage2/builtins.c Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/stage2/builtins.c Wed Jan 19 15:57:29 2000
@@ -168,6 +168,14 @@
if (kernel_type != KERNEL_TYPE_NONE)
unset_int15_handler ();
+ if (kernel_type != KERNEL_TYPE_NONE &&
+ kernel_type != KERNEL_TYPE_LINUX &&
+ kernel_type != KERNEL_TYPE_BIG_LINUX)
+ {
+ cls_hook_seg = 0;
+ cls();
+ }
+
switch (kernel_type)
{
case KERNEL_TYPE_FREEBSD:
@@ -2022,7 +2030,8 @@
bootdev = set_bootdev (hdbias);
/* Print the type of the filesystem. */
- print_fsys_type ();
+ if (!cls_hook_seg)
+ print_fsys_type ();
return 0;
}
@@ -2524,6 +2533,28 @@
};
+/* spiffy splash screen */
+static int
+splashscreen_func (char *arg, int flags)
+{
+ char * f = splashscreen_file;
+ char * p = arg;
+ while ((*f++ = *p++))
+ ;
+ return 0;
+}
+
+static struct builtin builtin_splashscreen =
+{
+ "splashscreen",
+ splashscreen_func,
+ BUILTIN_CMDLINE | BUILTIN_MENU,
+ "splashscreen FILE",
+ "Load file as splashscreen hook and call it each time "
+ "the screen is to be cleared"
+};
+
+
/* testload */
static int
testload_func (char *arg, int flags)
@@ -2750,6 +2781,7 @@
&builtin_rootnoverify,
&builtin_setkey,
&builtin_setup,
+ &builtin_splashscreen,
&builtin_testload,
&builtin_timeout,
&builtin_title,
diff -ur grub-0.5.94.orig/stage2/char_io.c grub-0.5.94/stage2/char_io.c
--- grub-0.5.94.orig/stage2/char_io.c Thu Nov 11 21:43:14 1999
+++ grub-0.5.94/stage2/char_io.c Wed Jan 19 15:38:06 2000
@@ -169,8 +169,9 @@
{
cls ();
- printf ("\n GRUB version %s (%dK lower / %dK upper memory)\n\n",
- version_string, mbi.mem_lower, mbi.mem_upper);
+ if (!cls_hook_seg)
+ printf ("\n GRUB version %s (%dK lower / %dK upper memory)\n\n",
+ version_string, mbi.mem_lower, mbi.mem_upper);
}
/* The number of the history entries. */
diff -ur grub-0.5.94.orig/stage2/cmdline.c grub-0.5.94/stage2/cmdline.c
--- grub-0.5.94.orig/stage2/cmdline.c Fri Nov 19 18:41:29 1999
+++ grub-0.5.94/stage2/cmdline.c Wed Jan 19 15:38:06 2000
@@ -182,7 +182,8 @@
;
grub_memmove (heap, old_entry, (int) cur_entry - (int) old_entry);
- grub_printf ("%s\n", old_entry);
+ if (!cls_hook_seg)
+ grub_printf ("%s\n", old_entry);
if (! *heap)
{
diff -ur grub-0.5.94.orig/stage2/shared.h grub-0.5.94/stage2/shared.h
--- grub-0.5.94.orig/stage2/shared.h Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/stage2/shared.h Wed Jan 19 15:38:06 2000
@@ -439,6 +439,18 @@
extern void assign_device_name (int drive, const char *device);
#endif
+extern char splashscreen_file[];
+/* the segment a loaded clear screen hook
+ * (splashscreen) resides in
+ */
+extern unsigned short
+cls_hook_seg;
+
+/* The menu geometry */
+extern int menu_w, menu_h, morig_x, morig_y;
+
+extern int timeout_x, timeout_y;
+
#ifndef STAGE1_5
/* GUI interface variables. */
extern int fallback_entry;
diff -ur grub-0.5.94.orig/stage2/stage2.c grub-0.5.94/stage2/stage2.c
--- grub-0.5.94.orig/stage2/stage2.c Wed Jan 19 12:58:36 2000
+++ grub-0.5.94/stage2/stage2.c Wed Jan 19 15:38:06 2000
@@ -38,13 +38,15 @@
return list;
}
+/* The (default) menu geometry */
+int menu_w = 71, menu_h = 12, morig_x = 3, morig_y = 3;
static void
print_entries (int y, int size, int first, char *menu_entries)
{
int i;
- gotoxy (77, y + 1);
+ gotoxy (morig_x+menu_w, y + 1);
if (first)
putchar (DISP_UP);
@@ -57,11 +59,11 @@
{
int j = 0;
- gotoxy (3, y + i);
+ gotoxy (morig_x, y + i);
while (*menu_entries)
{
- if (j < 71)
+ if (j < menu_w)
{
putchar (*menu_entries);
j++;
@@ -73,11 +75,11 @@
if (*(menu_entries - 1))
menu_entries++;
- for (; j < 71; j++)
+ for (; j < menu_w; j++)
putchar (' ');
}
- gotoxy (77, y + size);
+ gotoxy (morig_x+menu_w, y + size);
if (*menu_entries)
putchar (DISP_DOWN);
@@ -91,6 +93,9 @@
{
int i;
+ if (cls_hook_seg)
+ return;
+
#ifndef GRUB_UTIL
/* Color the menu. The menu is 75 * 14 characters. */
for (i = 0; i < 14; i++)
@@ -138,7 +143,7 @@
{
int x;
- for (x = 2; x < 75; x++)
+ for (x = morig_x-1; x < morig_x+menu_w+1; x++)
{
gotoxy (x, y);
set_attrib (attr);
@@ -167,11 +172,15 @@
#endif
}
+int timeout_x = 3, timeout_y = 22;
+#define TIMEOUT_TEXT \
+"The highlighted entry will be booted automatically in %d seconds. "
+
static void
run_menu (char *menu_entries, char *config_entries, int num_entries,
char *heap, int entryno)
{
- int c, time1, time2 = -1, first_entry = 0;
+ int c, time1, time2 = -1, first_entry = 0, firsttimer=1;
char *cur_entry;
/*
@@ -179,7 +188,7 @@
*/
restart:
- while (entryno > 11)
+ while (entryno > menu_h-1)
{
first_entry++;
entryno--;
@@ -190,8 +199,11 @@
nocursor ();
#endif
- print_border (3, 12);
+ print_border (morig_y, menu_h);
+
+ if (!cls_hook_seg)
+ {
#ifdef GRUB_UTIL
grub_printf ("\n
Use the up and down arrows for selecting which entry is highlighted.\n");
@@ -218,15 +230,16 @@
after (\'O\' for before) the selected line, \'d\' to remove the
selected line, or escape to go back to the main menu.");
}
-
- print_entries (3, 12, first_entry, menu_entries);
+ }
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
/* highlight initial line */
- set_line_highlight (4 + entryno);
+ set_line_highlight (morig_y+1 + entryno);
/* XX using RT clock now, need to initialize value */
while ((time1 = getrtsecs()) == 0xFF);
+ firsttimer=1;
while (1)
{
/* initilize to NULL just in case... */
@@ -237,14 +250,21 @@
if (grub_timeout <= 0)
{
grub_timeout = -1;
+ gotoxy (timeout_x, timeout_y);
+ printf (TIMEOUT_TEXT, 0);
break;
}
/* else not booting yet! */
time2 = time1;
- gotoxy (3, 22);
- printf ("The highlighted entry will be booted automatically in %d seconds. ", grub_timeout);
- gotoxy (74, 4 + entryno);
+ gotoxy (timeout_x, timeout_y);
+ if (!firsttimer)
+ printf (TIMEOUT_TEXT, grub_timeout+1);
+ else
+ firsttimer=0;
+ gotoxy (timeout_x, timeout_y);
+ printf (TIMEOUT_TEXT, grub_timeout);
+ gotoxy (morig_x+menu_w, morig_y+1 + entryno);
grub_timeout--;
}
@@ -254,42 +274,48 @@
if (grub_timeout >= 0)
{
- gotoxy (3, 22);
+ gotoxy (timeout_x, timeout_y);
+ printf (TIMEOUT_TEXT, grub_timeout+1);
+ gotoxy (timeout_x, timeout_y);
printf (" ");
grub_timeout = -1;
fallback_entry = -1;
- gotoxy (74, 4 + entryno);
+ gotoxy (morig_x+menu_w, morig_y+1 + entryno);
}
if ((c == KEY_UP) || (ASCII_CHAR (c) == 16))
{
if (entryno > 0)
{
- set_line_normal (4 + entryno);
+ set_line_normal (morig_y+1 + entryno);
entryno--;
- set_line_highlight (4 + entryno);
+ set_line_highlight (morig_y+1 + entryno);
}
else if (first_entry > 0)
{
+ set_line_normal (morig_y+1);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
first_entry--;
- print_entries (3, 12, first_entry, menu_entries);
- set_line_highlight (4);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
+ set_line_highlight (morig_y+1);
}
}
if (((c == KEY_DOWN) || (ASCII_CHAR (c) == 14))
&& (first_entry + entryno + 1) < num_entries)
{
- if (entryno < 11)
+ if (entryno < menu_h-1)
{
- set_line_normal (4 + entryno);
+ set_line_normal (morig_y+1 + entryno);
entryno++;
- set_line_highlight (4 + entryno);
+ set_line_highlight (morig_y+1 + entryno);
}
- else if (num_entries > 12 + first_entry)
+ else if (num_entries > menu_h + first_entry)
{
+ set_line_normal (morig_y+menu_h);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
first_entry++;
- print_entries (3, 12, first_entry, menu_entries);
- set_line_highlight (15);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
+ set_line_highlight (morig_y+menu_h);
}
}
@@ -304,7 +330,8 @@
{
if ((c == 'd') || (c == 'o') || (c == 'O'))
{
- set_line_normal (4 + entryno);
+ set_line_normal (morig_y+1 + entryno);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
/* insert after is almost exactly like insert before */
if (c == 'o')
@@ -342,12 +369,12 @@
if (entryno >= num_entries)
entryno--;
- if (first_entry && num_entries < 12 + first_entry)
+ if (first_entry && num_entries < menu_h + first_entry)
first_entry--;
}
- print_entries (3, 12, first_entry, menu_entries);
- set_line_highlight (4 + entryno);
+ print_entries (morig_y, menu_h, first_entry, menu_entries);
+ set_line_highlight (morig_y+1 + entryno);
}
cur_entry = menu_entries;
@@ -401,6 +428,15 @@
int num_entries = 0, i = 0;
char *new_heap;
+ morig_x = 3;
+ morig_y = 3;
+ menu_h = 12;
+ menu_w = 71;
+ timeout_x = 3;
+ timeout_y = 22;
+ cls_hook_seg = 0;
+ cls();
+
if (config_entries)
{
new_heap = heap;
@@ -496,12 +532,15 @@
{
cls ();
- if (config_entries)
- printf (" Booting \'%s\'\n\n",
- get_entry (menu_entries, first_entry + entryno, 0));
- else
- printf (" Booting command-list\n\n");
-
+ if (!cls_hook_seg)
+ {
+ if (config_entries)
+ printf (" Booting \'%s\'\n\n",
+ get_entry (menu_entries, first_entry + entryno, 0));
+ else
+ printf (" Booting command-list\n\n");
+ }
+
if (! cur_entry)
cur_entry = get_entry (config_entries, first_entry + entryno, 1);
@@ -696,6 +735,36 @@
grub_close ();
}
+ if (*splashscreen_file && grub_open (splashscreen_file) )
+ {
+ if ( grub_read ((char *) RAW_ADDR (0x50000), -1) > 0 )
+ {
+ cls_hook_seg = 0x5000;
+
+ morig_x = 2;
+ morig_y = 6;
+ menu_h = 20;
+ menu_w = 51;
+
+ timeout_x = 2;
+ timeout_y = 28; /* Grafix screen has 80x30 Chars */
+ }
+
+ /* grub_printf("would use splashscreen file %s\n", splashscreen_file); */
+
+ *splashscreen_file = '\0';
+ grub_close ();
+ }
+ else
+ {
+ morig_x = 3;
+ morig_y = 3;
+ menu_h = 12;
+ menu_w = 71;
+ timeout_x = 3;
+ timeout_y = 22;
+ }
+
if (! num_entries)
{
/* If no acceptable config file, goto command-line, starting
@@ -705,6 +774,7 @@
}
else
{
+ cls();
/* Run menu interface. */
run_menu (menu_entries, config_entries, num_entries,
menu_entries + menu_len, default_entry);
--- grub-0.5.94/stage2/boot.c.orig Thu Feb 10 21:16:20 2000
+++ grub-0.5.94/stage2/boot.c Mon Feb 14 19:29:56 2000
@@ -229,7 +229,7 @@
/* Handle special strings. */
if (substring ("normal", value) < 1)
- vid_mode = LINUX_VID_MODE_NORMAL;
+ vid_mode = LINUX_VID_MODE_NORMAL, cls_hook_seg = 0;
else if (substring ("ext", value) < 1)
vid_mode = LINUX_VID_MODE_EXTENDED;
else if (substring ("ask", value) < 1)
@@ -326,7 +326,8 @@
mbi.syms.a.addr = 0;
mbi.syms.a.pad = 0;
- printf (" [%s-%s", str2, str);
+ if (!cls_hook_seg)
+ printf (" [%s-%s", str2, str);
str = "";
@@ -489,7 +490,10 @@
}
if (!errnum)
- printf (", entry=0x%x]\n", (int) entry_addr);
+ {
+ if (!cls_hook_seg)
+ printf (", entry=0x%x]\n", (int) entry_addr);
+ }
else
{
putchar ('\n');