From 78ea0ddf6e8b65ebf2619c7ac1d09d32f0670066 Mon Sep 17 00:00:00 2001 From: Robin H. Johnson Date: Sun, 24 Feb 2008 19:07:19 -0800 Subject: [PATCH] Backport grub with GPT patch from main tree. --- sys-boot/grub/ChangeLog | 7 +- sys-boot/grub/files/grub-0.97-gpt.patch | 315 +++++++++++++++++++++++++++++++ sys-boot/grub/grub-0.97-r4.ebuild | 164 ++++++++++++++++ 3 files changed, 485 insertions(+), 1 deletions(-) create mode 100644 sys-boot/grub/files/grub-0.97-gpt.patch create mode 100644 sys-boot/grub/grub-0.97-r4.ebuild diff --git a/sys-boot/grub/ChangeLog b/sys-boot/grub/ChangeLog index 03b8bea..b7c0fa6 100644 --- a/sys-boot/grub/ChangeLog +++ b/sys-boot/grub/ChangeLog @@ -1,7 +1,12 @@ # ChangeLog for sys-boot/grub -# Copyright 1999-2007 Gentoo Foundation; Distributed under the GPL v2 +# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2 # $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/ChangeLog,v 1.74 2007/08/25 17:09:26 vapier Exp $ +*grub-0.97-r4 (25 Feb 2006) + + 25 Feb 2008; Robin H. Johnson +grub-0.97-gpt.patch: + Bug #178586, include support for booting from a GPT-style disk. + 25 Aug 2007; Mike Frysinger +files/grub-1.95-build.patch, grub-1.95.ebuild: Fix from Kevin Lacquement for building in parallel #185361. diff --git a/sys-boot/grub/files/grub-0.97-gpt.patch b/sys-boot/grub/files/grub-0.97-gpt.patch new file mode 100644 index 0000000..7b1a55c --- /dev/null +++ b/sys-boot/grub/files/grub-0.97-gpt.patch @@ -0,0 +1,315 @@ +diff -ruBbd --unidirectional-new-file grub-0.96/stage2/builtins.c grub-0.96-patched/stage2/builtins.c +--- grub-0.96/stage2/builtins.c 2004-06-20 09:33:04.000000000 -0400 ++++ grub-0.96-patched/stage2/builtins.c 2007-01-04 13:56:06.000000000 -0500 +@@ -1229,14 +1229,15 @@ + for (drive = 0x80; drive < 0x88; drive++) + { + unsigned long part = 0xFFFFFF; +- unsigned long start, len, offset, ext_offset; +- int type, entry; ++ unsigned long start, len, offset, ext_offset, gpt_offset; ++ int type, entry, gpt_count, gpt_size; + char buf[SECTOR_SIZE]; + + current_drive = drive; + while (next_partition (drive, 0xFFFFFF, &part, &type, + &start, &len, &offset, &entry, +- &ext_offset, buf)) ++ &ext_offset, &gpt_offset, ++ &gpt_count, &gpt_size, buf)) + { + if (type != PC_SLICE_TYPE_NONE + && ! IS_PC_SLICE_TYPE_BSD (type) +@@ -2806,8 +2807,8 @@ + { + int new_type; + unsigned long part = 0xFFFFFF; +- unsigned long start, len, offset, ext_offset; +- int entry, type; ++ unsigned long start, len, offset, ext_offset, gpt_offset; ++ int entry, type, gpt_count, gpt_size; + char mbr[512]; + + /* Get the drive and the partition. */ +@@ -2844,7 +2845,14 @@ + /* Look for the partition. */ + while (next_partition (current_drive, 0xFFFFFF, &part, &type, + &start, &len, &offset, &entry, +- &ext_offset, mbr)) ++ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) ++ /* The partition may not be a GPT partition. */ ++ if (gpt_offset != 0) ++ { ++ errnum = ERR_BAD_ARGUMENT; ++ return 1; ++ } ++ + { + if (part == current_partition) + { +diff -ruBbd --unidirectional-new-file grub-0.96/stage2/disk_io.c grub-0.96-patched/stage2/disk_io.c +--- grub-0.96/stage2/disk_io.c 2004-05-23 12:35:24.000000000 -0400 ++++ grub-0.96-patched/stage2/disk_io.c 2007-01-04 14:01:08.000000000 -0500 +@@ -21,6 +21,7 @@ + + #include + #include ++#include + + #ifdef SUPPORT_NETBOOT + # define GRUB 1 +@@ -502,8 +503,8 @@ + set_partition_hidden_flag (int hidden) + { + unsigned long part = 0xFFFFFF; +- unsigned long start, len, offset, ext_offset; +- int entry, type; ++ unsigned long start, len, offset, ext_offset, gpt_offset; ++ int entry, type, gpt_count, gpt_size; + char mbr[512]; + + /* The drive must be a hard disk. */ +@@ -524,7 +525,14 @@ + /* Look for the partition. */ + while (next_partition (current_drive, 0xFFFFFF, &part, &type, + &start, &len, &offset, &entry, +- &ext_offset, mbr)) ++ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) ++ /* The partition may not be a GPT partition. */ ++ if (gpt_offset != 0) ++ { ++ errnum = ERR_BAD_ARGUMENT; ++ return 1; ++ } ++ + { + if (part == current_partition) + { +@@ -577,11 +585,14 @@ + unsigned long *partition, int *type, + unsigned long *start, unsigned long *len, + unsigned long *offset, int *entry, +- unsigned long *ext_offset, char *buf) ++ unsigned long *ext_offset, ++ unsigned long *gpt_offset, int *gpt_count, ++ int *gpt_size, char *buf) + { + /* Forward declarations. */ + auto int next_bsd_partition (void); + auto int next_pc_slice (void); ++ auto int next_gpt_slice(void); + + /* Get next BSD partition in current PC slice. */ + int next_bsd_partition (void) +@@ -666,6 +677,40 @@ + return 0; + } + ++ /* If this is a GPT partition table, read it as such. */ ++ if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT) ++ { ++ struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf; ++ ++ /* Read in the GPT Partition table header. */ ++ if (! rawread (drive, 1, 0, SECTOR_SIZE, buf)) ++ return 0; ++ ++ if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000) ++ { ++ /* Let gpt_offset point to the first entry in the GPT ++ partition table. This can also be used by callers of ++ next_partition to determine if a entry comes from a ++ GPT partition table or not. */ ++ *gpt_offset = hdr->partitions; ++ *gpt_count = hdr->maxpart; ++ *gpt_size = hdr->partentry_size; ++ ++ return next_gpt_slice(); ++ } ++ else ++ { ++ /* This is not a valid header for a GPT partition table. ++ Re-read the MBR or the boot sector of the extended ++ partition. */ ++ if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) ++ return 0; ++ } ++ } ++ ++ /* Not a GPT partition. */ ++ *gpt_offset = 0; ++ + /* Increase the entry number. */ + (*entry)++; + +@@ -710,6 +755,43 @@ + return 1; + } + ++ /* Get the next GPT slice. */ ++ int next_gpt_slice (void) ++ { ++ struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf; ++ /* Make GPT partitions show up as PC slices. */ ++ int pc_slice_no = (*partition & 0xFF0000) >> 16; ++ ++ /* If this is the first time... */ ++ if (pc_slice_no == 0xFF) ++ { ++ pc_slice_no = -1; ++ *entry = -1; ++ } ++ ++ do { ++ (*entry)++; ++ ++ if (*entry >= *gpt_count) ++ { ++ errnum = ERR_NO_PART; ++ return 0; ++ } ++ /* Read in the GPT Partition table entry. */ ++ if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf)) ++ return 0; ++ } while (! (gptentry->type1 && gptentry->type2)); ++ ++ pc_slice_no++; ++ *start = gptentry->start; ++ *len = gptentry->end - gptentry->start + 1; ++ *type = PC_SLICE_TYPE_EXT2FS; ++ *entry = pc_slice_no; ++ *partition = (*entry << 16) | 0xFFFF; ++ ++ return 1; ++ } ++ + /* Start the body of this function. */ + + #ifndef STAGE1_5 +@@ -717,6 +799,9 @@ + return 0; + #endif + ++ if (*partition != 0xFFFFFF && *gpt_offset != 0) ++ return next_gpt_slice (); ++ + /* If previous partition is a BSD partition or a PC slice which + contains BSD partitions... */ + if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff)) +@@ -755,6 +840,9 @@ + unsigned long dest_partition = current_partition; + unsigned long part_offset; + unsigned long ext_offset; ++ unsigned long gpt_offset; ++ int gpt_count; ++ int gpt_size; + int entry; + char buf[SECTOR_SIZE]; + int bsd_part, pc_slice; +@@ -766,7 +854,8 @@ + int ret = next_partition (current_drive, dest_partition, + ¤t_partition, ¤t_slice, + &part_start, &part_length, +- &part_offset, &entry, &ext_offset, buf); ++ &part_offset, &entry, &ext_offset, ++ &gpt_offset, &gpt_count, &gpt_size, buf); + bsd_part = (current_partition >> 8) & 0xFF; + pc_slice = current_partition >> 16; + return ret; +diff -ruBbd --unidirectional-new-file grub-0.96/stage2/gpt.h grub-0.96-patched/stage2/gpt.h +--- grub-0.96/stage2/gpt.h 1969-12-31 19:00:00.000000000 -0500 ++++ grub-0.96-patched/stage2/gpt.h 2007-01-04 13:52:14.000000000 -0500 +@@ -0,0 +1,68 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2005,2006 Free Software Foundation, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef _GPT_H ++#define _GPT_H ++ ++typedef signed char grub_int8_t; ++typedef signed short grub_int16_t; ++typedef signed int grub_int32_t; ++typedef signed long long int grub_int64_t; ++typedef unsigned char grub_uint8_t; ++typedef unsigned short grub_uint16_t; ++typedef unsigned int grub_uint32_t; ++typedef unsigned long long int grub_uint64_t; ++ ++struct grub_gpt_header ++{ ++ grub_uint64_t magic; ++ grub_uint32_t version; ++ grub_uint32_t headersize; ++ grub_uint32_t crc32; ++ grub_uint32_t unused1; ++ grub_uint64_t primary; ++ grub_uint64_t backup; ++ grub_uint64_t start; ++ grub_uint64_t end; ++ grub_uint8_t guid[16]; ++ grub_uint64_t partitions; ++ grub_uint32_t maxpart; ++ grub_uint32_t partentry_size; ++ grub_uint32_t partentry_crc32; ++} __attribute__ ((packed)); ++ ++struct grub_gpt_partentry ++{ ++ grub_uint64_t type1; ++ grub_uint64_t type2; ++ grub_uint8_t guid[16]; ++ grub_uint64_t start; ++ grub_uint64_t end; ++ grub_uint8_t attrib; ++ char name[72]; ++} __attribute__ ((packed)); ++ ++#define GPT_HEADER_MAGIC 0x5452415020494645UL ++ ++#define GPT_ENTRY_SECTOR(size,entry) \ ++ ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS) ++#define GPT_ENTRY_INDEX(size,entry) \ ++ ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1) ++ ++#endif /* _GPT_H */ +diff -ruBbd --unidirectional-new-file grub-0.96/stage2/pc_slice.h grub-0.96-patched/stage2/pc_slice.h +--- grub-0.96/stage2/pc_slice.h 2003-07-09 07:45:53.000000000 -0400 ++++ grub-0.96-patched/stage2/pc_slice.h 2007-01-04 13:52:14.000000000 -0500 +@@ -115,6 +115,7 @@ + #define PC_SLICE_TYPE_LINUX_EXTENDED 0x85 + #define PC_SLICE_TYPE_VSTAFS 0x9e + #define PC_SLICE_TYPE_DELL_UTIL 0xde ++#define PC_SLICE_TYPE_GPT 0xee + #define PC_SLICE_TYPE_LINUX_RAID 0xfd + + +diff -ruBbd --unidirectional-new-file grub-0.96/stage2/shared.h grub-0.96-patched/stage2/shared.h +--- grub-0.96/stage2/shared.h 2004-06-19 12:40:09.000000000 -0400 ++++ grub-0.96-patched/stage2/shared.h 2007-01-04 13:52:15.000000000 -0500 +@@ -934,7 +934,9 @@ + unsigned long *partition, int *type, + unsigned long *start, unsigned long *len, + unsigned long *offset, int *entry, +- unsigned long *ext_offset, char *buf); ++ unsigned long *ext_offset, ++ unsigned long *gpt_offset, int *gpt_count, ++ int *gpt_size, char *buf); + + /* Sets device to the one represented by the SAVED_* parameters. */ + int make_saved_active (void); diff --git a/sys-boot/grub/grub-0.97-r4.ebuild b/sys-boot/grub/grub-0.97-r4.ebuild new file mode 100644 index 0000000..948ab84 --- /dev/null +++ b/sys-boot/grub/grub-0.97-r4.ebuild @@ -0,0 +1,164 @@ +# Copyright 1999-2008 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-0.97-r4.ebuild,v 1.2 2008/02/25 02:08:22 robbat2 Exp $ + +inherit mount-boot eutils flag-o-matic toolchain-funcs autotools + +PATCHVER="1.4" +DESCRIPTION="GNU GRUB Legacy boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" +SRC_URI="mirror://gentoo/${P}.tar.gz + ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz + mirror://gentoo/splash.xpm.gz + mirror://gentoo/${P}-patches-${PATCHVER}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86 ~x86-fbsd" +IUSE="static netboot custom-cflags" + +DEPEND=">=sys-libs/ncurses-5.2-r5" +PROVIDE="virtual/bootloader" + +src_unpack() { + unpack ${A} + cd "${S}" + + # patch breaks booting for some people #111885 + rm "${WORKDIR}"/patch/400_* + + epatch "${FILESDIR}"/grub-0.97-gpt.patch + + if [[ -n ${PATCHVER} ]] ; then + EPATCH_SUFFIX="patch" + epatch "${WORKDIR}"/patch + eautoreconf + fi +} + +src_compile() { + filter-flags -fPIE #168834 + + use amd64 && multilib_toolchain_setup x86 + + unset BLOCK_SIZE #73499 + + ### i686-specific code in the boot loader is a bad idea; disabling to ensure + ### at least some compatibility if the hard drive is moved to an older or + ### incompatible system. + + # grub-0.95 added -fno-stack-protector detection, to disable ssp for stage2, + # but the objcopy's (faulty) test fails if -fstack-protector is default. + # create a cache telling configure that objcopy is ok, and add -C to econf + # to make use of the cache. + # + # CFLAGS has to be undefined running econf, else -fno-stack-protector detection fails. + # STAGE2_CFLAGS is not allowed to be used on emake command-line, it overwrites + # -fno-stack-protector detected by configure, removed from netboot's emake. + use custom-cflags || unset CFLAGS + + export grub_cv_prog_objcopy_absolute=yes #79734 + use static && append-ldflags -static + + # build the net-bootable grub first, but only if "netboot" is set + if use netboot ; then + econf \ + --libdir=/lib \ + --datadir=/usr/lib/grub \ + --exec-prefix=/ \ + --disable-auto-linux-mem-opt \ + --enable-diskless \ + --enable-{3c{5{03,07,09,29,95},90x},cs89x0,davicom,depca,eepro{,100}} \ + --enable-{epic100,exos205,ni5210,lance,ne2100,ni{50,65}10,natsemi} \ + --enable-{ne,ns8390,wd,otulip,rtl8139,sis900,sk-g16,smc9000,tiara} \ + --enable-{tulip,via-rhine,w89c840} || die "netboot econf failed" + + emake w89c840_o_CFLAGS="-O" || die "making netboot stuff" + + mv -f stage2/{nbgrub,pxegrub} "${S}"/ + mv -f stage2/stage2 stage2/stage2.netboot + + make clean || die "make clean failed" + fi + + # Now build the regular grub + # Note that FFS and UFS2 support are broken for now - stage1_5 files too big + econf \ + --libdir=/lib \ + --datadir=/usr/lib/grub \ + --exec-prefix=/ \ + --disable-auto-linux-mem-opt || die "econf failed" + emake || die "making regular stuff" +} + +src_test() { + # non-default block size also give false pass/fails. + unset BLOCK_SIZE + make check || die "make check failed" +} + +src_install() { + make DESTDIR="${D}" install || die + if use netboot ; then + exeinto /usr/lib/grub/${CHOST} + doexe nbgrub pxegrub stage2/stage2.netboot || die "netboot install" + fi + + insinto /boot/grub + doins "${DISTDIR}"/splash.xpm.gz + newins docs/menu.lst grub.conf.sample + + dodoc AUTHORS BUGS ChangeLog NEWS README THANKS TODO + newdoc docs/menu.lst grub.conf.sample +} + +setup_boot_dir() { + local dir="${1}" + + [[ ! -e "${dir}" ]] && die "${dir} does not exist!" + [[ ! -e "${dir}"/grub ]] && mkdir "${dir}/grub" + + # change menu.lst to grub.conf + if [[ ! -e "${dir}"/grub/grub.conf ]] && [[ -e "${dir}"/grub/menu.lst ]] ; then + mv -f "${dir}"/grub/menu.lst "${dir}"/grub/grub.conf + ewarn + ewarn "*** IMPORTANT NOTE: menu.lst has been renamed to grub.conf" + ewarn + fi + + if [[ ! -e "${dir}"/grub/menu.lst ]]; then + einfo "Linking from new grub.conf name to menu.lst" + ln -snf grub.conf "${dir}"/grub/menu.lst + fi + + [[ -e "${dir}"/grub/stage2 ]] && mv "${dir}"/grub/stage2{,.old} + + einfo "Copying files from /lib/grub and /usr/lib/grub to ${dir}" + for x in /lib*/grub/*/* /usr/lib*/grub/*/* ; do + [[ -f "${x}" ]] && cp -p "${x}" "${dir}"/grub/ + done + + if [[ -e "${dir}"/grub/grub.conf ]] ; then + egrep \ + -v '^[[:space:]]*(#|$|default|fallback|initrd|password|splashimage|timeout|title)' \ + "${dir}"/grub/grub.conf | \ + /sbin/grub --batch \ + --device-map="${dir}"/grub/device.map \ + > /dev/null + fi +} + +pkg_postinst() { + [[ "${ROOT}" != "/" ]] && return 0 + [[ -n ${DONT_MOUNT_BOOT} ]] && return 0 + setup_boot_dir /boot + einfo "To install grub files to another device (like a usb stick), just run:" + einfo " emerge --config =${PF}" +} + +pkg_config() { + local dir + einfo "Enter the directory where you want to setup grub:" + read dir + setup_boot_dir "${dir}" +} -- 1.5.4.2