summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO90
-rw-r--r--.gitignore16
-rw-r--r--040_all_grub-0.96-nxstack.patch623
-rw-r--r--2gb_limit.patch49
-rw-r--r--PKGBUILD181
-rw-r--r--crossreference_manpages.patch48
-rw-r--r--ext3_256byte_inode.patch (renamed from grub-inode-size.patch)21
-rw-r--r--ext4_block_group.patch177
-rw-r--r--ext4_fix_variable_sized_inodes.patch33
-rw-r--r--ext4_support.patch (renamed from ext4.patch)116
-rw-r--r--find-grub-dir.patch56
-rw-r--r--geometry-26kernel.patch236
-rw-r--r--graphics.patch2310
-rw-r--r--grub-0.97-ldflags-objcopy-remove-build-id.patch196
-rw-r--r--grub-install_addsyncs.patch57
-rw-r--r--grub-install_aoe_support.patch23
-rw-r--r--grub-install_regexp.patch30
-rw-r--r--grub-install_xvd.patch13
-rw-r--r--grub-special_device_names.patch13
-rw-r--r--grub-xvd_drives.patch51
-rw-r--r--i2o.patch45
-rw-r--r--initrd_max_address.patch (renamed from 05-grub-0.97-initrdaddr.diff)13
-rw-r--r--intelmac.patch8
-rw-r--r--menu.lst_gnu-hurd.patch21
-rw-r--r--modern-automake.patch (renamed from automake-pkglib.patch)43
-rw-r--r--more-raid.patch100
-rw-r--r--mprotect.patch40
-rw-r--r--no-combine-stack-adjustments.patch27
-rw-r--r--no-pie.patch40
-rw-r--r--no-reorder-functions.patch27
-rw-r--r--objcopy-absolute.patch42
-rw-r--r--print_func.patch82
-rw-r--r--raid.patch72
-rw-r--r--raid_cciss.patch98
-rw-r--r--savedefault.patch183
-rw-r--r--snapshot.patch872
-rw-r--r--special-devices.patch18
-rw-r--r--splashimage_help.patch35
-rw-r--r--static-vars-on-stack.patch75
-rw-r--r--use_grub-probe_in_grub-install.patch148
-rw-r--r--xfs_freeze.patch22
41 files changed, 5188 insertions, 1162 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 8b21efef70da..fb2a5ea9b452 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,14 +1,17 @@
pkgbase = grub-legacy
pkgdesc = A GNU multiboot boot loader
pkgver = 0.97
- pkgrel = 25
+ pkgrel = 29
url = http://www.gnu.org/software/grub/
arch = i686
arch = x86_64
license = GPL
+ makedepends = autoconf
+ makedepends = gcc
depends = ncurses
depends = diffutils
depends = sed
+ depends = lib32-glibc
optdepends = xfsprogs: freezing of xfs /boot in install-grub script
conflicts = grub
backup = boot/grub/menu.lst
@@ -16,32 +19,77 @@ pkgbase = grub-legacy
source = ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz.sig
source = menu.lst
source = install-grub
- source = 040_all_grub-0.96-nxstack.patch
- source = 05-grub-0.97-initrdaddr.diff
- source = i2o.patch
- source = special-devices.patch
- source = more-raid.patch
+ source = snapshot.patch
+ source = menu.lst_gnu-hurd.patch
+ source = graphics.patch
+ source = raid.patch
+ source = raid_cciss.patch
+ source = xfs_freeze.patch
+ source = 2gb_limit.patch
+ source = grub-special_device_names.patch
+ source = grub-xvd_drives.patch
+ source = initrd_max_address.patch
+ source = splashimage_help.patch
+ source = grub-install_addsyncs.patch
+ source = grub-install_regexp.patch
+ source = grub-install_aoe_support.patch
+ source = grub-install_xvd.patch
+ source = geometry-26kernel.patch
+ source = print_func.patch
+ source = mprotect.patch
+ source = savedefault.patch
+ source = find-grub-dir.patch
source = intelmac.patch
- source = grub-inode-size.patch
- source = ext4.patch
- source = grub-0.97-ldflags-objcopy-remove-build-id.patch
- source = automake-pkglib.patch
+ source = crossreference_manpages.patch
+ source = ext3_256byte_inode.patch
+ source = use_grub-probe_in_grub-install.patch
+ source = objcopy-absolute.patch
+ source = no-reorder-functions.patch
+ source = modern-automake.patch
+ source = no-combine-stack-adjustments.patch
+ source = no-pie.patch
+ source = static-vars-on-stack.patch
+ source = ext4_support.patch
+ source = ext4_fix_variable_sized_inodes.patch
+ source = ext4_block_group.patch
validpgpkeys = 1C2F76A695C9C8DCA55E4A431DDAE7A2FE06BDEF
sha1sums = 2580626c4579bd99336d3af4482c346c95dac4fb
sha1sums = SKIP
sha1sums = 33d43d48000b2027f9baec8fc99d33e0c4500c96
sha1sums = 60e8f7e4c113b85165fd5d9cd724e8413a337a12
- sha1sums = 157b81dbad3576536b08642242accfa1aeb093a9
- sha1sums = adbb4685c98797ffb4dc83561ec75698991dddbd
- sha1sums = f2e0dff29a7c8a45e90aa07298a1b2a9a9d29afc
- sha1sums = c5e2c94ed0e759590b9eb38c9d979f075d19d7c0
- sha1sums = 45fe668a3779664fb292591f426976b6c784d6c8
- sha1sums = 066d7ab1ae442f88e94c9e4f1867ac6682965d06
- sha1sums = 0436aa6fa0b6f768289172f983a3f4b69384629e
- sha1sums = a36f34e51efed540f1ddafd78e9c9f6d83e4c8d4
- sha1sums = 61c4b58d2eaa3c1561d8e9d8fc41341ce8882869
- sha1sums = 776ed278eb8ff80e949834f763fad68b8741e7cd
+ sha1sums = 395c1a4243d393059bc77a458158347dfd685484
+ sha1sums = 9001de20e5b6eb32c9747cb6e71aae88f918b9fe
+ sha1sums = 3d3281b2bf2b353db125297d058049209b4536fc
+ sha1sums = 207a0a258cff448de804a26ec212c104b0c67dd4
+ sha1sums = eb832d9ee7ab588cad67b1f613d60519d3ede547
+ sha1sums = 9a938adbccbd42f47a3c4380d19bc0b67e9f4425
+ sha1sums = e7e1f954a4b528bd1f987a1c8259da870c5c12ad
+ sha1sums = 61c4b5ad2253ab856943c2c57c8505c880bd30d1
+ sha1sums = 74e90f10baa2eafaf5e4cdb7c618c5d7fd83152f
+ sha1sums = de68226dc1dbacf5315c4367a77e798d67bbbd97
+ sha1sums = 4816712bcb6541ca85583a479b46ba578665ab3f
+ sha1sums = 711fbc4099e41f3d44c8442cd674b46234560b9a
+ sha1sums = 0dd7ab0c782530b6b4d62156cec96ce74074346a
+ sha1sums = 7db04fe9c755f5e93aade57ed4d4ed62ee5de4be
+ sha1sums = 127e098a0f301ef835fb7b341dc19a126974dff3
+ sha1sums = 42fb758e3226869d05d2295d424f03eaa7704b1c
+ sha1sums = caec864afccf8ae01c92b25d14d0e0daea4e51b1
+ sha1sums = 0c0c8c1beed6684cd9cb54c40f5e785ea33b8692
+ sha1sums = 92e5baef9bfae6c0d3122bf05138ad022f0bc04d
+ sha1sums = 81ff955f91b25423ffed0cdf4ba31953fb2784c4
+ sha1sums = a07861fbbb116b8052649d54abffe610a968c293
+ sha1sums = 6a880733ad84ffebeef05515ebdf1ea451a4d054
+ sha1sums = 02f13de04b932093d07f9a52adf20df7f0468654
+ sha1sums = 8f6f13c0f752e20e690337488a178286ef1c381d
+ sha1sums = 07558de2935f4eefec243a6966095b68aa3b6e70
+ sha1sums = 610243204b776901a9696ab65c0729ec8fdb84d1
+ sha1sums = c5aab6d3a5269054fc2e7f110ddc180d5595604d
+ sha1sums = 721bb91d381ee3e51c2e2af0b4cfa004032e15b1
+ sha1sums = 63a0eac56b9f3436a0baa522a3642d209956b54c
+ sha1sums = 51b4dfd479491a3decc25d7ef66d434a7cbe12a2
+ sha1sums = 028bcd02efa5cf6b1dab5e6cbc8690b50ea7425f
+ sha1sums = 421ed77f2bb7aacce7ae558c2d97a4b209a07ca0
+ sha1sums = 02a24bc24ab672d7d5e2b6ec2af6e8240b29fba9
makedepends_x86_64 = gcc-multilib
pkgname = grub-legacy
-
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 9226724f0a40..000000000000
--- a/.gitignore
+++ /dev/null
@@ -1,16 +0,0 @@
-*
-!.gitignore
-!PKGBUILD
-!.SRCINFO
-!040_all_grub-0.96-nxstack.patch
-!05-grub-0.97-initrdaddr.diff
-!automake-pkglib.patch
-!ext4.patch
-!grub-0.97-ldflags-objcopy-remove-build-id.patch
-!grub-inode-size.patch
-!i2o.patch
-!install-grub
-!intelmac.patch
-!menu.lst
-!more-raid.patch
-!special-devices.patch
diff --git a/040_all_grub-0.96-nxstack.patch b/040_all_grub-0.96-nxstack.patch
deleted file mode 100644
index 121941c75787..000000000000
--- a/040_all_grub-0.96-nxstack.patch
+++ /dev/null
@@ -1,623 +0,0 @@
-Fix NX segfaulting on amd64.
-
-Patch by Peter Jones.
-
-http://lists.gnu.org/archive/html/bug-grub/2005-03/msg00011.html
-
---- grub-0.97/grub/asmstub.c
-+++ grub-0.97/grub/asmstub.c
-@@ -42,6 +42,7 @@
- #include <sys/time.h>
- #include <termios.h>
- #include <signal.h>
-+#include <sys/mman.h>
-
- #ifdef __linux__
- # include <sys/ioctl.h> /* ioctl */
-@@ -79,7 +80,7 @@
- struct apm_info apm_bios_info;
-
- /* Emulation requirements. */
--char *grub_scratch_mem = 0;
-+void *grub_scratch_mem = 0;
-
- struct geometry *disks = 0;
-
-@@ -103,14 +104,62 @@
- static unsigned int serial_speed;
- #endif /* SIMULATE_SLOWNESS_OF_SERIAL */
-
-+/* This allocates page-aligned storage of the specified size, which must be
-+ * a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE)
-+ */
-+#ifdef __linux__
-+static void *
-+grub_mmap_alloc(size_t len)
-+{
-+ int mmap_flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_EXECUTABLE;
-+
-+#ifdef MAP_32BIT
-+ mmap_flags |= MAP_32BIT;
-+#endif
-+ /* Mark the simulated stack executable, as GCC uses stack trampolines
-+ * to implement nested functions. */
-+ return mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0);
-+}
-+#else /* !defined(__linux__) */
-+static void *
-+grub_mmap_alloc(size_t len)
-+{
-+ int fd = 0, offset = 0, ret = 0;
-+ void *pa = MAP_FAILED;
-+ char template[] = "/tmp/grub_mmap_alloc_XXXXXX";
-+ errno_t e;
-+
-+ fd = mkstemp(template);
-+ if (fd < 0)
-+ return pa;
-+
-+ unlink(template);
-+
-+ ret = ftruncate(fd, len);
-+ if (ret < 0)
-+ return pa;
-+
-+ /* Mark the simulated stack executable, as GCC uses stack trampolines
-+ * to implement nested functions. */
-+ pa = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC,
-+ MAP_PRIVATE|MAP_EXECUTABLE, fd, offset);
-+
-+ e = errno;
-+ close(fd);
-+ errno = e;
-+ return pa;
-+}
-+#endif /* defined(__linux__) */
-+
- /* The main entry point into this mess. */
- int
- grub_stage2 (void)
- {
- /* These need to be static, because they survive our stack transitions. */
- static int status = 0;
-- static char *realstack;
-- char *scratch, *simstack;
-+ static void *realstack;
-+ void *simstack_alloc_base, *simstack;
-+ size_t simstack_size, page_size;
- int i;
-
- /* We need a nested function so that we get a clean stack frame,
-@@ -140,9 +189,35 @@
- }
-
- assert (grub_scratch_mem == 0);
-- scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
-- assert (scratch);
-- grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
-+
-+ /* Allocate enough pages for 0x100000 + EXTENDED_SIZE + 15, and
-+ * make sure the memory is aligned to a multiple of the system's
-+ * page size */
-+ page_size = sysconf (_SC_PAGESIZE);
-+ simstack_size = ( 0x100000 + EXTENDED_MEMSIZE + 15);
-+ if (simstack_size % page_size)
-+ {
-+ /* If we're not on a page_size boundary, round up to the next one */
-+ simstack_size &= ~(page_size-1);
-+ simstack_size += page_size;
-+ }
-+
-+ /* Add one for a PROT_NONE boundary page at each end. */
-+ simstack_size += 2 * page_size;
-+
-+ simstack_alloc_base = grub_mmap_alloc(simstack_size);
-+ assert (simstack_alloc_base != MAP_FAILED);
-+
-+ /* mark pages above and below our simstack area as innaccessable.
-+ * If the implementation we're using doesn't support that, then the
-+ * new protection modes are undefined. It's safe to just ignore
-+ * them, though. It'd be nice if we knew that we'd get a SEGV for
-+ * touching the area, but that's all. it'd be nice to have. */
-+ mprotect (simstack_alloc_base, page_size, PROT_NONE);
-+ mprotect ((void *)((unsigned long)simstack_alloc_base +
-+ simstack_size - page_size), page_size, PROT_NONE);
-+
-+ grub_scratch_mem = (void *)((unsigned long)simstack_alloc_base + page_size);
-
- /* FIXME: simulate the memory holes using mprot, if available. */
-
-@@ -215,7 +290,7 @@
- device_map = 0;
- free (disks);
- disks = 0;
-- free (scratch);
-+ munmap(simstack_alloc_base, simstack_size);
- grub_scratch_mem = 0;
-
- if (serial_device)
---- grub-0.97/stage2/builtins.c
-+++ grub-0.97/stage2/builtins.c
-@@ -131,63 +131,98 @@
- }
-
-
-+/* blocklist_read_helper nee disk_read_blocklist_func was a nested
-+ * function, to which pointers were taken and exposed globally. Even
-+ * in the GNU-C nested functions extension, they have local linkage,
-+ * and aren't guaranteed to be accessable *at all* outside of their
-+ * containing scope.
-+ *
-+ * Above and beyond all of that, the variables within blocklist_func_context
-+ * are originally local variables, with local (not even static) linkage,
-+ * from within blocklist_func. These were each referenced by
-+ * disk_read_blocklist_func, which is only called from other functions
-+ * through a globally scoped pointer.
-+ *
-+ * The documentation in GCC actually uses the words "all hell will break
-+ * loose" to describe this scenario.
-+ *
-+ * Also, "start_sector" was also used uninitialized, but gcc doesn't warn
-+ * about it (possibly because of the scoping madness?)
-+ */
-+
-+static struct {
-+ int start_sector;
-+ int num_sectors;
-+ int num_entries;
-+ int last_length;
-+} blocklist_func_context = {
-+ .start_sector = 0,
-+ .num_sectors = 0,
-+ .num_entries = 0,
-+ .last_length = 0
-+};
-+
-+/* Collect contiguous blocks into one entry as many as possible,
-+ and print the blocklist notation on the screen. */
-+static void
-+blocklist_read_helper (int sector, int offset, int length)
-+{
-+ int *start_sector = &blocklist_func_context.start_sector;
-+ int *num_sectors = &blocklist_func_context.num_sectors;
-+ int *num_entries = &blocklist_func_context.num_entries;
-+ int *last_length = &blocklist_func_context.last_length;
-+
-+ if (*num_sectors > 0)
-+ {
-+ if (*start_sector + *num_sectors == sector
-+ && offset == 0 && *last_length == SECTOR_SIZE)
-+ {
-+ *num_sectors++;
-+ *last_length = length;
-+ return;
-+ }
-+ else
-+ {
-+ if (*last_length == SECTOR_SIZE)
-+ grub_printf ("%s%d+%d", *num_entries ? "," : "",
-+ *start_sector - part_start, *num_sectors);
-+ else if (*num_sectors > 1)
-+ grub_printf ("%s%d+%d,%d[0-%d]", *num_entries ? "," : "",
-+ *start_sector - part_start, *num_sectors-1,
-+ *start_sector + *num_sectors-1 - part_start,
-+ *last_length);
-+ else
-+ grub_printf ("%s%d[0-%d]", *num_entries ? "," : "",
-+ *start_sector - part_start, *last_length);
-+ *num_entries++;
-+ *num_sectors = 0;
-+ }
-+ }
-+
-+ if (offset > 0)
-+ {
-+ grub_printf("%s%d[%d-%d]", *num_entries ? "," : "",
-+ sector-part_start, offset, offset+length);
-+ *num_entries++;
-+ }
-+ else
-+ {
-+ *start_sector = sector;
-+ *num_sectors = 1;
-+ *last_length = length;
-+ }
-+}
-+
- /* blocklist */
- static int
- blocklist_func (char *arg, int flags)
- {
- char *dummy = (char *) RAW_ADDR (0x100000);
-- int start_sector;
-- int num_sectors = 0;
-- int num_entries = 0;
-- int last_length = 0;
--
-- auto void disk_read_blocklist_func (int sector, int offset, int length);
--
-- /* Collect contiguous blocks into one entry as many as possible,
-- and print the blocklist notation on the screen. */
-- auto void disk_read_blocklist_func (int sector, int offset, int length)
-- {
-- if (num_sectors > 0)
-- {
-- if (start_sector + num_sectors == sector
-- && offset == 0 && last_length == SECTOR_SIZE)
-- {
-- num_sectors++;
-- last_length = length;
-- return;
-- }
-- else
-- {
-- if (last_length == SECTOR_SIZE)
-- grub_printf ("%s%d+%d", num_entries ? "," : "",
-- start_sector - part_start, num_sectors);
-- else if (num_sectors > 1)
-- grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "",
-- start_sector - part_start, num_sectors-1,
-- start_sector + num_sectors-1 - part_start,
-- last_length);
-- else
-- grub_printf ("%s%d[0-%d]", num_entries ? "," : "",
-- start_sector - part_start, last_length);
-- num_entries++;
-- num_sectors = 0;
-- }
-- }
--
-- if (offset > 0)
-- {
-- grub_printf("%s%d[%d-%d]", num_entries ? "," : "",
-- sector-part_start, offset, offset+length);
-- num_entries++;
-- }
-- else
-- {
-- start_sector = sector;
-- num_sectors = 1;
-- last_length = length;
-- }
-- }
-
-+ int *start_sector = &blocklist_func_context.start_sector;
-+ int *num_sectors = &blocklist_func_context.num_sectors;
-+ int *num_entries = &blocklist_func_context.num_entries;
-+
- /* Open the file. */
- if (! grub_open (arg))
- return 1;
-@@ -204,15 +241,15 @@
- grub_printf (")");
-
- /* Read in the whole file to DUMMY. */
-- disk_read_hook = disk_read_blocklist_func;
-+ disk_read_hook = blocklist_read_helper;
- if (! grub_read (dummy, -1))
- goto fail;
-
- /* The last entry may not be printed yet. Don't check if it is a
- * full sector, since it doesn't matter if we read too much. */
-- if (num_sectors > 0)
-- grub_printf ("%s%d+%d", num_entries ? "," : "",
-- start_sector - part_start, num_sectors);
-+ if (*num_sectors > 0)
-+ grub_printf ("%s%d+%d", *num_entries ? "," : "",
-+ *start_sector - part_start, *num_sectors);
-
- grub_printf ("\n");
-
-@@ -1868,6 +1905,77 @@
-
-
- /* install */
-+static struct {
-+ int saved_sector;
-+ int installaddr;
-+ int installlist;
-+ char *stage2_first_buffer;
-+} install_func_context = {
-+ .saved_sector = 0,
-+ .installaddr = 0,
-+ .installlist = 0,
-+ .stage2_first_buffer = NULL,
-+};
-+
-+/* Save the first sector of Stage2 in STAGE2_SECT. */
-+/* Formerly disk_read_savesect_func with local scope inside install_func */
-+static void
-+install_savesect_helper(int sector, int offset, int length)
-+{
-+ if (debug)
-+ printf ("[%d]", sector);
-+
-+ /* ReiserFS has files which sometimes contain data not aligned
-+ on sector boundaries. Returning an error is better than
-+ silently failing. */
-+ if (offset != 0 || length != SECTOR_SIZE)
-+ errnum = ERR_UNALIGNED;
-+
-+ install_func_context.saved_sector = sector;
-+}
-+
-+/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and INSTALLSECT. */
-+/* Formerly disk_read_blocklist_func with local scope inside install_func */
-+static void
-+install_blocklist_helper (int sector, int offset, int length)
-+{
-+ int *installaddr = &install_func_context.installaddr;
-+ int *installlist = &install_func_context.installlist;
-+ char **stage2_first_buffer = &install_func_context.stage2_first_buffer;
-+ /* Was the last sector full? */
-+ static int last_length = SECTOR_SIZE;
-+
-+ if (debug)
-+ printf("[%d]", sector);
-+
-+ if (offset != 0 || last_length != SECTOR_SIZE)
-+ {
-+ /* We found a non-sector-aligned data block. */
-+ errnum = ERR_UNALIGNED;
-+ return;
-+ }
-+
-+ last_length = length;
-+
-+ if (*((unsigned long *) (*installlist - 4))
-+ + *((unsigned short *) *installlist) != sector
-+ || *installlist == (int) *stage2_first_buffer + SECTOR_SIZE + 4)
-+ {
-+ *installlist -= 8;
-+
-+ if (*((unsigned long *) (*installlist - 8)))
-+ errnum = ERR_WONT_FIT;
-+ else
-+ {
-+ *((unsigned short *) (*installlist + 2)) = (*installaddr >> 4);
-+ *((unsigned long *) (*installlist - 4)) = sector;
-+ }
-+ }
-+
-+ *((unsigned short *) *installlist) += 1;
-+ *installaddr += 512;
-+}
-+
- static int
- install_func (char *arg, int flags)
- {
-@@ -1875,8 +1983,12 @@
- char *stage1_buffer = (char *) RAW_ADDR (0x100000);
- char *stage2_buffer = stage1_buffer + SECTOR_SIZE;
- char *old_sect = stage2_buffer + SECTOR_SIZE;
-- char *stage2_first_buffer = old_sect + SECTOR_SIZE;
-- char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE;
-+ /* stage2_first_buffer used to be defined as:
-+ * char *stage2_first_buffer = old_sect + SECTOR_SIZE; */
-+ char **stage2_first_buffer = &install_func_context.stage2_first_buffer;
-+ /* and stage2_second_buffer was:
-+ * char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; */
-+ char *stage2_second_buffer = old_sect + SECTOR_SIZE + SECTOR_SIZE;
- /* XXX: Probably SECTOR_SIZE is reasonable. */
- char *config_filename = stage2_second_buffer + SECTOR_SIZE;
- char *dummy = config_filename + SECTOR_SIZE;
-@@ -1885,10 +1997,11 @@
- int src_drive, src_partition, src_part_start;
- int i;
- struct geometry dest_geom, src_geom;
-- int saved_sector;
-+ int *saved_sector = &install_func_context.saved_sector;
- int stage2_first_sector, stage2_second_sector;
- char *ptr;
-- int installaddr, installlist;
-+ int *installaddr = &install_func_context.installaddr;
-+ int *installlist = &install_func_context.installlist;
- /* Point to the location of the name of a configuration file in Stage 2. */
- char *config_file_location;
- /* If FILE is a Stage 1.5? */
-@@ -1897,67 +2010,13 @@
- int is_open = 0;
- /* If LBA is forced? */
- int is_force_lba = 0;
-- /* Was the last sector full? */
-- int last_length = SECTOR_SIZE;
--
-+
-+ *stage2_first_buffer = old_sect + SECTOR_SIZE;
- #ifdef GRUB_UTIL
- /* If the Stage 2 is in a partition mounted by an OS, this will store
- the filename under the OS. */
- char *stage2_os_file = 0;
- #endif /* GRUB_UTIL */
--
-- auto void disk_read_savesect_func (int sector, int offset, int length);
-- auto void disk_read_blocklist_func (int sector, int offset, int length);
--
-- /* Save the first sector of Stage2 in STAGE2_SECT. */
-- auto void disk_read_savesect_func (int sector, int offset, int length)
-- {
-- if (debug)
-- printf ("[%d]", sector);
--
-- /* ReiserFS has files which sometimes contain data not aligned
-- on sector boundaries. Returning an error is better than
-- silently failing. */
-- if (offset != 0 || length != SECTOR_SIZE)
-- errnum = ERR_UNALIGNED;
--
-- saved_sector = sector;
-- }
--
-- /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and
-- INSTALLSECT. */
-- auto void disk_read_blocklist_func (int sector, int offset, int length)
-- {
-- if (debug)
-- printf("[%d]", sector);
--
-- if (offset != 0 || last_length != SECTOR_SIZE)
-- {
-- /* We found a non-sector-aligned data block. */
-- errnum = ERR_UNALIGNED;
-- return;
-- }
--
-- last_length = length;
--
-- if (*((unsigned long *) (installlist - 4))
-- + *((unsigned short *) installlist) != sector
-- || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4)
-- {
-- installlist -= 8;
--
-- if (*((unsigned long *) (installlist - 8)))
-- errnum = ERR_WONT_FIT;
-- else
-- {
-- *((unsigned short *) (installlist + 2)) = (installaddr >> 4);
-- *((unsigned long *) (installlist - 4)) = sector;
-- }
-- }
--
-- *((unsigned short *) installlist) += 1;
-- installaddr += 512;
-- }
-
- /* First, check the GNU-style long option. */
- while (1)
-@@ -1987,10 +2049,10 @@
- addr = skip_to (0, file);
-
- /* Get the installation address. */
-- if (! safe_parse_maxint (&addr, &installaddr))
-+ if (! safe_parse_maxint (&addr, installaddr))
- {
- /* ADDR is not specified. */
-- installaddr = 0;
-+ *installaddr = 0;
- ptr = addr;
- errnum = 0;
- }
-@@ -2084,17 +2146,17 @@
- = (dest_drive & BIOS_FLAG_FIXED_DISK);
-
- /* Read the first sector of Stage 2. */
-- disk_read_hook = disk_read_savesect_func;
-- if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)
-+ disk_read_hook = install_savesect_helper;
-+ if (grub_read (*stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)
- goto fail;
-
-- stage2_first_sector = saved_sector;
-+ stage2_first_sector = *saved_sector;
-
- /* Read the second sector of Stage 2. */
- if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE)
- goto fail;
-
-- stage2_second_sector = saved_sector;
-+ stage2_second_sector = *saved_sector;
-
- /* Check for the version of Stage 2. */
- if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS))
-@@ -2110,27 +2172,27 @@
-
- /* If INSTALLADDR is not specified explicitly in the command-line,
- determine it by the Stage 2 id. */
-- if (! installaddr)
-+ if (! *installaddr)
- {
- if (! is_stage1_5)
- /* Stage 2. */
-- installaddr = 0x8000;
-+ *installaddr = 0x8000;
- else
- /* Stage 1.5. */
-- installaddr = 0x2000;
-+ *installaddr = 0x2000;
- }
-
- *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR))
- = stage2_first_sector;
- *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS))
-- = installaddr;
-+ = *installaddr;
- *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT))
-- = installaddr >> 4;
-+ = *installaddr >> 4;
-
-- i = (int) stage2_first_buffer + SECTOR_SIZE - 4;
-+ i = (int) *stage2_first_buffer + SECTOR_SIZE - 4;
- while (*((unsigned long *) i))
- {
-- if (i < (int) stage2_first_buffer
-+ if (i < (int) *stage2_first_buffer
- || (*((int *) (i - 4)) & 0x80000000)
- || *((unsigned short *) i) >= 0xA00
- || *((short *) (i + 2)) == 0)
-@@ -2144,13 +2206,13 @@
- i -= 8;
- }
-
-- installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4;
-- installaddr += SECTOR_SIZE;
-+ *installlist = (int) *stage2_first_buffer + SECTOR_SIZE + 4;
-+ *installaddr += SECTOR_SIZE;
-
- /* Read the whole of Stage2 except for the first sector. */
- grub_seek (SECTOR_SIZE);
-
-- disk_read_hook = disk_read_blocklist_func;
-+ disk_read_hook = install_blocklist_helper;
- if (! grub_read (dummy, -1))
- goto fail;
-
-@@ -2233,7 +2295,7 @@
- /* Skip the first sector. */
- grub_seek (SECTOR_SIZE);
-
-- disk_read_hook = disk_read_savesect_func;
-+ disk_read_hook = install_savesect_helper;
- if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE)
- goto fail;
-
-@@ -2303,7 +2365,7 @@
- else
- #endif /* GRUB_UTIL */
- {
-- if (! devwrite (saved_sector - part_start, 1, stage2_buffer))
-+ if (! devwrite (*saved_sector - part_start, 1, stage2_buffer))
- goto fail;
- }
- }
-@@ -2325,7 +2387,7 @@
- goto fail;
- }
-
-- if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
-+ if (fwrite (*stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
- {
- fclose (fp);
- errnum = ERR_WRITE;
-@@ -2352,7 +2414,7 @@
- goto fail;
-
- if (! devwrite (stage2_first_sector - src_part_start, 1,
-- stage2_first_buffer))
-+ *stage2_first_buffer))
- goto fail;
-
- if (! devwrite (stage2_second_sector - src_part_start, 1,
---- grub-0.97/stage2/shared.h
-+++ grub-0.97/stage2/shared.h
-@@ -36,8 +36,8 @@
-
- /* Maybe redirect memory requests through grub_scratch_mem. */
- #ifdef GRUB_UTIL
--extern char *grub_scratch_mem;
--# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
-+extern void *grub_scratch_mem;
-+# define RAW_ADDR(x) ((x) + (unsigned long) grub_scratch_mem)
- # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
- #else
- # define RAW_ADDR(x) (x)
diff --git a/2gb_limit.patch b/2gb_limit.patch
new file mode 100644
index 000000000000..9468518b8f14
--- /dev/null
+++ b/2gb_limit.patch
@@ -0,0 +1,49 @@
+
+ Author: Goswin Brederlow
+ Status: pending
+ Updated by: Otavio Salvador - resync with 0.97 code
+
+Index: b/stage2/char_io.c
+===================================================================
+--- a/stage2/char_io.c
++++ b/stage2/char_io.c
+@@ -1231,13 +1231,13 @@
+ #endif /* ! STAGE1_5 */
+
+ int
+-memcheck (int addr, int len)
++memcheck (unsigned long int addr, unsigned long int len)
+ {
+ #ifdef GRUB_UTIL
+- auto int start_addr (void);
+- auto int end_addr (void);
++ auto unsigned long int start_addr (void);
++ auto int unsigned long end_addr (void);
+
+- auto int start_addr (void)
++ auto unsigned long int start_addr (void)
+ {
+ int ret;
+ # if defined(HAVE_START_SYMBOL)
+@@ -1248,7 +1248,7 @@
+ return ret;
+ }
+
+- auto int end_addr (void)
++ auto unsigned long int end_addr (void)
+ {
+ int ret;
+ # if defined(HAVE_END_SYMBOL)
+Index: b/stage2/shared.h
+===================================================================
+--- a/stage2/shared.h
++++ b/stage2/shared.h
+@@ -921,7 +921,7 @@
+ int nul_terminate (char *str);
+ int get_based_digit (int c, int base);
+ int safe_parse_maxint (char **str_ptr, int *myint_ptr);
+-int memcheck (int start, int len);
++int memcheck (unsigned long int start, unsigned long int len);
+ void grub_putstr (const char *str);
+
+ #ifndef NO_DECOMPRESSION
diff --git a/PKGBUILD b/PKGBUILD
index 8597ad9c8b3a..61686323b8c1 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,96 +1,147 @@
-# $Id: PKGBUILD 142375 2011-11-08 22:04:23Z ronald $
-# Maintainer: Ronald van Haren <ronald.archlinux.org>
-# Maintainer: ava1ar <mail(dot)avatar(at)gmail(dot)com>
+# Contributor: Ronald van Haren <ronald.archlinux.org>
+# Contributor: ava1ar <mail(dot)avatar(at)gmail(dot)com>
+# Maintainer: Wilken Gottwalt <wilken dot gottwalt at posteo dot net>
pkgname=grub-legacy
_srcname=grub
pkgver=0.97
-pkgrel=25
+pkgrel=29
pkgdesc="A GNU multiboot boot loader"
arch=('i686' 'x86_64')
license=('GPL')
url="http://www.gnu.org/software/grub/"
depends=('ncurses' 'diffutils' 'sed' 'lib32-glibc')
conflicts=('grub')
+makedepends=('autoconf' 'gcc')
makedepends_x86_64=('gcc-multilib')
optdepends=('xfsprogs: freezing of xfs /boot in install-grub script')
source=(ftp://alpha.gnu.org/gnu/grub/${_srcname}-${pkgver}.tar.gz{,.sig}
menu.lst
install-grub
- 040_all_grub-0.96-nxstack.patch
- 05-grub-0.97-initrdaddr.diff
- i2o.patch
- special-devices.patch
- more-raid.patch
+ snapshot.patch
+ menu.lst_gnu-hurd.patch
+ graphics.patch
+ raid.patch
+ raid_cciss.patch
+ xfs_freeze.patch
+ 2gb_limit.patch
+ grub-special_device_names.patch
+ grub-xvd_drives.patch
+ initrd_max_address.patch
+ splashimage_help.patch
+ grub-install_addsyncs.patch
+ grub-install_regexp.patch
+ grub-install_aoe_support.patch
+ grub-install_xvd.patch
+ geometry-26kernel.patch
+ print_func.patch
+ mprotect.patch
+ savedefault.patch
+ find-grub-dir.patch
intelmac.patch
- grub-inode-size.patch
- ext4.patch
- grub-0.97-ldflags-objcopy-remove-build-id.patch
- automake-pkglib.patch)
+ crossreference_manpages.patch
+ ext3_256byte_inode.patch
+ use_grub-probe_in_grub-install.patch
+ objcopy-absolute.patch
+ no-reorder-functions.patch
+ modern-automake.patch
+ no-combine-stack-adjustments.patch
+ no-pie.patch
+ static-vars-on-stack.patch
+ ext4_support.patch
+ ext4_fix_variable_sized_inodes.patch
+ ext4_block_group.patch)
backup=('boot/grub/menu.lst')
sha1sums=('2580626c4579bd99336d3af4482c346c95dac4fb'
'SKIP'
'33d43d48000b2027f9baec8fc99d33e0c4500c96'
'60e8f7e4c113b85165fd5d9cd724e8413a337a12'
- '157b81dbad3576536b08642242accfa1aeb093a9'
- 'adbb4685c98797ffb4dc83561ec75698991dddbd'
- 'f2e0dff29a7c8a45e90aa07298a1b2a9a9d29afc'
- 'c5e2c94ed0e759590b9eb38c9d979f075d19d7c0'
- '45fe668a3779664fb292591f426976b6c784d6c8'
- '066d7ab1ae442f88e94c9e4f1867ac6682965d06'
- '0436aa6fa0b6f768289172f983a3f4b69384629e'
- 'a36f34e51efed540f1ddafd78e9c9f6d83e4c8d4'
- '61c4b58d2eaa3c1561d8e9d8fc41341ce8882869'
- '776ed278eb8ff80e949834f763fad68b8741e7cd')
+ '395c1a4243d393059bc77a458158347dfd685484'
+ '9001de20e5b6eb32c9747cb6e71aae88f918b9fe'
+ '3d3281b2bf2b353db125297d058049209b4536fc'
+ '207a0a258cff448de804a26ec212c104b0c67dd4'
+ 'eb832d9ee7ab588cad67b1f613d60519d3ede547'
+ '9a938adbccbd42f47a3c4380d19bc0b67e9f4425'
+ 'e7e1f954a4b528bd1f987a1c8259da870c5c12ad'
+ '61c4b5ad2253ab856943c2c57c8505c880bd30d1'
+ '74e90f10baa2eafaf5e4cdb7c618c5d7fd83152f'
+ 'de68226dc1dbacf5315c4367a77e798d67bbbd97'
+ '4816712bcb6541ca85583a479b46ba578665ab3f'
+ '711fbc4099e41f3d44c8442cd674b46234560b9a'
+ '0dd7ab0c782530b6b4d62156cec96ce74074346a'
+ '7db04fe9c755f5e93aade57ed4d4ed62ee5de4be'
+ '127e098a0f301ef835fb7b341dc19a126974dff3'
+ '42fb758e3226869d05d2295d424f03eaa7704b1c'
+ 'caec864afccf8ae01c92b25d14d0e0daea4e51b1'
+ '0c0c8c1beed6684cd9cb54c40f5e785ea33b8692'
+ '92e5baef9bfae6c0d3122bf05138ad022f0bc04d'
+ '81ff955f91b25423ffed0cdf4ba31953fb2784c4'
+ 'a07861fbbb116b8052649d54abffe610a968c293'
+ '6a880733ad84ffebeef05515ebdf1ea451a4d054'
+ '02f13de04b932093d07f9a52adf20df7f0468654'
+ '8f6f13c0f752e20e690337488a178286ef1c381d'
+ '07558de2935f4eefec243a6966095b68aa3b6e70'
+ '610243204b776901a9696ab65c0729ec8fdb84d1'
+ 'c5aab6d3a5269054fc2e7f110ddc180d5595604d'
+ '721bb91d381ee3e51c2e2af0b4cfa004032e15b1'
+ '63a0eac56b9f3436a0baa522a3642d209956b54c'
+ '51b4dfd479491a3decc25d7ef66d434a7cbe12a2'
+ '028bcd02efa5cf6b1dab5e6cbc8690b50ea7425f'
+ '421ed77f2bb7aacce7ae558c2d97a4b209a07ca0'
+ '02a24bc24ab672d7d5e2b6ec2af6e8240b29fba9')
validpgpkeys=('1C2F76A695C9C8DCA55E4A431DDAE7A2FE06BDEF') # Yoshinori K. Okuji <SURNAME at gnu org>
-build() {
- cd ${srcdir}/${_srcname}-${pkgver}
-
- # optimizations break the build -- disable them
- # adding special devices to grub, patches are from fedora
- patch -Np1 -i ../special-devices.patch
- patch -Np1 -i ../i2o.patch
- patch -Np1 -i ../more-raid.patch
- patch -Np1 -i ../intelmac.patch
- # Add support for bigger inode size to e2fs_stage1_5
- patch -Np1 -i ../grub-inode-size.patch
- # Add ext4 support
- # http://www.mail-archive.com/bug-grub@gnu.org/msg11458.html
- patch -Np1 -i ../ext4.patch
- # binutils fix
- patch -Np1 -i ../grub-0.97-ldflags-objcopy-remove-build-id.patch
- # "pkglib" is a reserved keyword in automake fix
- patch -Np1 -i ../automake-pkglib.patch
+prepare() {
+ cd ${srcdir}/${_srcname}-${pkgver}
- sed -e'/^AC_PROG_CC/ a\AM_PROG_CC_C_O\ ' -i "${srcdir}/${_srcname}-${pkgver}/configure.ac"
- sed -e'/^AC_PROG_CC/ a\AM_PROG_AS\ ' -i "${srcdir}/${_srcname}-${pkgver}/configure.ac"
+ patch -Np1 -i ../snapshot.patch
+ patch -Np1 -i ../menu.lst_gnu-hurd.patch
+ patch -Np1 -i ../graphics.patch
+ patch -Np1 -i ../raid.patch
+ patch -Np1 -i ../raid_cciss.patch
+ patch -Np1 -i ../xfs_freeze.patch
+ patch -Np1 -i ../2gb_limit.patch
+ patch -Np1 -i ../grub-special_device_names.patch
+ patch -Np1 -i ../grub-xvd_drives.patch
+ patch -Np1 -i ../initrd_max_address.patch
+ patch -Np1 -i ../splashimage_help.patch
+ patch -Np1 -i ../grub-install_addsyncs.patch
+ patch -Np1 -i ../grub-install_regexp.patch
+ patch -Np1 -i ../grub-install_aoe_support.patch
+ patch -Np1 -i ../grub-install_xvd.patch
+ patch -Np1 -i ../geometry-26kernel.patch
+ patch -Np1 -i ../print_func.patch
+ patch -Np1 -i ../mprotect.patch
+ patch -Np1 -i ../savedefault.patch
+ patch -Np1 -i ../find-grub-dir.patch
+ patch -Np1 -i ../intelmac.patch
+ patch -Np1 -i ../crossreference_manpages.patch
+ patch -Np1 -i ../ext3_256byte_inode.patch
+ patch -Np1 -i ../use_grub-probe_in_grub-install.patch
+ patch -Np1 -i ../objcopy-absolute.patch
+ patch -Np1 -i ../no-reorder-functions.patch
+ patch -Np1 -i ../modern-automake.patch
+ patch -Np1 -i ../no-combine-stack-adjustments.patch
+ patch -Np1 -i ../no-pie.patch
+ patch -Np1 -i ../static-vars-on-stack.patch
+ patch -Np1 -i ../ext4_support.patch
+ patch -Np1 -i ../ext4_fix_variable_sized_inodes.patch
+ patch -Np1 -i ../ext4_block_group.patch
+}
- ## recreate ./configure script with the required changes in LDFLAGS and objcopy
- aclocal
- autoconf
- autoreconf -i
- automake
+build() {
+ cd ${srcdir}/${_srcname}-${pkgver}
- if [ "$CARCH" = "x86_64" ]; then
- # patch from gentoo for fixing a segfault
- patch -Np1 -i ../040_all_grub-0.96-nxstack.patch
- # patch from frugalware to make it boot when more than 2GB ram installed
- patch -Np1 -i ../05-grub-0.97-initrdaddr.diff
- CFLAGS+=" -static -fno-strict-aliasing -fno-stack-protector" ./configure --prefix=/usr --bindir=/usr/bin --sbindir=/usr/bin \
- --mandir=/usr/share/man --infodir=/usr/share/info
- else
- CFLAGS+=" -fno-strict-aliasing -fno-stack-protector" ./configure --prefix=/usr --bindir=/usr/bin --sbindir=/usr/bin \
- --mandir=/usr/share/man --infodir=/usr/share/info
- fi
+ autoreconf -fiv
+ CFLAGS= LDFLAGS= ./configure --prefix=/usr --libdir=/usr/lib --bindir=/usr/bin \
+ --sbindir=/usr/bin --mandir=/usr/share/man --infodir=/usr/share/info --disable-auto-linux-mem-opt
+ make -j1
}
package() {
- cd ${srcdir}/${_srcname}-${pkgver}
-
- CFLAGS= make
- make DESTDIR=${pkgdir} install
- install -D -m644 ../menu.lst ${pkgdir}/boot/grub/menu.lst
- install -D -m755 ../install-grub ${pkgdir}/usr/bin/install-grub
+ cd ${srcdir}/${_srcname}-${pkgver}
+ make DESTDIR=${pkgdir} install
+ install -D -m644 ../menu.lst ${pkgdir}/boot/grub/menu.lst
+ install -D -m755 ../install-grub ${pkgdir}/usr/bin/install-grub
}
diff --git a/crossreference_manpages.patch b/crossreference_manpages.patch
new file mode 100644
index 000000000000..3df646000758
--- /dev/null
+++ b/crossreference_manpages.patch
@@ -0,0 +1,48 @@
+Index: b/docs/Makefile.am
+===================================================================
+--- a/docs/Makefile.am
++++ b/docs/Makefile.am
+@@ -37,14 +37,14 @@
+ $(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+ if MAINTAINER_MODE
+-$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
++$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN) $(srcdir)/grub.8.additions $(srcdir)/help2man.additions
+ $(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
+- --section=8 --output=$@ $<
++ --section=8 --include=$@.additions --include=$(srcdir)/help2man.additions --output=$@ $<
+
+-$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
++$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN) $(srcdir)/grub-install.8.additions $(srcdir)/help2man.additions
+ chmod 755 $<
+ $(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
+- --section=8 --output=$@ $<
++ --section=8 --include=$@.additions --include=$(srcdir)/help2man.additions --output=$@ $<
+
+ $(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
+ $(PERL) $(srcdir)/$(HELP2MAN) \
+Index: b/docs/grub.8.additions
+===================================================================
+--- /dev/null
++++ b/docs/grub.8.additions
+@@ -0,0 +1,3 @@
++[SEE ALSO]
++.BR update-grub (8),
++.BR grub-install (8).
+Index: b/docs/grub-install.8.additions
+===================================================================
+--- /dev/null
++++ b/docs/grub-install.8.additions
+@@ -0,0 +1,3 @@
++[SEE ALSO]
++.BR grub (8),
++.BR update-grub (8).
+Index: b/docs/help2man.additions
+===================================================================
+--- /dev/null
++++ b/docs/help2man.additions
+@@ -0,0 +1,4 @@
++[>SEE ALSO]
++You may need to install the
++.B grub\-legacy\-doc
++package.
diff --git a/grub-inode-size.patch b/ext3_256byte_inode.patch
index f5ceb110bff0..0a409d45742d 100644
--- a/grub-inode-size.patch
+++ b/ext3_256byte_inode.patch
@@ -1,6 +1,10 @@
-diff -Naur grub-0.97-800/stage2/fsys_ext2fs.c grub-0.97-810/stage2/fsys_ext2fs.c
---- grub-0.97-800/stage2/fsys_ext2fs.c 2008-07-21 00:40:21.668879475 -0600
-+++ grub-0.97-810/stage2/fsys_ext2fs.c 2008-07-21 01:01:11.063953773 -0600
+
+Patch from Red Hat. See #463236, #463123 (and #491076 for the reviewed version)
+
+Index: b/stage2/fsys_ext2fs.c
+===================================================================
+--- a/stage2/fsys_ext2fs.c
++++ b/stage2/fsys_ext2fs.c
@@ -79,7 +79,52 @@
__u32 s_rev_level; /* Revision level */
__u16 s_def_resuid; /* Default uid for reserved blocks */
@@ -59,12 +63,12 @@ diff -Naur grub-0.97-800/stage2/fsys_ext2fs.c grub-0.97-810/stage2/fsys_ext2fs.c
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s)))
-+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
-+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
++#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
++#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
+#define EXT2_GOOD_OLD_INODE_SIZE 128
-+#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+ EXT2_GOOD_OLD_INODE_SIZE : \
-+ (s)->s_inode_size)
++#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
++ EXT2_GOOD_OLD_INODE_SIZE : \
++ (s)->s_inode_size)
+#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
+
/* linux/ext2_fs.h */
@@ -97,4 +101,3 @@ diff -Naur grub-0.97-800/stage2/fsys_ext2fs.c grub-0.97-810/stage2/fsys_ext2fs.c
printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
-
diff --git a/ext4_block_group.patch b/ext4_block_group.patch
new file mode 100644
index 000000000000..37f161a08ffe
--- /dev/null
+++ b/ext4_block_group.patch
@@ -0,0 +1,177 @@
+Description: Fix ext4 block group handling
+ Backported distantly from grub2, particularly:
+ https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e20aa39ea4298011ba716087713cff26c6c52006
+Author: Colin Watson <cjwatson@debian.org>
+Bug-Debian: https://bugs.debian.org/511121
+Last-Update: 2018-10-25
+
+Index: b/stage2/fsys_ext2fs.c
+===================================================================
+--- a/stage2/fsys_ext2fs.c
++++ b/stage2/fsys_ext2fs.c
+@@ -41,6 +41,8 @@
+ typedef unsigned short __u16;
+ typedef __signed__ int __s32;
+ typedef unsigned int __u32;
++typedef __signed__ long long __s64;
++typedef unsigned long long __u64;
+
+ /*
+ * Constants relative to the data blocks, from ext2_fs.h
+@@ -51,6 +53,13 @@
+ #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+ #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
++/* Superblock filesystem feature flags (RO compatible) */
++#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
++
++/* Superblock filesystem feature flags (back-incompatible) */
++#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
++#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
++
+ /* Inode flags */
+ #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
+
+@@ -122,7 +131,7 @@
+ __u32 s_hash_seed[4]; /* HTREE hash seed */
+ __u8 s_def_hash_version; /* Default hash version to use */
+ __u8 s_jnl_backup_type; /* Default type of journal backup */
+- __u16 s_reserved_word_pad;
++ __u16 s_desc_size; /* Group desc. size: INCOMPAT_64BIT */
+ __u32 s_default_mount_opts;
+ __u32 s_first_meta_bg; /* First metablock group */
+ __u32 s_mkfs_time; /* When the filesystem was created */
+@@ -284,13 +293,20 @@
+ #define PATH_MAX 1024 /* include/linux/limits.h */
+ #define MAX_LINK_COUNT 5 /* number of symbolic links to follow */
+
++/* Information about a "mounted" ext2 filesystem. */
++struct ext2_data
++ {
++ int log_group_desc_size;
++ };
++
+ /* made up, these are pointers into FSYS_BUF */
+ /* read once, always stays there: */
+ #define SUPERBLOCK \
+ ((struct ext2_super_block *)(FSYS_BUF))
++#define FS_DATA \
++ ((struct ext2_data *)((int)SUPERBLOCK + sizeof(struct ext2_super_block)))
+ #define GROUP_DESC \
+- ((struct ext2_group_desc *) \
+- ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))
++ ((int)((int)FS_DATA + sizeof(struct ext2_data)))
+ #define INODE \
+ ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK)))
+ #define DATABLOCK1 \
+@@ -357,6 +373,20 @@
+ || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
+ retval = 0;
+
++ if (SUPERBLOCK->s_rev_level != EXT2_GOOD_OLD_REV
++ && (SUPERBLOCK->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
++ && SUPERBLOCK->s_desc_size != 0
++ && (SUPERBLOCK->s_desc_size & (SUPERBLOCK->s_desc_size - 1)) == 0
++ && (SUPERBLOCK->s_desc_size & 0x1fe0))
++ {
++ __u16 b = SUPERBLOCK->s_desc_size;
++ for (FS_DATA->log_group_desc_size = 0;
++ b != (1 << FS_DATA->log_group_desc_size);
++ FS_DATA->log_group_desc_size++);
++ }
++ else
++ FS_DATA->log_group_desc_size = 5;
++
+ return retval;
+ }
+
+@@ -623,6 +653,32 @@
+ return INODE->i_blocks == ea_blocks;
+ }
+
++static int
++is_power_of (__u64 a, __u64 b)
++{
++ __u64 c;
++ /* Prevent overflow assuming b < 8. */
++ if (a >= (1LL << 60))
++ return 0;
++ for (c = 1; c <= a; c *= b);
++ return (c == a);
++}
++
++static int
++ext2fs_group_has_super_block (__u64 group)
++{
++ if (!(SUPERBLOCK->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
++ return 1;
++ /* Algorithm looked up in Linux source. */
++ if (group <= 1)
++ return 1;
++ /* Even number is never a power of odd number. */
++ if (!(group & 1))
++ return 0;
++ return (is_power_of (group, 7) || is_power_of (group, 5) ||
++ is_power_of (group, 3));
++}
++
+ /* preconditions: ext2fs_mount already executed, therefore supblk in buffer
+ * known as SUPERBLOCK
+ * returns: 0 if error, nonzero iff we were able to find the file successfully
+@@ -635,8 +691,9 @@
+ {
+ int current_ino = EXT2_ROOT_INO; /* start at the root */
+ int updir_ino = current_ino; /* the parent of the current directory */
+- int group_id; /* which group the inode is in */
+- int group_desc; /* fs pointer to that group */
++ __u64 full_offset;
++ __u64 group_id; /* which group the inode is in */
++ __u64 group_desc; /* fs pointer to that group */
+ int desc; /* index within that group */
+ int ino_blk; /* fs pointer of the inode's information */
+ int str_chk = 0; /* used to hold the results of a string compare */
+@@ -675,23 +732,37 @@
+
+ /* look up an inode */
+ group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);
+- group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
+- desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1);
++ full_offset = group_id << FS_DATA->log_group_desc_size;
++ group_desc = full_offset >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
++ desc = full_offset & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
++ if ((SUPERBLOCK->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
++ && group_desc >= SUPERBLOCK->s_first_meta_bg)
++ {
++ __u64 first_block_group;
++ /* Find the first block group for which a descriptor is stored in
++ the given block. */
++ first_block_group = (group_desc << (EXT2_BLOCK_SIZE_BITS (SUPERBLOCK)
++ - FS_DATA->log_group_desc_size));
++ group_desc = first_block_group * SUPERBLOCK->s_blocks_per_group;
++ if (ext2fs_group_has_super_block (first_block_group))
++ group_desc++;
++ }
++ else
++ /* Superblock. */
++ group_desc++;
+ #ifdef E2DEBUG
+ printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group,
+ EXT2_DESC_PER_BLOCK (SUPERBLOCK));
+ printf ("group_id=%d group_desc=%d desc=%d\n", group_id, group_desc, desc);
+ #endif /* E2DEBUG */
+- if (!ext2_rdfsb (
+- (WHICH_SUPER + group_desc + SUPERBLOCK->s_first_data_block),
+- (int) GROUP_DESC))
++ if (!ext2_rdfsb (SUPERBLOCK->s_first_data_block + group_desc, GROUP_DESC))
+ {
+ return 0;
+ }
+- gdp = GROUP_DESC;
++ gdp = (struct ext2_group_desc *)(GROUP_DESC + desc);
+ inodes_per_block = EXT2_BLOCK_SIZE (SUPERBLOCK) / EXT2_INODE_SIZE(SUPERBLOCK);
+ inode_offset = ((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group));
+- ino_blk = gdp[desc].bg_inode_table + (inode_offset / inodes_per_block);
++ ino_blk = gdp->bg_inode_table + (inode_offset / inodes_per_block);
+ #ifdef E2DEBUG
+ printf ("inode table fsblock=%d\n", ino_blk);
+ #endif /* E2DEBUG */
diff --git a/ext4_fix_variable_sized_inodes.patch b/ext4_fix_variable_sized_inodes.patch
new file mode 100644
index 000000000000..d16802fb8fcc
--- /dev/null
+++ b/ext4_fix_variable_sized_inodes.patch
@@ -0,0 +1,33 @@
+Description: Add support for ext4 variable sized inodes
+ This is backwardly compatible with ext2/ext3 fixed sized inodes.
+Author: Colin King <colin.king@canonical.com>
+Bug-Debian: https://bugs.debian.org/511121
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/345488
+Last-Update: 2018-10-25
+
+Index: b/stage2/fsys_ext2fs.c
+===================================================================
+--- a/stage2/fsys_ext2fs.c
++++ b/stage2/fsys_ext2fs.c
+@@ -652,6 +652,8 @@
+ int off; /* offset within block of directory entry (off mod blocksize) */
+ int loc; /* location within a directory */
+ int blk; /* which data blk within dir entry (off div blocksize) */
++ int inodes_per_block; /* number of inodes in each block */
++ int inode_offset; /* inode offset in block */
+ long map; /* fs pointer of a particular block from dir entry */
+ struct ext2_dir_entry *dp; /* pointer to directory entry */
+ #ifdef E2DEBUG
+@@ -687,9 +689,9 @@
+ return 0;
+ }
+ gdp = GROUP_DESC;
+- ino_blk = gdp[desc].bg_inode_table +
+- (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
+- >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
++ inodes_per_block = EXT2_BLOCK_SIZE (SUPERBLOCK) / EXT2_INODE_SIZE(SUPERBLOCK);
++ inode_offset = ((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group));
++ ino_blk = gdp[desc].bg_inode_table + (inode_offset / inodes_per_block);
+ #ifdef E2DEBUG
+ printf ("inode table fsblock=%d\n", ino_blk);
+ #endif /* E2DEBUG */
diff --git a/ext4.patch b/ext4_support.patch
index 8a2f9bdb0a79..aeef4f4ad48c 100644
--- a/ext4.patch
+++ b/ext4_support.patch
@@ -1,8 +1,14 @@
-diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
---- grub-0.97/stage2/fsys_ext2fs.c 2004-08-08 20:19:18.000000000 +0200
-+++ grub-0.97-patch/stage2/fsys_ext2fs.c 2007-12-29 16:25:19.000000000
-+0100
-@@ -51,6 +51,9 @@ typedef unsigned int __u32;
+Description: Allow booting from ext4 partitions
+Author: Quentin Godfroy <godfroy@clipper.ens.fr>
+Bug-Debian: https://bugs.debian.org/511121
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/314350
+Last-Update: 2018-10-25
+
+Index: b/stage2/fsys_ext2fs.c
+===================================================================
+--- a/stage2/fsys_ext2fs.c
++++ b/stage2/fsys_ext2fs.c
+@@ -51,6 +51,9 @@
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
@@ -12,7 +18,7 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
/* include/linux/ext2_fs.h */
struct ext2_super_block
{
-@@ -191,6 +194,42 @@ struct ext2_dir_entry
+@@ -236,6 +239,42 @@
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
~EXT2_DIR_ROUND)
@@ -55,12 +61,12 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
/* ext2/super.c */
#define log2(n) ffz(~(n))
-@@ -279,6 +318,26 @@ ext2_rdfsb (int fsblock, int buffer)
- EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
+@@ -332,6 +371,27 @@
+ EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
}
+/* Walk through extents index tree to find the good leaf */
-+static struct ext4_extent_header *
++static struct ext4_extent_header *
+ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block)
+{
+ int i;
@@ -79,32 +85,42 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
+ return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block));
+}
+
++
/* from
ext2/inode.c:ext2_bmap()
*/
---- grub-0.97/stage2/fsys_ext2fs.c~ 2008-12-28 20:19:00.000000000 +0100
-+++ grub-0.97/stage2/fsys_ext2fs.c 2008-12-28 20:19:00.000000000 +0100
-@@ -366,83 +366,106 @@
- }
+@@ -340,7 +400,6 @@
+ static int
+ ext2fs_block_map (int logical_block)
+ {
+-
+ #ifdef E2DEBUG
+ unsigned char *i;
+ for (i = (unsigned char *) INODE;
+@@ -361,82 +420,106 @@
printf ("logical block %d\n", logical_block);
#endif /* E2DEBUG */
--
+
- /* if it is directly pointed to by the inode, return that physical addr */
- if (logical_block < EXT2_NDIR_BLOCKS)
-- {
--#ifdef E2DEBUG
++ if (!(INODE->i_flags & EXT4_EXTENTS_FL))
+ {
++ /* if it is directly pointed to by the inode, return that physical addr */
++ if (logical_block < EXT2_NDIR_BLOCKS)
++ {
+ #ifdef E2DEBUG
- printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
- printf ("returning %d\n", INODE->i_block[logical_block]);
--#endif /* E2DEBUG */
++ printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
++ printf ("returning %d\n", INODE->i_block[logical_block]);
+ #endif /* E2DEBUG */
- return INODE->i_block[logical_block];
- }
- /* else */
- logical_block -= EXT2_NDIR_BLOCKS;
- /* try the indirect block */
- if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
-+ /* standard ext2 inode */
-+ if (!(INODE->i_flags & EXT4_EXTENTS_FL))
- {
+- {
- if (mapblock1 != 1
- && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
- {
@@ -136,13 +152,6 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
- return -1;
- }
- mapblock2 = bnum;
-+ /* if it is directly pointed to by the inode, return that physical addr */
-+ if (logical_block < EXT2_NDIR_BLOCKS)
-+ {
-+#ifdef E2DEBUG
-+ printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
-+ printf ("returning %d\n", INODE->i_block[logical_block]);
-+#endif /* E2DEBUG */
+ return INODE->i_block[logical_block];
+ }
+ /* else */
@@ -150,12 +159,11 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
+ /* try the indirect block */
+ if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
+ {
-+ if (mapblock1 != 1
-+ && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
-+ {
-+ errnum = ERR_FSYS_CORRUPT;
-+ return -1;
-+ }
++ if (mapblock1 != 1 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
+ mapblock1 = 1;
+ return ((__u32 *) DATABLOCK1)[logical_block];
+ }
@@ -165,21 +173,20 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
+ if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
+ {
+ int bnum;
-+ if (mapblock1 != 2
-+ && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
-+ {
-+ errnum = ERR_FSYS_CORRUPT;
-+ return -1;
-+ }
++ if (mapblock1 != 2 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
+ mapblock1 = 2;
+ if ((bnum = (((__u32 *) DATABLOCK1)
+ [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))
+ != mapblock2
+ && !ext2_rdfsb (bnum, DATABLOCK2))
-+ {
-+ errnum = ERR_FSYS_CORRUPT;
-+ return -1;
-+ }
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
+ mapblock2 = bnum;
+ return ((__u32 *) DATABLOCK2)
+ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
@@ -210,9 +217,11 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
+ errnum = ERR_FSYS_CORRUPT;
+ return -1;
+ }
++
return ((__u32 *) DATABLOCK2)
- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
-- }
++ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
+ }
- /* else */
- mapblock2 = -1;
- logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
@@ -221,8 +230,7 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
- {
- errnum = ERR_FSYS_CORRUPT;
- return -1;
-+ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
- }
+- }
- mapblock1 = 3;
- if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
- [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
@@ -236,23 +244,25 @@ diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
- [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
- & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
- DATABLOCK2))
-+ /* inode is in extents format */
-+ else
++ /* inode is in extents format */
++ else
{
+ int i;
-+ struct ext4_extent_header *extent_hdr = ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block);
++ struct ext4_extent_header *extent_hdr =
++ ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block);
+ struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1);
+ if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC)
-+ {
-+ errnum = ERR_FSYS_CORRUPT;
-+ return -1;
-+ }
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
+ for (i = 0; i<extent_hdr->eh_entries; i++)
+ {
+ if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15))
+ return (logical_block - extent[i].ee_block + extent[i].ee_start);
+ }
+ /* We should not arrive here */
++
errnum = ERR_FSYS_CORRUPT;
return -1;
}
diff --git a/find-grub-dir.patch b/find-grub-dir.patch
new file mode 100644
index 000000000000..f891c84568cf
--- /dev/null
+++ b/find-grub-dir.patch
@@ -0,0 +1,56 @@
+Index: b/util/grub-set-default.in
+===================================================================
+--- a/util/grub-set-default.in
++++ b/util/grub-set-default.in
+@@ -74,18 +74,45 @@
+ exit 1
+ fi
+
++find_grub_dir ()
++{
++ echo -n "Searching for GRUB installation directory ... " >&2
++
++ for d in $grub_dirs ; do
++ if [ -d "$d" ] ; then
++ grub_dir="$d"
++ break
++ fi
++ done
++
++ if [ -z "$grub_dir" ] ; then
++ abort "No GRUB directory found.\n###"
++ else
++ echo "found: $grub_dir" >&2
++ fi
++
++ echo $grub_dir
++}
++
++grub_dirs="/boot/grub /boot/boot/grub"
++
+ # Determine the GRUB directory. This is different among OSes.
+-grubdir=${rootdir}/boot/grub
+-if test -d ${grubdir}; then
++# if rootdir has been informed use it or find grubdir otherwise
++if [ -n "${rootdir}" ]; then
++ grubdir=${rootdir}/boot/grub
++ if test -d ${grubdir}; then
+ :
+-else
++ else
+ grubdir=${rootdir}/grub
+ if test -d ${grubdir}; then
+- :
++ :
+ else
+- echo "No GRUB directory found under ${rootdir}/" 1>&2
+- exit 1
++ echo "No GRUB directory found under ${rootdir}/" 1>&2
++ exit 1
+ fi
++ fi
++else
++ grubdir=$(find_grub_dir)
+ fi
+
+ file=${grubdir}/default
diff --git a/geometry-26kernel.patch b/geometry-26kernel.patch
new file mode 100644
index 000000000000..91d85281887a
--- /dev/null
+++ b/geometry-26kernel.patch
@@ -0,0 +1,236 @@
+
+ Date: 2005-11-11
+ Author: Otavio Salvador
+ Comment: Stolen from Fedora grub package.
+ Put geometry discover inside of grub code since kernel 2.6
+ doesn't do that anymore.
+
+Index: b/lib/device.c
+===================================================================
+--- a/lib/device.c
++++ b/lib/device.c
+@@ -131,6 +131,152 @@
+ #include <shared.h>
+ #include <device.h>
+
++#if defined(__linux__)
++/* The 2.6 kernel has removed all of the geometry handling for IDE drives
++ * that did fixups for LBA, etc. This means that the geometry we get
++ * with the ioctl has a good chance of being wrong. So, we get to
++ * also know about partition tables and try to read what the geometry
++ * is there. *grumble* Very closely based on code from cfdisk
++ */
++static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) {
++ struct hd_geometry hdg;
++
++ if (ioctl (fd, HDIO_GETGEO, &hdg))
++ return;
++
++ *cyl = hdg.cylinders;
++ *heads = hdg.heads;
++ *sectors = hdg.sectors;
++}
++
++struct partition {
++ unsigned char boot_ind; /* 0x80 - active */
++ unsigned char head; /* starting head */
++ unsigned char sector; /* starting sector */
++ unsigned char cyl; /* starting cylinder */
++ unsigned char sys_ind; /* What partition type */
++ unsigned char end_head; /* end head */
++ unsigned char end_sector; /* end sector */
++ unsigned char end_cyl; /* end cylinder */
++ unsigned char start4[4]; /* starting sector counting from 0 */
++ unsigned char size4[4]; /* nr of sectors in partition */
++};
++
++#define ALIGNMENT 2
++typedef union {
++ struct {
++ unsigned char align[ALIGNMENT];
++ unsigned char b[SECTOR_SIZE];
++ } c;
++ struct {
++ unsigned char align[ALIGNMENT];
++ unsigned char buffer[0x1BE];
++ struct partition part[4];
++ unsigned char magicflag[2];
++ } p;
++} partition_table;
++
++#define PART_TABLE_FLAG0 0x55
++#define PART_TABLE_FLAG1 0xAA
++
++static void
++get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads,
++ int *sectors) {
++ struct partition *p;
++ int i,h,s,hh,ss;
++ int first = 1;
++ int bad = 0;
++
++ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
++ bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
++ /* Matthew Wilcox: slightly friendlier version of
++ fatal(_("Bad signature on partition table"), 3);
++ */
++ fprintf(stderr, "Unknown partition table signature\n");
++ return;
++ }
++
++ hh = ss = 0;
++ for (i=0; i<4; i++) {
++ p = &(bufp->p.part[i]);
++ if (p->sys_ind != 0) {
++ h = p->end_head + 1;
++ s = (p->end_sector & 077);
++ if (first) {
++ hh = h;
++ ss = s;
++ first = 0;
++ } else if (hh != h || ss != s)
++ bad = 1;
++ }
++ }
++
++ if (!first && !bad) {
++ *heads = hh;
++ *sectors = ss;
++ }
++}
++
++static long long my_lseek (unsigned int fd, long long offset,
++ unsigned int origin)
++{
++#if defined(__linux__) && (!defined(__GLIBC__) || \
++ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
++ /* Maybe libc doesn't have large file support. */
++ loff_t offset, result;
++ static int _llseek (uint filedes, ulong hi, ulong lo,
++ loff_t *res, uint wh);
++ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
++ loff_t *, res, uint, wh);
++
++ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0)
++ return (long long) -1;
++ return result;
++#else
++ return lseek(fd, offset, SEEK_SET);
++#endif
++}
++
++static void get_linux_geometry (int fd, struct geometry *geom) {
++ long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0;
++ long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0;
++ partition_table bufp;
++ char *buff, *buf_unaligned;
++
++ buf_unaligned = malloc(sizeof(partition_table) + 4095);
++ buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) &
++ (~(4096-1)));
++
++ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors);
++
++ if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) {
++ fprintf(stderr, "Unable to seek");
++ }
++
++ if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) {
++ memcpy(bufp.c.b, buff, SECTOR_SIZE);
++ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors);
++ } else {
++ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno));
++ }
++
++ if (pt_head && pt_sectors) {
++ int cyl_size;
++
++ geom->heads = pt_head;
++ geom->sectors = pt_sectors;
++ cyl_size = pt_head * pt_sectors;
++ geom->cylinders = geom->total_sectors/cyl_size;
++ } else {
++ geom->heads = kern_head;
++ geom->sectors = kern_sectors;
++ geom->cylinders = kern_cyl;
++ }
++
++ return;
++}
++#endif
++
+ /* Get the geometry of a drive DRIVE. */
+ void
+ get_drive_geometry (struct geometry *geom, char **map, int drive)
+@@ -151,19 +297,15 @@
+ #if defined(__linux__)
+ /* Linux */
+ {
+- struct hd_geometry hdg;
+ unsigned long long nr;
+
+- if (ioctl (fd, HDIO_GETGEO, &hdg))
+- goto fail;
+-
+ if (ioctl (fd, BLKGETSIZE64, &nr))
+ goto fail;
+
+ /* Got the geometry, so save it. */
+- geom->cylinders = hdg.cylinders;
+- geom->heads = hdg.heads;
+- geom->sectors = hdg.sectors;
++ get_linux_geometry(fd, geom);
++ if (!geom->heads && !geom->cylinders && !geom->sectors)
++ goto fail;
+ geom->total_sectors = nr / 512;
+
+ goto success;
+@@ -984,6 +1126,7 @@
+ {
+ char dev[PATH_MAX]; /* XXX */
+ int fd;
++ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+
+ if ((partition & 0x00FF00) != 0x00FF00)
+ {
+@@ -1018,35 +1161,13 @@
+ errnum = ERR_NO_PART;
+ return 0;
+ }
+-
+-#if defined(__linux__) && (!defined(__GLIBC__) || \
+- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
+- /* Maybe libc doesn't have large file support. */
+- {
+- loff_t offset, result;
+- static int _llseek (uint filedes, ulong hi, ulong lo,
+- loff_t *res, uint wh);
+- _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
+- loff_t *, res, uint, wh);
+
+- offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
+- if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
+- {
+- errnum = ERR_DEV_VALUES;
+- return 0;
+- }
+- }
+-#else
+- {
+- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+
+- if (lseek (fd, offset, SEEK_SET) != offset)
+- {
+- errnum = ERR_DEV_VALUES;
+- return 0;
+- }
+- }
+-#endif
++ if (my_lseek(fd, offset, SEEK_SET) != offset)
++ {
++ errnum = ERR_DEV_VALUES;
++ return 0;
++ }
+
+ if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
+ {
diff --git a/graphics.patch b/graphics.patch
new file mode 100644
index 000000000000..e9dbc15e9717
--- /dev/null
+++ b/graphics.patch
@@ -0,0 +1,2310 @@
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -606,6 +606,11 @@
+ [ --enable-diskless enable diskless support])
+ AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
+
++dnl Graphical splashscreen support
++AC_ARG_ENABLE(graphics,
++ [ --disable-graphics disable graphics terminal support])
++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
++
+ dnl Hercules terminal
+ AC_ARG_ENABLE(hercules,
+ [ --disable-hercules disable hercules terminal support])
+Index: b/stage2/asm.S
+===================================================================
+--- a/stage2/asm.S
++++ b/stage2/asm.S
+@@ -2216,7 +2216,304 @@
+ pop %ebx
+ pop %ebp
+ ret
+-
++
++
++/* graphics mode functions */
++#ifdef SUPPORT_GRAPHICS
++VARIABLE(cursorX)
++.word 0
++VARIABLE(cursorY)
++.word 0
++VARIABLE(cursorCount)
++.word 0
++VARIABLE(cursorBuf)
++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++
++
++/*
++ * set_int1c_handler(void)
++ */
++ENTRY(set_int1c_handler)
++ pushl %edi
++
++ /* save the original int1c handler */
++ movl $0x70, %edi
++ movw (%edi), %ax
++ movw %ax, ABS(int1c_offset)
++ movw 2(%edi), %ax
++ movw %ax, ABS(int1c_segment)
++
++ /* save the new int1c handler */
++ movw $ABS(int1c_handler), %ax
++ movw %ax, (%edi)
++ xorw %ax, %ax
++ movw %ax, 2(%edi)
++
++ popl %edi
++ ret
++
++
++/*
++ * unset_int1c_handler(void)
++ */
++ENTRY(unset_int1c_handler)
++ pushl %edi
++
++ /* check if int1c_handler is set */
++ movl $0x70, %edi
++ movw $ABS(int1c_handler), %ax
++ cmpw %ax, (%edi)
++ jne int1c_1
++ xorw %ax, %ax
++ cmpw %ax, 2(%edi)
++ jne int1c_1
++
++ /* restore the original */
++ movw ABS(int1c_offset), %ax
++ movw %ax, (%edi)
++ movw ABS(int1c_segment), %ax
++ movw %ax, 2(%edi)
++
++int1c_1:
++ popl %edi
++ ret
++
++
++/*
++ * blinks graphics cursor
++ */
++ .code16
++write_data:
++ movw $0, %ax
++ movw %ax, %ds
++
++ mov $0xA000, %ax /* video in es:di */
++ mov %ax, %es
++ mov $80, %ax
++ movw $ABS(cursorY), %si
++ mov %ds:(%si), %bx
++ mul %bx
++ movw $ABS(cursorX), %si
++ mov %ds:(%si), %bx
++ shr $3, %bx /* %bx /= 8 */
++ add %bx, %ax
++ mov %ax, %di
++
++ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */
++
++ /* prepare for data moving */
++ mov $16, %dx /* altura da fonte */
++ mov $80, %bx /* bytes por linha */
++
++write_loop:
++ movb %ds:(%si), %al
++ xorb $0xff, %al
++ movb %al, %ds:(%si) /* invert cursorBuf */
++ movb %al, %es:(%di) /* write to video */
++ add %bx, %di
++ inc %si
++ dec %dx
++ jg write_loop
++ ret
++
++int1c_handler:
++ pusha
++ mov $0, %ax
++ mov %ax, %ds
++ mov $ABS(cursorCount), %si
++ mov %ds:(%si), %ax
++ inc %ax
++ mov %ax, %ds:(%si)
++ cmp $9, %ax
++ jne int1c_done
++
++ mov $0, %ax
++ mov %ax, %ds:(%si)
++ call write_data
++
++int1c_done:
++ popa
++ iret
++ /* call previous int1c handler */
++ /* ljmp */
++ .byte 0xea
++int1c_offset: .word 0
++int1c_segment: .word 0
++ .code32
++
++
++/*
++ * unsigned char set_videomode(unsigned char mode)
++ * BIOS call "INT 10H Function 0h" to set video mode
++ * Call with %ah = 0x0
++ * %al = video mode
++ * Returns old videomode.
++ */
++ENTRY(set_videomode)
++ pushl %ebp
++ movl %esp,%ebp
++ pushl %ebx
++ pushl %ecx
++
++ movb 8(%ebp), %cl
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ xorb %al, %al
++ movb $0xf, %ah
++ int $0x10 /* Get Current Video mode */
++ movb %al, %ch
++ xorb %ah, %ah
++ movb %cl, %al
++ int $0x10 /* Set Video mode */
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movb %ch, %al
++
++ popl %ecx
++ popl %ebx
++ popl %ebp
++ ret
++
++
++/*
++ * int get_videomode()
++ * BIOS call "INT 10H Function 0Fh" to get current video mode
++ * Call with %al = 0x0
++ * %ah = 0xF
++ * Returns current videomode.
++ */
++ENTRY(get_videomode)
++ pushl %ebp
++ movl %esp,%ebp
++ pushl %ebx
++ pushl %ecx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ xorb %al, %al
++ movb $0xF, %ah
++ int $0x10 /* Get Current Video mode */
++ movb %al, %cl /* For now we only want display mode */
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movb %cl, %al
++
++ popl %ecx
++ popl %ebx
++ popl %ebp
++ ret
++
++
++/*
++ * unsigned char * graphics_get_font()
++ * BIOS call "INT 10H Function 11h" to set font
++ * Call with %ah = 0x11
++ */
++ENTRY(graphics_get_font)
++ push %ebp
++ push %ebx
++ push %ecx
++ push %edx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ movw $0x1130, %ax
++ movb $6, %bh /* font 8x16 */
++ int $0x10
++ movw %bp, %dx
++ movw %es, %cx
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movw %cx, %ax
++ shll $4, %eax
++ movw %dx, %ax
++
++ pop %edx
++ pop %ecx
++ pop %ebx
++ pop %ebp
++ ret
++
++
++/*
++ * graphics_set_palette(index, red, green, blue)
++ * BIOS call "INT 10H Function 10h" to set individual dac register
++ * Call with %ah = 0x10
++ * %bx = register number
++ * %ch = new value for green (0-63)
++ * %cl = new value for blue (0-63)
++ * %dh = new value for red (0-63)
++ */
++
++ENTRY(graphics_set_palette)
++ push %ebp
++ push %eax
++ push %ebx
++ push %ecx
++ push %edx
++
++ movw $0x3c8, %bx /* address write mode register */
++
++ /* wait vertical retrace */
++ movw $0x3da, %dx
++l1b:
++ inb %dx, %al /* wait vertical active display */
++ test $8, %al
++ jnz l1b
++
++l2b:
++ inb %dx, %al /* wait vertical retrace */
++ test $8, %al
++ jnz l2b
++
++ mov %bx, %dx
++ movb 0x18(%esp), %al /* index */
++ outb %al, %dx
++ inc %dx
++
++ movb 0x1c(%esp), %al /* red */
++ outb %al, %dx
++
++ movb 0x20(%esp), %al /* green */
++ outb %al, %dx
++
++ movb 0x24(%esp), %al /* blue */
++ outb %al, %dx
++
++ movw 0x18(%esp), %bx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ movb %bl, %bh
++ movw $0x1000, %ax
++ int $0x10
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ pop %edx
++ pop %ecx
++ pop %ebx
++ pop %eax
++ pop %ebp
++ ret
++#endif /* SUPPORT_GRAPHICS */
++
++
+ /*
+ * getrtsecs()
+ * if a seconds value can be read, read it and return it (BCD),
+Index: b/stage2/builtins.c
+===================================================================
+--- a/stage2/builtins.c
++++ b/stage2/builtins.c
+@@ -28,6 +28,10 @@
+ #include <filesys.h>
+ #include <term.h>
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifdef SUPPORT_NETBOOT
+ # define GRUB 1
+ # include <etherboot.h>
+@@ -237,12 +241,22 @@
+ static int
+ boot_func (char *arg, int flags)
+ {
++ struct term_entry *prev_term = current_term;
+ /* Clear the int15 handler if we can boot the kernel successfully.
+ This assumes that the boot code never fails only if KERNEL_TYPE is
+ not KERNEL_TYPE_NONE. Is this assumption is bad? */
+ if (kernel_type != KERNEL_TYPE_NONE)
+ unset_int15_handler ();
+
++ /* if our terminal needed initialization, we should shut it down
++ * before booting the kernel, but we want to save what it was so
++ * we can come back if needed */
++ if (current_term->shutdown)
++ {
++ current_term->shutdown();
++ current_term = term_table; /* assumption: console is first */
++ }
++
+ #ifdef SUPPORT_NETBOOT
+ /* Shut down the networking. */
+ cleanup_net ();
+@@ -306,6 +320,13 @@
+ return 1;
+ }
+
++ /* if we get back here, we should go back to what our term was before */
++ current_term = prev_term;
++ if (current_term->startup)
++ /* if our terminal fails to initialize, fall back to console since
++ * it should always work */
++ if (current_term->startup() == 0)
++ current_term = term_table; /* we know that console is first */
+ return 0;
+ }
+
+@@ -852,6 +873,251 @@
+ };
+ #endif /* SUPPORT_NETBOOT */
+
++#ifdef SUPPORT_GRAPHICS
++
++static int splashimage_func(char *arg, int flags) {
++ int i;
++
++ /* filename can only be 256 characters due to our buffer size */
++ if (grub_strlen(arg) > 256) {
++ grub_printf("Splash image filename too large\n");
++ grub_printf("Press any key to continue...");
++ getkey();
++ return 1;
++ }
++
++ /* get rid of TERM_NEED_INIT from the graphics terminal. */
++ for (i = 0; term_table[i].name; i++) {
++ if (grub_strcmp (term_table[i].name, "graphics") == 0) {
++ term_table[i].flags &= ~TERM_NEED_INIT;
++ break;
++ }
++ }
++
++ graphics_set_splash(arg);
++
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ if (graphics_init() == 0) {
++ /* Fallback to default term */
++ current_term = term_table;
++ max_lines = current_term->max_lines;
++ if (current_term->cls)
++ current_term->cls();
++ grub_printf("Failed to set splash image and/or graphics mode\n");
++ return 1;
++ }
++ graphics_cls();
++ }
++
++ if (flags == BUILTIN_MENU)
++ current_term = term_table + i;
++
++ return 0;
++}
++
++static struct builtin builtin_splashimage =
++{
++ "splashimage",
++ splashimage_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "splashimage FILE",
++ "Load FILE as the background image when in graphics mode."
++};
++
++
++/* shade */
++static int
++shade_func(char *arg, int flags)
++{
++ int new_shade;
++
++ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
++ return (1);
++
++ if (shade != new_shade) {
++ shade = new_shade;
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ graphics_init();
++ graphics_cls();
++ }
++ }
++
++ return 0;
++}
++
++static struct builtin builtin_shade =
++{
++ "shade",
++ shade_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "shade INTEGER",
++ "If set to 0, disables the use of shaded text, else enables it."
++};
++
++
++/* foreground */
++static int
++foreground_func(char *arg, int flags)
++{
++ if (grub_strlen(arg) == 6) {
++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++ foreground = (r << 16) | (g << 8) | b;
++ if (graphics_inited)
++ graphics_set_palette(15, r, g, b);
++
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct builtin builtin_foreground =
++{
++ "foreground",
++ foreground_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "foreground RRGGBB",
++ "Sets the foreground color when in graphics mode."
++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* background */
++static int
++background_func(char *arg, int flags)
++{
++ if (grub_strlen(arg) == 6) {
++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++ background = (r << 16) | (g << 8) | b;
++ if (graphics_inited)
++ graphics_set_palette(0, r, g, b);
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct builtin builtin_background =
++{
++ "background",
++ background_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "background RRGGBB",
++ "Sets the background color when in graphics mode."
++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* border */
++static int
++border_func(char *arg, int flags)
++{
++ if (grub_strlen(arg) == 6) {
++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++ window_border = (r << 16) | (g << 8) | b;
++ if (graphics_inited)
++ graphics_set_palette(0x11, r, g, b);
++
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct builtin builtin_border =
++{
++ "border",
++ border_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "border RRGGBB",
++ "Sets the border video color when in graphics mode."
++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* viewport */
++static int
++viewport_func (char *arg, int flags)
++{
++ int i;
++ int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
++ int *pos[4] = { &x0, &y0, &x1, &y1 };
++
++ if (!arg)
++ return (1);
++ for (i = 0; i < 4; i++) {
++ if (!*arg)
++ return (1);
++ while (*arg && (*arg == ' ' || *arg == '\t'))
++ ++arg;
++ if (!safe_parse_maxint(&arg, pos[i]))
++ return (1);
++ while (*arg && (*arg != ' ' && *arg != '\t'))
++ ++arg;
++ }
++
++ /* minimum size is 65 colums and 16 rows */
++ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
++ return 1;
++
++ view_x0 = x0;
++ view_y0 = y0;
++ view_x1 = x1;
++ view_y1 = y1;
++
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ graphics_init();
++ graphics_cls();
++ }
++
++ return 0;
++}
++
++static struct builtin builtin_viewport =
++{
++ "viewport",
++ viewport_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "viewport x0 y0 x1 y1",
++ "Changes grub internals to output text in the window defined by"
++ " four parameters. The x and y parameters are 0 based. This option"
++ " only works with the graphics interface."
++};
++
++#endif /* SUPPORT_GRAPHICS */
++
++
++/* clear */
++static int
++clear_func()
++{
++ if (current_term->cls)
++ current_term->cls();
++
++ return 0;
++}
++
++static struct builtin builtin_clear =
++{
++ "clear",
++ clear_func,
++ BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
++ "clear",
++ "Clear the screen"
++};
++
+
+ /* displayapm */
+ static int
+@@ -1454,14 +1720,20 @@
+
+
+ /* help */
+-#define MAX_SHORT_DOC_LEN 39
+-#define MAX_LONG_DOC_LEN 66
+-
+ static int
+ help_func (char *arg, int flags)
+ {
+- int all = 0;
+-
++ int all = 0, max_short_doc_len, max_long_doc_len;
++ max_short_doc_len = 39;
++ max_long_doc_len = 66;
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
++ max_long_doc_len = (view_x1 - view_x0) - 14;
++ }
++#endif
++
+ if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
+ {
+ all = 1;
+@@ -1491,13 +1763,13 @@
+
+ len = grub_strlen ((*builtin)->short_doc);
+ /* If the length of SHORT_DOC is too long, truncate it. */
+- if (len > MAX_SHORT_DOC_LEN - 1)
+- len = MAX_SHORT_DOC_LEN - 1;
++ if (len > max_short_doc_len - 1)
++ len = max_short_doc_len - 1;
+
+ for (i = 0; i < len; i++)
+ grub_putchar ((*builtin)->short_doc[i]);
+
+- for (; i < MAX_SHORT_DOC_LEN; i++)
++ for (; i < max_short_doc_len; i++)
+ grub_putchar (' ');
+
+ if (! left)
+@@ -1546,10 +1818,10 @@
+ int i;
+
+ /* If LEN is too long, fold DOC. */
+- if (len > MAX_LONG_DOC_LEN)
++ if (len > max_long_doc_len)
+ {
+ /* Fold this line at the position of a space. */
+- for (len = MAX_LONG_DOC_LEN; len > 0; len--)
++ for (len = max_long_doc_len; len > 0; len--)
+ if (doc[len - 1] == ' ')
+ break;
+ }
+@@ -4085,7 +4357,7 @@
+ };
+
+
+-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
+ /* terminal */
+ static int
+ terminal_func (char *arg, int flags)
+@@ -4244,17 +4516,29 @@
+ end:
+ current_term = term_table + default_term;
+ current_term->flags = term_flags;
+-
++
+ if (lines)
+ max_lines = lines;
+ else
+- /* 24 would be a good default value. */
+- max_lines = 24;
+-
++ max_lines = current_term->max_lines;
++
+ /* If the interface is currently the command-line,
+ restart it to repaint the screen. */
+- if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
++ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
++ if (prev_term->shutdown)
++ prev_term->shutdown();
++ if (current_term->startup) {
++ /* If startup fails, return to previous term */
++ if (current_term->startup() == 0) {
++ current_term = prev_term;
++ max_lines = current_term->max_lines;
++ if (current_term->cls) {
++ current_term->cls();
++ }
++ }
++ }
+ grub_longjmp (restart_cmdline_env, 0);
++ }
+
+ return 0;
+ }
+@@ -4264,7 +4548,7 @@
+ "terminal",
+ terminal_func,
+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
++ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
+ "Select a terminal. When multiple terminals are specified, wait until"
+ " you push any key to continue. If both console and serial are specified,"
+ " the terminal to which you input a key first will be selected. If no"
+@@ -4276,7 +4560,7 @@
+ " seconds. The option --lines specifies the maximum number of lines."
+ " The option --silent is used to suppress messages."
+ };
+-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
+
+
+ #ifdef SUPPORT_SERIAL
+@@ -4795,13 +5079,20 @@
+ /* The table of builtin commands. Sorted in dictionary order. */
+ struct builtin *builtin_table[] =
+ {
++#ifdef SUPPORT_GRAPHICS
++ &builtin_background,
++#endif
+ &builtin_blocklist,
+ &builtin_boot,
+ #ifdef SUPPORT_NETBOOT
+ &builtin_bootp,
+ #endif /* SUPPORT_NETBOOT */
++#ifdef SUPPORT_GRAPHICS
++ &builtin_border,
++#endif
+ &builtin_cat,
+ &builtin_chainloader,
++ &builtin_clear,
+ &builtin_cmp,
+ &builtin_color,
+ &builtin_configfile,
+@@ -4821,6 +5112,9 @@
+ &builtin_embed,
+ &builtin_fallback,
+ &builtin_find,
++#ifdef SUPPORT_GRAPHICS
++ &builtin_foreground,
++#endif
+ &builtin_fstest,
+ &builtin_geometry,
+ &builtin_halt,
+@@ -4864,9 +5158,13 @@
+ #endif /* SUPPORT_SERIAL */
+ &builtin_setkey,
+ &builtin_setup,
+-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
++#ifdef SUPPORT_GRAPHICS
++ &builtin_shade,
++ &builtin_splashimage,
++#endif /* SUPPORT_GRAPHICS */
++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
+ &builtin_terminal,
+-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
+ #ifdef SUPPORT_SERIAL
+ &builtin_terminfo,
+ #endif /* SUPPORT_SERIAL */
+@@ -4880,5 +5178,8 @@
+ &builtin_unhide,
+ &builtin_uppermem,
+ &builtin_vbeprobe,
++#ifdef SUPPORT_GRAPHICS
++ &builtin_viewport,
++#endif
+ 0
+ };
+Index: b/stage2/char_io.c
+===================================================================
+--- a/stage2/char_io.c
++++ b/stage2/char_io.c
+@@ -29,12 +29,17 @@
+ # include <serial.h>
+ #endif
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifndef STAGE1_5
+ struct term_entry term_table[] =
+ {
+ {
+ "console",
+ 0,
++ 24,
+ console_putchar,
+ console_checkkey,
+ console_getkey,
+@@ -43,13 +48,16 @@
+ console_cls,
+ console_setcolorstate,
+ console_setcolor,
+- console_setcursor
++ console_setcursor,
++ 0,
++ 0
+ },
+ #ifdef SUPPORT_SERIAL
+ {
+ "serial",
+ /* A serial device must be initialized. */
+ TERM_NEED_INIT,
++ 24,
+ serial_putchar,
+ serial_checkkey,
+ serial_getkey,
+@@ -58,6 +66,8 @@
+ serial_cls,
+ serial_setcolorstate,
+ 0,
++ 0,
++ 0,
+ 0
+ },
+ #endif /* SUPPORT_SERIAL */
+@@ -65,6 +75,7 @@
+ {
+ "hercules",
+ 0,
++ 24,
+ hercules_putchar,
+ console_checkkey,
+ console_getkey,
+@@ -73,11 +84,30 @@
+ hercules_cls,
+ hercules_setcolorstate,
+ hercules_setcolor,
+- hercules_setcursor
++ hercules_setcursor,
++ 0,
++ 0
+ },
+ #endif /* SUPPORT_HERCULES */
++#ifdef SUPPORT_GRAPHICS
++ { "graphics",
++ TERM_NEED_INIT, /* flags */
++ 30, /* number of lines */
++ graphics_putchar, /* putchar */
++ console_checkkey, /* checkkey */
++ console_getkey, /* getkey */
++ graphics_getxy, /* getxy */
++ graphics_gotoxy, /* gotoxy */
++ graphics_cls, /* cls */
++ graphics_setcolorstate, /* setcolorstate */
++ graphics_setcolor, /* setcolor */
++ graphics_setcursor, /* nocursor */
++ graphics_init, /* initialize */
++ graphics_end /* shutdown */
++ },
++#endif /* SUPPORT_GRAPHICS */
+ /* This must be the last entry. */
+- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+
+ /* This must be console. */
+@@ -305,9 +335,10 @@
+
+ /* XXX: These should be defined in shared.h, but I leave these here,
+ until this code is freezed. */
+-#define CMDLINE_WIDTH 78
+ #define CMDLINE_MARGIN 10
+-
++
++ /* command-line limits */
++ int cmdline_width = 78, col_start = 0;
+ int xpos, lpos, c, section;
+ /* The length of PROMPT. */
+ int plen;
+@@ -338,7 +369,7 @@
+
+ /* If the cursor is in the first section, display the first section
+ instead of the second. */
+- if (section == 1 && plen + lpos < CMDLINE_WIDTH)
++ if (section == 1 && plen + lpos < cmdline_width)
+ cl_refresh (1, 0);
+ else if (xpos - count < 1)
+ cl_refresh (1, 0);
+@@ -354,7 +385,7 @@
+ grub_putchar ('\b');
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+ }
+
+@@ -364,7 +395,7 @@
+ lpos += count;
+
+ /* If the cursor goes outside, scroll the screen to the right. */
+- if (xpos + count >= CMDLINE_WIDTH)
++ if (xpos + count >= cmdline_width)
+ cl_refresh (1, 0);
+ else
+ {
+@@ -383,7 +414,7 @@
+ }
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+ }
+
+@@ -398,14 +429,14 @@
+ if (full)
+ {
+ /* Recompute the section number. */
+- if (lpos + plen < CMDLINE_WIDTH)
++ if (lpos + plen < cmdline_width)
+ section = 0;
+ else
+- section = ((lpos + plen - CMDLINE_WIDTH)
+- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
++ section = ((lpos + plen - cmdline_width)
++ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
+
+ /* From the start to the end. */
+- len = CMDLINE_WIDTH;
++ len = cmdline_width;
+ pos = 0;
+ grub_putchar ('\r');
+
+@@ -445,8 +476,8 @@
+ if (! full)
+ offset = xpos - 1;
+
+- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
+- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
++ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
++ + cmdline_width - plen - CMDLINE_MARGIN);
+ xpos = lpos + 1 - start;
+ start += offset;
+ }
+@@ -471,7 +502,7 @@
+
+ /* If the cursor is at the last position, put `>' or a space,
+ depending on if there are more characters in BUF. */
+- if (pos == CMDLINE_WIDTH)
++ if (pos == cmdline_width)
+ {
+ if (start + len < llen)
+ grub_putchar ('>');
+@@ -488,7 +519,7 @@
+ grub_putchar ('\b');
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+
+ /* Initialize the command-line. */
+@@ -518,10 +549,10 @@
+
+ llen += l;
+ lpos += l;
+- if (xpos + l >= CMDLINE_WIDTH)
++ if (xpos + l >= cmdline_width)
+ cl_refresh (1, 0);
+- else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
+- cl_refresh (0, CMDLINE_WIDTH - xpos);
++ else if (xpos + l + llen - lpos > cmdline_width)
++ cl_refresh (0, cmdline_width - xpos);
+ else
+ cl_refresh (0, l + llen - lpos);
+ }
+@@ -533,12 +564,22 @@
+ grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
+ llen -= count;
+
+- if (xpos + llen + count - lpos > CMDLINE_WIDTH)
+- cl_refresh (0, CMDLINE_WIDTH - xpos);
++ if (xpos + llen + count - lpos > cmdline_width)
++ cl_refresh (0, cmdline_width - xpos);
+ else
+ cl_refresh (0, llen + count - lpos);
+ }
+
++ max_lines = current_term->max_lines;
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ cmdline_width = (view_x1 - view_x0) - 2;
++ col_start = view_x0;
++ max_lines = view_y1 - view_y0;
++ }
++#endif
++
+ plen = grub_strlen (prompt);
+ llen = grub_strlen (cmdline);
+
+@@ -1006,6 +1047,48 @@
+ }
+ #endif /* ! STAGE1_5 */
+
++#ifndef STAGE1_5
++/* Internal pager. */
++int
++do_more (void)
++{
++ if (count_lines >= 0)
++ {
++ count_lines++;
++ if (count_lines >= max_lines - 2)
++ {
++ int tmp;
++
++ /* It's important to disable the feature temporarily, because
++ the following grub_printf call will print newlines. */
++ count_lines = -1;
++
++ grub_printf("\n");
++ if (current_term->setcolorstate)
++ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
++
++ grub_printf ("[Hit return to continue]");
++
++ if (current_term->setcolorstate)
++ current_term->setcolorstate (COLOR_STATE_NORMAL);
++
++
++ do
++ {
++ tmp = ASCII_CHAR (getkey ());
++ }
++ while (tmp != '\n' && tmp != '\r');
++ grub_printf ("\r \r");
++
++ /* Restart to count lines. */
++ count_lines = 0;
++ return 1;
++ }
++ }
++ return 0;
++}
++#endif
++
+ /* Display an ASCII character. */
+ void
+ grub_putchar (int c)
+@@ -1034,38 +1117,11 @@
+
+ if (c == '\n')
+ {
++ int flag;
+ /* Internal `more'-like feature. */
+- if (count_lines >= 0)
+- {
+- count_lines++;
+- if (count_lines >= max_lines - 2)
+- {
+- int tmp;
+-
+- /* It's important to disable the feature temporarily, because
+- the following grub_printf call will print newlines. */
+- count_lines = -1;
+-
+- if (current_term->setcolorstate)
+- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+-
+- grub_printf ("\n[Hit return to continue]");
+-
+- if (current_term->setcolorstate)
+- current_term->setcolorstate (COLOR_STATE_NORMAL);
+-
+- do
+- {
+- tmp = ASCII_CHAR (getkey ());
+- }
+- while (tmp != '\n' && tmp != '\r');
+- grub_printf ("\r \r");
+-
+- /* Restart to count lines. */
+- count_lines = 0;
+- return;
+- }
+- }
++ flag = do_more ();
++ if (flag)
++ return;
+ }
+
+ current_term->putchar (c);
+@@ -1090,7 +1146,7 @@
+ cls (void)
+ {
+ /* If the terminal is dumb, there is no way to clean the terminal. */
+- if (current_term->flags & TERM_DUMB)
++ if (current_term->flags & TERM_DUMB)
+ grub_putchar ('\n');
+ else
+ current_term->cls ();
+@@ -1217,6 +1273,16 @@
+ return ! errnum;
+ }
+
++void
++grub_memcpy(void *dest, const void *src, int len)
++{
++ int i;
++ register char *d = (char*)dest, *s = (char*)src;
++
++ for (i = 0; i < len; i++)
++ d[i] = s[i];
++}
++
+ void *
+ grub_memmove (void *to, const void *from, int len)
+ {
+Index: b/stage2/cmdline.c
+===================================================================
+--- a/stage2/cmdline.c
++++ b/stage2/cmdline.c
+@@ -50,10 +50,11 @@
+ void
+ print_cmdline_message (int forever)
+ {
+- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n"
+- " lists possible command completions. Anywhere else TAB lists the possible\n"
+- " completions of a device/filename.%s ]\n",
+- (forever ? "" : " ESC at any time exits."));
++ grub_printf(" [ Minimal BASH-like line editing is supported. For\n"
++ " the first word, TAB lists possible command\n"
++ " completions. Anywhere else TAB lists the possible\n"
++ " completions of a device/filename.%s ]\n",
++ (forever ? "" : " ESC at any time\n exits."));
+ }
+
+ /* Find the builtin whose command name is COMMAND and return the
+Index: b/stage2/graphics.c
+===================================================================
+--- /dev/null
++++ b/stage2/graphics.c
+@@ -0,0 +1,585 @@
++/*
++ * graphics.c - graphics mode support for GRUB
++ * Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
++ * on a patch by Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
++ * Options and enhancements made by Herton Ronaldo Krzesinski
++ * <herton@mandriva.com>
++ *
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2001,2002 Red Hat, Inc.
++ * Portions copyright (C) 2000 Conectiva, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifdef SUPPORT_GRAPHICS
++
++#include <term.h>
++#include <shared.h>
++#include <graphics.h>
++
++int saved_videomode;
++unsigned char *font8x16;
++
++int graphics_inited = 0;
++static char splashimage[256];
++
++int shade = 1, no_cursor = 0;
++
++#define VSHADOW VSHADOW1
++unsigned char VSHADOW1[38400];
++unsigned char VSHADOW2[38400];
++unsigned char VSHADOW4[38400];
++unsigned char VSHADOW8[38400];
++
++/* define the default viewable area */
++int view_x0 = 0;
++int view_y0 = 0;
++int view_x1 = 80;
++int view_y1 = 30;
++
++/* text buffer has to be kept around so that we can write things as we
++ * scroll and the like */
++unsigned short text[80 * 30];
++
++/* graphics options */
++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
++
++/* current position */
++static int fontx = 0;
++static int fonty = 0;
++
++/* global state so that we don't try to recursively scroll or cursor */
++static int no_scroll = 0;
++
++/* color state */
++static int graphics_standard_color = A_NORMAL;
++static int graphics_normal_color = A_NORMAL;
++static int graphics_highlight_color = A_REVERSE;
++static int graphics_current_color = A_NORMAL;
++static color_state graphics_color_state = COLOR_STATE_STANDARD;
++
++static inline void outb(unsigned short port, unsigned char val)
++{
++ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
++}
++
++static void MapMask(int value) {
++ outb(0x3c4, 2);
++ outb(0x3c5, value);
++}
++
++/* bit mask register */
++static void BitMask(int value) {
++ outb(0x3ce, 8);
++ outb(0x3cf, value);
++}
++
++/* move the graphics cursor location to col, row */
++static void graphics_setxy(int col, int row) {
++ if (col >= view_x0 && col < view_x1) {
++ fontx = col;
++ cursorX = col << 3;
++ }
++ if (row >= view_y0 && row < view_y1) {
++ fonty = row;
++ cursorY = row << 4;
++ }
++}
++
++/* scroll the screen */
++static void graphics_scroll() {
++ int i, j, k;
++
++ /* we don't want to scroll recursively... that would be bad */
++ if (no_scroll)
++ return;
++ no_scroll = 1;
++
++ /* disable pager temporarily */
++ k = count_lines;
++ count_lines = -1;
++
++ /* move everything up a line */
++ for (j = view_y0 + 1; j < view_y1; j++) {
++ graphics_gotoxy(view_x0, j - 1);
++ for (i = view_x0; i < view_x1; i++) {
++ graphics_putchar(text[j * 80 + i]);
++ }
++ }
++
++ /* last line should be blank */
++ graphics_gotoxy(view_x0, view_y1 - 1);
++ for (i = view_x0; i < view_x1; i++)
++ graphics_putchar(' ');
++ graphics_setxy(view_x0, view_y1 - 1);
++
++ count_lines = k;
++
++ no_scroll = 0;
++}
++
++/* Set the splash image */
++void graphics_set_splash(char *splashfile) {
++ grub_strcpy(splashimage, splashfile);
++}
++
++/* Get the current splash image */
++char *graphics_get_splash(void) {
++ return splashimage;
++}
++
++/*
++ * Initialize a vga16 graphics display with the palette based off of
++ * the image in splashimage. If the image doesn't exist, leave graphics
++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
++ * text/ text pixel pixel colors disply scrn system
++ * grph resol box resolution pages addr
++ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP
++ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder
++ * G . . 640x480 16 . . UltraVision+256K EGA
++ */
++int graphics_init()
++{
++ if (!graphics_inited) {
++ saved_videomode = set_videomode(0x12);
++ if (get_videomode() != 0x12) {
++ set_videomode(saved_videomode);
++ return 0;
++ }
++ graphics_inited = 1;
++ }
++ else
++ return 1;
++
++ font8x16 = (unsigned char*)graphics_get_font();
++
++ /* make sure that the highlight color is set correctly */
++ graphics_highlight_color = ((graphics_normal_color >> 4) |
++ ((graphics_normal_color & 0xf) << 4));
++
++ graphics_cls();
++
++ if (!read_image(splashimage)) {
++ grub_printf("Failed to read splash image (%s)\n", splashimage);
++ grub_printf("Press any key to continue...");
++ getkey();
++ set_videomode(saved_videomode);
++ graphics_inited = 0;
++ return 0;
++ }
++
++ set_int1c_handler();
++
++ return 1;
++}
++
++/* Leave graphics mode */
++void graphics_end(void)
++{
++ if (graphics_inited) {
++ unset_int1c_handler();
++ set_videomode(saved_videomode);
++ graphics_inited = 0;
++ no_cursor = 0;
++ }
++}
++
++/* Print ch on the screen. Handle any needed scrolling or the like */
++void graphics_putchar(int ch) {
++ ch &= 0xff;
++
++ graphics_cursor(0);
++
++ if (ch == '\n') {
++ if (fonty + 1 < view_y1)
++ graphics_setxy(fontx, fonty + 1);
++ else
++ graphics_scroll();
++ graphics_cursor(1);
++ return;
++ } else if (ch == '\r') {
++ graphics_setxy(view_x0, fonty);
++ graphics_cursor(1);
++ return;
++ }
++
++ graphics_cursor(0);
++
++ text[fonty * 80 + fontx] = ch;
++ text[fonty * 80 + fontx] &= 0x00ff;
++ if (graphics_current_color & 0xf0)
++ text[fonty * 80 + fontx] |= 0x100;
++
++ graphics_cursor(0);
++
++ if ((fontx + 1) >= view_x1) {
++ graphics_setxy(view_x0, fonty);
++ if (fonty + 1 < view_y1)
++ graphics_setxy(view_x0, fonty + 1);
++ else
++ graphics_scroll();
++ graphics_cursor(1);
++ do_more ();
++ graphics_cursor(0);
++ } else {
++ graphics_setxy(fontx + 1, fonty);
++ }
++
++ graphics_cursor(1);
++}
++
++/* get the current location of the cursor */
++int graphics_getxy(void) {
++ return (fontx << 8) | fonty;
++}
++
++void graphics_gotoxy(int x, int y) {
++ graphics_cursor(0);
++
++ graphics_setxy(x, y);
++
++ graphics_cursor(1);
++}
++
++void graphics_cls(void) {
++ int i;
++ unsigned char *mem, *s1, *s2, *s4, *s8;
++
++ graphics_cursor(0);
++ graphics_gotoxy(view_x0, view_y0);
++
++ mem = (unsigned char*)VIDEOMEM;
++ s1 = (unsigned char*)VSHADOW1;
++ s2 = (unsigned char*)VSHADOW2;
++ s4 = (unsigned char*)VSHADOW4;
++ s8 = (unsigned char*)VSHADOW8;
++
++ for (i = 0; i < 80 * 30; i++)
++ text[i] = ' ';
++ graphics_cursor(1);
++
++ BitMask(0xff);
++
++ /* plane 1 */
++ MapMask(1);
++ grub_memcpy(mem, s1, 38400);
++
++ /* plane 2 */
++ MapMask(2);
++ grub_memcpy(mem, s2, 38400);
++
++ /* plane 3 */
++ MapMask(4);
++ grub_memcpy(mem, s4, 38400);
++
++ /* plane 4 */
++ MapMask(8);
++ grub_memcpy(mem, s8, 38400);
++
++ MapMask(15);
++
++ if (no_cursor) {
++ no_cursor = 0;
++ set_int1c_handler();
++ }
++}
++
++void graphics_setcolorstate (color_state state) {
++ switch (state) {
++ case COLOR_STATE_STANDARD:
++ graphics_current_color = graphics_standard_color;
++ break;
++ case COLOR_STATE_NORMAL:
++ graphics_current_color = graphics_normal_color;
++ break;
++ case COLOR_STATE_HIGHLIGHT:
++ graphics_current_color = graphics_highlight_color;
++ break;
++ default:
++ graphics_current_color = graphics_standard_color;
++ break;
++ }
++
++ graphics_color_state = state;
++}
++
++void graphics_setcolor (int normal_color, int highlight_color) {
++ graphics_normal_color = normal_color;
++ graphics_highlight_color = highlight_color;
++
++ graphics_setcolorstate (graphics_color_state);
++}
++
++int graphics_setcursor (int on) {
++ if (!no_cursor && !on) {
++ no_cursor = 1;
++ unset_int1c_handler();
++ graphics_cursor(0);
++ }
++ else if(no_cursor && on) {
++ no_cursor = 0;
++ set_int1c_handler();
++ graphics_cursor(1);
++ }
++ return 0;
++}
++
++/* Read in the splashscreen image and set the palette up appropriately.
++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
++ * 640x480. */
++int read_image(char *s)
++{
++ char buf[32], pal[16], c;
++ unsigned char base, mask, *s1, *s2, *s4, *s8;
++ unsigned i, len, idx, colors, x, y, width, height;
++
++ if (!grub_open(s))
++ return 0;
++
++ /* read header */
++ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
++ grub_close();
++ return 0;
++ }
++
++ /* parse info */
++ while (grub_read(&c, 1)) {
++ if (c == '"')
++ break;
++ }
++
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ i = 0;
++ width = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ width = width * 10 + c - '0';
++ else
++ break;
++ }
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ height = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ height = height * 10 + c - '0';
++ else
++ break;
++ }
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ colors = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ colors = colors * 10 + c - '0';
++ else
++ break;
++ }
++
++ base = 0;
++ while (grub_read(&c, 1) && c != '"')
++ ;
++
++ /* palette */
++ for (i = 0, idx = 1; i < colors; i++) {
++ len = 0;
++
++ while (grub_read(&c, 1) && c != '"')
++ ;
++ grub_read(&c, 1); /* char */
++ base = c;
++ grub_read(buf, 4); /* \t c # */
++
++ while (grub_read(&c, 1) && c != '"') {
++ if (len < sizeof(buf))
++ buf[len++] = c;
++ }
++
++ if (len == 6 && idx < 15) {
++ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
++ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
++ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
++
++ pal[idx] = base;
++ graphics_set_palette(idx, r, g, b);
++ ++idx;
++ }
++ }
++
++ x = y = len = 0;
++
++ s1 = (unsigned char*)VSHADOW1;
++ s2 = (unsigned char*)VSHADOW2;
++ s4 = (unsigned char*)VSHADOW4;
++ s8 = (unsigned char*)VSHADOW8;
++
++ for (i = 0; i < 38400; i++)
++ s1[i] = s2[i] = s4[i] = s8[i] = 0;
++
++ /* parse xpm data */
++ while (y < height) {
++ while (1) {
++ if (!grub_read(&c, 1)) {
++ grub_close();
++ return 0;
++ }
++ if (c == '"')
++ break;
++ }
++
++ while (grub_read(&c, 1) && c != '"') {
++ for (i = 1; i < 15; i++)
++ if (pal[i] == c) {
++ c = i;
++ break;
++ }
++
++ mask = 0x80 >> (x & 7);
++ if (c & 1)
++ s1[len + (x >> 3)] |= mask;
++ if (c & 2)
++ s2[len + (x >> 3)] |= mask;
++ if (c & 4)
++ s4[len + (x >> 3)] |= mask;
++ if (c & 8)
++ s8[len + (x >> 3)] |= mask;
++
++ if (++x >= 640) {
++ x = 0;
++
++ if (y < 480)
++ len += 80;
++ ++y;
++ }
++ }
++ }
++
++ grub_close();
++
++ graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
++ background & 63);
++ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
++ foreground & 63);
++ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63,
++ window_border & 63);
++
++ return 1;
++}
++
++/* Convert a character which is a hex digit to the appropriate integer */
++int hex(int v)
++{
++ if (v >= 'A' && v <= 'F')
++ return (v - 'A' + 10);
++ if (v >= 'a' && v <= 'f')
++ return (v - 'a' + 10);
++ return (v - '0');
++}
++
++void graphics_cursor(int set) {
++ unsigned char *pat, *mem, *ptr, chr[16 << 2];
++ int i, ch, invert, offset;
++
++ if (set && (no_cursor || no_scroll))
++ return;
++
++ offset = cursorY * 80 + fontx;
++ ch = text[fonty * 80 + fontx] & 0xff;
++ invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
++ pat = font8x16 + (ch << 4);
++
++ mem = (unsigned char*)VIDEOMEM + offset;
++
++ if (!set) {
++ for (i = 0; i < 16; i++) {
++ unsigned char mask = pat[i];
++
++ if (!invert) {
++ chr[i ] = ((unsigned char*)VSHADOW1)[offset];
++ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
++ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
++ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
++
++ if (shade) {
++ if (ch == DISP_VERT || ch == DISP_LL ||
++ ch == DISP_UR || ch == DISP_LR) {
++ unsigned char pmask = ~(pat[i] >> 1);
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ }
++ if (i > 0 && ch != DISP_VERT) {
++ unsigned char pmask = ~(pat[i - 1] >> 1);
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
++ pmask = ~pat[i - 1];
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ }
++ }
++ }
++ chr[i ] |= mask;
++ chr[16 + i] |= mask;
++ chr[32 + i] |= mask;
++ chr[48 + i] |= mask;
++
++ offset += 80;
++ }
++ else {
++ chr[i ] = mask;
++ chr[16 + i] = mask;
++ chr[32 + i] = mask;
++ chr[48 + i] = mask;
++ }
++ }
++ }
++ else {
++ MapMask(15);
++ ptr = mem;
++ for (i = 0; i < 16; i++, ptr += 80) {
++ cursorBuf[i] = pat[i];
++ *ptr = ~pat[i];
++ }
++ return;
++ }
++
++ offset = 0;
++ for (i = 1; i < 16; i <<= 1, offset += 16) {
++ int j;
++
++ MapMask(i);
++ ptr = mem;
++ for (j = 0; j < 16; j++, ptr += 80)
++ *ptr = chr[j + offset];
++ }
++
++ MapMask(15);
++}
++
++#endif /* SUPPORT_GRAPHICS */
+Index: b/stage2/graphics.h
+===================================================================
+--- /dev/null
++++ b/stage2/graphics.h
+@@ -0,0 +1,44 @@
++/* graphics.h - graphics console interface */
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2002 Free Software Foundation, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef GRAPHICS_H
++#define GRAPHICS_H
++
++/* magic constant */
++#define VIDEOMEM 0xA0000
++
++/* function prototypes */
++char *graphics_get_splash(void);
++
++int read_image(char *s);
++void graphics_cursor(int set);
++
++/* function prototypes for asm functions */
++void * graphics_get_font();
++void graphics_set_palette(int idx, int red, int green, int blue);
++void set_int1c_handler();
++void unset_int1c_handler();
++
++extern short cursorX, cursorY;
++extern char cursorBuf[16];
++extern int shade;
++extern int view_x0, view_y0, view_x1, view_y1;
++
++#endif /* GRAPHICS_H */
+Index: b/stage2/Makefile.am
+===================================================================
+--- a/stage2/Makefile.am
++++ b/stage2/Makefile.am
+@@ -7,7 +7,7 @@
+ fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
+ imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
+ nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
+- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
++ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
+ EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
+
+ # For <stage1.h>.
+@@ -19,7 +19,7 @@
+ disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
+ fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+ fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
+- terminfo.c tparm.c
++ terminfo.c tparm.c graphics.c
+ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
+ -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+ -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+@@ -79,8 +79,14 @@
+ HERCULES_FLAGS =
+ endif
+
++if GRAPHICS_SUPPORT
++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
++else
++GRAPHICS_FLAGS =
++endif
++
+ STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
++ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
+
+ STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
+ STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
+@@ -90,7 +96,8 @@
+ cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+ fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
+ fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
+- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
++ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
++ graphics.c
+ pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+Index: b/stage2/shared.h
+===================================================================
+--- a/stage2/shared.h
++++ b/stage2/shared.h
+@@ -796,6 +796,11 @@
+ /* Set the cursor position. */
+ void gotoxy (int x, int y);
+
++/* Internal pager
++ Returns 1 = if pager was used
++ 0 = if pager wasn't used */
++int do_more (void);
++
+ /* Displays an ASCII character. IBM displays will translate some
+ characters to special graphical ones (see the DISP_* constants). */
+ void grub_putchar (int c);
+@@ -875,6 +880,7 @@
+ int grub_tolower (int c);
+ int grub_isspace (int c);
+ int grub_strncat (char *s1, const char *s2, int n);
++void grub_memcpy(void *dest, const void *src, int len);
+ void *grub_memmove (void *to, const void *from, int len);
+ void *grub_memset (void *start, int c, int len);
+ int grub_strncat (char *s1, const char *s2, int n);
+Index: b/stage2/stage2.c
+===================================================================
+--- a/stage2/stage2.c
++++ b/stage2/stage2.c
+@@ -20,6 +20,12 @@
+ #include <shared.h>
+ #include <term.h>
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
++int col_start, col_end, row_start, box_size;
++
+ grub_jmp_buf restart_env;
+
+ #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
+@@ -105,13 +111,13 @@
+ if (highlight && current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+
+- gotoxy (2, y);
++ gotoxy (2 + col_start, y);
+ grub_putchar (' ');
+- for (x = 3; x < 75; x++)
++ for (x = 3 + col_start; x < (col_end - 5); x++)
+ {
+- if (*entry && x <= 72)
++ if (*entry && x <= (col_end - 8))
+ {
+- if (x == 72)
++ if (x == (col_end - 8))
+ grub_putchar (DISP_RIGHT);
+ else
+ grub_putchar (*entry++);
+@@ -119,7 +125,7 @@
+ else
+ grub_putchar (' ');
+ }
+- gotoxy (74, y);
++ gotoxy ((col_end - 6), y);
+
+ if (current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_STANDARD);
+@@ -131,7 +137,7 @@
+ {
+ int i;
+
+- gotoxy (77, y + 1);
++ gotoxy ((col_end - 3), y + 1);
+
+ if (first)
+ grub_putchar (DISP_UP);
+@@ -151,14 +157,14 @@
+ menu_entries++;
+ }
+
+- gotoxy (77, y + size);
++ gotoxy ((col_end - 3), y + size);
+
+ if (*menu_entries)
+ grub_putchar (DISP_DOWN);
+ else
+ grub_putchar (' ');
+
+- gotoxy (74, y + entryno + 1);
++ gotoxy ((col_end - 6), y + entryno + 1);
+ }
+
+ static void
+@@ -196,30 +202,30 @@
+ if (current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_NORMAL);
+
+- gotoxy (1, y);
++ gotoxy (1 + col_start, y);
+
+ grub_putchar (DISP_UL);
+- for (i = 0; i < 73; i++)
++ for (i = col_start; i < (col_end - 7); i++)
+ grub_putchar (DISP_HORIZ);
+ grub_putchar (DISP_UR);
+
+ i = 1;
+ while (1)
+ {
+- gotoxy (1, y + i);
++ gotoxy (1 + col_start, y + i);
+
+ if (i > size)
+ break;
+
+ grub_putchar (DISP_VERT);
+- gotoxy (75, y + i);
++ gotoxy ((col_end - 5), y + i);
+ grub_putchar (DISP_VERT);
+
+ i++;
+ }
+
+ grub_putchar (DISP_LL);
+- for (i = 0; i < 73; i++)
++ for (i = col_start; i < (col_end - 7); i++)
+ grub_putchar (DISP_HORIZ);
+ grub_putchar (DISP_LR);
+
+@@ -233,6 +239,7 @@
+ {
+ int c, time1, time2 = -1, first_entry = 0;
+ char *cur_entry = 0;
++ struct term_entry *prev_term = NULL;
+
+ /*
+ * Main loop for menu UI.
+@@ -250,6 +257,22 @@
+ }
+ }
+
++ col_start = 0;
++ col_end = 80;
++ row_start = 0;
++ box_size = 12;
++ /* if we're using viewport we need to make sure to setup
++ coordinates correctly. */
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ col_start = view_x0;
++ col_end = view_x1;
++ row_start = view_y0;
++ box_size = (view_y1 - view_y0) - 13;
++ }
++#endif
++
+ /* If the timeout was expired or wasn't set, force to show the menu
+ interface. */
+ if (grub_timeout < 0)
+@@ -302,36 +325,36 @@
+ if (current_term->flags & TERM_DUMB)
+ print_entries_raw (num_entries, first_entry, menu_entries);
+ else
+- print_border (3, 12);
++ print_border (3 + row_start, box_size);
+
+ grub_printf ("\n\
+- Use the %c and %c keys to select which entry is highlighted.\n",
++ Use the %c and %c keys to select which entry is highlighted.\n",
+ DISP_UP, DISP_DOWN);
+
+ if (! auth && password)
+ {
+ printf ("\
+- Press enter to boot the selected OS or \'p\' to enter a\n\
+- password to unlock the next set of features.");
++ Press enter to boot the selected OS or \'p\' to enter a\n\
++ password to unlock the next set of features.");
+ }
+ else
+ {
+ if (config_entries)
+ printf ("\
+- Press enter to boot the selected OS, \'e\' to edit the\n\
+- commands before booting, or \'c\' for a command-line.");
++ Press enter to boot the selected OS, \'e\' to edit the\n\
++ commands before booting, or \'c\' for a command-line.");
+ else
+ printf ("\
+- Press \'b\' to boot, \'e\' to edit the selected command in the\n\
+- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
+- after (\'O\' for before) the selected line, \'d\' to remove the\n\
+- selected line, or escape to go back to the main menu.");
++ Press \'b\' to boot, \'e\' to edit the selected command in the\n\
++ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
++ after (\'O\' for before) the selected line, \'d\' to remove the\n\
++ selected line, or escape to go back to the main menu.");
+ }
+
+ if (current_term->flags & TERM_DUMB)
+ grub_printf ("\n\nThe selected entry is %d ", entryno);
+ else
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ /* XX using RT clock now, need to initialize value */
+@@ -358,10 +381,10 @@
+ entryno, grub_timeout);
+ else
+ {
+- gotoxy (3, 22);
+- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ",
++ gotoxy (3 + col_start, 10 + box_size + row_start);
++ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ",
+ grub_timeout);
+- gotoxy (74, 4 + entryno);
++ gotoxy ((col_end - 6), 4 + entryno + row_start);
+ }
+
+ grub_timeout--;
+@@ -387,12 +410,12 @@
+ if (current_term->flags & TERM_DUMB)
+ grub_putchar ('\r');
+ else
+- gotoxy (3, 22);
++ gotoxy (3 + col_start, 10 + box_size + row_start);
+ printf (" ");
+ grub_timeout = -1;
+ fallback_entryno = -1;
+ if (! (current_term->flags & TERM_DUMB))
+- gotoxy (74, 4 + entryno);
++ gotoxy ((col_end - 6), 4 + entryno + row_start);
+ }
+
+ /* We told them above (at least in SUPPORT_SERIAL) to use
+@@ -408,12 +431,12 @@
+ {
+ if (entryno > 0)
+ {
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ entryno--;
+- print_entry (4 + entryno, 1,
++ print_entry (4 + entryno + row_start, 1,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+@@ -421,7 +444,7 @@
+ else if (first_entry > 0)
+ {
+ first_entry--;
+- print_entries (3, 12, first_entry, entryno,
++ print_entries (3 + row_start, box_size, first_entry, entryno,
+ menu_entries);
+ }
+ }
+@@ -433,29 +456,29 @@
+ entryno++;
+ else
+ {
+- if (entryno < 11)
++ if (entryno < (box_size - 1))
+ {
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ entryno++;
+- print_entry (4 + entryno, 1,
++ print_entry (4 + entryno + row_start, 1,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ }
+- else if (num_entries > 12 + first_entry)
++ else if (num_entries > box_size + first_entry)
+ {
+ first_entry++;
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+ }
+ }
+ else if (c == 7)
+ {
+ /* Page Up */
+- first_entry -= 12;
++ first_entry -= box_size;
+ if (first_entry < 0)
+ {
+ entryno += first_entry;
+@@ -463,20 +486,20 @@
+ if (entryno < 0)
+ entryno = 0;
+ }
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+ else if (c == 3)
+ {
+ /* Page Down */
+- first_entry += 12;
++ first_entry += box_size;
+ if (first_entry + entryno + 1 >= num_entries)
+ {
+- first_entry = num_entries - 12;
++ first_entry = num_entries - box_size;
+ if (first_entry < 0)
+ first_entry = 0;
+ entryno = num_entries - first_entry - 1;
+ }
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ if (config_entries)
+@@ -489,7 +512,7 @@
+ if ((c == 'd') || (c == 'o') || (c == 'O'))
+ {
+ if (! (current_term->flags & TERM_DUMB))
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+@@ -537,7 +560,7 @@
+
+ if (entryno >= num_entries)
+ entryno--;
+- if (first_entry && num_entries < 12 + first_entry)
++ if (first_entry && num_entries < box_size + first_entry)
+ first_entry--;
+ }
+
+@@ -549,7 +572,7 @@
+ grub_printf ("\n");
+ }
+ else
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ cur_entry = menu_entries;
+@@ -570,7 +593,7 @@
+ if (current_term->flags & TERM_DUMB)
+ grub_printf ("\r ");
+ else
+- gotoxy (1, 21);
++ gotoxy (1 + col_start, 9 + box_size + row_start);
+
+ /* Wipe out the previously entered password */
+ grub_memset (entered, 0, sizeof (entered));
+@@ -717,6 +740,15 @@
+
+ cls ();
+ setcursor (1);
++ /* if our terminal needed initialization, we should shut it down
++ * before booting the kernel, but we want to save what it was so
++ * we can come back if needed */
++ prev_term = current_term;
++ if (current_term->shutdown)
++ {
++ current_term->shutdown();
++ current_term = term_table; /* assumption: console is first */
++ }
+
+ while (1)
+ {
+@@ -752,6 +784,13 @@
+ break;
+ }
+
++ /* if we get back here, we should go back to what our term was before */
++ current_term = prev_term;
++ if (current_term->startup)
++ /* if our terminal fails to initialize, fall back to console since
++ * it should always work */
++ if (current_term->startup() == 0)
++ current_term = term_table; /* we know that console is first */
+ show_menu = 1;
+ goto restart;
+ }
+@@ -1054,6 +1093,16 @@
+ while (is_preset);
+ }
+
++ /* go ahead and make sure the terminal is setup */
++ if (current_term->startup)
++ {
++ /* If initialization fails, go back to default terminal */
++ if (current_term->startup() == 0)
++ {
++ current_term = term_table;
++ }
++ }
++
+ if (! num_entries)
+ {
+ /* If no acceptable config file, goto command-line, starting
+Index: b/stage2/term.h
+===================================================================
+--- a/stage2/term.h
++++ b/stage2/term.h
+@@ -60,6 +60,8 @@
+ const char *name;
+ /* The feature flags defined above. */
+ unsigned long flags;
++ /* Default for maximum number of lines if not specified */
++ unsigned short max_lines;
+ /* Put a character. */
+ void (*putchar) (int c);
+ /* Check if any input character is available. */
+@@ -79,6 +81,10 @@
+ void (*setcolor) (int normal_color, int highlight_color);
+ /* Turn on/off the cursor. */
+ int (*setcursor) (int on);
++ /* function to start a terminal */
++ int (*startup) (void);
++ /* function to use to shutdown a terminal */
++ void (*shutdown) (void);
+ };
+
+ /* This lists up available terminals. */
+@@ -124,4 +130,24 @@
+ int hercules_setcursor (int on);
+ #endif
+
++#ifdef SUPPORT_GRAPHICS
++extern int foreground, background, window_border, graphics_inited, saved_videomode;
++
++void graphics_set_splash(char *splashfile);
++int set_videomode(int mode);
++int get_videomode(void);
++void graphics_putchar (int c);
++int graphics_getxy(void);
++void graphics_gotoxy(int x, int y);
++void graphics_cls(void);
++void graphics_setcolorstate (color_state state);
++void graphics_setcolor (int normal_color, int highlight_color);
++int graphics_setcursor (int on);
++int graphics_init(void);
++void graphics_end(void);
++
++int hex(int v);
++void graphics_set_palette(int idx, int red, int green, int blue);
++#endif /* SUPPORT_GRAPHICS */
++
+ #endif /* ! GRUB_TERM_HEADER */
diff --git a/grub-0.97-ldflags-objcopy-remove-build-id.patch b/grub-0.97-ldflags-objcopy-remove-build-id.patch
deleted file mode 100644
index 2b7cc32d02e3..000000000000
--- a/grub-0.97-ldflags-objcopy-remove-build-id.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-diff --git a/Makefile.in b/Makefile.in
-index 6652366..ba058eb 100644
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -112,6 +112,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/acinclude.m4 b/acinclude.m4
-index 368839c..32b3fa6 100644
---- a/acinclude.m4
-+++ b/acinclude.m4
-@@ -57,7 +57,7 @@ else
- fi
- grub_cv_prog_objcopy_absolute=yes
- for link_addr in 2000 8000 7C00; do
-- if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
-+ if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr -Wl,--build-id=none conftest.o -o conftest.exec]); then :
- else
- AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
- fi
-diff --git a/configure.ac b/configure.ac
-index bb9e1d9..9ac5c9f 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -115,6 +115,9 @@ if test "x$ac_cv_prog_gcc" = xyes; then
- fi
- fi
-
-+LOADER_LDFLAGS="-Wl,--build-id=none"
-+AC_SUBST(LOADER_LDFLAGS)
-+
- AC_SUBST(STAGE1_CFLAGS)
- AC_SUBST(STAGE2_CFLAGS)
- AC_SUBST(GRUB_CFLAGS)
-diff --git a/docs/Makefile.in b/docs/Makefile.in
-index 3e2de4b..7b2c94d 100644
---- a/docs/Makefile.in
-+++ b/docs/Makefile.in
-@@ -131,6 +131,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/grub/Makefile.in b/grub/Makefile.in
-index 136c38f..7c23ebe 100644
---- a/grub/Makefile.in
-+++ b/grub/Makefile.in
-@@ -108,6 +108,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/lib/Makefile.in b/lib/Makefile.in
-index 3dae206..449e126 100644
---- a/lib/Makefile.in
-+++ b/lib/Makefile.in
-@@ -107,6 +107,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/netboot/Makefile.in b/netboot/Makefile.in
-index 75ac299..0275768 100644
---- a/netboot/Makefile.in
-+++ b/netboot/Makefile.in
-@@ -108,6 +108,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/stage1/Makefile.am b/stage1/Makefile.am
-index 0afc285..3d83356 100644
---- a/stage1/Makefile.am
-+++ b/stage1/Makefile.am
-@@ -5,7 +5,7 @@ CLEANFILES = $(nodist_pkglib_DATA)
-
- # We can't use builtins or standard includes.
- AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
--LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
-+LDFLAGS = $(LOADER_LDFLAGS) -nostdlib -Wl,-N,-Ttext,7C00
-
- noinst_PROGRAMS = stage1.exec
- stage1_exec_SOURCES = stage1.S stage1.h
-diff --git a/stage1/Makefile.in b/stage1/Makefile.in
-index 7134bdf..ee4477f 100644
---- a/stage1/Makefile.in
-+++ b/stage1/Makefile.in
-@@ -110,9 +110,10 @@ INSTALL_DATA = @INSTALL_DATA@
- INSTALL_PROGRAM = @INSTALL_PROGRAM@
- INSTALL_SCRIPT = @INSTALL_SCRIPT@
- INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
-+LDFLAGS = $(LOADER_LDFLAGS) -nostdlib -Wl,-N,-Ttext,7C00
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-diff --git a/stage2/Makefile.am b/stage2/Makefile.am
-index f8e6d42..ff6f347 100644
---- a/stage2/Makefile.am
-+++ b/stage2/Makefile.am
-@@ -55,11 +55,11 @@ noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
- endif
- MOSTLYCLEANFILES = $(noinst_PROGRAMS)
-
--PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
--START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
--NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0
--PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
--START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
-+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200 $(LOADER_LDFLAGS)
-+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 $(LOADER_LDFLAGS)
-+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0 $(LOADER_LDFLAGS)
-+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 $(LOADER_LDFLAGS)
-+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 $(LOADER_LDFLAGS)
-
- if NETBOOT_SUPPORT
- NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1
-@@ -82,7 +82,7 @@ endif
- STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
-
--STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
-+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 $(LOADER_LDFLAGS)
- STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
-
- # For stage2 target.
-diff --git a/stage2/Makefile.in b/stage2/Makefile.in
-index d0062bd..88b2038 100644
---- a/stage2/Makefile.in
-+++ b/stage2/Makefile.in
-@@ -355,6 +355,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-@@ -468,11 +469,11 @@ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
- @DISKLESS_SUPPORT_FALSE@noinst_DATA = pre_stage2 start start_eltorito
- @DISKLESS_SUPPORT_TRUE@noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
- MOSTLYCLEANFILES = $(noinst_PROGRAMS)
--PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
--START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
--NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0
--PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
--START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
-+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200 $(LOADER_LDFLAGS)
-+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 $(LOADER_LDFLAGS)
-+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0 $(LOADER_LDFLAGS)
-+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 $(LOADER_LDFLAGS)
-+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 $(LOADER_LDFLAGS)
- @NETBOOT_SUPPORT_FALSE@NETBOOT_FLAGS =
- @NETBOOT_SUPPORT_TRUE@NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1
- @SERIAL_SUPPORT_FALSE@SERIAL_FLAGS =
-@@ -482,7 +483,7 @@ START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
- STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
-
--STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
-+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 $(LOADER_LDFLAGS)
- STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
-
- # For stage2 target.
-diff --git a/util/Makefile.in b/util/Makefile.in
-index e700cf7..cd3bf51 100644
---- a/util/Makefile.in
-+++ b/util/Makefile.in
-@@ -113,6 +113,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
- LDFLAGS = @LDFLAGS@
- LIBOBJS = @LIBOBJS@
- LIBS = @LIBS@
-+LOADER_LDFLAGS = @LOADER_LDFLAGS@
- LTLIBOBJS = @LTLIBOBJS@
- MAINT = @MAINT@
- MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
diff --git a/grub-install_addsyncs.patch b/grub-install_addsyncs.patch
new file mode 100644
index 000000000000..390c40c2db57
--- /dev/null
+++ b/grub-install_addsyncs.patch
@@ -0,0 +1,57 @@
+
+ Date: 2005-11-11
+ Author: Otavio Salvador
+ Comment: Stolen from Fedora grub package.
+ Add syncs to ensure that filesystem cache are flushed.
+
+ -- Original comment, below
+
+I just found another semi-critical bug, whose fix should really get
+into 0.91.
+
+It turns out that "grub-install" doesn't have any "sync" calls to make
+sure any filesystem caches are coherent with the raw devices they are
+on top of... so if your filesystem waits to write out any data from the
+copy command in the script to put the "stage1" and "stage2" in their
+final location, you're hosed.
+
+I found this because it just bit me on one of my systems running stock
+RedHat 7.2 with a large "stage2".
+
+The only script that is patched here is "grub-install". The others
+don't appear to need it as they either unmount things first or don't
+refer to devices.
+
+Hmm. Maybe the right fix is to make the "sync" system call when
+starting the GRUB shell with a device map that refers to any real disks
+or something like that.
+
+ Erich Stefan Boleyn <erich@uruk.org> http://www.uruk.org/
+"Reality is truly stranger than fiction; Probably why fiction is so popular"
+
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -384,6 +384,10 @@
+ # Create a safe temporary file.
+ test -n "$mklog" && log_file=`$mklog`
+
++ # Before all invocations of the grub shell, call sync to make sure
++ # the raw device is in sync with any bufferring in filesystems.
++ sync
++
+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+ quit
+ EOF
+@@ -509,6 +513,10 @@
+ # Create a safe temporary file.
+ test -n "$mklog" && log_file=`$mklog`
+
++# Before all invocations of the grub shell, call sync to make sure
++# the raw device is in sync with any bufferring in filesystems.
++sync
++
+ # Now perform the installation.
+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+ root $root_drive
diff --git a/grub-install_aoe_support.patch b/grub-install_aoe_support.patch
new file mode 100644
index 000000000000..fef89aec1c6f
--- /dev/null
+++ b/grub-install_aoe_support.patch
@@ -0,0 +1,23 @@
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -148,13 +148,16 @@
+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+ -e 's%\(fd[0-9]*\)$%\1%' \
+ -e 's%/part[0-9]*$%/disc%' \
+- -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
++ -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
++ -e 's%\(e[0-9]\.[0-9]*\).*$%\1%'`
+ tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
+ -e 's%.*d[0-9]*p%%' \
+ -e 's%.*/fd[0-9]*$%%' \
+ -e 's%.*/floppy/[0-9]*$%%' \
+ -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
+- -e 's%.*c[0-7]d[0-9]*p%%'`
++ -e 's%.*c[0-7]d[0-9]*p*%%' \
++ -e 's%.*e[0-9]\.[0-9]*p%%' \
++ -e 's%.*e[0-9]\.[0-9]*\$%%'`
+ ;;
+ gnu*)
+ tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
diff --git a/grub-install_regexp.patch b/grub-install_regexp.patch
new file mode 100644
index 000000000000..78d286c04359
--- /dev/null
+++ b/grub-install_regexp.patch
@@ -0,0 +1,30 @@
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -179,7 +179,7 @@
+
+ # Get the drive name.
+ tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
+- | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
++ | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
+
+ # If not found, print an error message and exit.
+ if test "x$tmp_drive" = x; then
+@@ -196,13 +196,13 @@
+ gnu*)
+ if echo $tmp_part | grep "^s" >/dev/null; then
+ tmp_pc_slice=`echo $tmp_part \
+- | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
++ | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
+ tmp_drive=`echo "$tmp_drive" \
+ | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+ fi
+- if echo $tmp_part | grep "[a-g]$" >/dev/null; then
++ if echo $tmp_part | grep "[a-z]$" >/dev/null; then
+ tmp_bsd_partition=`echo "$tmp_part" \
+- | sed "s%[^a-g]*\([a-g]\)$%\1%"`
++ | sed "s%[^a-z]*\([a-z]\)$%\1%"`
+ tmp_drive=`echo "$tmp_drive" \
+ | sed "s%)%,$tmp_bsd_partition)%"`
+ fi
diff --git a/grub-install_xvd.patch b/grub-install_xvd.patch
new file mode 100644
index 000000000000..4e01d38134cb
--- /dev/null
+++ b/grub-install_xvd.patch
@@ -0,0 +1,13 @@
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -104,7 +104,7 @@
+ )"
+
+ # Convert RAID devices list into a list of disks
+- tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
++ tmp_disks=`echo "$devices" | sed -e 's%\(\(s\|h\|xv\)d[a-z]\)[0-9]*$%\1%' \
+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+ -e 's%\(fd[0-9]*\)$%\1%' \
+ -e 's%/part[0-9]*$%/disc%' \
diff --git a/grub-special_device_names.patch b/grub-special_device_names.patch
new file mode 100644
index 000000000000..cce811d05988
--- /dev/null
+++ b/grub-special_device_names.patch
@@ -0,0 +1,13 @@
+Index: b/lib/device.c
+===================================================================
+--- a/lib/device.c
++++ b/lib/device.c
+@@ -973,6 +973,8 @@
+ else
+ {
+ if ((strncmp (dev, "/dev/ataraid/", 13) == 0) ||
++ (strncmp (dev, "/dev/ida/", 9) == 0) ||
++ (strncmp (dev, "/dev/cciss/", 11) == 0) ||
+ (strncmp (dev, "/dev/rd/", 8) == 0))
+ strcpy (dev + strlen(dev), "p");
+ }
diff --git a/grub-xvd_drives.patch b/grub-xvd_drives.patch
new file mode 100644
index 000000000000..52c777383678
--- /dev/null
+++ b/grub-xvd_drives.patch
@@ -0,0 +1,51 @@
+Index: b/lib/device.c
+===================================================================
+--- a/lib/device.c
++++ b/lib/device.c
+@@ -395,6 +395,16 @@
+ #endif
+ }
+
++static void
++get_xvd_disk_name (char *name, int unit)
++{
++#ifdef __linux__
++ sprintf (name, "/dev/xvd%c", unit + 'a');
++#else
++# warning "Xen XVD drives cannot be guessed in your operating system."
++ *name = 0;
++#endif
++}
+ #ifdef __linux__
+ static void
+ get_dac960_disk_name (char *name, int controller, int drive)
+@@ -788,7 +798,28 @@
+ num_hd++;
+ }
+ }
+-
++
++#ifdef __linux__
++ /* Xen Virtual Disks. */
++ for (i = 0; i < 16; i++)
++ {
++ char name[16];
++
++ get_xvd_disk_name (name, i);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++#endif
++
+ #ifdef __linux__
+ /* This is for DAC960 - we have
+ /dev/rd/c<controller>d<logical drive>p<partition>.
diff --git a/i2o.patch b/i2o.patch
deleted file mode 100644
index 2af846c90f5e..000000000000
--- a/i2o.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-Only in grub-0.94/docs: grub.info
-Only in grub-0.94/docs: multiboot.info
-diff -ur grub-0.94/lib/device.c grub-0.94.new/lib/device.c
---- grub-0.94/lib/device.c 2004-05-07 04:50:36.375238696 +0200
-+++ grub-0.94.new/lib/device.c 2004-05-07 04:48:57.611253104 +0200
-@@ -419,6 +419,12 @@
- {
- sprintf (name, "/dev/rd/c%dd%d", controller, drive);
- }
-+
-+static void
-+get_i2o_disk_name (char *name, int unit)
-+{
-+ sprintf (name, "/dev/i2o/hd%c", unit + 'a');
-+}
- #endif
-
- /* Check if DEVICE can be read. If an error occurs, return zero,
-@@ -789,6 +795,26 @@
- }
- }
- }
-+
-+ /* I2O disks. */
-+ for (i = 0; i < 8; i++)
-+ {
-+ char name[16];
-+
-+ get_i2o_disk_name (name, i);
-+ if (check_device (name))
-+ {
-+ (*map)[num_hd + 0x80] = strdup (name);
-+ assert ((*map)[num_hd + 0x80]);
-+
-+ /* If the device map file is opened, write the map. */
-+ if (fp)
-+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+
-+ num_hd++;
-+ }
-+ }
-+
- #endif /* __linux__ */
-
- /* OK, close the device map file if opened. */
diff --git a/05-grub-0.97-initrdaddr.diff b/initrd_max_address.patch
index ccf5f3e54874..b04574b70e3d 100644
--- a/05-grub-0.97-initrdaddr.diff
+++ b/initrd_max_address.patch
@@ -1,5 +1,14 @@
---- grub-0.96/stage2/boot.c
-+++ grub-0.96/stage2/boot.c
+
+ Date: 2005-11-11
+ Author: Otavio Salvador
+ Comment: Stolen from SuSE grub package.
+ It fix the max address of initrd image and include a safe
+ default in case of it isn't available
+
+Index: b/stage2/boot.c
+===================================================================
+--- a/stage2/boot.c
++++ b/stage2/boot.c
@@ -824,8 +824,11 @@
moveto = (mbi.mem_upper + 0x400) << 10;
diff --git a/intelmac.patch b/intelmac.patch
index a3fabc7330d1..3b293a7d2b79 100644
--- a/intelmac.patch
+++ b/intelmac.patch
@@ -1,5 +1,7 @@
---- grub-0.97.orig/stage2/asm.S 2004-06-19 18:55:22.000000000 +0200
-+++ grub-0.97/stage2/asm.S 2006-04-21 11:10:52.000000000 +0200
+Index: b/stage2/asm.S
+===================================================================
+--- a/stage2/asm.S
++++ b/stage2/asm.S
@@ -1651,7 +1651,29 @@
jnz 3f
ret
@@ -64,4 +66,4 @@
+
call EXT_C(prot_to_real)
.code16
-
+
diff --git a/menu.lst_gnu-hurd.patch b/menu.lst_gnu-hurd.patch
new file mode 100644
index 000000000000..68c7bb8fac46
--- /dev/null
+++ b/menu.lst_gnu-hurd.patch
@@ -0,0 +1,21 @@
+Index: b/docs/menu.lst
+===================================================================
+--- a/docs/menu.lst
++++ b/docs/menu.lst
+@@ -11,11 +11,12 @@
+ # Fallback to the second entry.
+ fallback 1
+
+-# For booting GNU/Hurd
+-title GNU/Hurd
++# For booting GNU (also known as GNU/Hurd)
++title GNU (also known as GNU/Hurd)
+ root (hd0,0)
+-kernel /boot/gnumach.gz root=hd0s1
+-module /boot/serverboot.gz
++kernel /boot/gnumach.gz root=device:hd0s1
++module /hurd/ext2fs.static --multiboot-command-line=${kernel-command-line} --host-priv-port=${host-port} --device-master-port=${device-port} --exec-server-task=${exec-task} -T typed ${root} $(task-create) $(task-resume)
++module /lib/ld.so.1 /hurd/exec $(exec-task=task-create)
+
+ # For booting GNU/Linux
+ title GNU/Linux
diff --git a/automake-pkglib.patch b/modern-automake.patch
index a3fff27a129e..42855eaf6ffc 100644
--- a/automake-pkglib.patch
+++ b/modern-automake.patch
@@ -1,16 +1,37 @@
+Description: Adjust to work with modern Automake
+Author: Colin Watson <cjwatson@debian.org>
+Bug-Debian: http://bugs.debian.org/724383
+Forwarded: no
+Last-Update: 2013-09-24
+
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -60,8 +60,7 @@
+ _AM_DEPENDENCIES(CC)
+
+ dnl Because recent automake complains about AS, set it here.
+-CCAS="$CC"
+-AC_SUBST(CCAS)
++AM_PROG_AS
+
+ AC_ARG_WITH(binutils,
+ [ --with-binutils=DIR search the directory DIR to find binutils])
+Index: b/stage1/Makefile.am
+===================================================================
--- a/stage1/Makefile.am
+++ b/stage1/Makefile.am
-@@ -1,7 +1,7 @@
+@@ -1,5 +1,5 @@
-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-nodist_pkglib_DATA = stage1
-+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-+nodist_stage_DATA = stage1
++pkgdatadir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
++nodist_pkgdata_DATA = stage1
--CLEANFILES = $(nodist_pkglib_DATA)
-+CLEANFILES = $(nodist_stage_DATA)
+ CLEANFILES = $(nodist_pkglib_DATA)
- # We can't use builtins or standard includes.
- AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
+Index: b/stage2/Makefile.am
+===================================================================
--- a/stage2/Makefile.am
+++ b/stage2/Makefile.am
@@ -27,12 +27,12 @@
@@ -18,13 +39,13 @@
# Stage 2 and Stage 1.5's.
-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
++pkgdatadir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec
if DISKLESS_SUPPORT
-pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
++pkgdata_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
nbgrub pxegrub
@@ -33,7 +54,7 @@
xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
else
-pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
++pkgdata_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
noinst_DATA = pre_stage2 start start_eltorito
@@ -42,7 +63,7 @@
endif
-CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
-+CLEANFILES = $(stage_DATA) $(noinst_DATA) $(BUILT_SOURCES)
++CLEANFILES = $(pkgdata_DATA) $(noinst_DATA) $(BUILT_SOURCES)
stage2_size.h: pre_stage2
-rm -f stage2_size.h
diff --git a/more-raid.patch b/more-raid.patch
deleted file mode 100644
index 39db23474b9b..000000000000
--- a/more-raid.patch
+++ /dev/null
@@ -1,100 +0,0 @@
---- grub-0.95/lib/device.c.moreraid 2004-11-30 17:09:36.736099360 -0500
-+++ grub-0.95/lib/device.c 2004-11-30 17:12:17.319686944 -0500
-@@ -544,6 +544,17 @@
- }
-
- static void
-+get_cciss_disk_name (char * name, int controller, int drive)
-+{
-+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
-+}
-+
-+static void
-+get_cpqarray_disk_name (char * name, int controller, int drive)
-+{
-+ sprintf (name, "/dev/ida/c%dd%d", controller, drive);
-+}
-+static void
- get_ataraid_disk_name (char *name, int unit)
- {
- sprintf (name, "/dev/ataraid/d%c", unit + '0');
-@@ -920,7 +931,7 @@
-
- for (controller = 0; controller < 8; controller++)
- {
-- for (drive = 0; drive < 15; drive++)
-+ for (drive = 0; drive < 32; drive++)
- {
- char name[24];
-
-@@ -940,6 +951,70 @@
- }
- }
- #endif /* __linux__ */
-+
-+#ifdef __linux__
-+ /* This is for cciss - we have
-+ /dev/cciss/c<controller>d<logical drive>p<partition>.
-+
-+ cciss driver currently supports up to 8 controllers, 16 logical
-+ drives, and 7 partitions. */
-+ {
-+ int controller, drive;
-+
-+ for (controller = 0; controller < 8; controller++)
-+ {
-+ for (drive = 0; drive < 16; drive++)
-+ {
-+ char name[24];
-+
-+ get_cciss_disk_name (name, controller, drive);
-+ if (check_device (name))
-+ {
-+ (*map)[num_hd + 0x80] = strdup (name);
-+ assert ((*map)[num_hd + 0x80]);
-+
-+ /* If the device map file is opened, write the map. */
-+ if (fp)
-+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+
-+ num_hd++;
-+ }
-+ }
-+ }
-+ }
-+#endif /* __linux__ */
-+
-+#ifdef __linux__
-+ /* This is for cpqarray - we have
-+ /dev/ida/c<controller>d<logical drive>p<partition>.
-+
-+ cpqarray driver currently supports up to 8 controllers, 16 logical
-+ drives, and 15 partitions. */
-+ {
-+ int controller, drive;
-+
-+ for (controller = 0; controller < 8; controller++)
-+ {
-+ for (drive = 0; drive < 15; drive++)
-+ {
-+ char name[24];
-+
-+ get_cpqarray_disk_name (name, controller, drive);
-+ if (check_device (name))
-+ {
-+ (*map)[num_hd + 0x80] = strdup (name);
-+ assert ((*map)[num_hd + 0x80]);
-+
-+ /* If the device map file is opened, write the map. */
-+ if (fp)
-+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+
-+ num_hd++;
-+ }
-+ }
-+ }
-+ }
-+#endif /* __linux__ */
-
- /* OK, close the device map file if opened. */
- if (fp)
diff --git a/mprotect.patch b/mprotect.patch
new file mode 100644
index 000000000000..7d3e2ee3ae70
--- /dev/null
+++ b/mprotect.patch
@@ -0,0 +1,40 @@
+Index: b/grub/asmstub.c
+===================================================================
+--- a/grub/asmstub.c
++++ b/grub/asmstub.c
+@@ -42,6 +42,12 @@
+ #include <sys/time.h>
+ #include <termios.h>
+ #include <signal.h>
++#include <sys/mman.h>
++
++#include <limits.h>
++#ifndef PAGESIZE
++#define PAGESIZE 4096
++#endif
+
+ #ifdef __linux__
+ # include <sys/ioctl.h> /* ioctl */
+@@ -148,6 +154,22 @@
+ assert (grub_scratch_mem == 0);
+ scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
+ assert (scratch);
++
++ {
++ char *p;
++ int ret;
++
++ /* Align to a multiple of PAGESIZE, assumed to be a power of two. */
++ p = (char *) (((long) scratch) & ~(PAGESIZE - 1));
++
++ /* The simulated stack needs to be executable, since GCC uses stack
++ * trampolines to implement nested functions.
++ */
++ ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15,
++ PROT_READ | PROT_WRITE | PROT_EXEC);
++ assert (ret == 0);
++ }
++
+ grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
+
+ /* FIXME: simulate the memory holes using mprot, if available. */
diff --git a/no-combine-stack-adjustments.patch b/no-combine-stack-adjustments.patch
new file mode 100644
index 000000000000..0609be6708ca
--- /dev/null
+++ b/no-combine-stack-adjustments.patch
@@ -0,0 +1,27 @@
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -127,6 +127,22 @@
+ if test "x$no_reorder_functions_flag" = xyes; then
+ STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-reorder-functions"
+ fi
++ # GCC >= 4.6 supports -fno-combine-stack-adjustments; this defends us
++ # against optimisations that confuse the stack games played by GRUB
++ # itself.
++ AC_CACHE_CHECK([whether gcc has -fno-combine-stack-adjustments],
++ no_combine_stack_adjustments_flag, [
++ saved_CFLAGS=$CFLAGS
++ CFLAGS="-fno-combine-stack-adjustments"
++ AC_TRY_COMPILE(,
++ ,
++ no_combine_stack_adjustments_flag=yes,
++ no_combine_stack_adjustments_flag=no)
++ CFLAGS=$saved_CFLAGS
++ ])
++ if test "x$no_combine_stack_adjustments_flag" = xyes; then
++ GRUB_CFLAGS="$GRUB_CFLAGS -fno-combine-stack-adjustments"
++ fi
+ fi
+ fi
+
diff --git a/no-pie.patch b/no-pie.patch
new file mode 100644
index 000000000000..83246796a9a4
--- /dev/null
+++ b/no-pie.patch
@@ -0,0 +1,40 @@
+Description: Disable PIE for stage1 and stage2
+ This is no use for freestanding binaries and causes an explosion in binary
+ size.
+Author: Colin Watson <cjwatson@debian.org>
+Forwarded: no
+Last-Update: 2016-10-08
+
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -143,6 +143,28 @@
+ if test "x$no_combine_stack_adjustments_flag" = xyes; then
+ GRUB_CFLAGS="$GRUB_CFLAGS -fno-combine-stack-adjustments"
+ fi
++ # Disable PIE if possible.
++ AC_CACHE_CHECK([whether gcc has -fno-PIE],
++ no_pie_flag, [
++ saved_CFLAGS=$CFLAGS
++ CFLAGS="-fno-PIE"
++ AC_TRY_COMPILE(, , no_pie_flag=yes, no_pie_flag=no)
++ CFLAGS=$saved_CFLAGS
++ ])
++ if test "x$no_pie_flag" = xyes; then
++ STAGE1_CFLAGS="$STAGE1_CFLAGS -fno-PIE"
++ STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-PIE"
++ fi
++ AC_CACHE_CHECK([whether gcc has -no-pie],
++ no_pie_linker_flag, [
++ saved_LDFLAGS=$LDFLAGS
++ LDFLAGS="-no-pie"
++ AC_TRY_LINK(, , no_pie_linker_flag=yes, no_pie_linker_flag=no)
++ LDFLAGS=$saved_LDFLAGS
++ ])
++ if test "x$no_pie_linker_flag" = xyes; then
++ LDFLAGS="$LDFLAGS -no-pie"
++ fi
+ fi
+ fi
+
diff --git a/no-reorder-functions.patch b/no-reorder-functions.patch
new file mode 100644
index 000000000000..4ec4b3558552
--- /dev/null
+++ b/no-reorder-functions.patch
@@ -0,0 +1,27 @@
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -112,6 +112,22 @@
+ if test "x$grub_cv_cc_no_stack_protector" = xyes; then
+ STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector"
+ fi
++ # GCC >= 3.3 supports -fno-reorder-functions; this defends us against
++ # unlikely-to-be-executed functions being linked before _start with GCC
++ # >= 4.6.
++ AC_CACHE_CHECK([whether gcc has -fno-reorder-functions],
++ no_reorder_functions_flag, [
++ saved_CFLAGS=$CFLAGS
++ CFLAGS="-fno-reorder-functions"
++ AC_TRY_COMPILE(,
++ ,
++ no_reorder_functions_flag=yes,
++ no_reorder_functions_flag=no)
++ CFLAGS=$saved_CFLAGS
++ ])
++ if test "x$no_reorder_functions_flag" = xyes; then
++ STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-reorder-functions"
++ fi
+ fi
+ fi
+
diff --git a/objcopy-absolute.patch b/objcopy-absolute.patch
new file mode 100644
index 000000000000..3f8d2fbaf5b0
--- /dev/null
+++ b/objcopy-absolute.patch
@@ -0,0 +1,42 @@
+Description: Fix objcopy build-id handling
+ Take only .text section into account, as newer toolchains generate unique
+ build ids.
+ .
+ Backported from GRUB 2.
+Author: Lubomir Kundrak <lkundrak@redhat.com>
+Forwarded: no
+Last-Update: 2016-10-09
+
+Index: b/acinclude.m4
+===================================================================
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -61,7 +61,7 @@
+ else
+ AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
+ fi
+- if AC_TRY_COMMAND([${OBJCOPY-objcopy} -O binary conftest.exec conftest]); then :
++ if AC_TRY_COMMAND([${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then :
+ else
+ AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files])
+ fi
+Index: b/stage1/Makefile.am
+===================================================================
+--- a/stage1/Makefile.am
++++ b/stage1/Makefile.am
+@@ -12,4 +12,4 @@
+
+ SUFFIXES = .exec
+ .exec:
+- $(OBJCOPY) -O binary $< $@
++ $(OBJCOPY) -O binary -R .note* -R .comment* $< $@
+Index: b/stage2/Makefile.am
+===================================================================
+--- a/stage2/Makefile.am
++++ b/stage2/Makefile.am
+@@ -276,4 +276,4 @@
+ # General rule for making a raw binary.
+ SUFFIXES = .exec
+ .exec:
+- $(OBJCOPY) -O binary $< $@
++ $(OBJCOPY) -O binary -R .note* -R .comment* $< $@
diff --git a/print_func.patch b/print_func.patch
new file mode 100644
index 000000000000..b482857af846
--- /dev/null
+++ b/print_func.patch
@@ -0,0 +1,82 @@
+2006-01-05 Otavio Salvador <otavio@debian.org>
+
+ * Rediff.
+
+2005-16-10 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * docs/grub.texi: Added print command description.
+ * stage2/builtins.c(print_func): New function.
+ (builtin_print): New variable.
+ (builtin_table): Added builtin_print in table.
+
+Debian Status Following:
+ Added by: Otavio Salvador
+ Date: 2006-01-05
+
+Index: b/docs/grub.texi
+===================================================================
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -2696,6 +2696,7 @@
+ * module:: Load a module
+ * modulenounzip:: Load a module without decompression
+ * pause:: Wait for a key press
++* print:: Print a message
+ * quit:: Exit from the grub shell
+ * reboot:: Reboot your computer
+ * read:: Read data from memory
+@@ -3102,6 +3103,16 @@
+ @end deffn
+
+
++@node print
++@subsection print
++
++@deffn Command print message @dots{}
++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
++message will cause the speaker to emit the standard beep sound, which is
++useful for visually impaired people.
++@end deffn
++
++
+ @node quit
+ @subsection quit
+
+Index: b/stage2/builtins.c
+===================================================================
+--- a/stage2/builtins.c
++++ b/stage2/builtins.c
+@@ -2595,6 +2595,25 @@
+ "Probe I/O ports used for the drive DRIVE."
+ };
+
++/* print */
++static int
++print_func (char *arg, int flags)
++{
++ printf("%s\n", arg);
++
++ return 0;
++}
++
++static struct builtin builtin_print =
++{
++ "print",
++ print_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
++ "print [MESSAGE ...]",
++ "Print MESSAGE."
++};
++
++
+
+ /* kernel */
+ static int
+@@ -5142,6 +5161,7 @@
+ &builtin_parttype,
+ &builtin_password,
+ &builtin_pause,
++ &builtin_print,
+ #ifdef GRUB_UTIL
+ &builtin_quit,
+ #endif /* GRUB_UTIL */
diff --git a/raid.patch b/raid.patch
new file mode 100644
index 000000000000..18c250dd7c96
--- /dev/null
+++ b/raid.patch
@@ -0,0 +1,72 @@
+
+Copyright: Charles Steinkuehler <charles@steinkuehler.net>, except he borrowed
+some code from other sources. He's cooperative about rewriting and/or doing
+the paperwork.
+Upstream: pending
+
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -81,6 +81,50 @@
+ EOF
+ }
+
++# Usage: getraid_mdadm mddevice
++# Routine to find a physical device from an md device
++# If found, the first grub BIOS device (from device.map) is returned
++# If no BIOS drives match the RAID devices, the first device returned
++# from mdadm -D is returned
++getraid_mdadm() {
++ device=$1
++ mdadm=$(mdadm -D "$device") || {
++ echo "$PROG: mdadm -D $device failed" >&2
++ exit 1
++ }
++ eval "$(
++ echo "$mdadm" | awk '
++ $1 == "Number" && $2 == "Major" { start = 1; next }
++ $1 == "UUID" { print "uuid=" $3; start = 0; next }
++ !start { next }
++ $2 == 0 && $3 == 0 { next }
++ { devices = devices "\n" $NF }
++ END { print "devices='\''" devices "'\''" }
++ '
++ )"
++
++ # Convert RAID devices list into a list of disks
++ tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
++ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
++ -e 's%\(fd[0-9]*\)$%\1%' \
++ -e 's%/part[0-9]*$%/disc%' \
++ -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
++ -e '/^$/d' |
++ sed -n '1h;2,$H;${g;s/\n/|/g;p}'`
++
++ # Find first BIOS disk that's a member of the RAID array
++ # Default to first RAID member if no tmp_disks are BIOS devices
++ set -- `egrep $tmp_disks $device_map | \
++ sort | \
++ sed -n 1p `
++ device=${2:-${tmp_disks%%|*}}
++
++ # Return first partition on BIOS disk that's part of the RAID
++ echo "$devices" | \
++ sed -n "\:${device}:p" | \
++ sed -n 1p
++}
++
+ # Usage: convert os_device
+ # Convert an OS device to the corresponding GRUB drive.
+ # This part is OS-specific.
+@@ -96,6 +140,10 @@
+ # Break the device name into the disk part and the partition part.
+ case "$host_os" in
+ linux*)
++ # Find an actual physical device if we're passed a RAID device
++ case $1 in
++ /dev/md*) set -- `getraid_mdadm $1`
++ esac
+ tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+ -e 's%\(fd[0-9]*\)$%\1%' \
diff --git a/raid_cciss.patch b/raid_cciss.patch
new file mode 100644
index 000000000000..ad92016d5c2d
--- /dev/null
+++ b/raid_cciss.patch
@@ -0,0 +1,98 @@
+Index: b/lib/device.c
+===================================================================
+--- a/lib/device.c
++++ b/lib/device.c
+@@ -403,6 +403,18 @@
+ }
+
+ static void
++get_cciss_disk_name (char *name, int controller, int drive)
++{
++ sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
++}
++
++static void
++get_ida_disk_name (char *name, int controller, int drive)
++{
++ sprintf (name, "/dev/ida/c%dd%d", controller, drive);
++}
++
++static void
+ get_ataraid_disk_name (char *name, int unit)
+ {
+ sprintf (name, "/dev/ataraid/d%c", unit + '0');
+@@ -830,6 +842,74 @@
+ }
+ }
+ }
++
++ /* This is for CCISS, its like the DAC960 - we have
++ /dev/cciss/<controller>d<logical drive>p<partition>
++
++ It currently supports up to 3 controllers, 10 logical volumes
++ and 10 partitions
++
++ Code gratuitously copied from DAC960 above.
++ Horms <horms@verge.net.au> 23rd July 2004
++ */
++ {
++ int controller, drive;
++
++ for (controller = 0; controller < 2; controller++)
++ {
++ for (drive = 0; drive < 9; drive++)
++ {
++ char name[24];
++
++ get_cciss_disk_name (name, controller, drive);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++ }
++ }
++
++ /* This is for Compaq Smart Array, its like the DAC960 - we have
++ /dev/ida/<controller>d<logical drive>p<partition>
++
++ It currently supports up to 3 controllers, 10 logical volumes
++ and 15 partitions
++
++ Code gratuitously copied from DAC960 above.
++ Piotr Roszatycki <dexter@debian.org>
++ */
++ {
++ int controller, drive;
++
++ for (controller = 0; controller < 2; controller++)
++ {
++ for (drive = 0; drive < 9; drive++)
++ {
++ char name[24];
++
++ get_ida_disk_name (name, controller, drive);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++ }
++ }
+ #endif /* __linux__ */
+
+ /* OK, close the device map file if opened. */
diff --git a/savedefault.patch b/savedefault.patch
new file mode 100644
index 000000000000..e0749b9e8b72
--- /dev/null
+++ b/savedefault.patch
@@ -0,0 +1,183 @@
+Index: b/stage2/builtins.c
+===================================================================
+--- a/stage2/builtins.c
++++ b/stage2/builtins.c
+@@ -86,6 +86,10 @@
+ inside other functions. */
+ static int configfile_func (char *arg, int flags);
+
++static int savedefault_helper (char *arg, int flags);
++
++static int savedefault_shell (char *arg, int flags);
++
+ /* Initialize the data for builtins. */
+ void
+ init_builtins (void)
+@@ -3512,7 +3516,109 @@
+ static int
+ savedefault_func (char *arg, int flags)
+ {
+-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
++#if !defined(SUPPORT_DISKLESS)
++ #if !defined(GRUB_UTIL)
++ return savedefault_helper(arg, flags);
++ #else
++ return savedefault_shell(arg, flags);
++ #endif
++#else /* !SUPPORT_DISKLESS */
++ errnum = ERR_UNRECOGNIZED;
++ return 1;
++#endif /* !SUPPORT_DISKLESS */
++}
++
++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
++/* savedefault_shell */
++static int
++savedefault_shell(char *arg, int flags)
++ {
++ int once_only = 0;
++ int new_default;
++ int curr_default = -1;
++ int curr_prev_default = -1;
++ int new_prev_default = -1;
++ FILE *fp;
++ size_t bytes = 10;
++ char line[bytes];
++ char *default_file = (char *) DEFAULT_FILE_BUF;
++ char buf[bytes];
++ int i;
++
++ while (1)
++ {
++ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
++ {
++ char *p = arg + sizeof ("--default=") - 1;
++ if (! safe_parse_maxint (&p, &new_default))
++ return 1;
++ arg = skip_to (0, arg);
++ }
++ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
++ {
++ once_only = 1;
++ arg = skip_to (0, arg);
++ }
++ else
++ break;
++ }
++
++ *default_file = 0;
++ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
++ for (i = grub_strlen(default_file); i >= 0; i--)
++ if (default_file[i] == '/')
++ {
++ i++;
++ break;
++ }
++ default_file[i] = 0;
++ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
++
++ if(!(fp = fopen(default_file,"r")))
++ {
++ errnum = ERR_READ;
++ goto fail;
++ }
++
++ fgets(line, bytes, fp);
++ fclose(fp);
++
++ sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
++
++ if(curr_default != -1)
++ new_prev_default = curr_default;
++ else
++ {
++ if(curr_prev_default != -1)
++ new_prev_default = curr_prev_default;
++ else
++ new_prev_default = 0;
++ }
++
++ if(once_only)
++ sprintf(buf, "%d:%d", new_prev_default, new_default);
++ else
++ sprintf(buf, "%d", new_default);
++
++ if(!(fp = fopen(default_file,"w")))
++ {
++ errnum = ERR_READ;
++ goto fail;
++ }
++
++ fprintf(fp, buf);
++
++fail:
++ fclose(fp);
++ return errnum;
++}
++#endif
++
++/* savedefault_helper */
++static int
++savedefault_helper (char *arg, int flags)
++{
++#if !defined(SUPPORT_DISKLESS)
+ unsigned long tmp_drive = saved_drive;
+ unsigned long tmp_partition = saved_partition;
+ char *default_file = (char *) DEFAULT_FILE_BUF;
+@@ -3588,22 +3694,26 @@
+
+ disk_read_hook = disk_read_savesect_func;
+ len = grub_read (buf, sizeof (buf));
++ buf[9]='\0';/* Make sure grub_strstr() below terminates */
+ disk_read_hook = 0;
+ grub_close ();
+
+- if (len != sizeof (buf))
+- {
+- /* This is too small. Do not modify the file manually, please! */
+- errnum = ERR_READ;
+- goto fail;
+- }
+-
+ if (sector_count > 2)
+ {
+ /* Is this possible?! Too fragmented! */
+ errnum = ERR_FSYS_CORRUPT;
+ goto fail;
+ }
++
++ char *tmp;
++ if((tmp = grub_strstr(buf, ":")) != NULL)
++ {
++ int f_len = grub_strlen(buf) - grub_strlen(tmp);
++ char *def;
++ buf[f_len] = '\0';
++ def = buf;
++ safe_parse_maxint (&def, &entryno);
++ }
+
+ /* Set up a string to be written. */
+ grub_memset (buf, '\n', sizeof (buf));
+Index: b/stage2/stage2.c
+===================================================================
+--- a/stage2/stage2.c
++++ b/stage2/stage2.c
+@@ -934,8 +934,16 @@
+ len = grub_read (buf, sizeof (buf));
+ if (len > 0)
+ {
+- buf[sizeof (buf) - 1] = 0;
+- safe_parse_maxint (&p, &saved_entryno);
++ char *tmp;
++ char *def;
++ if((tmp = grub_strstr(p, ":")) != NULL)
++ {
++ *tmp++;
++ grub_strcpy(&def, &tmp);
++ }else
++ grub_strcpy(&def, &p);
++
++ safe_parse_maxint (&def, &saved_entryno);
+ }
+
+ grub_close ();
diff --git a/snapshot.patch b/snapshot.patch
new file mode 100644
index 000000000000..9388ccba7d1a
--- /dev/null
+++ b/snapshot.patch
@@ -0,0 +1,872 @@
+Description: Upstream snapshot up to 2009-07-02
+
+--- grub-0.97.orig/ChangeLog
++++ grub-0.97/ChangeLog
+@@ -1,3 +1,120 @@
++2009-07-02 Pavel Roskin <proski@gnu.org>
++
++ * docs/boot.S: Fix missing newline at the end.
++ * docs/boot.S.texi: Regenerate.
++
++2008-05-20 Robert Millan <rmh@aybabtu.com>
++
++ * netboot/cs89x0.c: Fix license violation.
++ * netboot/cs89x0.h: Likewise.
++
++2008-04-10 Pavel Roskin <proski@gnu.org>
++
++ * configure.ac: Always use "_cv_" in cache variables for
++ compatibility with Autoconf 2.62.
++
++2008-03-28 Robert Millan <rmh@aybabtu.com>
++
++ Surpass 1 TiB disk addressing limit. Note: there are no plans to handle
++ the 2 TiB disk limit in GRUB Legacy, since that would need considerable
++ rework. If you have >2TiB disks, use GRUB 2 instead.
++
++ * grub/asmstub.c (biosdisk): Add unsigned qualifier to `sector'.
++ * stage2/bios.c (biosdisk): Likewise.
++ * stage2/disk_io.c (rawread, devread, rawwrite, devwrite): Likewise.
++ * stage2/shared.h (rawread, devread, rawwrite, devwrite): Likewise.
++ * lib/device.c (get_drive_geometry): Replace BLKGETSIZE with
++ BLKGETSIZE64.
++
++2007-10-29 Pavel Roskin <proski@gnu.org>
++
++ * configure.ac: Test if '--build-id=none' is supported by the
++ linker and add it to LDFLAGS if possible. Build ID causes
++ objcopy to generate huge binary files.
++ * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when
++ linking, so that build ID doesn't break the test.
++ * stage1/Makefile.am: Preserve LDFLAGS, use stage1_exec_LDFLAGS.
++
++2007-02-22 Pavel Roskin <proski@gnu.org>
++
++ * stage2/iso9660.h: Remove unnecessary packed attributes.
++
++2007-02-22 Robert Millan <rmh@aybabtu.com>
++
++ * util/mkbimage: Update my email address, and remove my name from
++ some places where unnecessary credit is given.
++
++2006-09-10 Pavel Roskin <proski@gnu.org>
++
++ * netboot/natsemi.c: Fix compile error with gcc 4.1.1. Cast
++ cannot make a variable volatile - it should be declared as such.
++ * netboot/sis900.c: Likewise.
++
++2006-09-08 Pavel Roskin <proski@gnu.org>
++
++ * netboot/etherboot.h: Remove incorrect extern declarations of
++ the variables later declared static. Move BOOTP_DATA_ADDR ...
++ * netboot/main.c: ... here. Eliminate end_of_rfc1533 - it's
++ write-only.
++
++2006-06-24 Robert Millan <robertmh@gnu.org>
++
++ * lib/device.c (write_to_partition): /dev/ataraid/ and /dev/rd/
++ partitions have a "p" prefix. Add it.
++
++2006-06-24 Robert Millan <robertmh@gnu.org>
++
++ * lib/device.c (get_i2o_disk_name): New function.
++ (init_device_map) [__linux__]: Add support for I2O devices.
++
++2006-05-02 Pavel Roskin <proski@gnu.org>
++
++ * stage2/stage2.c (run_menu): Fix "savedefault" to save only top
++ level menu positions. Remember current position when calling a
++ submenu. Don't recalculate it when booting from a submenu.
++
++ * grub/main.c (main): Make sure the boot drive number doesn't
++ exceed 255.
++
++2006-05-02 Vesa Jaaskelainen <chaac@nic.fi>
++
++ * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2
++ to GRUB Legacy. Problem reported by Gerardo Richarte.
++
++2006-04-23 Robert Millan <robertmh@gnu.org>
++
++ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine.
++
++2006-04-20 Robert Millan <robertmh@gnu.org>
++
++ Fixes for kernel of FreeBSD:
++ * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl
++ before opening a device for writing.
++ * util/grub-install.in: Devices don't have this "r" prefix anymore.
++
++2006-04-16 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * docs/multiboot.texi: Correct the offset of address
++ fields. Reported by Jeroen Dekkers.
++
++2006-03-21 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * stage2/builtins.c (setup_func): Specify the size of DEVICE to
++ grub_strncat instead of a strange number 256. Reported by Vitaly
++ Fertman <vitaly@namesys.com>.
++
++2005-09-29 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * docs/multiboot.texi: Fix a bug in the byte order of
++ boot_device. I hope this won't affect any OS image.
++ Increased the version number to 0.6.94.
++
++2005-09-28 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * stage2/boot.c (load_image): Even if an OS image is an ELF
++ object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is
++ specified.
++
+ 2005-05-08 Yoshinori K. Okuji <okuji@enbug.org>
+
+ * configure.ac (AC_INIT): Upgraded to 0.97.
+--- grub-0.97.orig/THANKS
++++ grub-0.97/THANKS
+@@ -92,7 +92,7 @@
+ Neal H Walfield <neal@walfield.org>
+ Neelkanth Natu <neelnatu@yahoo.com>
+ OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
+-Pavel Roskin <pavel_roskin@geocities.com>
++Pavel Roskin <proski@gnu.org>
+ Per Lundberg <plundis@byggdok.se>
+ Peter Astrand <altic@lysator.liu.se>
+ Ralf Medow <ralf.medow@t-online.de>
+@@ -121,3 +121,4 @@
+ Yedidyah Bar-David <didi@post.tau.ac.il>
+ Yury V. Umanets <umka@namesys.com>
+ Yuri Zaporogets <yuriz@ukr.net>
++Vitaly Fertman <vitaly@namesys.com>
+--- grub-0.97.orig/acinclude.m4
++++ grub-0.97/acinclude.m4
+@@ -57,7 +57,7 @@
+ fi
+ grub_cv_prog_objcopy_absolute=yes
+ for link_addr in 2000 8000 7C00; do
+- if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
++ if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} ${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
+ else
+ AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
+ fi
+--- grub-0.97.orig/configure.ac
++++ grub-0.97/configure.ac
+@@ -86,13 +86,13 @@
+ fi
+ STAGE1_CFLAGS="-O2"
+ GRUB_CFLAGS="-O2"
+- AC_CACHE_CHECK([whether optimization for size works], size_flag, [
++ AC_CACHE_CHECK([whether optimization for size works], grub_cv_cc_Os, [
+ saved_CFLAGS=$CFLAGS
+ CFLAGS="-Os -g"
+- AC_TRY_COMPILE(, , size_flag=yes, size_flag=no)
++ AC_TRY_COMPILE(, , grub_cv_cc_Os=yes, grub_cv_cc_Os=no)
+ CFLAGS=$saved_CFLAGS
+ ])
+- if test "x$size_flag" = xyes; then
++ if test "x$grub_cv_cc_Os" = xyes; then
+ STAGE2_CFLAGS="-Os"
+ else
+ STAGE2_CFLAGS="-O2 -fno-strength-reduce -fno-unroll-loops"
+@@ -100,16 +100,16 @@
+ # OpenBSD has a GCC extension for protecting applications from
+ # stack smashing attacks, but GRUB doesn't want this feature.
+ AC_CACHE_CHECK([whether gcc has -fno-stack-protector],
+- no_stack_protector_flag, [
++ grub_cv_cc_no_stack_protector, [
+ saved_CFLAGS=$CFLAGS
+ CFLAGS="-fno-stack-protector"
+ AC_TRY_COMPILE(,
+ ,
+- no_stack_protector_flag=yes,
+- no_stack_protector_flag=no)
++ grub_cv_cc_no_stack_protector=yes,
++ grub_cv_cc_no_stack_protector=no)
+ CFLAGS=$saved_CFLAGS
+ ])
+- if test "x$no_stack_protector_flag" = xyes; then
++ if test "x$grub_cv_cc_no_stack_protector" = xyes; then
+ STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector"
+ fi
+ fi
+@@ -123,33 +123,44 @@
+ CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused -Wshadow"
+ CPPFLAGS="$CPPFLAGS -Wpointer-arith"
+
+-AC_CACHE_CHECK([whether -Wundef works], undef_flag, [
++AC_CACHE_CHECK([whether -Wundef works], grub_cv_cc_Wundef, [
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="-Wundef"
+- AC_TRY_COMPILE(, , undef_flag=yes, undef_flag=no)
++ AC_TRY_COMPILE(, , grub_cv_cc_Wundef=yes, grub_cv_cc_Wundef=no)
+ CPPFLAGS="$saved_CPPFLAGS"
+ ])
+
+ # The options `-falign-*' are supported by gcc 3.0 or later.
+ # Probably it is sufficient to only check for -falign-loops.
+-AC_CACHE_CHECK([whether -falign-loops works], [falign_loop_flag], [
++AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="-falign-loops=1"
+- AC_TRY_COMPILE(, , [falign_loop_flag=yes], [falign_loop_flag=no])
++ AC_TRY_COMPILE(, , [grub_cv_cc_falign_loop=yes], [grub_cv_cc_falign_loop=no])
+ CPPFLAGS="$saved_CPPFLAGS"
+ ])
+
+ # Force no alignment to save space.
+-if test "x$falign_loop_flag" = xyes; then
++if test "x$grub_cv_cc_falign_loop" = xyes; then
+ CPPFLAGS="$CPPFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+ else
+ CPPFLAGS="$CPPFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+ fi
+
+-if test "x$undef_flag" = xyes; then
++if test "x$grub_cv_cc_Wundef" = xyes; then
+ CPPFLAGS="$CPPFLAGS -Wundef"
+ fi
+
++# Check if build ID can be disabled in the linker
++AC_MSG_CHECKING([whether linker accepts `--build-id=none'])
++save_LDFLAGS="$LDFLAGS"
++LDFLAGS="$LDFLAGS -Wl,--build-id=none"
++AC_TRY_LINK(, , build_id_flag=yes, build_id_flag=no)
++AC_MSG_RESULT([$build_id_flag])
++LDFLAGS="$save_LDFLAGS"
++if test "x$build_id_flag" = xyes; then
++ LDFLAGS="$LDFLAGS -Wl,--build-id=none"
++fi
++
+ if test "x$with_binutils" != x; then
+ dnl AC_PATH_TOOL(OBJCOPY, objcopy, , "$with_binutils:$PATH")
+ AC_PATH_PROG(OBJCOPY, objcopy, , "$with_binutils:$PATH")
+--- grub-0.97.orig/docs/boot.S
++++ grub-0.97/docs/boot.S
+@@ -77,4 +77,3 @@
+
+ /* Our stack area. */
+ .comm stack, STACK_SIZE
+-
+\ No newline at end of file
+--- grub-0.97.orig/docs/boot.S.texi
++++ grub-0.97/docs/boot.S.texi
+@@ -77,4 +77,3 @@
+
+ /* @r{Our stack area.} */
+ .comm stack, STACK_SIZE
+-
+\ No newline at end of file
+--- grub-0.97.orig/docs/grub.8
++++ grub-0.97/docs/grub.8
+@@ -1,5 +1,5 @@
+ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
+-.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
++.TH GRUB "8" "September 2005" "grub (GNU GRUB 0.97)" FSF
+ .SH NAME
+ grub \- the grub shell
+ .SH SYNOPSIS
+--- grub-0.97.orig/docs/multiboot.texi
++++ grub-0.97/docs/multiboot.texi
+@@ -25,7 +25,7 @@
+ @ifinfo
+ Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
+ Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
+-Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of
+ this manual provided the copyright notice and this permission notice
+@@ -57,7 +57,7 @@
+ @vskip 0pt plus 1filll
+ Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
+ Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
+-Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of
+ this manual provided the copyright notice and this permission notice
+@@ -80,7 +80,7 @@
+ @top Multiboot Specification
+
+ This file documents Multiboot Specification, the proposal for the boot
+-sequence standard. This edition documents version 0.6.93.
++sequence standard. This edition documents version 0.6.94.
+ @end ifnottex
+
+ @menu
+@@ -426,7 +426,7 @@
+ kernel.
+
+ If bit 16 in the @samp{flags} word is set, then the fields at offsets
+-8-24 in the Multiboot header are valid, and the boot loader should use
++12-28 in the Multiboot header are valid, and the boot loader should use
+ them instead of the fields in the actual executable header to calculate
+ where to load the OS image. This information does not need to be
+ provided if the kernel image is in @sc{elf} format, but it @emph{must}
+@@ -677,7 +677,7 @@
+ @example
+ @group
+ +-------+-------+-------+-------+
+-| drive | part1 | part2 | part3 |
++| part3 | part2 | part1 | drive |
+ +-------+-------+-------+-------+
+ @end group
+ @end example
+@@ -1197,6 +1197,13 @@
+ @item
+ The maintainer changes to the GNU GRUB maintainer team
+ @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
++
++@item
++The byte order of the @samp{boot_device} in Multiboot information is
++reversed. This was a mistake.
++
++@item
++The offset of the address fields were wrong.
+ @end itemize
+
+ @item 0.6
+--- grub-0.97.orig/grub/asmstub.c
++++ grub-0.97/grub/asmstub.c
+@@ -55,6 +55,10 @@
+ # endif /* ! BLKFLSBUF */
+ #endif /* __linux__ */
+
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++# include <sys/sysctl.h>
++#endif
++
+ /* We want to prevent any circularararity in our stubs, as well as
+ libc name clashes. */
+ #define WITHOUT_LIBC_STUBS 1
+@@ -777,7 +781,39 @@
+
+ /* Open read/write, or read-only if that failed. */
+ if (! read_only)
+- disks[drive].flags = open (devname, O_RDWR);
++ {
++/* By default, kernel of FreeBSD does not allow overwriting MBR */
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++#define GEOM_SYSCTL "kern.geom.debugflags"
++ int old_flags, flags;
++ size_t sizeof_int = sizeof (int);
++
++ if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
++ grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++
++ if ((old_flags & 0x10) == 0)
++ {
++ /* "allow foot shooting", see geom(4) */
++ flags = old_flags | 0x10;
++
++ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
++ {
++ flags = old_flags;
++ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++ }
++ }
++ else
++ flags = old_flags;
++#endif
++ disks[drive].flags = open (devname, O_RDWR);
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++ if (flags != old_flags)
++ {
++ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
++ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++ }
++#endif
++ }
+
+ if (disks[drive].flags == -1)
+ {
+@@ -926,7 +962,7 @@
+
+ int
+ biosdisk (int subfunc, int drive, struct geometry *geometry,
+- int sector, int nsec, int segment)
++ unsigned int sector, int nsec, int segment)
+ {
+ char *buf;
+ int fd = geometry->flags;
+--- grub-0.97.orig/grub/main.c
++++ grub-0.97/grub/main.c
+@@ -32,6 +32,7 @@
+ #define WITHOUT_LIBC_STUBS 1
+ #include <shared.h>
+ #include <term.h>
++#include <device.h>
+
+ char *program_name = 0;
+ int use_config_file = 1;
+@@ -192,6 +193,12 @@
+ perror ("strtoul");
+ exit (1);
+ }
++ if (boot_drive >= NUM_DISKS)
++ {
++ fprintf (stderr, "boot_drive should be from 0 to %d\n",
++ NUM_DISKS - 1);
++ exit (1);
++ }
+ break;
+
+ case OPT_NO_CONFIG_FILE:
+--- grub-0.97.orig/lib/device.c
++++ grub-0.97/lib/device.c
+@@ -69,9 +69,9 @@
+ # ifndef CDROM_GET_CAPABILITY
+ # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
+ # endif /* ! CDROM_GET_CAPABILITY */
+-# ifndef BLKGETSIZE
+-# define BLKGETSIZE _IO(0x12,96) /* return device size */
+-# endif /* ! BLKGETSIZE */
++# ifndef BLKGETSIZE64
++# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */
++# endif /* ! BLKGETSIZE64 */
+ #endif /* __linux__ */
+
+ /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
+@@ -152,19 +152,19 @@
+ /* Linux */
+ {
+ struct hd_geometry hdg;
+- unsigned long nr;
++ unsigned long long nr;
+
+ if (ioctl (fd, HDIO_GETGEO, &hdg))
+ goto fail;
+
+- if (ioctl (fd, BLKGETSIZE, &nr))
++ if (ioctl (fd, BLKGETSIZE64, &nr))
+ goto fail;
+
+ /* Got the geometry, so save it. */
+ geom->cylinders = hdg.cylinders;
+ geom->heads = hdg.heads;
+ geom->sectors = hdg.sectors;
+- geom->total_sectors = nr;
++ geom->total_sectors = nr / 512;
+
+ goto success;
+ }
+@@ -407,6 +407,12 @@
+ {
+ sprintf (name, "/dev/ataraid/d%c", unit + '0');
+ }
++
++static void
++get_i2o_disk_name (char *name, char unit)
++{
++ sprintf (name, "/dev/i2o/hd%c", unit);
++}
+ #endif
+
+ /* Check if DEVICE can be read. If an error occurs, return zero,
+@@ -801,6 +807,29 @@
+ }
+ }
+ }
++
++ /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
++ {
++ int unit;
++
++ for (unit = 'a'; unit < 'f'; unit++)
++ {
++ char name[24];
++
++ get_i2o_disk_name (name, unit);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++ }
+ #endif /* __linux__ */
+
+ /* OK, close the device map file if opened. */
+@@ -861,6 +890,12 @@
+ if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+ strcpy (dev + strlen(dev) - 5, "/part");
+ }
++ else
++ {
++ if ((strncmp (dev, "/dev/ataraid/", 13) == 0) ||
++ (strncmp (dev, "/dev/rd/", 8) == 0))
++ strcpy (dev + strlen(dev), "p");
++ }
+ sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
+
+ /* Open the partition. */
+--- grub-0.97.orig/netboot/cs89x0.c
++++ grub-0.97/netboot/cs89x0.c
+@@ -1,3 +1,21 @@
++/**
++ Per an email message from Russ Nelson <nelson@crynwr.com> on
++ 18 March 2008 this file is now licensed under GPL Version 2.
++
++ From: Russ Nelson <nelson@crynwr.com>
++ Date: Tue, 18 Mar 2008 12:42:00 -0400
++ Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
++ -- quote from email
++ As copyright holder, if I say it doesn't conflict with the GPL,
++ then it doesn't conflict with the GPL.
++
++ However, there's no point in causing people's brains to overheat,
++ so yes, I grant permission for the code to be relicensed under the
++ GPLv2. Please make sure that this change in licensing makes its
++ way upstream. -russ
++ -- quote from email
++**/
++
+ /* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
+ /*
+ Permission is granted to distribute the enclosed cs89x0.[ch] driver
+--- grub-0.97.orig/netboot/cs89x0.h
++++ grub-0.97/netboot/cs89x0.h
+@@ -1,3 +1,21 @@
++/**
++ Per an email message from Russ Nelson <nelson@crynwr.com> on
++ 18 March 2008 this file is now licensed under GPL Version 2.
++
++ From: Russ Nelson <nelson@crynwr.com>
++ Date: Tue, 18 Mar 2008 12:42:00 -0400
++ Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
++ -- quote from email
++ As copyright holder, if I say it doesn't conflict with the GPL,
++ then it doesn't conflict with the GPL.
++
++ However, there's no point in causing people's brains to overheat,
++ so yes, I grant permission for the code to be relicensed under the
++ GPLv2. Please make sure that this change in licensing makes its
++ way upstream. -russ
++ -- quote from email
++**/
++
+ /* Copyright, 1988-1992, Russell Nelson, Crynwr Software
+
+ This program is free software; you can redistribute it and/or modify
+--- grub-0.97.orig/netboot/etherboot.h
++++ grub-0.97/netboot/etherboot.h
+@@ -531,9 +531,6 @@
+ extern int network_ready;
+ extern struct rom_info rom;
+ extern struct arptable_t arptable[MAX_ARP];
+-extern struct bootpd_t bootp_data;
+-#define BOOTP_DATA_ADDR (&bootp_data)
+-extern unsigned char *end_of_rfc1533;
+
+ /* config.c */
+ extern struct nic nic;
+--- grub-0.97.orig/netboot/main.c
++++ grub-0.97/netboot/main.c
+@@ -56,7 +56,8 @@
+ static unsigned long netmask;
+ static struct bootpd_t bootp_data;
+ static unsigned long xid;
+-static unsigned char *end_of_rfc1533 = NULL;
++
++#define BOOTP_DATA_ADDR (&bootp_data)
+
+ #ifndef NO_DHCP_SUPPORT
+ #endif /* NO_DHCP_SUPPORT */
+@@ -967,7 +968,6 @@
+
+ if (block == 0)
+ {
+- end_of_rfc1533 = NULL;
+ vendorext_isvalid = 0;
+
+ if (grub_memcmp (p, rfc1533_cookie, 4))
+@@ -1021,7 +1021,7 @@
+ }
+ else if (c == RFC1533_END)
+ {
+- end_of_rfc1533 = endp = p;
++ endp = p;
+ continue;
+ }
+ else if (c == RFC1533_NETMASK)
+--- grub-0.97.orig/netboot/natsemi.c
++++ grub-0.97/netboot/natsemi.c
+@@ -608,7 +608,7 @@
+ const char *p) /* Packet */
+ {
+ u32 status, to, nstype;
+- u32 tx_status;
++ volatile u32 tx_status;
+
+ /* Stop the transmitter */
+ outl(TxOff, ioaddr + ChipCmd);
+@@ -647,7 +647,7 @@
+
+ to = currticks() + TX_TIMEOUT;
+
+- while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
++ while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
+ /* wait */ ;
+
+ if (currticks() >= to) {
+--- grub-0.97.orig/netboot/sis900.c
++++ grub-0.97/netboot/sis900.c
+@@ -901,7 +901,7 @@
+ const char *p) /* Packet */
+ {
+ u32 status, to, nstype;
+- u32 tx_status;
++ volatile u32 tx_status;
+
+ /* Stop the transmitter */
+ outl(TxDIS, ioaddr + cr);
+@@ -940,7 +940,7 @@
+
+ to = currticks() + TX_TIMEOUT;
+
+- while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
++ while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
+ /* wait */ ;
+
+ if (currticks() >= to) {
+--- grub-0.97.orig/stage1/Makefile.am
++++ grub-0.97/stage1/Makefile.am
+@@ -5,7 +5,7 @@
+
+ # We can't use builtins or standard includes.
+ AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
+-LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
++stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
+
+ noinst_PROGRAMS = stage1.exec
+ stage1_exec_SOURCES = stage1.S stage1.h
+--- grub-0.97.orig/stage2/bios.c
++++ grub-0.97/stage2/bios.c
+@@ -47,7 +47,7 @@
+ return the error number. Otherwise, return 0. */
+ int
+ biosdisk (int read, int drive, struct geometry *geometry,
+- int sector, int nsec, int segment)
++ unsigned int sector, int nsec, int segment)
+ {
+ int err;
+
+--- grub-0.97.orig/stage2/boot.c
++++ grub-0.97/stage2/boot.c
+@@ -1,7 +1,7 @@
+ /* boot.c - load and bootstrap a kernel */
+ /*
+ * GRUB -- GRand Unified Bootloader
+- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
++ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -96,7 +96,7 @@
+ lh = (struct linux_kernel_header *) buffer;
+
+ /* ELF loading supported if multiboot, FreeBSD and NetBSD. */
+- if ((type == KERNEL_TYPE_MULTIBOOT
++ if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE))
+ || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
+ || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
+ || suggested_type == KERNEL_TYPE_NETBSD)
+--- grub-0.97.orig/stage2/builtins.c
++++ grub-0.97/stage2/builtins.c
+@@ -3830,15 +3830,15 @@
+ {
+ char tmp[16];
+ grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
+- grub_strncat (device, tmp, 256);
++ grub_strncat (device, tmp, sizeof (device));
+ }
+ if ((partition & 0x00FF00) != 0x00FF00)
+ {
+ char tmp[16];
+ grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
+- grub_strncat (device, tmp, 256);
++ grub_strncat (device, tmp, sizeof (device));
+ }
+- grub_strncat (device, ")", 256);
++ grub_strncat (device, ")", sizeof (device));
+ }
+
+ int embed_stage1_5 (char *stage1_5, int drive, int partition)
+--- grub-0.97.orig/stage2/disk_io.c
++++ grub-0.97/stage2/disk_io.c
+@@ -137,7 +137,7 @@
+ }
+
+ int
+-rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
++rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf)
+ {
+ int slen, sectors_per_vtrack;
+ int sector_size_bits = log2 (buf_geom.sector_size);
+@@ -261,7 +261,7 @@
+ */
+ if (disk_read_func)
+ {
+- int sector_num = sector;
++ unsigned int sector_num = sector;
+ int length = buf_geom.sector_size - byte_offset;
+ if (length > size)
+ length = size;
+@@ -291,7 +291,7 @@
+
+
+ int
+-devread (int sector, int byte_offset, int byte_len, char *buf)
++devread (unsigned int sector, int byte_offset, int byte_len, char *buf)
+ {
+ /*
+ * Check partition boundaries
+@@ -330,7 +330,7 @@
+
+ #ifndef STAGE1_5
+ int
+-rawwrite (int drive, int sector, char *buf)
++rawwrite (int drive, unsigned int sector, char *buf)
+ {
+ if (sector == 0)
+ {
+@@ -363,7 +363,7 @@
+ }
+
+ int
+-devwrite (int sector, int sector_count, char *buf)
++devwrite (unsigned int sector, int sector_count, char *buf)
+ {
+ #if defined(GRUB_UTIL) && defined(__linux__)
+ if (current_partition != 0xFFFFFF
+--- grub-0.97.orig/stage2/iso9660.h
++++ grub-0.97/stage2/iso9660.h
+@@ -73,11 +73,11 @@
+
+ typedef struct __iso_16bit {
+ u_int16_t l, b;
+-} iso_16bit_t __attribute__ ((packed));
++} iso_16bit_t;
+
+ typedef struct __iso_32bit {
+ u_int32_t l, b;
+-} iso_32bit_t __attribute__ ((packed));
++} iso_32bit_t;
+
+ typedef u_int8_t iso_date_t[7];
+
+--- grub-0.97.orig/stage2/shared.h
++++ grub-0.97/stage2/shared.h
+@@ -499,7 +499,11 @@
+ unsigned char linear_reserved_field_position;
+ unsigned long max_pixel_clock;
+
+- unsigned char reserved3[189];
++ /* Reserved field to make structure to be 256 bytes long, VESA BIOS
++ Extension 3.0 Specification says to reserve 189 bytes here but
++ that doesn't make structure to be 256 bytes. So additional one is
++ added here. */
++ unsigned char reserved3[189 + 1];
+ } __attribute__ ((packed));
+
+
+@@ -807,7 +811,7 @@
+ /* Low-level disk I/O */
+ int get_diskinfo (int drive, struct geometry *geometry);
+ int biosdisk (int subfunc, int drive, struct geometry *geometry,
+- int sector, int nsec, int segment);
++ unsigned int sector, int nsec, int segment);
+ void stop_floppy (void);
+
+ /* Command-line interface functions. */
+@@ -920,10 +924,10 @@
+ int gunzip_read (char *buf, int len);
+ #endif /* NO_DECOMPRESSION */
+
+-int rawread (int drive, int sector, int byte_offset, int byte_len, char *buf);
+-int devread (int sector, int byte_offset, int byte_len, char *buf);
+-int rawwrite (int drive, int sector, char *buf);
+-int devwrite (int sector, int sector_len, char *buf);
++int rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf);
++int devread (unsigned int sector, int byte_offset, int byte_len, char *buf);
++int rawwrite (int drive, unsigned int sector, char *buf);
++int devwrite (unsigned int sector, int sector_len, char *buf);
+
+ /* Parse a device string and initialize the global parameters. */
+ char *set_device (char *device);
+--- grub-0.97.orig/stage2/stage2.c
++++ grub-0.97/stage2/stage2.c
+@@ -651,7 +651,10 @@
+ *(new_heap++) = 0;
+
+ if (config_entries)
+- run_menu (heap, NULL, new_num_entries, new_heap, 0);
++ {
++ current_entryno = first_entry + entryno;
++ run_menu (heap, NULL, new_num_entries, new_heap, 0);
++ }
+ else
+ {
+ cls ();
+@@ -727,7 +730,8 @@
+ cur_entry = get_entry (config_entries, first_entry + entryno, 1);
+
+ /* Set CURRENT_ENTRYNO for the command "savedefault". */
+- current_entryno = first_entry + entryno;
++ if (config_entries)
++ current_entryno = first_entry + entryno;
+
+ if (run_script (cur_entry, heap))
+ {
+--- grub-0.97.orig/stamp-h.in
++++ grub-0.97/stamp-h.in
+@@ -0,0 +1 @@
++timestamp
+--- grub-0.97.orig/util/grub-install.in
++++ grub-0.97/util/grub-install.in
+@@ -112,8 +112,8 @@
+ tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
+ tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
+ freebsd* | kfreebsd*-gnu)
+- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
+- | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
++ tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
++ | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
+ tmp_part=`echo "$1" \
+ | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
+ | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
+--- grub-0.97.orig/util/mkbimage
++++ grub-0.97/util/mkbimage
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ # MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode
+ # C) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>
+-# C) 2001,2002,2003 Robert Millan <robertmh@gnu.org>
++# C) 2001,2002,2003 Robert Millan <rmh@aybabtu.com>
+
+
+ # This program is free software; you can redistribute it and/or modify
+@@ -94,15 +94,13 @@
+ display Version information and exit
+
+ Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
+-Copyright (c) 2001,2002 Robert Millan <zeratul2@wanadoo.es>.
+ GPLed."
+
+ version="mkbimage $version_number
+
+-Written by Thierry Laronde and Robert Millan.
++Written by Thierry Laronde.
+
+ Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
+-Copyright (c) 2001,2002,2003 Robert Millan <zeratul2@wanadoo.es>.
+
+ This is free software under the GPL version 2 or later; see the source for
+ copying conditions. There is NO warranty, not even for MERCHANTABILITY or
diff --git a/special-devices.patch b/special-devices.patch
deleted file mode 100644
index 894f3e8872e8..000000000000
--- a/special-devices.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- grub-0.93/lib/device.c.raid 2002-05-20 05:53:46.000000000 -0400
-+++ grub-0.93/lib/device.c 2002-12-28 23:24:10.000000000 -0500
-@@ -689,7 +689,14 @@
- if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
- strcpy (dev + strlen(dev) - 5, "/part");
- }
-- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
-+
-+ sprintf (dev + strlen(dev), "%s%d",
-+ /* Compaq smart and others */
-+ (strncmp(dev, "/dev/ida/", 9) == 0 ||
-+ strncmp(dev, "/dev/ataraid/", 13) == 0 ||
-+ strncmp(dev, "/dev/cciss/", 11) == 0 ||
-+ strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
-+ ((partition >> 16) & 0xFF) + 1);
-
- /* Open the partition. */
- fd = open (dev, O_RDWR);
diff --git a/splashimage_help.patch b/splashimage_help.patch
new file mode 100644
index 000000000000..afc9006a4709
--- /dev/null
+++ b/splashimage_help.patch
@@ -0,0 +1,35 @@
+
+ Date: 2005-11-11
+ Author: Otavio Salvador
+ Comment: Stolen from Fedora grub package.
+ Add document entry for splashimage option.
+
+Index: b/docs/grub.texi
+===================================================================
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -2199,6 +2199,7 @@
+ * rarp:: Initialize a network device via RARP
+ * serial:: Set up a serial device
+ * setkey:: Configure the key map
++* splashimage:: Use a splash image
+ * terminal:: Choose a terminal
+ * terminfo:: Define escape sequences for a terminal
+ * tftpserver:: Specify a TFTP server
+@@ -2578,6 +2579,16 @@
+ @end deffn
+
+
++@node splashimage
++@subsection splashimage
++
++@deffn Command splashimage file
++Select an image to use as the background image. This should be
++specified using normal GRUB device naming syntax. The format of the
++file is a gzipped xpm which is 640x480 with a 14 color palette.
++@end deffn
++
++
+ @node terminal
+ @subsection terminal
+
diff --git a/static-vars-on-stack.patch b/static-vars-on-stack.patch
new file mode 100644
index 000000000000..ce97a331dec0
--- /dev/null
+++ b/static-vars-on-stack.patch
@@ -0,0 +1,75 @@
+Description: Put pointers to static variables as arguments on the new stack
+ to get it working with gcc 7.
+Author: Bernhard Ãœbelacker <bernhardu@mailbox.org>
+Forwarded: no
+Bug-Debian: https://bugs.debian.org/898553
+Last-Update: 2018-07-06
+
+Index: b/grub/asmstub.c
+===================================================================
+--- a/grub/asmstub.c
++++ b/grub/asmstub.c
+@@ -123,32 +123,42 @@
+ char *scratch, *simstack;
+ int i;
+
+- auto void doit (void);
++ auto void doit_wrapper (void);
++ auto void doit (jmp_buf *p_env_for_exit, int *p_status);
+
++ void doit_wrapper (void)
++ {
++ asm volatile ("movl %%esp, %0\n\t"
++ "movl %2, %%esp\n\t" /* Make sure our stack lives in the simulated memory area. */
++ "pushl %1\n\t" /* Put realstack on the new stack */
++ "pushl %3\n\t" /* Put &status on the new stack */
++ "pushl %4\n\t" /* Put &env_for_exit on the new stack */
++ "call *%5\n\t" /* Call doit */
++ "popl %0\n\t" /* Remove &env_for_exit from the stack */
++ "popl %0\n\t" /* Remove &status from the stack */
++ "popl %0\n\t" /* Retrieve realstack from the new stack */
++ "movl %1, %%esp\n" /* Switch back to the original stack */
++ : "=&r" (realstack)
++ : "0" (realstack), "r" (simstack), "r" (&status), "r" (&env_for_exit), "r" (doit));
++ }
++
+ /* We need a nested function so that we get a clean stack frame,
+ regardless of how the code is optimized. */
+- void doit (void)
++ void doit (jmp_buf *p_env_for_exit, int *p_status)
+ {
+- /* Make sure our stack lives in the simulated memory area. */
+- asm volatile ("movl %%esp, %0\n\tmovl %1, %%esp\n"
+- : "=&r" (realstack) : "r" (simstack));
+-
+ /* Do a setjmp here for the stop command. */
+- if (! setjmp (env_for_exit))
++ if (! setjmp (*p_env_for_exit))
+ {
+ /* Actually enter the generic stage2 code. */
+- status = 0;
++ *p_status = 0;
+ init_bios_info ();
+ }
+ else
+ {
+ /* If ERRNUM is non-zero, then set STATUS to non-zero. */
+ if (errnum)
+- status = 1;
++ *p_status = 1;
+ }
+-
+- /* Replace our stack before we use any local variables. */
+- asm volatile ("movl %0, %%esp\n" : : "r" (realstack));
+ }
+
+ assert (grub_scratch_mem == 0);
+@@ -211,7 +221,7 @@
+
+ /* Set our stack, and go for it. */
+ simstack = (char *) PROTSTACKINIT;
+- doit ();
++ doit_wrapper ();
+
+ /* I don't know if this is necessary really. */
+ sync ();
diff --git a/use_grub-probe_in_grub-install.patch b/use_grub-probe_in_grub-install.patch
new file mode 100644
index 000000000000..d6d5bc78bc1d
--- /dev/null
+++ b/use_grub-probe_in_grub-install.patch
@@ -0,0 +1,148 @@
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -137,106 +137,12 @@
+ exit 1
+ fi
+
+- # Break the device name into the disk part and the partition part.
+- case "$host_os" in
+- linux*)
+ # Find an actual physical device if we're passed a RAID device
+ case $1 in
+- /dev/md*) set -- `getraid_mdadm $1`
++ /dev/md* | /dev/md/*) set -- `getraid_mdadm $1`
+ esac
+- tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
+- -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+- -e 's%\(fd[0-9]*\)$%\1%' \
+- -e 's%/part[0-9]*$%/disc%' \
+- -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
+- -e 's%\(e[0-9]\.[0-9]*\).*$%\1%'`
+- tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
+- -e 's%.*d[0-9]*p%%' \
+- -e 's%.*/fd[0-9]*$%%' \
+- -e 's%.*/floppy/[0-9]*$%%' \
+- -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
+- -e 's%.*c[0-7]d[0-9]*p*%%' \
+- -e 's%.*e[0-9]\.[0-9]*p%%' \
+- -e 's%.*e[0-9]\.[0-9]*\$%%'`
+- ;;
+- gnu*)
+- tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
+- tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
+- freebsd* | kfreebsd*-gnu)
+- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
+- | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
+- tmp_part=`echo "$1" \
+- | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
+- | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
+- ;;
+- netbsd* | knetbsd*-gnu)
+- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
+- | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
+- tmp_part=`echo "$1" \
+- | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
+- ;;
+- *)
+- echo "grub-install does not support your OS yet." 1>&2
+- exit 1 ;;
+- esac
+-
+- # Get the drive name.
+- tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
+- | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
+-
+- # If not found, print an error message and exit.
+- if test "x$tmp_drive" = x; then
+- echo "$1 does not have any corresponding BIOS drive." 1>&2
+- exit 1
+- fi
+
+- if test "x$tmp_part" != x; then
+- # If a partition is specified, we need to translate it into the
+- # GRUB's syntax.
+- case "$host_os" in
+- linux*)
+- echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
+- gnu*)
+- if echo $tmp_part | grep "^s" >/dev/null; then
+- tmp_pc_slice=`echo $tmp_part \
+- | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
+- tmp_drive=`echo "$tmp_drive" \
+- | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+- fi
+- if echo $tmp_part | grep "[a-z]$" >/dev/null; then
+- tmp_bsd_partition=`echo "$tmp_part" \
+- | sed "s%[^a-z]*\([a-z]\)$%\1%"`
+- tmp_drive=`echo "$tmp_drive" \
+- | sed "s%)%,$tmp_bsd_partition)%"`
+- fi
+- echo "$tmp_drive" ;;
+- freebsd* | kfreebsd*-gnu)
+- if echo $tmp_part | grep "^s" >/dev/null; then
+- tmp_pc_slice=`echo $tmp_part \
+- | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
+- tmp_drive=`echo "$tmp_drive" \
+- | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+- fi
+- if echo $tmp_part | grep "[a-h]$" >/dev/null; then
+- tmp_bsd_partition=`echo "$tmp_part" \
+- | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
+- tmp_drive=`echo "$tmp_drive" \
+- | sed "s%)%,$tmp_bsd_partition)%"`
+- fi
+- echo "$tmp_drive" ;;
+- netbsd* | knetbsd*-gnu)
+- if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
+- tmp_bsd_partition=`echo "$tmp_part" \
+- | sed "s%\([a-p]\)$%\1%"`
+- tmp_drive=`echo "$tmp_drive" \
+- | sed "s%)%,$tmp_bsd_partition)%"`
+- fi
+- echo "$tmp_drive" ;;
+- esac
+- else
+- # If no partition is specified, just print the drive name.
+- echo "$tmp_drive"
+- fi
++ GRUB_LEGACY_0_BASED_PARTITIONS=1 grub-probe --device-map=${device_map} -t drive -d "$1"
+ }
+
+ # Usage: resolve_symlink file
+@@ -265,9 +171,7 @@
+ # Usage: find_device file
+ # Find block device on which the file resides.
+ find_device () {
+- # For now, this uses the program `df' to get the device name, but is
+- # this really portable?
+- tmp_fname=`df $1/ | sed -n 's%.*\(/dev/[^ ]*\).*%\1%p'`
++ tmp_fname=`grub-probe --device-map=${device_map} -t device $1/`
+
+ if test -z "$tmp_fname"; then
+ echo "Could not find device for $1" 2>&1
+@@ -384,22 +288,7 @@
+ if test -f "$device_map"; then
+ :
+ else
+- # Create a safe temporary file.
+- test -n "$mklog" && log_file=`$mklog`
+-
+- # Before all invocations of the grub shell, call sync to make sure
+- # the raw device is in sync with any bufferring in filesystems.
+- sync
+-
+- $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+-quit
+-EOF
+- if grep "Error [0-9]*: " $log_file >/dev/null; then
+- cat $log_file 1>&2
+- exit 1
+- fi
+-
+- rm -f $log_file
++ grub-mkdevicemap $no_floppy --device-map=$device_map
+ fi
+
+ # Make sure that there is no duplicated entry.
diff --git a/xfs_freeze.patch b/xfs_freeze.patch
new file mode 100644
index 000000000000..694456006bfd
--- /dev/null
+++ b/xfs_freeze.patch
@@ -0,0 +1,22 @@
+Index: b/util/grub-install.in
+===================================================================
+--- a/util/grub-install.in
++++ b/util/grub-install.in
+@@ -470,6 +470,17 @@
+ test -n "$mkimg" && img_file=`$mkimg`
+ test -n "$mklog" && log_file=`$mklog`
+
++# GRUB will try to verify that stage2 is accessible using its own
++# filesystem drivers. Make sure it's committed to disk.
++sync
++
++# On XFS, sync() is not enough.
++if [ x"`grub-probe --device-map=${device_map} -t fs ${grubdir}`" = "xxfs" ] ; then
++ xfs_freeze -f ${grubdir} && xfs_freeze -u ${grubdir}
++ # We don't have set -e. If xfs_freeze failed, it's worth trying anyway,
++ # maybe we're lucky.
++fi
++
+ for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+ count=5
+ tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"`