summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Legner2015-06-12 11:26:48 +0200
committerSimon Legner2015-06-12 11:26:48 +0200
commit46422992f7cc2291ab4af881b29ceca5b0aa3667 (patch)
tree0bd138eb0ea40d9cc1faf4fef4b3a6595a347d89
downloadaur-46422992f7cc2291ab4af881b29ceca5b0aa3667.tar.gz
Initial import
-rw-r--r--.SRCINFO44
-rw-r--r--040_all_grub-0.96-nxstack.patch623
-rw-r--r--05-grub-0.97-initrdaddr.diff16
-rw-r--r--PKGBUILD95
-rw-r--r--automake-pkglib.patch48
-rw-r--r--ext4.patch263
-rw-r--r--grub-0.97-ldflags-objcopy-remove-build-id.patch196
-rw-r--r--grub-inode-size.patch100
-rw-r--r--grub.install20
-rw-r--r--i2o.patch45
-rwxr-xr-xinstall-grub204
-rw-r--r--intelmac.patch67
-rw-r--r--menu.lst48
-rw-r--r--more-raid.patch100
-rw-r--r--special-devices.patch18
15 files changed, 1887 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..c61025286e5c
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,44 @@
+pkgbase = grub-legacy
+ pkgdesc = A GNU multiboot boot loader
+ pkgver = 0.97
+ pkgrel = 25
+ url = http://www.gnu.org/software/grub/
+ install = grub.install
+ arch = i686
+ arch = x86_64
+ license = GPL
+ depends = ncurses
+ depends = diffutils
+ depends = sed
+ optdepends = xfsprogs: freezing of xfs /boot in install-grub script
+ conflicts = grub
+ backup = boot/grub/menu.lst
+ source = ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz
+ 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 = intelmac.patch
+ source = grub-inode-size.patch
+ source = ext4.patch
+ source = grub-0.97-ldflags-objcopy-remove-build-id.patch
+ source = automake-pkglib.patch
+ sha1sums = 2580626c4579bd99336d3af4482c346c95dac4fb
+ sha1sums = 33d43d48000b2027f9baec8fc99d33e0c4500c96
+ sha1sums = 60e8f7e4c113b85165fd5d9cd724e8413a337a12
+ sha1sums = 157b81dbad3576536b08642242accfa1aeb093a9
+ sha1sums = adbb4685c98797ffb4dc83561ec75698991dddbd
+ sha1sums = f2e0dff29a7c8a45e90aa07298a1b2a9a9d29afc
+ sha1sums = c5e2c94ed0e759590b9eb38c9d979f075d19d7c0
+ sha1sums = 45fe668a3779664fb292591f426976b6c784d6c8
+ sha1sums = 066d7ab1ae442f88e94c9e4f1867ac6682965d06
+ sha1sums = 0436aa6fa0b6f768289172f983a3f4b69384629e
+ sha1sums = a36f34e51efed540f1ddafd78e9c9f6d83e4c8d4
+ sha1sums = 61c4b58d2eaa3c1561d8e9d8fc41341ce8882869
+ sha1sums = 776ed278eb8ff80e949834f763fad68b8741e7cd
+
+pkgname = grub-legacy
+
diff --git a/040_all_grub-0.96-nxstack.patch b/040_all_grub-0.96-nxstack.patch
new file mode 100644
index 000000000000..121941c75787
--- /dev/null
+++ b/040_all_grub-0.96-nxstack.patch
@@ -0,0 +1,623 @@
+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/05-grub-0.97-initrdaddr.diff b/05-grub-0.97-initrdaddr.diff
new file mode 100644
index 000000000000..ccf5f3e54874
--- /dev/null
+++ b/05-grub-0.97-initrdaddr.diff
@@ -0,0 +1,16 @@
+--- grub-0.96/stage2/boot.c
++++ grub-0.96/stage2/boot.c
+@@ -824,8 +824,11 @@
+ moveto = (mbi.mem_upper + 0x400) << 10;
+
+ moveto = (moveto - len) & 0xfffff000;
+- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
+- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
++ max_addr = LINUX_INITRD_MAX_ADDRESS;
++ if (lh->header == LINUX_MAGIC_SIGNATURE &&
++ lh->version >= 0x0203 &&
++ lh->initrd_addr_max < max_addr)
++ max_addr = lh->initrd_addr_max;
+ if (moveto + len >= max_addr)
+ moveto = (max_addr - len) & 0xfffff000;
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..d9a23485e640
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,95 @@
+# $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>
+
+pkgname=grub-legacy
+_srcname=grub
+pkgver=0.97
+pkgrel=25
+pkgdesc="A GNU multiboot boot loader"
+arch=('i686' 'x86_64')
+license=('GPL')
+url="http://www.gnu.org/software/grub/"
+depends=('ncurses' 'diffutils' 'sed')
+conflicts=('grub')
+[ "$CARCH" = 'x86_64' ] && makedepends=('gcc-multilib')
+optdepends=('xfsprogs: freezing of xfs /boot in install-grub script')
+source=(ftp://alpha.gnu.org/gnu/grub/${_srcname}-${pkgver}.tar.gz
+ 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
+ intelmac.patch
+ grub-inode-size.patch
+ ext4.patch
+ grub-0.97-ldflags-objcopy-remove-build-id.patch
+ automake-pkglib.patch)
+backup=('boot/grub/menu.lst')
+install=grub.install
+sha1sums=('2580626c4579bd99336d3af4482c346c95dac4fb'
+ '33d43d48000b2027f9baec8fc99d33e0c4500c96'
+ '60e8f7e4c113b85165fd5d9cd724e8413a337a12'
+ '157b81dbad3576536b08642242accfa1aeb093a9'
+ 'adbb4685c98797ffb4dc83561ec75698991dddbd'
+ 'f2e0dff29a7c8a45e90aa07298a1b2a9a9d29afc'
+ 'c5e2c94ed0e759590b9eb38c9d979f075d19d7c0'
+ '45fe668a3779664fb292591f426976b6c784d6c8'
+ '066d7ab1ae442f88e94c9e4f1867ac6682965d06'
+ '0436aa6fa0b6f768289172f983a3f4b69384629e'
+ 'a36f34e51efed540f1ddafd78e9c9f6d83e4c8d4'
+ '61c4b58d2eaa3c1561d8e9d8fc41341ce8882869'
+ '776ed278eb8ff80e949834f763fad68b8741e7cd')
+
+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
+
+ 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"
+
+ ## recreate ./configure script with the required changes in LDFLAGS and objcopy
+ aclocal
+ autoconf
+ autoreconf -i
+ automake
+
+ 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" ./configure --prefix=/usr --bindir=/usr/bin --sbindir=/usr/bin \
+ --mandir=/usr/share/man --infodir=/usr/share/info
+ else
+ CFLAGS="-fno-strict-aliasing" ./configure --prefix=/usr --bindir=/usr/bin --sbindir=/usr/bin \
+ --mandir=/usr/share/man --infodir=/usr/share/info
+ fi
+}
+
+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
+
+}
diff --git a/automake-pkglib.patch b/automake-pkglib.patch
new file mode 100644
index 000000000000..a3fff27a129e
--- /dev/null
+++ b/automake-pkglib.patch
@@ -0,0 +1,48 @@
+--- a/stage1/Makefile.am
++++ b/stage1/Makefile.am
+@@ -1,7 +1,7 @@
+-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
+-nodist_pkglib_DATA = stage1
++stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
++nodist_stage_DATA = stage1
+
+-CLEANFILES = $(nodist_pkglib_DATA)
++CLEANFILES = $(nodist_stage_DATA)
+
+ # We can't use builtins or standard includes.
+ AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
+--- a/stage2/Makefile.am
++++ b/stage2/Makefile.am
+@@ -27,12 +27,12 @@
+ -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
+
+ # Stage 2 and Stage 1.5's.
+-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
++stagedir = $(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 \
+ 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
+@@ -43,7 +43,7 @@
+ reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
+ 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 \
+ 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
+@@ -112,7 +112,7 @@
+ BUILT_SOURCES = stage2_size.h
+ endif
+
+-CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
++CLEANFILES = $(stage_DATA) $(noinst_DATA) $(BUILT_SOURCES)
+
+ stage2_size.h: pre_stage2
+ -rm -f stage2_size.h
diff --git a/ext4.patch b/ext4.patch
new file mode 100644
index 000000000000..8a2f9bdb0a79
--- /dev/null
+++ b/ext4.patch
@@ -0,0 +1,263 @@
+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;
+ #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+ #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
++/* Inode flags */
++#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
++
+ /* include/linux/ext2_fs.h */
+ struct ext2_super_block
+ {
+@@ -191,6 +194,42 @@ struct ext2_dir_entry
+ #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
+ ~EXT2_DIR_ROUND)
+
++/* linux/ext4_fs_extents.h */
++/*
++ * This is the extent on-disk structure.
++ * It's used at the bottom of the tree.
++ */
++struct ext4_extent {
++ __u32 ee_block; /* first logical block extent covers */
++ __u16 ee_len; /* number of blocks covered by extent */
++ __u16 ee_start_hi; /* high 16 bits of physical block */
++ __u32 ee_start; /* low 32 bits of physical block */
++};
++
++/*
++ * This is index on-disk structure.
++ * It's used at all the levels except the bottom.
++ */
++struct ext4_extent_idx {
++ __u32 ei_block; /* index covers logical blocks from 'block' */
++ __u32 ei_leaf; /* pointer to the physical block of the next *
++ * level. leaf or next index could be there */
++ __u16 ei_leaf_hi; /* high 16 bits of physical block */
++ __u16 ei_unused;
++};
++
++/*
++ * Each block (leaves and indexes), even inode-stored has header.
++ */
++struct ext4_extent_header {
++ __u16 eh_magic; /* probably will support different formats */
++ __u16 eh_entries; /* number of valid entries */
++ __u16 eh_max; /* capacity of store in entries */
++ __u16 eh_depth; /* has tree real underlying blocks? */
++ __u32 eh_generation; /* generation of the tree */
++};
++
++#define EXT4_EXT_MAGIC 0xf30a
+
+ /* ext2/super.c */
+ #define log2(n) ffz(~(n))
+@@ -279,6 +318,26 @@ ext2_rdfsb (int fsblock, int buffer)
+ EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
+ }
+
++/* Walk through extents index tree to find the good leaf */
++static struct ext4_extent_header *
++ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block)
++{
++ int i;
++ struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1);
++ if (extent_block->eh_magic != EXT4_EXT_MAGIC)
++ return NULL;
++ if (extent_block->eh_depth == 0)
++ return extent_block;
++ for (i = 0; i < extent_block->eh_entries; i++)
++ {
++ if (logical_block < index[i].ei_block)
++ break;
++ }
++ if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1))
++ return NULL;
++ 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 @@
+ }
+ 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
+- 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))
+- {
+- errnum = ERR_FSYS_CORRUPT;
+- return -1;
+- }
+- mapblock1 = 1;
+- return ((__u32 *) DATABLOCK1)[logical_block];
+- }
+- /* else */
+- logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
+- /* now try the double indirect block */
+- 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;
+- }
+- 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;
+- }
+- 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 */
++ logical_block -= EXT2_NDIR_BLOCKS;
++ /* 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;
++ }
++ mapblock1 = 1;
++ return ((__u32 *) DATABLOCK1)[logical_block];
++ }
++ /* else */
++ logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
++ /* now try the double indirect block */
++ 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;
++ }
++ 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;
++ }
++ mapblock2 = bnum;
++ return ((__u32 *) DATABLOCK2)
++ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
++ }
++ /* else */
++ mapblock2 = -1;
++ logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
++ if (mapblock1 != 3
++ && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
++ mapblock1 = 3;
++ if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
++ [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
++ * 2)],
++ DATABLOCK2))
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
++ if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
++ [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
++ & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
++ DATABLOCK2))
++ {
++ errnum = ERR_FSYS_CORRUPT;
++ return -1;
++ }
+ return ((__u32 *) DATABLOCK2)
+- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
+- }
+- /* else */
+- mapblock2 = -1;
+- logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
+- if (mapblock1 != 3
+- && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
+- {
+- 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)
+- * 2)],
+- DATABLOCK2))
+- {
+- errnum = ERR_FSYS_CORRUPT;
+- return -1;
+- }
+- if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
+- [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
+- & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
+- DATABLOCK2))
++ /* 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 *extent = (struct ext4_extent *) (extent_hdr + 1);
++ if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC)
++ {
++ 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;
+ }
+- return ((__u32 *) DATABLOCK2)
+- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
+ }
+
+ /* preconditions: all preconds of ext2fs_block_map */
diff --git a/grub-0.97-ldflags-objcopy-remove-build-id.patch b/grub-0.97-ldflags-objcopy-remove-build-id.patch
new file mode 100644
index 000000000000..2b7cc32d02e3
--- /dev/null
+++ b/grub-0.97-ldflags-objcopy-remove-build-id.patch
@@ -0,0 +1,196 @@
+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-inode-size.patch b/grub-inode-size.patch
new file mode 100644
index 000000000000..f5ceb110bff0
--- /dev/null
+++ b/grub-inode-size.patch
@@ -0,0 +1,100 @@
+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
+@@ -79,7 +79,52 @@
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+- __u32 s_reserved[235]; /* Padding to the end of the block */
++ /*
++ * These fields are for EXT2_DYNAMIC_REV superblocks only.
++ *
++ * Note: the difference between the compatible feature set and
++ * the incompatible feature set is that if there is a bit set
++ * in the incompatible feature set that the kernel doesn't
++ * know about, it should refuse to mount the filesystem.
++ *
++ * e2fsck's requirements are more strict; if it doesn't know
++ * about a feature in either the compatible or incompatible
++ * feature set, it must abort and not try to meddle with
++ * things it doesn't understand...
++ */
++ __u32 s_first_ino; /* First non-reserved inode */
++ __u16 s_inode_size; /* size of inode structure */
++ __u16 s_block_group_nr; /* block group # of this superblock */
++ __u32 s_feature_compat; /* compatible feature set */
++ __u32 s_feature_incompat; /* incompatible feature set */
++ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
++ __u8 s_uuid[16]; /* 128-bit uuid for volume */
++ char s_volume_name[16]; /* volume name */
++ char s_last_mounted[64]; /* directory where last mounted */
++ __u32 s_algorithm_usage_bitmap; /* For compression */
++ /*
++ * Performance hints. Directory preallocation should only
++ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
++ */
++ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
++ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
++ __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
++ /*
++ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
++ */
++ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
++ __u32 s_journal_inum; /* inode number of journal file */
++ __u32 s_journal_dev; /* device number of journal file */
++ __u32 s_last_orphan; /* start of list of inodes to delete */
++ __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;
++ __u32 s_default_mount_opts;
++ __u32 s_first_meta_bg; /* First metablock group */
++ __u32 s_mkfs_time; /* When the filesystem was created */
++ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
++ __u32 s_reserved[172]; /* Padding to the end of the block */
+ };
+
+ struct ext2_group_desc
+@@ -218,6 +263,14 @@
+ #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_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_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
++
+ /* linux/ext2_fs.h */
+ #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
+ /* kind of from ext2/super.c */
+@@ -553,7 +606,7 @@
+ gdp = GROUP_DESC;
+ ino_blk = gdp[desc].bg_inode_table +
+ (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
+- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
++ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
+ #ifdef E2DEBUG
+ printf ("inode table fsblock=%d\n", ino_blk);
+ #endif /* E2DEBUG */
+@@ -565,13 +618,12 @@
+ /* reset indirect blocks! */
+ mapblock2 = mapblock1 = -1;
+
+- raw_inode = INODE +
+- ((current_ino - 1)
+- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
++ raw_inode = (struct ext2_inode *)((char *)INODE +
++ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
++ EXT2_INODE_SIZE (SUPERBLOCK));
+ #ifdef E2DEBUG
+ printf ("ipb=%d, sizeof(inode)=%d\n",
+- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
+- sizeof (struct ext2_inode));
++ EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
+ 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/grub.install b/grub.install
new file mode 100644
index 000000000000..c1f077d59d92
--- /dev/null
+++ b/grub.install
@@ -0,0 +1,20 @@
+infodir=/usr/share/info
+filelist=(grub.info multiboot.info)
+
+post_install() {
+ [ -x usr/bin/install-info ] || return 0
+ for file in ${filelist[@]}; do
+ install-info $infodir/$file.gz $infodir/dir 2> /dev/null
+ done
+}
+
+post_upgrade() {
+ post_install $1
+}
+
+pre_remove() {
+ [ -x usr/bin/install-info ] || return 0
+ for file in ${filelist[@]}; do
+ install-info --delete $infodir/$file.gz $infodir/dir 2> /dev/null
+ done
+}
diff --git a/i2o.patch b/i2o.patch
new file mode 100644
index 000000000000..2af846c90f5e
--- /dev/null
+++ b/i2o.patch
@@ -0,0 +1,45 @@
+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/install-grub b/install-grub
new file mode 100755
index 000000000000..70b06600b202
--- /dev/null
+++ b/install-grub
@@ -0,0 +1,204 @@
+#!/bin/bash
+
+#
+# This is a little helper script that tries to convert linux-style device
+# names to grub-style. It's not very smart, so it
+# probably won't work for more complicated setups.
+#
+# If it doesn't work for you, try installing grub manually:
+#
+# # mkdir -p /boot/grub
+# # cp /usr/lib/grub/i386-pc/* /boot/grub/
+#
+# Then start up the 'grub' shell and run something like the following:
+#
+# grub> root (hd0,0)
+# grub> setup (hd0)
+#
+# The "root" line should point to the partition your kernel is located on,
+# /boot if you have a separate boot partition, otherwise your root (/).
+#
+# The "setup" line tells grub which disc/partition to install the
+# bootloader to. In the example above, it will install to the MBR of the
+# primary master hard drive.
+#
+
+usage() {
+ echo "usage: install-grub <install_device> [boot_device]"
+ echo
+ echo "where <install_device> is the device where Grub will be installed"
+ echo "and [boot_device] is the partition that contains the /boot"
+ echo "directory (auto-detected if omitted)"
+ echo
+ echo "examples: install-grub /dev/hda"
+ echo " install-grub /dev/hda /dev/hda1"
+ echo
+ exit 0
+}
+
+## new install-grub, code was taken from setup script
+ROOTDEV=${1}
+PART_ROOT=${2}
+
+if [ "${ROOTDEV}" = "" ]; then
+ usage
+fi
+if [ "${PART_ROOT}" = "" ]; then
+ PART_ROOT=$(mount | grep "on /boot type" | cut -d' ' -f 1)
+fi
+if [ "$PART_ROOT" = "" ]; then
+ PART_ROOT=$(mount | grep "on / type" | cut -d' ' -f 1)
+fi
+if [ "${PART_ROOT}" = "" ]; then
+ echo "error: could not determine BOOT_DEVICE, please specify manually" >&2
+ exit 1
+fi
+
+
+get_grub_map() {
+ [ -e /tmp/dev.map ] && rm /tmp/dev.map
+ /sbin/grub --no-floppy --device-map /tmp/dev.map >/tmp/grub.log 2>&1 <<EOF
+quit
+EOF
+}
+
+mapdev() {
+ partition_flag=0
+ device_found=0
+ devs=$(cat /tmp/dev.map | grep -v fd | sed 's/ *\t/ /' | sed ':a;$!N;$!ba;s/\n/ /g')
+ linuxdevice=$(echo $1 | cut -b1-8)
+ if [ "$(echo ${1} | egrep '[0-9]$')" ]; then
+ # /dev/hdXY
+ pnum=$(echo ${1} | cut -b9-)
+ pnum=$((${pnum}-1))
+ partition_flag=1
+ fi
+ for dev in ${devs}; do
+ if [ "(" = $(echo ${dev} | cut -b1) ]; then
+ grubdevice="${dev}"
+ else
+ if [ "${dev}" = "${linuxdevice}" ]; then
+ device_found=1
+ break
+ fi
+ fi
+ done
+ if [ "${device_found}" = "1" ]; then
+ if [ "${partition_flag}" = "0" ]; then
+ echo "${grubdevice}"
+ else
+ grubdevice_stringlen=${#grubdevice}
+ let grubdevice_stringlen--
+ grubdevice=$(echo $grubdevice | cut -b1-$grubdevice_stringlen)
+ echo "${grubdevice},${pnum})"
+ fi
+ else
+ echo " DEVICE NOT FOUND"
+ fi
+}
+
+dogrub() {
+ get_grub_map
+ if [ ! -f /boot/grub/menu.lst ]; then
+ echo "Error: Couldn't find /boot/grub/menu.lst. Is GRUB installed?"
+ exit 1
+ fi
+ # try to auto-configure GRUB...
+ if [ "${PART_ROOT}" != "" -a "$S_GRUB" != "1" ]; then
+ grubdev=$(mapdev ${PART_ROOT})
+ # look for a separately-mounted /boot partition
+ bootdev=$(mount | grep /boot | cut -d' ' -f 1)
+ if [ "${grubdev}" != "" -o "${bootdev}" != "" ]; then
+ cp /boot/grub/menu.lst /tmp/.menu.lst
+ # remove the default entries by truncating the file at our little tag (#-*)
+ head -n $(cat /tmp/.menu.lst | grep -n '#-\*' | cut -d: -f 1) /tmp/.menu.lst >/boot/grub/menu.lst
+ rm -f /tmp/.menu.lst
+
+ for kernel in /boot/vmlinuz-linux* /boot/vmlinuz26-*; do
+ if [ ${kernel} == "/boot/vmlinuz-linux*" ] || [ ${kernel} == "/boot/vmlinuz26-*" ] ; then
+ echo > /dev/null
+ else
+ VMLINUZ=$( echo ${kernel} | cut -c 7- )
+
+ if [ "$( echo ${VMLINUZ} | cut -c -13 )" = "vmlinuz-linux" ]; then # new naming scheme for linux > 3.0
+ extension=$( echo ${VMLINUZ} | cut -c 14- )
+ INITRAMFS_BASENAME=initramfs-linux${extension}
+ else # old naming scheme for lts kernel
+ extension=$( echo ${VMLINUZ} | cut -c 10- )
+ INITRAMFS_BASENAME=kernel26${extension}
+ fi
+
+ echo "" >>/boot/grub/menu.lst
+ echo "# (0) Arch Linux" >>/boot/grub/menu.lst
+ echo "title Arch Linux - ${VMLINUZ}" >>/boot/grub/menu.lst
+ subdir=
+ if [ "${bootdev}" != "" ]; then
+ grubdev=$(mapdev ${bootdev})
+ else
+ subdir="/boot"
+ fi
+ echo "root ${grubdev}" >>/boot/grub/menu.lst
+ echo "kernel ${subdir}/${VMLINUZ} root=${PART_ROOT} ro" >>/boot/grub/menu.lst
+ echo "initrd ${subdir}/${INITRAMFS_BASENAME}.img" >>/boot/grub/menu.lst
+ echo "" >>/boot/grub/menu.lst
+
+ # adding fallback/full image
+ echo "# (1) Arch Linux" >>/boot/grub/menu.lst
+ echo "title Arch Linux Fallback - ${VMLINUZ}" >>/boot/grub/menu.lst
+ echo "root ${grubdev}" >>/boot/grub/menu.lst
+ echo "kernel ${subdir}/${VMLINUZ} root=${PART_ROOT} ro" >>/boot/grub/menu.lst
+ echo "initrd ${subdir}/${INITRAMFS_BASENAME}-fallback.img" >>/boot/grub/menu.lst
+ echo "" >>/boot/grub/menu.lst
+ fi
+ done
+ fi
+ fi
+
+ echo "Installing the GRUB bootloader..."
+ cp -a /usr/lib/grub/i386-pc/* /boot/grub/
+ sync
+
+ # freeze xfs filesystems to enable grub installation on xfs filesystems
+ if [ -x /usr/sbin/xfs_freeze ]; then
+ [ "$(stat -fLc %T /boot)" == "xfs" ] && /usr/sbin/xfs_freeze -f /boot > /dev/null 2>&1
+ [ "$(stat -fLc %T /)" == "xfs" ] && /usr/sbin/xfs_freeze -f / > /dev/null 2>&1
+ fi
+
+ # look for a separately-mounted /boot partition
+ bootpart=$(mount | grep /boot | cut -d' ' -f 1)
+ if [ "${bootpart}" = "" ]; then
+ bootpart=${PART_ROOT}
+ fi
+ bootpart=$(mapdev ${bootpart})
+ bootdev=$(mapdev ${ROOTDEV})
+ if [ "${bootpart}" = "" ]; then
+ echo "Error: Missing/Invalid root device: ${bootpart}"
+ exit 1
+ fi
+
+ echo ${bootpart}
+ echo ${bootdev}
+ /sbin/grub --no-floppy --batch >/tmp/grub.log 2>&1 <<EOF
+root ${bootpart}
+setup ${bootdev}
+quit
+EOF
+ cat /tmp/grub.log
+
+ # unfreeze xfs filesystems
+ if [ -x /usr/sbin/xfs_freeze ]; then
+ [ "$(stat -fLc %T /boot)" == "xfs" ] && /usr/sbin/xfs_freeze -u /boot > /dev/null 2>&1
+ [ "$(stat -fLc %T /)" == "xfs" ] && /usr/sbin/xfs_freeze -u / > /dev/null 2>&1
+ fi
+ if grep "Error [0-9]*: " /tmp/grub.log >/dev/null; then
+ echo "Error installing GRUB. (see /tmp/grub.log for output)"
+ exit 1
+ fi
+ echo "GRUB was successfully installed."
+
+ rm -f /tmp/grub.log
+
+ exit 0
+}
+
+dogrub
diff --git a/intelmac.patch b/intelmac.patch
new file mode 100644
index 000000000000..a3fabc7330d1
--- /dev/null
+++ b/intelmac.patch
@@ -0,0 +1,67 @@
+--- 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
+@@ -1651,7 +1651,29 @@
+ jnz 3f
+ ret
+
+-3: /* use keyboard controller */
++3: /*
++ * try to switch gateA20 using PORT92, the "Fast A20 and Init"
++ * register
++ */
++ mov $0x92, %dx
++ inb %dx, %al
++ /* skip the port92 code if it's unimplemented (read returns 0xff) */
++ cmpb $0xff, %al
++ jz 6f
++
++ /* set or clear bit1, the ALT_A20_GATE bit */
++ movb 4(%esp), %ah
++ testb %ah, %ah
++ jz 4f
++ orb $2, %al
++ jmp 5f
++4: and $0xfd, %al
++
++ /* clear the INIT_NOW bit don't accidently reset the machine */
++5: and $0xfe, %al
++ outb %al, %dx
++
++6: /* use keyboard controller */
+ pushl %eax
+
+ call gloop1
+@@ -1661,9 +1683,12 @@
+
+ gloopint1:
+ inb $K_STATUS
++ cmpb $0xff, %al
++ jz gloopint1_done
+ andb $K_IBUF_FUL, %al
+ jnz gloopint1
+
++gloopint1_done:
+ movb $KB_OUTPUT_MASK, %al
+ cmpb $0, 0x8(%esp)
+ jz gdoit
+@@ -1684,6 +1709,8 @@
+
+ gloop1:
+ inb $K_STATUS
++ cmpb $0xff, %al
++ jz gloop2ret
+ andb $K_IBUF_FUL, %al
+ jnz gloop1
+
+@@ -1991,6 +2018,11 @@
+ ENTRY(console_getkey)
+ push %ebp
+
++wait_for_key:
++ call EXT_C(console_checkkey)
++ incl %eax
++ jz wait_for_key
++
+ call EXT_C(prot_to_real)
+ .code16
+
diff --git a/menu.lst b/menu.lst
new file mode 100644
index 000000000000..a0c7529deef7
--- /dev/null
+++ b/menu.lst
@@ -0,0 +1,48 @@
+# Config file for GRUB - The GNU GRand Unified Bootloader
+# /boot/grub/menu.lst
+
+# DEVICE NAME CONVERSIONS
+#
+# Linux Grub
+# -------------------------
+# /dev/fd0 (fd0)
+# /dev/sda (hd0)
+# /dev/sdb2 (hd1,1)
+# /dev/sda3 (hd0,2)
+#
+
+# FRAMEBUFFER RESOLUTION SETTINGS
+# +-------------------------------------------------+
+# | 640x480 800x600 1024x768 1280x1024
+# ----+--------------------------------------------
+# 256 | 0x301=769 0x303=771 0x305=773 0x307=775
+# 32K | 0x310=784 0x313=787 0x316=790 0x319=793
+# 64K | 0x311=785 0x314=788 0x317=791 0x31A=794
+# 16M | 0x312=786 0x315=789 0x318=792 0x31B=795
+# +-------------------------------------------------+
+# for more details and different resolutions see
+# https://wiki.archlinux.org/index.php/GRUB#Framebuffer_resolution
+
+# general configuration:
+timeout 5
+default 0
+color light-blue/black light-cyan/blue
+
+# boot sections follow
+# each is implicitly numbered from 0 in the order of appearance below
+#
+# TIP: If you want a 1024x768 framebuffer, add "vga=773" to your kernel line.
+#
+#-*
+
+# (0) Arch Linux
+title Arch Linux [/boot/vmlinuz-linux]
+root (hd0,0)
+kernel /vmlinuz-linux root=/dev/sda3 ro
+initrd /initramfs-linux.img
+
+# (1) Windows
+#title Windows
+#rootnoverify (hd0,0)
+#makeactive
+#chainloader +1
diff --git a/more-raid.patch b/more-raid.patch
new file mode 100644
index 000000000000..39db23474b9b
--- /dev/null
+++ b/more-raid.patch
@@ -0,0 +1,100 @@
+--- 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/special-devices.patch b/special-devices.patch
new file mode 100644
index 000000000000..894f3e8872e8
--- /dev/null
+++ b/special-devices.patch
@@ -0,0 +1,18 @@
+--- 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);