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