summaryrefslogtreecommitdiffstats
path: root/abs/core/grub
diff options
context:
space:
mode:
Diffstat (limited to 'abs/core/grub')
-rw-r--r--abs/core/grub/040_all_grub-0.96-nxstack.patch623
-rw-r--r--abs/core/grub/05-grub-0.97-initrdaddr.diff16
-rw-r--r--abs/core/grub/PKGBUILD81
-rw-r--r--abs/core/grub/grub-0.97-gpt.patch315
-rw-r--r--abs/core/grub/grub-inode-size.patch94
-rw-r--r--abs/core/grub/i2o.patch45
-rwxr-xr-xabs/core/grub/install-grub187
-rw-r--r--abs/core/grub/intelmac.patch67
-rw-r--r--abs/core/grub/menu.lst46
-rw-r--r--abs/core/grub/more-raid.patch100
-rw-r--r--abs/core/grub/special-devices.patch18
11 files changed, 1592 insertions, 0 deletions
diff --git a/abs/core/grub/040_all_grub-0.96-nxstack.patch b/abs/core/grub/040_all_grub-0.96-nxstack.patch
new file mode 100644
index 0000000..121941c
--- /dev/null
+++ b/abs/core/grub/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/abs/core/grub/05-grub-0.97-initrdaddr.diff b/abs/core/grub/05-grub-0.97-initrdaddr.diff
new file mode 100644
index 0000000..ccf5f3e
--- /dev/null
+++ b/abs/core/grub/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/abs/core/grub/PKGBUILD b/abs/core/grub/PKGBUILD
new file mode 100644
index 0000000..398d782
--- /dev/null
+++ b/abs/core/grub/PKGBUILD
@@ -0,0 +1,81 @@
+# $Id: PKGBUILD 356 2008-04-18 22:56:27Z aaron $
+# Maintainer: judd <jvinet@zeroflux.org>
+
+pkgname=grub
+pkgver=0.97
+pkgrel=21
+pkgdesc="A GNU multiboot boot loader"
+arch=('i686' 'x86_64')
+license=('GPL')
+url="http://www.gnu.org/software/grub/"
+groups=('base')
+depends=('ncurses' 'diffutils' 'sed')
+source=(ftp://alpha.gnu.org/gnu/grub/grub-$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
+ grub-0.97-gpt.patch)
+backup=('boot/grub/menu.lst')
+md5sums=('cd3f3eb54446be6003156158d51f4884'
+ 'cce52ae9ee1f8686cd700b3c967e78f9'
+ '3182c4ae4963a16930bc772bba89dacf'
+ 'eb9d69c46af3a0667c1f651817d7f075'
+ 'ccd2d757e79e3a03dc19ede7391ed328'
+ '826fdbf446067f9861baf9f6a69a4583'
+ '49f6d4bcced0bc8bbcff273f3254bbfa'
+ 'f41f702014a064918d7afc6fc23baa6e'
+ '175dc6b9f4ab94e8056c3afb3e34460a'
+ 'ada26cbc681907823cc4ff2a55b97866'
+ '52cd09a6966f12961d11f7b3b7e76bd2')
+
+build() {
+ cd $startdir/src/$pkgname-$pkgver
+
+ #set destination architecture here
+ DESTARCH="i686"
+ #DESTARCH="x86_64"
+
+ # optimizations break the build -- disable them
+ # adding special devices to grub, patches are from fedora
+ patch -Np1 -i ../special-devices.patch || return 1
+ patch -Np1 -i ../i2o.patch || return 1
+ patch -Np1 -i ../more-raid.patch || return 1
+ patch -Np1 -i ../intelmac.patch || return 1
+ # Add support for bigger inode size to e2fs_stage1_5
+ patch -Np1 -i ../grub-inode-size.patch || return 1
+ # Add gpt support
+ # http://bugs.archlinux.org/task/9864
+ patch -Np1 -i ../grub-0.97-gpt.patch || return 1
+
+ #arch64 fixes for static build
+ if [ "$CARCH" = "x86_64" ]; then
+ echo "this package has to be built on i686, won't compile on x86_64"
+ sleep 5
+ else
+ if [ "$DESTARCH" = "x86_64" ]; then
+ # patch from gentoo for fixing a segfault
+ patch -Np1 -i ../040_all_grub-0.96-nxstack.patch || return 1
+ # patch from frugalware to make it boot when more than 2GB ram installed
+ patch -Np1 -i ../05-grub-0.97-initrdaddr.diff || return 1
+ CFLAGS="-static" ./configure --prefix=/usr --bindir=/bin --sbindir=/sbin
+ else
+ CFLAGS= ./configure --prefix=/usr --bindir=/bin --sbindir=/sbin
+ fi
+ fi
+
+ CFLAGS= make || return 1
+ make DESTDIR=$startdir/pkg install
+ install -D -m644 ../menu.lst $startdir/pkg/boot/grub/menu.lst
+ install -D -m755 ../install-grub $startdir/pkg/sbin/install-grub
+
+ if [ "$DESTARCH" = "x86_64" ]; then
+ # fool makepkg into building a x86_64 package
+ export CARCH="x86_64"
+ fi
+}
diff --git a/abs/core/grub/grub-0.97-gpt.patch b/abs/core/grub/grub-0.97-gpt.patch
new file mode 100644
index 0000000..7b1a55c
--- /dev/null
+++ b/abs/core/grub/grub-0.97-gpt.patch
@@ -0,0 +1,315 @@
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/builtins.c grub-0.96-patched/stage2/builtins.c
+--- grub-0.96/stage2/builtins.c 2004-06-20 09:33:04.000000000 -0400
++++ grub-0.96-patched/stage2/builtins.c 2007-01-04 13:56:06.000000000 -0500
+@@ -1229,14 +1229,15 @@
+ for (drive = 0x80; drive < 0x88; drive++)
+ {
+ unsigned long part = 0xFFFFFF;
+- unsigned long start, len, offset, ext_offset;
+- int type, entry;
++ unsigned long start, len, offset, ext_offset, gpt_offset;
++ int type, entry, gpt_count, gpt_size;
+ char buf[SECTOR_SIZE];
+
+ current_drive = drive;
+ while (next_partition (drive, 0xFFFFFF, &part, &type,
+ &start, &len, &offset, &entry,
+- &ext_offset, buf))
++ &ext_offset, &gpt_offset,
++ &gpt_count, &gpt_size, buf))
+ {
+ if (type != PC_SLICE_TYPE_NONE
+ && ! IS_PC_SLICE_TYPE_BSD (type)
+@@ -2806,8 +2807,8 @@
+ {
+ int new_type;
+ unsigned long part = 0xFFFFFF;
+- unsigned long start, len, offset, ext_offset;
+- int entry, type;
++ unsigned long start, len, offset, ext_offset, gpt_offset;
++ int entry, type, gpt_count, gpt_size;
+ char mbr[512];
+
+ /* Get the drive and the partition. */
+@@ -2844,7 +2845,14 @@
+ /* Look for the partition. */
+ while (next_partition (current_drive, 0xFFFFFF, &part, &type,
+ &start, &len, &offset, &entry,
+- &ext_offset, mbr))
++ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
++ /* The partition may not be a GPT partition. */
++ if (gpt_offset != 0)
++ {
++ errnum = ERR_BAD_ARGUMENT;
++ return 1;
++ }
++
+ {
+ if (part == current_partition)
+ {
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/disk_io.c grub-0.96-patched/stage2/disk_io.c
+--- grub-0.96/stage2/disk_io.c 2004-05-23 12:35:24.000000000 -0400
++++ grub-0.96-patched/stage2/disk_io.c 2007-01-04 14:01:08.000000000 -0500
+@@ -21,6 +21,7 @@
+
+ #include <shared.h>
+ #include <filesys.h>
++#include <gpt.h>
+
+ #ifdef SUPPORT_NETBOOT
+ # define GRUB 1
+@@ -502,8 +503,8 @@
+ set_partition_hidden_flag (int hidden)
+ {
+ unsigned long part = 0xFFFFFF;
+- unsigned long start, len, offset, ext_offset;
+- int entry, type;
++ unsigned long start, len, offset, ext_offset, gpt_offset;
++ int entry, type, gpt_count, gpt_size;
+ char mbr[512];
+
+ /* The drive must be a hard disk. */
+@@ -524,7 +525,14 @@
+ /* Look for the partition. */
+ while (next_partition (current_drive, 0xFFFFFF, &part, &type,
+ &start, &len, &offset, &entry,
+- &ext_offset, mbr))
++ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
++ /* The partition may not be a GPT partition. */
++ if (gpt_offset != 0)
++ {
++ errnum = ERR_BAD_ARGUMENT;
++ return 1;
++ }
++
+ {
+ if (part == current_partition)
+ {
+@@ -577,11 +585,14 @@
+ unsigned long *partition, int *type,
+ unsigned long *start, unsigned long *len,
+ unsigned long *offset, int *entry,
+- unsigned long *ext_offset, char *buf)
++ unsigned long *ext_offset,
++ unsigned long *gpt_offset, int *gpt_count,
++ int *gpt_size, char *buf)
+ {
+ /* Forward declarations. */
+ auto int next_bsd_partition (void);
+ auto int next_pc_slice (void);
++ auto int next_gpt_slice(void);
+
+ /* Get next BSD partition in current PC slice. */
+ int next_bsd_partition (void)
+@@ -666,6 +677,40 @@
+ return 0;
+ }
+
++ /* If this is a GPT partition table, read it as such. */
++ if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT)
++ {
++ struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
++
++ /* Read in the GPT Partition table header. */
++ if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
++ return 0;
++
++ if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
++ {
++ /* Let gpt_offset point to the first entry in the GPT
++ partition table. This can also be used by callers of
++ next_partition to determine if a entry comes from a
++ GPT partition table or not. */
++ *gpt_offset = hdr->partitions;
++ *gpt_count = hdr->maxpart;
++ *gpt_size = hdr->partentry_size;
++
++ return next_gpt_slice();
++ }
++ else
++ {
++ /* This is not a valid header for a GPT partition table.
++ Re-read the MBR or the boot sector of the extended
++ partition. */
++ if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
++ return 0;
++ }
++ }
++
++ /* Not a GPT partition. */
++ *gpt_offset = 0;
++
+ /* Increase the entry number. */
+ (*entry)++;
+
+@@ -710,6 +755,43 @@
+ return 1;
+ }
+
++ /* Get the next GPT slice. */
++ int next_gpt_slice (void)
++ {
++ struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf;
++ /* Make GPT partitions show up as PC slices. */
++ int pc_slice_no = (*partition & 0xFF0000) >> 16;
++
++ /* If this is the first time... */
++ if (pc_slice_no == 0xFF)
++ {
++ pc_slice_no = -1;
++ *entry = -1;
++ }
++
++ do {
++ (*entry)++;
++
++ if (*entry >= *gpt_count)
++ {
++ errnum = ERR_NO_PART;
++ return 0;
++ }
++ /* Read in the GPT Partition table entry. */
++ if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
++ return 0;
++ } while (! (gptentry->type1 && gptentry->type2));
++
++ pc_slice_no++;
++ *start = gptentry->start;
++ *len = gptentry->end - gptentry->start + 1;
++ *type = PC_SLICE_TYPE_EXT2FS;
++ *entry = pc_slice_no;
++ *partition = (*entry << 16) | 0xFFFF;
++
++ return 1;
++ }
++
+ /* Start the body of this function. */
+
+ #ifndef STAGE1_5
+@@ -717,6 +799,9 @@
+ return 0;
+ #endif
+
++ if (*partition != 0xFFFFFF && *gpt_offset != 0)
++ return next_gpt_slice ();
++
+ /* If previous partition is a BSD partition or a PC slice which
+ contains BSD partitions... */
+ if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
+@@ -755,6 +840,9 @@
+ unsigned long dest_partition = current_partition;
+ unsigned long part_offset;
+ unsigned long ext_offset;
++ unsigned long gpt_offset;
++ int gpt_count;
++ int gpt_size;
+ int entry;
+ char buf[SECTOR_SIZE];
+ int bsd_part, pc_slice;
+@@ -766,7 +854,8 @@
+ int ret = next_partition (current_drive, dest_partition,
+ &current_partition, &current_slice,
+ &part_start, &part_length,
+- &part_offset, &entry, &ext_offset, buf);
++ &part_offset, &entry, &ext_offset,
++ &gpt_offset, &gpt_count, &gpt_size, buf);
+ bsd_part = (current_partition >> 8) & 0xFF;
+ pc_slice = current_partition >> 16;
+ return ret;
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/gpt.h grub-0.96-patched/stage2/gpt.h
+--- grub-0.96/stage2/gpt.h 1969-12-31 19:00:00.000000000 -0500
++++ grub-0.96-patched/stage2/gpt.h 2007-01-04 13:52:14.000000000 -0500
+@@ -0,0 +1,68 @@
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2002,2005,2006 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 _GPT_H
++#define _GPT_H
++
++typedef signed char grub_int8_t;
++typedef signed short grub_int16_t;
++typedef signed int grub_int32_t;
++typedef signed long long int grub_int64_t;
++typedef unsigned char grub_uint8_t;
++typedef unsigned short grub_uint16_t;
++typedef unsigned int grub_uint32_t;
++typedef unsigned long long int grub_uint64_t;
++
++struct grub_gpt_header
++{
++ grub_uint64_t magic;
++ grub_uint32_t version;
++ grub_uint32_t headersize;
++ grub_uint32_t crc32;
++ grub_uint32_t unused1;
++ grub_uint64_t primary;
++ grub_uint64_t backup;
++ grub_uint64_t start;
++ grub_uint64_t end;
++ grub_uint8_t guid[16];
++ grub_uint64_t partitions;
++ grub_uint32_t maxpart;
++ grub_uint32_t partentry_size;
++ grub_uint32_t partentry_crc32;
++} __attribute__ ((packed));
++
++struct grub_gpt_partentry
++{
++ grub_uint64_t type1;
++ grub_uint64_t type2;
++ grub_uint8_t guid[16];
++ grub_uint64_t start;
++ grub_uint64_t end;
++ grub_uint8_t attrib;
++ char name[72];
++} __attribute__ ((packed));
++
++#define GPT_HEADER_MAGIC 0x5452415020494645UL
++
++#define GPT_ENTRY_SECTOR(size,entry) \
++ ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
++#define GPT_ENTRY_INDEX(size,entry) \
++ ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
++
++#endif /* _GPT_H */
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/pc_slice.h grub-0.96-patched/stage2/pc_slice.h
+--- grub-0.96/stage2/pc_slice.h 2003-07-09 07:45:53.000000000 -0400
++++ grub-0.96-patched/stage2/pc_slice.h 2007-01-04 13:52:14.000000000 -0500
+@@ -115,6 +115,7 @@
+ #define PC_SLICE_TYPE_LINUX_EXTENDED 0x85
+ #define PC_SLICE_TYPE_VSTAFS 0x9e
+ #define PC_SLICE_TYPE_DELL_UTIL 0xde
++#define PC_SLICE_TYPE_GPT 0xee
+ #define PC_SLICE_TYPE_LINUX_RAID 0xfd
+
+
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/shared.h grub-0.96-patched/stage2/shared.h
+--- grub-0.96/stage2/shared.h 2004-06-19 12:40:09.000000000 -0400
++++ grub-0.96-patched/stage2/shared.h 2007-01-04 13:52:15.000000000 -0500
+@@ -934,7 +934,9 @@
+ unsigned long *partition, int *type,
+ unsigned long *start, unsigned long *len,
+ unsigned long *offset, int *entry,
+- unsigned long *ext_offset, char *buf);
++ unsigned long *ext_offset,
++ unsigned long *gpt_offset, int *gpt_count,
++ int *gpt_size, char *buf);
+
+ /* Sets device to the one represented by the SAVED_* parameters. */
+ int make_saved_active (void);
diff --git a/abs/core/grub/grub-inode-size.patch b/abs/core/grub/grub-inode-size.patch
new file mode 100644
index 0000000..bef3bc1
--- /dev/null
+++ b/abs/core/grub/grub-inode-size.patch
@@ -0,0 +1,94 @@
+diff -Nrup a/stage2/fsys_ext2fs.c b/stage2/fsys_ext2fs.c
+--- a/stage2/fsys_ext2fs.c 2004-08-08 20:19:18.000000000 +0200
++++ b/stage2/fsys_ext2fs.c 2008-01-30 14:27:20.000000000 +0100
+@@ -79,7 +79,52 @@ struct ext2_super_block
+ __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,9 @@ struct ext2_dir_entry
+ #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_INODE_SIZE(s) (SUPERBLOCK->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 +601,7 @@ ext2fs_dir (char *dirname)
+ 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 +613,12 @@ ext2fs_dir (char *dirname)
+ /* 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/abs/core/grub/i2o.patch b/abs/core/grub/i2o.patch
new file mode 100644
index 0000000..2af846c
--- /dev/null
+++ b/abs/core/grub/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/abs/core/grub/install-grub b/abs/core/grub/install-grub
new file mode 100755
index 0000000..3eb7ce5
--- /dev/null
+++ b/abs/core/grub/install-grub
@@ -0,0 +1,187 @@
+#!/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
+VMLINUZ=vmlinuz26
+
+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
+ echo "" >>/boot/grub/menu.lst
+ echo "# (0) Arch Linux" >>/boot/grub/menu.lst
+ echo "title Arch Linux" >>/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
+ if [ "$VMLINUZ" = "vmlinuz26" ]; then
+ echo "initrd $subdir/kernel26.img" >>/boot/grub/menu.lst
+ fi
+ echo "" >>/boot/grub/menu.lst
+ # adding fallback/full image
+ echo "# (1) Arch Linux" >>/boot/grub/menu.lst
+ echo "title Arch Linux Fallback" >>/boot/grub/menu.lst
+ echo "root $grubdev" >>/boot/grub/menu.lst
+ echo "kernel $subdir/$VMLINUZ root=$PART_ROOT ro" >>/boot/grub/menu.lst
+ if [ "$VMLINUZ" = "vmlinuz26" ]; then
+ echo "initrd $subdir/kernel26-fallback.img" >>/boot/grub/menu.lst
+ fi
+ echo "" >>/boot/grub/menu.lst
+ 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
+ /usr/sbin/xfs_freeze -f /boot > /dev/null 2>&1
+ /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
+ /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
+ /usr/sbin/xfs_freeze -u /boot > /dev/null 2>&1
+ /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 \ No newline at end of file
diff --git a/abs/core/grub/intelmac.patch b/abs/core/grub/intelmac.patch
new file mode 100644
index 0000000..a3fabc7
--- /dev/null
+++ b/abs/core/grub/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/abs/core/grub/menu.lst b/abs/core/grub/menu.lst
new file mode 100644
index 0000000..57fcf0d
--- /dev/null
+++ b/abs/core/grub/menu.lst
@@ -0,0 +1,46 @@
+# Config file for GRUB - The GNU GRand Unified Bootloader
+# /boot/grub/menu.lst
+
+# DEVICE NAME CONVERSIONS
+#
+# Linux Grub
+# -------------------------
+# /dev/fd0 (fd0)
+# /dev/hda (hd0)
+# /dev/hdb2 (hd1,1)
+# /dev/hda3 (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
+# +-------------------------------------------------+
+
+# 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/vmlinuz26]
+root (hd0,0)
+kernel /vmlinuz26 root=/dev/hda3 ro
+initrd /kernel26.img
+
+# (1) Windows
+#title Windows
+#rootnoverify (hd0,0)
+#makeactive
+#chainloader +1
diff --git a/abs/core/grub/more-raid.patch b/abs/core/grub/more-raid.patch
new file mode 100644
index 0000000..39db234
--- /dev/null
+++ b/abs/core/grub/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/abs/core/grub/special-devices.patch b/abs/core/grub/special-devices.patch
new file mode 100644
index 0000000..894f3e8
--- /dev/null
+++ b/abs/core/grub/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);