]> git.proxmox.com Git - grub2.git/commitdiff
[ Colin Watson ]
authorPhilipp Hahn <hahn@univention.de>
Wed, 27 Jun 2018 07:13:54 +0000 (09:13 +0200)
committerPhilipp Hahn <hahn@univention.de>
Wed, 27 Jun 2018 07:14:45 +0000 (09:14 +0200)
[ Philipp Hahn ]
Disallow unsigned kernels if UEFI Secure Boot is enabled
(patch by Linn Crosetto <linn@hpe.com>)
Add patch to fix lockdown mode
(patch by Luca Boccassi <bluca@debian.org>)

26 files changed:
1  2 
debian/.git-dpm
debian/changelog
debian/patches/bootp_new_net_bootp6_command.patch
debian/patches/bootp_process_dhcpack_http_boot.patch
debian/patches/default_grub_d.patch
debian/patches/efinet_set_dns_from_uefi_proto.patch
debian/patches/efinet_set_network_from_uefi_devpath.patch
debian/patches/efinet_uefi_ipv6_pxe_support.patch
debian/patches/fix_lockdown.patch
debian/patches/freetype-pkg-config.patch
debian/patches/gfxpayload_dynamic.patch
debian/patches/grub-install-extra-removable.patch
debian/patches/install_locale_langpack.patch
debian/patches/install_powerpc_machtypes.patch
debian/patches/install_signed.patch
debian/patches/linuxefi.patch
debian/patches/linuxefi_disable_sb_fallback.patch
debian/patches/linuxefi_non_sb_fallback.patch
debian/patches/net_read_bracketed_ipv6_addr.patch
debian/patches/quick_boot.patch
debian/patches/replace-libgcrypt-crc.patch
debian/patches/restore_mkdevicemap.patch
debian/patches/series
debian/patches/sparc64-support.patch
debian/patches/syslinux-test-out-of-tree.patch
debian/patches/uefi_firmware_setup.patch

diff --cc debian/.git-dpm
index bd32e22666cb3949a9b50d85afc05143ab46eade,0000000000000000000000000000000000000000..c19ba18447cbaa16571c0da1048bcf4b4684911e
mode 100644,000000..100644
--- /dev/null
@@@ -1,8 -1,0 +1,8 @@@
- 56e169b950e2fdc17dfce4ec0bd63b59fa16f0b0
- 56e169b950e2fdc17dfce4ec0bd63b59fa16f0b0
 +# see git-dpm(1) from git-dpm package
++bd06522c349270c5142ad4837a2d5163c2c78138
++bd06522c349270c5142ad4837a2d5163c2c78138
 +59aeb1cfaa3d5bfd7bbeeee0f0d37f6d9eed51fe
 +59aeb1cfaa3d5bfd7bbeeee0f0d37f6d9eed51fe
 +grub2_2.02+dfsg1.orig.tar.xz
 +7a7b17051b32cef09493aaf21ac54f680ddc37b1
 +6217988
index f65518e0eff25afd9cf626949b615b938a4afde9,0000000000000000000000000000000000000000..6b69e0ae23638e46a0ffb7ef67fd5b1aa11e0221
mode 100644,000000..100644
--- /dev/null
@@@ -1,4717 -1,0 +1,4724 @@@
-  -- Colin Watson <cjwatson@debian.org>  Wed, 18 Apr 2018 14:26:37 +0100
 +grub2 (2.02+dfsg1-5) UNRELEASED; urgency=medium
 +
++  [ Colin Watson ]
 +  * Change Maintainer to pkg-grub-devel@alioth-lists.debian.net, following
 +    Alioth lists migration.
 +  * Backport from upstream:
 +    - Use grub-file to figure out whether multiboot2 should be used for
 +      Xen.gz (closes: #898947).
 +
++  [ Philipp Hahn ]
++  * Disallow unsigned kernels if UEFI Secure Boot is enabled
++    (patch by Linn Crosetto <linn@hpe.com>)
++  * Add patch to fix lockdown mode
++    (patch by Luca Boccassi <bluca@debian.org>)
++
++ -- Philipp Hahn <hahn@univention.de>  Wed, 27 Jun 2018 09:13:55 +0200
 +
 +grub2 (2.02+dfsg1-4) unstable; urgency=medium
 +
 +  * Adjust restore_mkdevicemap.patch to fix format-overflow warning with GCC
 +    7 (the overflow was in fact impossible in practice, but GCC couldn't
 +    prove that).
 +  * Cherry-pick upstream patch to disable -Wformat-truncation on GCC >= 7 in
 +    printf_unit_test.
 +  * Build with GCC 7 (closes: #892397).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 01 Apr 2018 10:49:48 +0100
 +
 +grub2 (2.02+dfsg1-3) unstable; urgency=medium
 +
 +  * sparc64: Don't use devspec to determine the OBP path (closes: #854568).
 +  * ieee1275: Fix crash in of_path_of_nvme when of_path is empty (closes:
 +    #891773).
 +  * sparc64: Limit nvme of_path_of_nvme to just SPARC.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 02 Mar 2018 12:53:34 +0000
 +
 +grub2 (2.02+dfsg1-2) unstable; urgency=medium
 +
 +  * Build-depend on libparted-dev on powerpc and ppc64 (closes: #891070).
 +  * Add support for modern sparc64 hardware (thanks, Eric Snowberg via John
 +    Paul Adrian Glaubitz; closes: #854568).
 +  * Build without PIE on sparc and sparc64 (thanks, John Paul Adrian
 +    Glaubitz; closes: #891733).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 28 Feb 2018 12:03:49 +0000
 +
 +grub2 (2.02+dfsg1-1) unstable; urgency=medium
 +
 +  * Switch to tracking debian/grub-extras/ using "git subtree" rather than
 +    submodules.
 +  * Update debian/README.source for Salsa migration.
 +  * Use pkg-config to find FreeType (closes: #887721).
 +  * Change various binary packages' priorities to optional, since "Priority:
 +    extra" is now deprecated.
 +  * Repack upstream tarball without grub-core/lib/libgcrypt*/cipher/crc.c,
 +    and provide a replacement implementation backported from more recent
 +    versions of libgcrypt (closes: #745409).
 +  * Cherry-pick upstream patch to avoid -Werror=unused-value build failure
 +    (closes: #890431).
 +  * Handle the case where udevadm exists but is non-functional, as warned
 +    about by Lintian 2.5.75.
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 17 Feb 2018 21:28:41 +0000
 +
 +grub2 (2.02-3) unstable; urgency=medium
 +
 +  * Use current location for upstream signing key
 +    (debian/upstream/signing-key.asc).
 +  * Update upstream signing key to a non-expired version.
 +  * Install bootinfo.txt and grub.chrp in grub-ieee1275-bin for ppc64, and
 +    install and use prep-bootdev on powerpc and ppc64 as well as ppc64el
 +    (thanks, John Paul Adrian Glaubitz; closes: #881730).
 +  * Cherry-pick upstream patch to change the default TSC calibration method
 +    to pmtimer on EFI systems (closes: #883193).
 +  * Move VCS to salsa.debian.org.
 +  * Consistently create /boot/grub in the postinst of all grub-<platform>
 +    packages (closes: #884883).
 +
 +  [ Debconf translations ]
 +  * [sq] Albanian (Silva Arapi; closes: #874497).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 10 Feb 2018 03:00:30 +0000
 +
 +grub2 (2.02-2) unstable; urgency=medium
 +
 +  * Comment out debian/watch lines for betas and pre-releases for now.
 +  * Cherry-pick upstream patch to allow mounting ext2/3/4 file systems that
 +    have the 'encrypt' feature enabled (closes: #840204).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 06 Jul 2017 18:02:02 +0100
 +
 +grub2 (2.02-1) unstable; urgency=medium
 +
 +  * New upstream release.
 +    - xen: Fix wrong register in relocator (closes: #799480).
 +  * Resolve symlinks for supported init paths as well as for /sbin/init
 +    (thanks, Felipe Sateler; closes: #842315).
 +
 +  [ Debconf translations ]
 +  * [sr] Serbian (Karolina Kalic; closes: #691288).
 +  * [sr@latin] Serbian Latin (Karolina Kalic; closes: #691289).
 +  * [pt] Portuguese (Rui Branco - DebianPT; closes: #864171).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 23 Jun 2017 13:47:39 +0100
 +
 +grub2 (2.02~beta3-5) unstable; urgency=medium
 +
 +  [ Steve McIntyre ]
 +  * Make grub-install check for errors from efibootmgr (closes: #853234).
 +    There are probably still underlying issues in other similar reported
 +    bugs, but they're more effectively tracked elsewhere (e.g. efibootmgr)
 +    at this point (closes: #756253, #852513).
 +
 +  [ Debconf translations ]
 +  * [ug] Uyghur (Abduqadir Abliz).
 +  * [es] Spanish (Manuel "Venturi" Porras Peralta; closes: #852977).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 11 Feb 2017 15:09:19 +0000
 +
 +grub2 (2.02~beta3-4) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Drop build-dependency on libxen-dev, unnecessary now that upstream has
 +    taken a copy of the necessary public headers.
 +  * Ensure that build-efi-images has a suitable PATH for running mkfs.msdos
 +    (thanks, Luca Boccassi; closes: #852001).
 +
 +  [ dann frazier ]
 +  * Add grub2/update_nvram template to allow users to disable NVRAM
 +    updates during package upgrades (LP: #1642298).
 +
 +  [ Debconf translations ]
 +  * [ro] Romanian (Andrei POPESCU).
 +  * [kk] Kazakh (Baurzhan Muftakhidinov).
 +  * [lt] Lithuanian (Rimas Kudelis).
 +  * [th] Thai (Theppitak Karoonboonyanan).
 +  * [sl] Slovenian (Vanja Cvelbar).
 +  * [pl] Polish (Łukasz Dulny).
 +  * [eu] Basque (Iñaki Larrañaga Murgoitio; closes: #851981).
 +  * [bg] Bulgarian (Damyan Ivanov; closes: #852024).
 +  * [de] German (Helge Kreutzmann; closes: #852027).
 +  * [vi] Vietnamese (Trần Ngọc Quân).
 +  * [ko] Korean (Changwoo Ryu; closes: #852061).
 +  * [ru] Russian (Yuri Kozlov; closes: #852064).
 +  * [tr] Turkish (Mert Dirik).
 +  * [it] Italian (Luca Monducci; closes: #852073).
 +  * [cs] Czech (Miroslav Kure; closes: #852189).
 +  * [be] Belarusian (Viktar Siarheichyk; closes: #852286).
 +  * [eo] Esperanto (Felipe Castro).
 +  * [uk] Ukrainian (Yatsenko Alexandr).
 +  * [pt_BR] Brazilian Portuguese (Adriano Rafael Gomes; closes: #852325).
 +  * [hr] Croatian (Tomislav Krznar).
 +  * [ca] Catalan (Innocent De Marchi; closes: #852331).
 +  * [fr] French (Baptiste Jammet; closes: #852341).
 +  * [da] Danish (Joe Hansen; closes: #852349).
 +  * [nl] Dutch (Frans Spiesschaert; closes: #852403).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 24 Jan 2017 11:39:45 +0000
 +
 +grub2 (2.02~beta3-3) unstable; urgency=medium
 +
 +  [ Chad MILLER ]
 +  * Signal to zpool that it should emit full names of constituent devices
 +    (closes: #824974, LP: #1527727).
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Fix support for IPv6 PXE booting under UEFI (LP: #1229458):
 +    - misc-fix-invalid-char-strtol.patch: fix strto*l methods invalid chars.
 +    - net_read_bracketed_ipv6_addr.patch: read bracketed IPv6 addresses.
 +    - bootp_new_net_bootp6_command.patch: add new bootp6 commands.
 +    - efinet_uefi_ipv6_pxe_support.patch: teach efinet to allow bootp6.
 +    - bootp_process_dhcpack_http_boot.patch: process DHCPACK, support HTTP.
 +    - efinet_set_network_from_uefi_devpath.patch: configure network from the
 +      devpath provided by the UEFI firmware.
 +    - efinet_set_dns_from_uefi_proto.patch: set DNS nameservers and search
 +      domains from the UEFI protocol.
 +  * debian/patches/install_signed.patch: update patch for the new names of
 +    the EFI binaries from shim.
 +  * debian/control: Breaks shim (<< 0.9+1474479173.6c180c6-0ubuntu1~) due to
 +    the renamed binaries in the new shim.
 +  * debian/postinst.in: call on to update-secureboot-policy on configure to
 +    make sure users can disable shim validation if necessary. 
 +  * debian/build-efi-images: add loopback and squash4 modules to the signed
 +    EFI images.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 01 Nov 2016 11:10:52 +0000
 +
 +grub2 (2.02~beta3-2) unstable; urgency=medium
 +
 +  * debian/watch: Switch URL scheme to HTTP.
 +  * Fix operator precedence in GRUB_DEVICE UUID tests (closes: #841680,
 +    #841741).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 31 Oct 2016 10:24:02 +0000
 +
 +grub2 (2.02~beta3-1) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * New upstream beta release.
 +  * syslinux_test: Fix out-of-tree build handling.
 +  * Drop "grub-shell: Pass -no-pad to xorriso when building floppy images".
 +    The floppy images built by grub-shell are no longer over the floppy
 +    limit, and this patch now itself causes fddboot_test failures.
 +  * Build with GCC 6 (closes: #835964).
 +  * linuxefi.patch: Adjust for libgcc removal.
 +  * Apply openSUSE patch to accept empty modules for now so that Xen builds
 +    work.
 +
 +  [ Debconf translations ]
 +  * [ja] Japanese (Takuma Yamada; closes: #815203, #817084).
 +
 +  [ Martin Pitt ]
 +  * debian/grub-common.init: Don't source /lib/init/vars.sh, we don't depend
 +    on initscripts (and don't want to). There is no reason why we would not
 +    use the LSB log_action_msg in non-verbose (default) mode, most other
 +    packages use it unconditionally (closes: #824875, LP: #1584134).
 +
 +  [ Steve Beattie ]
 +  * debian/rules: Disable PIE builds for GRUB modules (closes: #837493).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 16 Oct 2016 10:46:46 +0100
 +
 +grub2 (2.02~beta2-36) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Use HTTPS for Vcs-Git URL.
 +  * Add zfs, zfscrypt, and zfsinfo to signed EFI images (LP: #1542358).
 +
 +  [ Martin Pitt ]
 +  * debian/postinst.in, debian/kernel/zz-update-grub: Call
 +    systemd-detect-virt (which works under any init system, despite the
 +    name) instead of the Ubuntu specific running-in-container wrapper.
 +    (LP: #1539016)
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 05 Feb 2016 15:41:05 +0000
 +
 +grub2 (2.02~beta2-35) unstable; urgency=medium
 +
 +  * Apply the arm64 -mpc-relative-literal-loads workaround in configure
 +    rather than in debian/rules, to cope with toolchains that don't have the
 +    relevant patch applied.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 22 Jan 2016 11:02:10 +0000
 +
 +grub2 (2.02~beta2-34) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Remove duplicate Replaces on grub-ieee1275 (<< 2.00-4) from
 +    grub2-common.
 +  * Refer to /usr/share/common-licenses/GPL-3 rather than
 +    /usr/share/common-licenses/GPL.
 +  * Cherry-pick upstream patches to add more ACPI opcodes to acpihalt
 +    (closes: #766853, LP: #1530648).
 +  * Drop build-dependency on libusb-dev, since it was currently unused in
 +    any case; also explicitly configure with --disable-grub-emu-usb to avoid
 +    possible future ambiguity (closes: #810421).
 +  * Use dpkg-maintscript-helper to convert directories to symlinks in
 +    various upgrade cases, in place of hand-coded equivalents.
 +  * Change versioned Conflicts from grub-common and grub2-common into Breaks
 +    or Breaks+Replaces as appropriate.
 +  * Remove pragmas related to -Wunreachable-code (closes: #812047).
 +  * Temporarily work around arm64 build failure with gcc-5 >= 5.3.1-4 using
 +    -mpc-relative-literal-loads.
 +  * Backport various ZFS improvements from trunk (closes: #706415, #772797;
 +    LP: #1451476, #1530457).
 +
 +  [ Didier Roche ]
 +  * Use new plymouth theme path to set grub theme configuration.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 22 Jan 2016 10:03:00 +0000
 +
 +grub2 (2.02~beta2-33) unstable; urgency=high
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Cherry-picks to better handle TFTP timeouts on some arches: (LP: #1521612)
 +    - (7b386b7) efidisk: move device path helpers in core for efinet
 +    - (c52ae40) efinet: skip virtual IP devices when enumerating cards
 +    - (f348aee) efinet: enable hardware filters when opening interface
 +
 +  [ Lee Trager ]
 +  * Add raid5rec and raid6rec to signed EFI images (closes: #807385).
 +
 +  [ Colin Watson ]
 +  * CVE-2015-8370: Fix authentication bypass via backspace integer underflow
 +    (closes: #808122).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 16 Dec 2015 09:46:22 +0000
 +
 +grub2 (2.02~beta2-32) unstable; urgency=medium
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Cherry-pick patch to add SAS disks to the device list from the ofdisk
 +    module. (LP: #1517586)
 +
 +  [ dann frazier ]
 +  * Cherry-pick patch to open Simple Network Protocol exclusively.
 +    (LP: #1508893)
 +
 +  [ Linn Crosetto ]
 +  * Install arm64 signed images if UEFI Secure Boot is enabled (closes:
 +    #806178).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 25 Nov 2015 16:07:21 +0000
 +
 +grub2 (2.02~beta2-31) unstable; urgency=medium
 +
 +  * Cherry-pick upstream patch to fix XFS alignment treatment.
 +  * Cherry-pick upstream patch to fix XFS handling of symlink with
 +    crc-enabled filesystem.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 05 Nov 2015 15:08:03 +0000
 +
 +grub2 (2.02~beta2-30) unstable; urgency=medium
 +
 +  [ dann frazier ]
 +  * arm64/setjmp: Add missing license macro. (LP: #1459871)
 +
 +  [ Colin Watson ]
 +  * Cherry-pick upstream patches for XFS v5 support (closes: #772565).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 05 Nov 2015 12:30:27 +0000
 +
 +grub2 (2.02~beta2-29) unstable; urgency=medium
 +
 +  [ Linn Crosetto ]
 +  * Clean up docs, mpi, and other files (closes: #798607).
 +
 +  [ dann frazier ]
 +  * progress: avoid NULL dereference for net files. (LP: #1459872)
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 13 Oct 2015 23:36:46 +0100
 +
 +grub2 (2.02~beta2-28) unstable; urgency=medium
 +
 +  * Reduce the CFLAGS -O3 default on Ubuntu ppc64el to -O2; it introduces
 +    various -Werror failures and isn't worth it here.
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 06 Sep 2015 01:25:56 +0100
 +
 +grub2 (2.02~beta2-27) unstable; urgency=medium
 +
 +  [ Felix Zielcke ]
 +  * Remove Robert Millan from Uploaders with his permission. Thanks for
 +    all the work he did for GRUB 2!
 +  * Stop forcing gcc-4.9 for building.
 +  * Update to Policy 3.9.6.
 +  * Update the Browser URL for our git repository.
 +  * Use dpkg-buildflags at least for the host binaries.
 +  * Simplify Build-Depends.
 +
 +  [ Colin Watson ]
 +  * Go back to forcing a particular compiler version, but this time gcc-5.
 +    The reason for this is that new compiler versions often make slight
 +    changes to the size of compiled code which break delicate parts of GRUB,
 +    and we want to make sure that we test newer versions before switching to
 +    them.
 +  * Make builds that are not limited to architecture-dependent packages
 +    (i.e. dpkg-buildpackage -b) work on non-x86 architectures (closes:
 +    #744954).
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * debian/build-efi-images: Look for grub.cfg in $cmdpath too in
 +    gcdx64.efi, to simplify embedded scenarios: putting a grub.cfg snippet
 +    that loads the right "real" grub.cfg can be useful. (LP: #1468111)
 +  * debian/patches/uefi_firmware_setup.patch: Take into account that the
 +    UEFI variable OsIndicationsSupported is a bit field, and as such should
 +    be compared as hex values in 30_uefi-firmware.in. (LP: #1456911)
 +  * Update quick boot logic to handle abstractions for which there is no
 +    write support. (LP: #1274320)
 +
 +  [ dann frazier ]
 +  * d/p/arm64-set-correct-length-of-device-path-end-entry.patch: Fixes
 +    booting arm64 kernels on certain UEFI implementations. (LP: #1476882)
 +
 +  [ Debconf translations ]
 +  * [lv] Latvian (Rudolfs Mazurs; closes: #777648).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 04 Sep 2015 12:35:59 +0100
 +
 +grub2 (2.02~beta2-26) unstable; urgency=medium
 +
 +  [ William Grant ]
 +  * Fix linuxefi module to be included on x86_64-efi rather than amd64-efi.
 +    amd64-efi isn't a thing. (LP: #1464959)
 +
 +  [ Steven Chamberlain ]
 +  * Recognise Xen xbd and KVM virtio disks on kFreeBSD (closes: #786621).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 14 Jun 2015 10:02:19 +0100
 +
 +grub2 (2.02~beta2-25) unstable; urgency=medium
 +
 +  * Build-depend on dosfstools and mtools on arm64 as well as amd64.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 12 Jun 2015 12:29:19 +0100
 +
 +grub2 (2.02~beta2-24) unstable; urgency=medium
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Fix handling of --disk-module option (cherry-pick from fa335308).
 +    (Closes: #746596, LP: #1309735)
 +  * Fix double-free of LV names for mdraid (cherry-pick from fc535b32).
 +    (LP: #1330963)
 +
 +  [ dann frazier ]
 +  * Build image tarball on arm64
 +  * Only include linuxefi module in images for amd64. This module doesn't
 +    exist on other platforms like arm64, where GRUB chainloads to the kernel
 +    EFI stub.
 +
 +  [ Paulo Flabiano Smorigo ]
 +  * powerpc: Add a flag to avoid unnecessary optimizations (like vsx)
 +    (LP: #1459706).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 11 Jun 2015 17:08:09 +0100
 +
 +grub2 (2.02~beta2-23) unstable; urgency=medium
 +
 +  [ Debconf translations ]
 +  * [da] Danish (Joe Dalton; closes: #781333).
 +
 +  [ Felix Zielcke ]
 +  * Run the tests with LC_MESSAGES=C.UTF-8. Some tests fail with non
 +    english locale. (Closes: #782580)
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Backport from upstream:
 +    - arp, icmp: Fix handling in case of oversized or invalid packets.
 +      (LP: #1428005)
 +
 +  [ Robie Basak ]
 +  * Change the default GRUB_RECORDFAIL_TIMEOUT to 30, so interactive users
 +    still get the opporunity to intervene after a real boot failure, but
 +    headless users will not end up stuck after boot failures that were
 +    really power failures (closes: #782552, LP: #1443735).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 14 May 2015 16:18:33 +0100
 +
 +grub2 (2.02~beta2-22) unstable; urgency=medium
 +
 +  * Make grub-common's Suggests on grub-emu architecture-specific, to
 +    quieten debcheck.
 +  * Remove unnecessary feature test macros from hostfs, to fix building with
 +    glibc 2.20.
 +  * Backport from upstream:
 +    - Fix UEFI boot failure with some firmware that returns incorrect paths
 +      (closes: #735960).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 23 Mar 2015 15:30:15 +0000
 +
 +grub2 (2.02~beta2-21) unstable; urgency=medium
 +
 +  [ Mathieu Trudel-Lapierre ]
 +  * Fix overlap check in check_blocklists for load_env (backported patch
 +    from upstream commit 1f6af2a9; LP: #1311247).
 +
 +  [ Steve McIntyre ]
 +  * Add support for running a 64-bit Linux kernel on a 32-bit EFI (closes:
 +    #775202).
 +
 +  [ Colin Watson ]
 +  * Use mtmsr rather than mtmsrd in ppc64el-disable-vsx.patch, since the
 +    "VSX Available" bit is in the lower half of the MSR anyway, and mtmsrd
 +    faults on 32-bit systems (closes: #776400).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 27 Jan 2015 20:37:04 +0000
 +
 +grub2 (2.02~beta2-20) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Generate alternative init entries in advanced menu (closes: #757298,
 +    #773173).
 +  * When configuring grub-pc, copy unicode.pf2 to /boot/grub/ even if
 +    /boot/grub/grub.cfg does not exist yet; this matches the behaviour of
 +    grub-efi-* (thanks, Luca Capello; closes: #617196).
 +
 +  [ Debconf translations ]
 +  * [fi] Finnish (Timo Jyrinki; closes: #774060).
 +  * [mr] Marathi (sampada nakhare; closes: #773901).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 03 Jan 2015 12:39:52 +0000
 +
 +grub2 (2.02~beta2-19) unstable; urgency=medium
 +
 +  [ Steve McIntyre ]
 +  * Handle case insensitivity of VFAT filesystem on /boot/EFI when installing
 +    extra cpoy of grub-efi to the removable media path
 +    /boot/efi/EFI/BOOT/BOOT$ARCH.EFI (Closes: #773092)
 +  * Make the force_efi_extra_removable debconf prompt only show up when
 +    configuring grub-*efi*. Closes: #773004
 +
 +  [ Ian Campbell ]
 +  * Improvements to English wording of new debconf template from Justin B Rye.
 +  * Add debian/README.source.
 +
 +  [ Debconf translations ]
 +  * [eu] Basque (Iñaki Larrañaga Murgoitio, Closes: #772946)
 +  * [be] Belarusian (Viktar Siarheichyk, Closes: #773054)
 +  * [pt_BR] Brazilian Portuguese (Adriano Rafael Gomes, Closes: #773682)
 +  * [bg] Bulgarian (Damyan Ivanov, Closes: #772878)
 +  * [cs] Czech (Miroslav Kure, Closes: #772924)
 +  * [nl] Dutch (Frans Spiesschaert, Closes: 773637)
 +  * [eo] Esperanto (Felipe Castro, Closes: #773096)
 +  * [fi] Finnish (Timo Jyrinki, Closes: #772921)
 +  * [fr] French (Christian PERRIER, Closes: #772771)
 +  * [de] German (Martin Eberhard Schauer, Closes: #773664)
 +  * [el] Greek (Panagiotis Georgakopoulos, Closes: #773068)
 +  * [he] Hebrew (Omer Zak, Closes: #773377)
 +  * [is] Icelandic (Sveinn í Felli, Closes: #772922)
 +  * [it] Italian (Luca Monducci, Closes: #773553)
 +  * [kk] Kazakh (Baurzhan Muftakhidinov, Closes: #772916)
 +  * [lt] Lithuanian (Rimas Kudelis, Closes: #773060)
 +  * [pl] Polish (Łukasz Dulny, Closes: #772930)
 +  * [ro] Romanian (Andrei POPESCU, Closes: #773349)
 +  * [ru] Russian (Yuri Kozlov, Closes: #773211)
 +  * [sl] Slovenian (Vanja Cvelbar, Closes: #773508)
 +  * [es] Spanish (Manuel "Venturi" Porras Peralta, Closes: #773222)
 +  * [sv] Swedish (Martin Bagge & Anders Jonsson, Closes: 773208)
 +  * [th] Thai (Theppitak Karoonboonyanan, Closes: #773160)
 +  * [zh_TW] Traditional Chinese (Vincent W. Chen, Closes: #773418)
 +  * [tr] Turkish (Mert Dirik, Closes: #773666)
 +
 + -- Ian Campbell <ijc@debian.org>  Mon, 22 Dec 2014 11:55:33 +0000
 +
 +grub2 (2.02~beta2-18) unstable; urgency=medium
 +
 +  [ Steve McIntyre ]
 +  * Add support for forcing an extra copy of grub-efi to the removable
 +    media path /boot/efi/EFI/BOOT/BOOT$ARCH.EFI (#767037)
 +
 +  [ Ian Campbell ]
 +  * Add myself to Uploaders.
 +
 + -- Ian Campbell <ijc@debian.org>  Mon, 08 Dec 2014 08:38:38 +0000
 +
 +grub2 (2.02~beta2-17) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Fix up some pointer-to-integer casts in linuxefi so that it can build on
 +    i386-efi.
 +  * Backport from upstream:
 +    - Fix typo (gettext_print instead of gettext_printf) (LP: #1390766).
 +
 +  [ Ian Campbell ]
 +  * Correct syntax error in grub-xen-host bootstrap configuration file.
 +  * Log failure when grub-install fails in postinst, rather than failing the
 +    entire postinst. (Closes: #770412)
 +  * Arrange to insmod xzio and lzopio when booting a kernel as a Xen guest.
 +    (Closes: #755256)
 +
 + -- Ian Campbell <ijc@debian.org>  Sun, 30 Nov 2014 17:15:21 +0000
 +
 +grub2 (2.02~beta2-16) unstable; urgency=medium
 +
 +  [ Ian Campbell ]
 +  * Provide prebuilt grub-xen binaries for host use in a new grub-xen-host
 +    package.
 +  * Build/Install binaries into /boot/xen when installing grub-xen.
 +
 + -- Ian Campbell <ijc@debian.org>  Thu, 06 Nov 2014 13:32:01 +0000
 +
 +grub2 (2.02~beta2-15) unstable; urgency=medium
 +
 +  * Disable nvram installation again on chrp_ibm machines that are emulated
 +    by qemu; that doesn't have nvram devices so the nvram utility inevitably
 +    fails.
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 15 Oct 2014 21:34:02 +0100
 +
 +grub2 (2.02~beta2-14) unstable; urgency=medium
 +
 +  * On architectures without a real GRUB port, just build the utilities.
 +    This makes tools such as grub-probe and grub-fstest available
 +    everywhere, and makes grub-mount available on all Linux and kFreeBSD
 +    architectures.
 +  * Remove .MIPS.abiflags section from images (thanks, Jurica Stanojkovic,
 +    although I used a slightly simpler approach; closes: #762307).
 +  * Include a text attribute reset in the clear command for ppc
 +    (LP: #1295255).
 +  * Disable VSX instruction on powerpc startup to fix booting on ppc64el.
 +  * Stop adding a CHRP note on chrp_ibm machines, since that apparently
 +    breaks PowerVM and isn't needed on other machine types as far as we can
 +    tell (LP: #1334793).
 +  * Refactor flicker-free-boot configuration in debian/rules to reduce
 +    duplication.
 +  * Disable flicker-free-boot on Ubuntu ppc64el for now, as it isn't needed
 +    there and causes too many problems (LP: #1338471).
 +  * Use nvram rather than nvsetenv on chrp_ibm machines, since that tool is
 +    better-supported and copes with such things as nvram being missing in
 +    qemu.
 +  * Remove brace-expansion from the postrm, and switch the preinst and
 +    postrm to /bin/sh (closes: #762940).
 +  * On ppc64el, look for a PReP partition and install the core image to the
 +    first one if found.  For now this is done by borrowing prep-bootdev.c
 +    from grub-installer, incurring a dependency on libparted.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 26 Sep 2014 18:05:15 +0100
 +
 +grub2 (2.02~beta2-13) unstable; urgency=medium
 +
 +  * Drop gcc-4.9-multilib build-dependency on ppc64el again.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 19 Sep 2014 20:30:31 +0100
 +
 +grub2 (2.02~beta2-12) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Point Vcs-* fields back at master.
 +  * Support grub-emu on x32 (closes: #760428).
 +  * Adjust packaging for x32:
 +    - Build-depend on cpio on x32 as well.
 +    - Make grub-efi-ia32-bin and grub-efi-amd64-bin depend on efibootmgr on
 +      any Linux architecture for which they are built (in practice, adding
 +      x32).
 +    - Build grub-mount-udeb on x32 as well.
 +    - Add Lintian binary-from-other-architecture overrides where
 +      appropriate.
 +  * Apply patches from Paulo Flabiano Smorigo to allow building a 32-bit
 +    big-endian loader on ppc64el using -m32 -mbig-endian, replacing the
 +    cross-compiler hack.
 +
 +  [ Ian Campbell ]
 +  * Add dependency on efibootmgr to grub-efi-{arm,arm64}-bin.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 19 Sep 2014 15:19:26 +0100
 +
 +grub2 (2.02~beta2-11) unstable; urgency=medium
 +
 +  * Force grub-pc/mixed_legacy_and_grub2 to be reshown, rather than failing
 +    when it was already seen (closes: #749571).
 +  * Build with GCC 4.9 (closes: #748003).
 +  * Build for sparc64 (closes: #753784).
 +  * Fix an infinite loop in grub-mkconfig when kernel paths contain regex
 +    metacharacters.  Thanks to Heimo Stranner for the report.
 +  * On upgrade, if we find that one of the install devices no longer exists,
 +    ask the debconf question at priority critical rather than high.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 24 Jul 2014 09:11:31 +0100
 +
 +grub2 (2.02~beta2-10) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Add the true module to the signed image, since 05_debian_theme uses it.
 +    Thanks to Dimitri John Ledkov for the report.
 +  * Limit test suite parallelisation to 1; the test suite seems to have some
 +    isolation problems at higher levels at the moment (closes: #746856).
 +  * Simplify override_dh_install a bit.
 +  * Backport patches from upstream to make the network stack more responsive
 +    on busy networks (LP: #1314134).
 +
 +  [ Dimitri John Ledkov ]
 +  * Add support for nvme device in grub-mkdevicemap (closes: #746396,
 +    LP: #1275162).
 +
 +  [ Debconf translations ]
 +  * Korean (Changwoo Ryu, closes: #745559).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 08 May 2014 11:13:48 +0100
 +
 +grub2 (2.02~beta2-9) unstable; urgency=medium
 +
 +  * Backport from upstream:
 +    - Tolerate devices with no filesystem UUID returned by os-prober
 +      (LP: #1287436).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 10 Apr 2014 17:34:44 +0100
 +
 +grub2 (2.02~beta2-8) unstable; urgency=medium
 +
 +  [ Colin Watson ]
 +  * Backport from upstream:
 +    - ieee1275: check for IBM pseries emulated machine.
 +    - Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig
 +      (closes: #735935).
 +    - btrfs: fix get_root key comparison failures due to endianness.
 +  * Build-depend on automake (>= 1.10.1) to ensure that it meets configure's
 +    requirements (LP: #1299041).
 +  * When installing an image for use with UEFI Secure Boot, generate a
 +    load.cfg even if there are no device abstractions in use (LP: #1298399).
 +
 +  [ Jon Severinsson ]
 +  * Add Tanglu support, as in Debian except:
 +    - Enable splash screen by default (as Ubuntu)
 +    - Enable quiet and quick boot (as Ubuntu)
 +    - Enable the grub-common init script (as Ubuntu)
 +    - Enable dynamic gfxpayload (as Ubuntu)
 +    - Enable vt handover (as Ubuntu)
 +    - Use monochromatic theme by default (as Ubuntu)
 +    - Use Tanglu GRUB wallpaper by default.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 31 Mar 2014 16:30:37 +0100
 +
 +grub2 (2.02~beta2-7) experimental; urgency=medium
 +
 +  * Fix shift-held-down test not to clear other modifier key states
 +    (LP: #843804).
 +  * Explicitly pass an appropriate --target to grub-install in the postinst
 +    (suggested by Jordan Uggla).
 +  * Backport from upstream:
 +    - Use bootaa64.efi instead of bootaarch64.efi on arm64 to comply with
 +      EFI specification.  Also use grubaa64.efi for consistency.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 10 Mar 2014 13:39:33 +0000
 +
 +grub2 (2.02~beta2-6) experimental; urgency=medium
 +
 +  * Install bootinfo.txt and grub.chrp into grub-ieee1275-bin on powerpc and
 +    ppc64el.
 +  * Port yaboot logic to improve installation for various powerpc machine
 +    types.
 +  * Improve parsing of /etc/default/grub.d/*.cfg in C utilities
 +    (LP: #1273694).
 +  * Run grub-install on install or upgrade on grub-ieee1275/ppc64el.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 28 Jan 2014 23:50:55 +0000
 +
 +grub2 (2.02~beta2-5) experimental; urgency=medium
 +
 +  * Add a number of EFI debugging commands to the signed image (lsefi,
 +    lsefimmap, lsefisystab, lssal).
 +  * Add gfxterm_background to the signed image so that background_image
 +    works in UEFI Secure Boot mode.  Thanks to syscon-hh for the report.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 27 Jan 2014 10:03:00 +0000
 +
 +grub2 (2.02~beta2-4) experimental; urgency=medium
 +
 +  * Remove redundant build-dependencies on autoconf and automake, covered by
 +    dh-autoreconf.
 +  * In --enable-quick-boot mode, restore previous behaviour of using a
 +    hidden timeout if GRUB_HIDDEN_TIMEOUT=0 (thanks to Sebastien Bacher for
 +    the report).
 +  * Disable cpio test on kFreeBSD again for now; it fails within cpio itself
 +    with "field width not sufficient for storing rdev minor".
 +  * Copy shim.efi.signed to the correct path in UEFI Secure Boot mode.
 +    Thanks to syscon-hh for the report.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 20 Jan 2014 15:53:36 +0000
 +
 +grub2 (2.02~beta2-3) experimental; urgency=medium
 +
 +  * Pass VERBOSE=1 when running tests so that Automake will print test logs
 +    on failure.
 +  * Adjust Vcs-* fields to indicate the experimental branch.
 +  * Build-depend on cpio on architectures where we run the test suite, for
 +    tests/cpio_test.in.
 +  * Ignore EPERM when modifying kern.geom.debugflags on FreeBSD, fixing
 +    tests.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 17 Jan 2014 10:50:40 +0000
 +
 +grub2 (2.02~beta2-2) experimental; urgency=medium
 +
 +  * Convert patch handling to git-dpm.
 +  * Add bi-endian support to ELF parser (Tomohiro B Berry).
 +  * Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
 +    to appease "gcc -Werror=missing-prototypes".
 +  * Cherry-pick from upstream:
 +    - Change grub-macbless' manual page section to 8.
 +  * Install grub-glue-efi, grub-macbless, grub-render-label, and
 +    grub-syslinux2cfg.
 +  * grub-shell: Pass -no-pad to xorriso when building floppy images.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 16 Jan 2014 15:18:04 +0000
 +
 +grub2 (2.02~beta2-1) experimental; urgency=low
 +
 +  * New upstream beta release.
 +  * Drop qemu-utils build-dependency; the test suite no longer uses
 +    qemu-img.
 +  * Build grub-common, grub2-common, grub-themes-starfield, and grub-mount
 +    on ARM and ARM64 architectures.
 +  * Install grub-mkrescue in grub-common on all architectures.
 +  * Make grub-efi-ia32, grub-efi-amd64, and grub-efi-ia64 conflict with
 +    elilo.
 +  * Adjust the postinst of grub-efi-ia64, grub-efi-arm, and grub-efi-arm64
 +    to keep the EFI System Partition up to date with grub-install after it
 +    has been run once, like grub-efi-ia32 and grub-efi-amd64 already do.
 +  * Regularise indentation of "recordfail" in /etc/grub.d/10_linux.
 +  * Add alpha.gnu.org to debian/watch, for pre-releases.
 +  * Add OpenPGP signature checking configuration to watch file.
 +  * Drop mkconfig_skip_dmcrypt.patch; it breaks GRUB_ENABLE_CRYPTODISK=y,
 +    which is a better fix for the original problem (closes: #732245).
 +  * Fix mismerge of mkconfig_loopback.patch.
 +  * Build for ppc64el, using a powerpc cross-compiler at least for now.
 +  * Don't run gettext_strings_test; this test is mainly useful as an
 +    upstream maintenance check.
 +  * Silence warning if /usr/share/locale-langpack does not exist (closes:
 +    #732595).
 +  * Remove debian/grub-common.preinst, superseded by .maintscript files.
 +  * Install grub-file in grub-common.
 +  * Fix crash due to pointer confusion in grub-mkdevicemap, introduced while
 +    converting away from nested functions in 2.00+20131208-1.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 26 Dec 2013 00:52:47 +0000
 +
 +grub2 (2.00+20131208-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +    - Skip issuing cursor on/off sequences on Macs (closes: #683068).
 +    - Move grub-mknetdir to /usr/bin (closes: #688799).
 +    - Apply program name transformations at build-time rather than at
 +      run-time (closes: #696465).
 +    - Add info documentation for grub-mount (closes: #666427).
 +    - Clean up dangling references to grub-setup (LP: #1082045).
 +    - Avoid installing to sectors matching the signature of an Acer
 +      registration utility with several sightings in the wild (LP: #987022).
 +    - Document the need for GRUB_DEFAULT=saved in grub-set-default(8)
 +      (LP: #1102925).
 +    - Fix missing PVs if they don't contain an "interesting" LV (probably
 +      closes: #650724, #707613).
 +    - Reimplement grub-reboot to not depend on saved_entry (closes: #707695,
 +      LP: #704406).
 +    - Fix Ctrl-u handling to copy the killed characters to the kill buffer
 +      as UCS4 stored as grub_uint32_t rather than as 8-bit characters stored
 +      as char (closes: #710076).
 +    - Fix inconsistent use of GRUB_CRYPTODISK_ENABLE and
 +      GRUB_ENABLE_CRYPTODISK (LP: #1232237).
 +    - Support GRUB_DISABLE_SUBMENU configuration, and document submenu usage
 +      in grub-reboot(8) (closes: #690538).
 +    - Don't decompress initrd when booting with Xen (closes: #700197).
 +    - Document how to delete the whole environment block (closes: #726265).
 +    - Revamp hidden timeout handling by adding a new timeout_style
 +      environment variable and a corresponding GRUB_TIMEOUT_STYLE
 +      configuration key for grub-mkconfig.  This controls hidden-timeout
 +      handling more simply than the previous arrangements, and pressing any
 +      hotkeys associated with menu entries during the hidden timeout will
 +      now boot the corresponding menu entry immediately (LP: #1178618).  As
 +      part of merging this, radically simplify the mess that
 +      quick_boot.patch had made of /etc/grub.d/30_os-prober; if it finds
 +      other OSes it can now just set timeout_style=menu and make sure the
 +      timeout is non-zero.
 +    - On Linux, read partition start offsets from sysfs if possible
 +      (LP: #1237519).
 +    - New ports to arm-uboot, arm-efi, arm64-efi, i386-xen, and x86_64-xen.
 +  * Add grub-uboot*, grub-efi-arm*, and grub-xen* binary packages.
 +  * Ignore functional test failures for now as they are broken.
 +  * Move working directories around (build/<package> -> obj/<package>,
 +    build/stamps -> debian/stamps) so that "debian/rules build" still works
 +    after working directories have been created.
 +  * Drop "grub-mkrescue --diet" option; never merged upstream and only
 +    matters for floppies.  Please let me know if you were using this.
 +    Explicitly use -no-pad to build grub-rescue-floppy.img, which has an
 +    equivalent effect on size.
 +  * Break lupin-support (<< 0.55) due to the rewrite of grub-install in C.
 +  * Remove build-dependency on autogen, no longer needed.
 +  * Compress GRUB files on grub-rescue-floppy.img using xz.
 +  * Build-depend on wamerican, newly required by the test suite.
 +  * Run tests with LC_CTYPE=C.UTF-8, so that grub-fs-tester can handle UTF-8
 +    data correctly.
 +  * Update debian/legacy/update-grub to the version from grub 0.97-67.
 +  * Silence error message on initial installation when /etc/default/grub
 +    does not yet exist.
 +  * Add GRUB_RECOVERY_TITLE option, to allow the controversial "recovery
 +    mode" text to be customised (LP: #1240360).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 09 Dec 2013 00:21:45 +0000
 +
 +grub2 (2.00-20) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Sort gnumach kernels in version order (closes: #725451).
 +  * Move packaging to git, following upstream.  Adjust Vcs-* fields.
 +  * Remove obsolete DM-Upload-Allowed field.
 +  * Merge (completely!) from Ubuntu:
 +    - Handle probing striped DM-RAID devices (thanks, Robert Collins;
 +      LP: #803658).
 +    - Unconditionally create grub.cfg on our EFI boot partition in Secure
 +      Boot mode; GRUB always needs some configuration in this case to find
 +      /boot/grub, since we can't modify the signed image at install time
 +      (Steve Langasek, LP: #1236625).
 +    - If MokManager is present on the host system, copy it onto the EFI boot
 +      partition for use (Steve Langasek).
 +    - Adjust UEFI installation to cope with Kubuntu setting GRUB_DISTRIBUTOR
 +      (LP: #1242417).
 +    - If building for Ubuntu:
 +      + Bypass menu unless other OSes are installed or Shift is pressed.
 +      + Show the boot menu if the previous boot failed.
 +      + Set GRUB_GFXPAYLOAD_LINUX=keep unless it's known to be unsupported
 +        on the current hardware.
 +      + Set vt.handoff=7 for smooth handoff to kernel graphical mode.
 +      + In recovery mode, add nomodeset to the Linux kernel arguments, and
 +        remove the 'set gfxpayload=keep' command.
 +      + Set default timeout to 10 seconds.
 +      + Enable hidden timeout support by default.
 +    - Migrate timeout settings from menu.lst.
 +    - Probe FusionIO devices (LP: #1237519).
 +  * Make grub.cfg world-unreadable if even hashed passwords are in use
 +    (closes: #632598).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 14 Nov 2013 10:49:31 +0000
 +
 +grub2 (2.00-19) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Merge from Ubuntu:
 +    - debian/build-efi-images: Where possible, make use of the device path
 +      derived from the EFI Loaded Image Protocol to compute the prefix
 +      (LP: #1097570).
 +    - debian/build-efi-images: Add a netboot image target to our set of
 +      prebuilt EFI images (thanks, Steve Langasek).
 +  * Backport from upstream:
 +    - Handle partitions on non-512B EFI disks (LP: #1065281).
 +
 +  [ Phillip Susi ]
 +  * restore_mkdevicemap.patch: Fix dmraid uuid check to look for "DMRAID-"
 +    anywhere instead of only at the start, since kpartx prefixes it with
 +    "partN-" (LP: #1183915).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 18 Sep 2013 17:18:27 +0100
 +
 +grub2 (2.00-18) unstable; urgency=low
 +
 +  * Add gettext module to signed UEFI images (LP: #1104627).
 +  * Put the preprocessor definition for quiet-boot in the right place so
 +    that it actually takes effect.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 26 Aug 2013 17:23:09 +0100
 +
 +grub2 (2.00-17) unstable; urgency=low
 +
 +  * Really include patches to reduce visual clutter in normal mode when
 +    building for Ubuntu.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 15 Aug 2013 09:58:59 +0100
 +
 +grub2 (2.00-16) unstable; urgency=low
 +
 +  * Make reportbug script file robust against su authentication failures and
 +    missing LVM commands.
 +  * Backport from upstream:
 +    - Move @itemize after @subsection to satisfy texinfo-5.1.
 +    - grub-mkconfig: Fix detection of Emacs autosave files.
 +    - Fix spurious failure on Xen partition devices without disk devices
 +      (closes: #708614).
 +  * Merge from Ubuntu:
 +    - Treat Kubuntu as an alias for Ubuntu in GRUB_DISTRIBUTOR (Harald
 +      Sitter).
 +    - Make any EFI system boot into the shim (if installed) even if
 +      SecureBoot is disabled (Stéphane Graber).
 +    - Allow Shift to interrupt 'sleep --interruptible'.
 +    - If building for Ubuntu:
 +      + Reduce visual clutter in normal mode.
 +      + Remove verbose messages printed before reading configuration.
 +      + Suppress kernel/initrd progress messages, except in recovery mode.
 +      + Suppress "GRUB loading" message unless Shift is held down.
 +    - Skip Windows os-prober entries on Wubi systems.
 +  * Consolidate debian/rules logic for when to build signed images.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 15 Aug 2013 08:35:53 +0100
 +
 +grub2 (2.00-15) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Install reportbug presubj and script files in all binary packages.
 +  * Make grub-yeeloong.postinst explicitly install with
 +    --target=mipsel-loongson (closes: #708204).
 +  * Make grub-script-check fail on scripts containing no commands (closes:
 +    #713886).
 +  * Make the description of grub-firmware-qemu a little more generic, rather
 +    than assuming that bochsbios provides qemu's default BIOS image (closes:
 +    #714277).
 +  * Don't assume that the presence of /etc/default/grub or
 +    /etc/default/grub.d/*.cfg means that any particular item is set in it
 +    (LP: #1199731).
 +
 +  [ Debconf translations ]
 +  * Hungarian (Dr. Nagy Elemér Károly).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 13 Jul 2013 11:04:15 +0100
 +
 +grub2 (2.00-14) unstable; urgency=low
 +
 +  * Merge from Ubuntu:
 +    - Don't call update-grub in the zz-update-grub kernel hook if
 +      /boot/grub/grub.cfg doesn't exist.
 +    - acpihalt: expand parser to handle SSDTs and some more opcodes.  Fixes
 +      test suite hang with current seabios.
 +  * Remove kernel-specific grub.d conffiles that were dropped from packages
 +    built for all but their corresponding kernel type in 1.96+20090307-1
 +    (closes: #703539).
 +  * Look for grub-bios-setup in /usr/lib/grub/i386-pc/ as well (closes:
 +    #705636).
 +  * Merge 1.99-27.1 (thanks, Steve McIntyre):
 +    - Add entries for Windows Boot Manager found via UEFI in os-prober
 +      (closes: #698914).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 09 May 2013 00:14:55 +0100
 +
 +grub2 (2.00-13) experimental; urgency=low
 +
 +  * Backport from upstream:
 +    - Fix booting FreeBSD >= 9.1 amd64 kernels (closes: #699002).
 +  * Merge from Ubuntu:
 +    - Stop using the /usr/share/images/desktop-base/desktop-grub.png
 +      alternative as the fallback background if GRUB_DISTRIBUTOR is
 +      "Ubuntu".
 +    - source_grub2.py: Use attach_default_grub from apport's hookutils.
 +    - Output a menu entry for firmware setup on UEFI FastBoot systems.
 +    - Set a monochromatic theme and an appropriate background for Ubuntu.
 +    - Remove "GNU/Linux" from default distributor string for Ubuntu.
 +    - Apply Ubuntu GRUB Legacy changes to legacy update-grub script.
 +    - Apply patch from Fedora to add a "linuxefi" loader which boots kernels
 +      with EFI handover patches, avoiding ExitBootServices.
 +    - Temporarily make linuxefi refuse to validate kernels in the absence of
 +      a shim, until we get some other details worked out.
 +    - Automatically call linuxefi from linux if secure boot is enabled and
 +      the kernel is signed, to hand over to the kernel without calling
 +      ExitBootServices.  Otherwise, linux will fall through to previous
 +      code, call ExitBootServices itself, and boot the kernel normally.
 +    - Generate configuration for signed UEFI kernels if available.
 +    - On Ubuntu amd64, add a raw-uefi custom upload tarball for signing.
 +    - Install signed images if available and UEFI Secure Boot is enabled.
 +    - Add "splash" to default boot options on Ubuntu.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 01 Feb 2013 15:44:25 +0000
 +
 +grub2 (2.00-12) experimental; urgency=low
 +
 +  * Silence output from running-in-container.
 +  * Also skip update-grub when running in a container (LP: #1060404).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 24 Jan 2013 23:21:48 +0000
 +
 +grub2 (2.00-11) experimental; urgency=low
 +
 +  [ Adam Conrad ]
 +  * debian/{postinst,config}.in: Don't fail if /etc/default/grub.d
 +    configuration snippets exist, but /etc/default/grub does not.
 +
 +  [ Colin Watson ]
 +  * Merge wheezy branch up to 1.99-27, fixing overzealous removal of
 +    load_video call when GRUB_GFXPAYLOAD_LINUX is empty (closes: #661789).
 +  * Merge from Ubuntu:
 +    - If the postinst is running in a container, skip grub-install and all
 +      its associated questions (LP: #1060404).
 +    - Fix backslash-escaping in merge_debconf_into_conf (LP: #448413).  Note
 +      that this differs slightly from the fix in Ubuntu, which corrected
 +      behaviour when amending an existing configuration item but
 +      accidentally over-escaped when adding a new one.
 +    - Replace "single" with "recovery" when friendly-recovery is installed
 +      (LP: #575469).
 +    - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
 +      Ubuntu's backport of the grub-doc split (LP: #493968).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 21 Jan 2013 10:49:00 +0000
 +
 +grub2 (2.00-10) experimental; urgency=low
 +
 +  * Support parallel builds.
 +  * Remove /boot/grub/unicode.pf2 on purge of grub-efi-{amd64,i386} (closes:
 +    #697183).
 +  * Build with GCC 4.7.
 +  * Merge from Ubuntu:
 +    - Don't permit loading modules on UEFI Secure Boot (since in such a
 +      setup the GRUB core image must be signed but it has no provision for
 +      verifying module signatures).
 +    - Read /etc/default/grub.d/*.cfg after /etc/default/grub (LP: #901600).
 +    - Blacklist 1440x900x32 from VBE preferred mode handling until a better
 +      solution is available (LP: #701111).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 03 Jan 2013 09:38:25 +0000
 +
 +grub2 (2.00-9) experimental; urgency=low
 +
 +  * Ensure /boot/grub exists before copying files to it for EFI installs
 +    (closes: #696962).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 29 Dec 2012 23:44:51 +0000
 +
 +grub2 (2.00-8) experimental; urgency=low
 +
 +  * debian/apport/source_grub2.py:
 +    - Use context managers to avoid (harmless) file descriptor leaks.
 +    - Set a file encoding, per PEP 0263.
 +  * Drop grub-ieee1275-bin's dependency on bc in favour of powerpc-ibm-utils
 +    (>= 1.2.12-1) (cf. #625728).
 +  * Move powerpc-ibm-utils and powerpc-utils dependencies from
 +    grub-ieee1275-bin to grub-ieee1275 (closes: #693400).
 +  * Merge from Ubuntu:
 +    - Ignore symlink traversal failures in grub-mount readdir
 +      (LP: #1051306).
 +    - Fix incorrect initrd minimum address calculation (LP: #1055686).
 +    - Avoid assuming that gets is declared.
 +  * Copy unicode.pf2 to /boot/grub/ for EFI installs so that it is more
 +    likely to be readable by GRUB (closes: #661789).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 28 Dec 2012 17:34:32 +0000
 +
 +grub2 (2.00-7) experimental; urgency=low
 +
 +  * Backport from upstream:
 +    - Fix stderr leakage from grub-probe in is_path_readable_by_grub.
 +    - Fix tftp endianness problem.
 +  * Merge from Ubuntu:
 +    - Prefer translations from language packs (LP: #537998).  (No-op for
 +      Debian, but harmless.)
 +    - Avoid getting confused by inaccessible loop device backing paths
 +      (LP: #938724).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 26 Sep 2012 16:05:07 +0100
 +
 +grub2 (2.00-6) experimental; urgency=low
 +
 +  [ Colin Watson ]
 +  * Adjust package descriptions to talk about update-grub, not update-grub2.
 +  * Backport from upstream:
 +    - Fix grub-emu build on FreeBSD.
 +  * Revert gcc-4.6-multilib build-dependency change from 2.00-1, since
 +    kfreebsd-i386 and hurd-i386 don't have gcc-4.6-multilib.  Instead, make
 +    sure to only install efiemu32.o and efiemu64.o on (linux-)i386,
 +    kopensolaris-i386, and any-amd64.
 +  * Manually expand @PACKAGE@ symbols in grub-efi.postinst (closes:
 +    #688725), grub-linuxbios.postinst (closes: #688726), and grub2.postinst
 +    (closes: #688724).
 +
 +  [ Debconf translations ]
 +  * Lithuanian (Rimas Kudelis).  Closes: #675628
 +  * Galician (Jorge Barreiro).  Closes: #677389
 +  * Welsh (Daffyd Tomos).
 +  * Greek (galaxico).  Closes: #685201
 +  * Romanian (Andrei POPESCU).  Closes: #685477
 +  * Finnish (Timo Jyrinki).
 +
 +  [ Cyril Brulebois ]
 +  * Use xz compression for all binaries to save up some space on CD images
 +    (closes: #688773).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 25 Sep 2012 22:47:03 +0100
 +
 +grub2 (2.00-5) experimental; urgency=low
 +
 +  * Backport from upstream:
 +    - Remove extra layer of escaping from grub_probe.
 +    - Add efifwsetup module to reboot into firmware setup menu.
 +    - Revert incorrect off-by-one fix when embedding in MBR (LP: #1051154).
 +  * Switch watch file to point to ftp.gnu.org.
 +  * Build-depend on liblzma-dev, enabling 'grub-mkimage -C xz'.
 +  * Adjust /etc/grub.d/30_os-prober to detect Ubuntu's use of "recovery"
 +    rather than "single".
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 19 Sep 2012 08:52:27 +0100
 +
 +grub2 (2.00-4) experimental; urgency=low
 +
 +  * Fix platform postinsts to handle new core.img location.
 +  * Only fix up powerpc key repeat on IEEE1275 machines.  Fixes powerpc-emu
 +    compilation.
 +  * Move grub-install to grub2-common, since it's now common across
 +    platforms but clashes with grub-legacy.
 +  * Move grub-mknetdir to grub-common, since it's now common across
 +    platforms.
 +  * Make grub-install fall back to i386-pc if booted using EFI but the
 +    relevant *-efi target is not available (because only grub-pc is
 +    installed).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 14 Sep 2012 13:38:37 +0100
 +
 +grub2 (2.00-3) experimental; urgency=low
 +
 +  * Use dh-autoreconf.
 +  * Bail out if trying to run grub-mkconfig during upgrade to 2.00 (e.g.
 +    while configuring a kernel image), since the old /etc/grub.d/00_header
 +    conffile breaks until such time as grub-common is configured.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 13 Sep 2012 17:07:18 +0100
 +
 +grub2 (2.00-2) experimental; urgency=low
 +
 +  * Add -Wno-error=unused-result to HOST_CFLAGS for the moment, since at
 +    least grub-core/lib/crypto.c fails to compile on Ubuntu otherwise.
 +  * Update default/grub.md5sum to include Ubuntu maverick's default md5sum.
 +  * Autogenerate packaging files for grub-emu, in order that its postinst
 +    does not contain unexpanded @PACKAGE@ symbols.
 +  * Only try to install efiemu*.o into grub-emu on *-i386.
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 08 Sep 2012 10:32:33 +0100
 +
 +grub2 (2.00-1) experimental; urgency=low
 +
 +  [ Jordi Mallach, Colin Watson ]
 +  * New upstream release.
 +    - Add LUKS and GELI encrypted disk support (closes: #463107).
 +    - Lazy scanning to avoid accessing devices which aren't really used.
 +      This avoids boot delay due to slow device scanning (closes: #549905,
 +      #550015, #550083, #564252, #595059, #632408).
 +    - Don't override more informative errors when loading kernel/initrd
 +      (closes: #551630).
 +    - Support 4K-sector NTFS (closes: #567728).
 +    - Unify grub-mkrescue interface on powerpc with that on other
 +      architectures (closes: #570119).
 +    - Fix infinite recursion in gettext when translation fails (closes:
 +      #611537, #612454, #616487, #619618, #626853, #643608).
 +    - Add more missing quotes to grub-mkconfig (closes: #612417).
 +    - Import gnulib change to fix argp_help segfault with help filter
 +      (closes: #612692).
 +    - Support %1$d syntax in grub_printf (closes: #630647).
 +    - Use write-combining MTRR to speed up video with buggy BIOSes (closes:
 +      #630926).
 +    - Remove multiboot header from PXE images to avoid confusing ipxe
 +      (closes: #635877).
 +    - Fix crash when attempting to install to a non-BIOS disk (closes:
 +      #637208).
 +    - Fix handling of grub-mkrescue --xorriso= option (closes: #646788).
 +    - Use umask rather than chmod to create grub.cfg.new to avoid insecure
 +      grub.cfg (closes: #654599).
 +    - Improve font installation logic (closes: #654645).
 +    - Add grub-probe info documentation (closes: #666031).
 +    - Don't crash on canonicalize_file_name failure in grub-probe (closes:
 +      #677211).
 +
 +  [ Colin Watson ]
 +  * Adjust debian/watch to point to xz-compressed tarballs.
 +  * debian/grub.d/05_debian_theme: Source grub-mkconfig_lib from
 +    /usr/share/grub, not the /usr/lib/grub compatibility link.
 +  * Convert to source format 3.0 (quilt).  Developers, note that patches are
 +    stored applied in bzr; you may want to 'quilt pop -a' / 'quilt push -a'
 +    around merges.
 +  * Remove pointless debian/grub-mount-udeb.install.hurd-i386;
 +    grub-mount-udeb is not built on the Hurd.
 +  * Refactor debian/grub-common.install.hurd-i386 into .in files so that it
 +    imposes less of a maintenance burden.
 +  * Restore grub-mkdevicemap for now.  While it's kind of a mess, requiring
 +    lots of OS-specific code to iterate over all possible devices, we use it
 +    in a number of scripts to discover devices and reimplementing those in
 +    terms of something else would be very complicated.
 +  * Add grub-efi-ia64-bin and grub-efi-ia64 packages.  These are currently
 +    experimental, and grub-efi-ia64 does not automatically run grub-install.
 +  * Build-depend on gcc-4.6-multilib on kfreebsd-i386 and hurd-i386 as well
 +    as the other i386 architectures, since we need it to build efiemu32.o
 +    and efiemu64.o.
 +  * Add per-platform *-dbg packages containing files needed to use GRUB's
 +    GDB stub.  These are relatively large and thus worth splitting out.
 +  * Build-depend on ttf-dejavu-core for the starfield theme.
 +  * Add a grub-theme-starfield package containing the starfield theme.
 +  * Backport from upstream:
 +    - Don't decrease efi_mmap_size (LP: #1046429).
 +  * grub-common Suggests: console-setup for grub-kbdcomp (closes: #686815).
 +  * Silence error messages when translations are unavailable.
 +  * Don't pass *.module to dpkg-shlibdeps, avoiding lots of build-time
 +    warnings.
 +  * Move transitional package to Section: oldlibs.
 +  * Acknowledge NMU (closes: #676609).
 +
 +  [ Debconf translations ]
 +  * Lithuanian (Rimas Kudelis).  Closes: #675628
 +  * Galician (Jorge Barreiro).  Closes: #677389
 +  * Welsh (Daffyd Tomos).
 +  * Greek (galaxico).  Closes: #685201
 +  * Romanian (Andrei POPESCU).  Closes: #685477
 +  * Finnish (Timo Jyrinki).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 06 Sep 2012 19:04:21 +0100
 +
 +grub2 (1.99-27.1) unstable; urgency=medium
 +
 +  * NMU
 +  * Add entries for Windows Boot Manager found via UEFI in
 +    os-prober. Closes: #698914 before the Wheezy release.
 +
 + -- Steve McIntyre <93sam@debian.org>  Fri, 26 Apr 2013 23:53:34 +0100
 +
 +grub2 (1.99-27) unstable; urgency=low
 +
 +  * Amend gfxpayload_keep_default.patch to no longer remove the call to
 +    load_video when GRUB_GFXPAYLOAD_LINUX is empty (closes: #661789).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 20 Jan 2013 16:37:52 +0000
 +
 +grub2 (1.99-26) unstable; urgency=low
 +
 +  * Remove /boot/grub/unicode.pf2 on purge of grub-efi-{amd64,i386} (closes:
 +    #697183).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 02 Jan 2013 11:54:50 +0000
 +
 +grub2 (1.99-25) unstable; urgency=low
 +
 +  * Ensure /boot/grub exists before copying files to it for EFI installs
 +    (closes: #696962).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 29 Dec 2012 23:45:01 +0000
 +
 +grub2 (1.99-24) unstable; urgency=low
 +
 +  * Acknowledge NMU with thanks.
 +  * Fix namespace of EFI boot failure patch file added in NMU.
 +  * Copy unicode.pf2 to /boot/grub/ for EFI installs so that it is more
 +    likely to be readable by GRUB (closes: #661789).
 +  * Fix infinite recursion in gettext when translation fails (closes:
 +    #611537, #612454, #616487, #619618, #626853, #643608).
 +  * Fix grammar in Finnish translation (closes: #687681).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 28 Dec 2012 13:01:38 +0000
 +
 +grub2 (1.99-23.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Apply Ubuntu patch fixing some EFI boot failures (closes: #687320)
 +    - Thanks to Colin Watson.
 +
 + -- Michael Gilbert <mgilbert@debian.org>  Sun, 14 Oct 2012 04:09:51 -0400
 +
 +grub2 (1.99-23) unstable; urgency=low
 +
 +  [ Debconf translations ]
 +  * Lithuanian (Rimas Kudelis).  Closes: #675628
 +  * Galician (Jorge Barreiro).  Closes: #677389
 +  * Welsh (Daffyd Tomos).
 +  * Greek (galaxico).  Closes: #685201
 +  * Romanian (Andrei POPESCU).  Closes: #685477
 +  * Finnish (Timo Jyrinki).
 +
 +  [ Cyril Brulebois ]
 +  * Use xz compression for all binaries to save up some space on CD images
 +    (closes: #688773).
 +
 +  [ Colin Watson ]
 +  * Autogenerate packaging files for grub-emu (closes: #688727), in order
 +    that its postinst does not contain unexpanded @PACKAGE@ symbols.
 +  * Manually expand @PACKAGE@ symbols in grub-efi.postinst (closes:
 +    #688725), grub-linuxbios.postinst (closes: #688726), and grub2.postinst
 +    (closes: #688724).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 25 Sep 2012 18:59:18 +0100
 +
 +grub2 (1.99-22.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Apply upstream patches for hurd-i386:
 +    - Test inode number (Closes: #634799).
 +    - Disable zfs code on GNU/Hurd (Closes: #670069).
 +    - Add userland partition support (Closes: #670186).
 +  * Fix packages build without libfuse (Closes: #670189).
 +
 + -- Samuel Thibault <sthibault@debian.org>  Fri, 08 Jun 2012 01:19:00 +0200
 +
 +grub2 (1.99-22) unstable; urgency=low
 +
 +  [ Debconf translations ]
 +  * Khmer added (Khoem Sokhem)
 +  * Slovenian (Vanja Cvelbar).  Closes: #670616
 +  * Traditional Chinese (Vincent Chen).
 +  * Vietnamese (Hai Lang).
 +  * Marathi (Sampada Nakhare)
 +  * Finnish (Timo Jyrinki).  Closes: #673976
 +  * Latvian (Rūdolfs Mazurs).  Closes: #674697
 +
 +  [ Colin Watson ]
 +  * Make apport hook compatible with Python 3.
 +  * Add upstream r3476 (fix memory leak in grub_disk_read_small) to
 +    4k_sectors.patch, otherwise the larger disk cache due to
 +    efi_disk_cache.patch can cause EFI systems to run out of memory.
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 30 May 2012 10:38:40 +0100
 +
 +grub2 (1.99-21) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Fix hook calling for unaligned segments (closes: #666992,
 +      LP: #972250).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 03 Apr 2012 14:19:18 +0100
 +
 +grub2 (1.99-20) unstable; urgency=low
 +
 +  * Backport kFreeBSD support from upstream to 4k_sectors.patch.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 02 Apr 2012 21:53:02 +0100
 +
 +grub2 (1.99-19) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Add grub-probe to grub-mount-udeb (LP: #963471).
 +  * Backport from upstream:
 +    - Restore CFLAGS after efiemu check (closes: #665772).
 +    - Include __ctzdi2 and __ctzsi2 from libgcc if present (closes:
 +      #665993).
 +    - Support non-512B sectors and agglomerate reads.
 +
 +  [ Debconf translations ]
 +  * Croatian (Tomislav Krznar).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 02 Apr 2012 18:26:09 +0100
 +
 +grub2 (1.99-18) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Ensure that /sbin and /usr/sbin are in $PATH when running tests (closes:
 +    #662916).
 +  * mkconfig_loopback.patch: Use different GRUB loop devices for different
 +    OS loop devices (thanks, bcbc; LP: #888281).
 +  * Backport from upstream:
 +    - Add support for LZO compression in btrfs (LP: #727535).
 +    - Fix efiemu configure check.
 +
 +  [ Ilya Yanok ]
 +  * Backport from upstream:
 +    - Make FAT UUID uppercase to match Linux (LP: #948716).
 +
 +  [ Debconf translations ]
 +  * Norwegian Bokmål (Hans Fredrik Nordhaug). 
 +  * Gujarati (Kartik Mistry).  Closes: #663542
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 19 Mar 2012 18:24:33 +0000
 +
 +grub2 (1.99-17) unstable; urgency=low
 +
 +  * efi_disk_cache.patch: Fix incorrect GRUB_DISK_CACHE_BITS (LP: #944347).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 06 Mar 2012 17:43:42 +0000
 +
 +grub2 (1.99-16) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Build with -fno-asynchronous-unwind-tables to save space (closes:
 +      #662787).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 06 Mar 2012 12:45:42 +0000
 +
 +grub2 (1.99-15) unstable; urgency=low
 +
 +  [ Adam Conrad ]
 +  * grub.cfg_400.patch: Redirect grep stdout to /dev/null since
 +    grub-mkconfig is "exec > grub.cfg.new", which causes grep's input
 +    and output to be the same FD (LP: #934269) (closes: #652972)
 +  * efi_disk_cache.patch: Bump the disk cache on EFI systems to
 +    dramatically reduce load times for vmlinux/initrd (LP: #944347)
 +
 +  [ Colin Watson ]
 +  * no_libzfs.patch: Use xasprintf rather than asprintf.
 +  * Backport from upstream:
 +    - Rewrite XFS btree parsing; fixes invalid BMAP (closes: #657776).
 +    - Handle newer autotools, and add some missing quotes in the process.
 +      (Note that this moves grub-mkconfig_lib and update-grub_lib to
 +      /usr/share/grub; I added links in /usr/lib/grub for compatibility.)
 +    - Fix incorrect identifiers in bash-completion (closes: #661415).
 +    - Add support for GRUB_CMDLINE_GNUMACH (closes: #660493).
 +  * Build with GCC 4.6 (closes: #654727).
 +
 +  [ Debconf translations ]
 +  * Dutch (Jeroen Schot).  Closes: #651275
 +  * Bulgarian (Damyan Ivanov).  Closes: #653356
 +  * Icelandic (Sveinn í Felli). 
 +  * Ukrainian (Yatsenko Alexandr).  Closes: #654294
 +  * Italian (Luca Monducci).  Closes: #654304
 +  * Thai (Theppitak Karoonboonyanan).  Closes: #656551
 +  * Uyghur (Abduqadir Abliz)
 +  * Indonesian (Mahyuddin Susanto).  Closes: #656705
 +  * Hebrew (Omer Zak).  Closes: #656852
 +  * Turkish (Atila KOÇ).  Closes: #656907
 +  * Polish (Michał Kułach).  Closes: #657265
 +  * Asturian (Mikel González).
 +  * Dzongkha (Dawa Pemo)
 +  * Tamil (Dr.T.Vasudevan). 
 +  * Belarusian (Viktar Siarhiejczyk).  Closes: #662615
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 05 Mar 2012 16:58:01 +0000
 +
 +grub2 (1.99-14) unstable; urgency=low
 +
 +  * Rewrite no_libzfs.patch using a different approach.  (Closes: #648539)
 +
 + -- Robert Millan <rmh@debian.org>  Sun, 13 Nov 2011 00:14:38 +0100
 +
 +grub2 (1.99-13) unstable; urgency=low
 +
 +  [ Debconf translations ]
 +  * Portuguese (Miguel Figueiredo).  Closes: #641226
 +  * German (Martin Eberhard Schauer).  Closes: #641630
 +  * Sinhala (Danishka Navin).  Closes: #644080
 +  * Uyghur (Gheyret Tohti).  Closes: #627011
 +
 +  [ Robert Millan ]
 +  * LVM support for GNU/kFreeBSD.
 +    - kfreebsd_lvm.patch
 +  * Cherry-pick several ZFS updates from upstream Bazaar.
 +    - zfs_update.patch
 +  * Build without libzfs.
 +
 + -- Robert Millan <rmh@debian.org>  Fri, 11 Nov 2011 23:04:58 +0100
 +
 +grub2 (1.99-12) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * Fix grub-probe detection for LSI MegaRAID SAS devices on kFreeBSD.
 +    - kfreebsd_mfi_devices.patch
 +
 +  [ Colin Watson ]
 +  * Backport from upstream:
 +    - Canonicalise the path argument to grub-probe (closes: #637768).
 +    - Skip */README* as well as README* (LP: #537123).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 05 Sep 2011 15:17:20 +0100
 +
 +grub2 (1.99-11) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Honour GRUB_CMDLINE_LINUX_XEN_REPLACE and
 +      GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace
 +      GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the
 +      existing options which append; closes: #617538).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 08 Aug 2011 17:55:21 +0100
 +
 +grub2 (1.99-10) unstable; urgency=high
 +
 +  * Mark la_array as packed.
 +    - zfs_packed_la_array.patch
 +
 + -- Robert Millan <rmh@debian.org>  Sun, 07 Aug 2011 20:16:31 +0000
 +
 +grub2 (1.99-9) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Adjust apport hook to attach /boot/grub/device.map if it exists.
 +  * Fix regression in gfxterm background_color handling.
 +  * Improve detection of invalid shell syntax in apport hook.
 +
 +  [ Debconf translations ]
 +  * Esperanto (Felipe E. F. de Castro).  Closes: #632157
 +  * Slovak (Slavko).
 +
 +  [ Robert Millan ]
 +  * Enable grub-mount on kfreebsd-any.
 +  * Build grub-mount-udeb on kfreebsd-i386 and kfreebsd-amd64.
 +
 + -- Robert Millan <rmh@debian.org>  Mon, 25 Jul 2011 15:36:31 +0200
 +
 +grub2 (1.99-8) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * Avoid buggy versions of libgeom-dev (see #630107).  Closes: #630197
 +  * Fix grub-probe detection for ATA devices using `ata' driver on kFreeBSD 9.
 +    - kfreebsd-9_ada_devices.patch
 +
 +  [ Colin Watson ]
 +  * Update ntldr-img from grub-extras:
 +    - Handle ext3 inode sizes other than 128.
 +
 +  [ Debconf translations ]
 +  * Kazakh (Baurzhan Muftakhidinov). Closes: #630915
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 21 Jun 2011 02:10:10 +0100
 +
 +grub2 (1.99-7) unstable; urgency=low
 +
 +  [ Debconf translations ]
 +  * Basque (Iñaki Larrañaga Murgoitio).  Closes: #628716
 +  * Swedish (Martin Bagge / brother).  Closes: #628866
 +  * Czech (Miroslav Kure).  Closes: #628978
 +  * Brazilian Portuguese (Flamarion Jorge).  Closes: #629135
 +  * Spanish (Francisco Javier Cuadrado).  Closes: #629633
 +
 +  [ Colin Watson ]
 +  * Cope with btrfs / inside an encrypted block device (thanks, alexeagar;
 +    LP: #757631).
 +  * Merge from Ubuntu:
 +    - Give up scanning partitions after ten consecutive open failures
 +      (LP: #787461).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 16 Jun 2011 00:13:14 +0100
 +
 +grub2 (1.99-6) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Update Vcs-* fields for Alioth changes.
 +  * Backport from upstream, removing the need for Breaks: udev (<< 168-1):
 +    - Don't stat devices unless we have to.
 +
 +  [ Debconf translations ]
 +  * Catalan (Jordi Mallach).
 +  * Farsi (Behrad Eslamifar).  Closes: #628648
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 31 May 2011 09:20:54 +0100
 +
 +grub2 (1.99-5) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Change grub2/linux_cmdline and grub2/kfreebsd_cmdline descriptions to
 +    indicate that the command line is allowed to be empty, since this is a
 +    common source of confusion (thanks, Jordan Uggla).
 +  * On non-Ubuntu-derived systems, add Breaks: udev (<< 168-1) to
 +    grub-common, for the sake of (some?) users without initrds (closes:
 +    #627587).
 +
 +  [ Debconf translations ]
 +  * French (Christian Perrier)
 +  * Russian (Yuri Kozlov).  Closes: #628196
 +  * Simplified Chinese (YunQiang Su).  Closes: #628210
 +  * Japanese (Hideki Yamane).  Closes: #628382
 +  * Danish (Joe Hansen).  Closes: #628427
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 29 May 2011 21:58:55 +0100
 +
 +grub2 (1.99-4) unstable; urgency=low
 +
 +  * Make grub-<platform>-bin packages depend on grub-common rather than
 +    grub2-common, and add grub2-common dependencies to grub-<platform>.
 +    This ensures that grub-<platform>-bin packages are coinstallable with
 +    grub-legacy, making it easier to use them as build-dependencies.
 +  * Stop trying to install the non-existent grub-ofpathname(8) on sparc for
 +    now.  It will exist in the next upstream snapshot.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 19 May 2011 12:38:45 +0100
 +
 +grub2 (1.99-3) unstable; urgency=low
 +
 +  * Ship grub-mkrescue on non-Linux amd64/i386 architectures.
 +  * Don't try to ship grub-mkrescue on sparc.
 +  * Drop boot_blocklist_hack.patch, fixed differently upstream some time ago
 +    by being smarter about filesystem-root-relative path conversion.
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 18 May 2011 14:06:51 +0100
 +
 +grub2 (1.99-2) unstable; urgency=low
 +
 +  * Include both old and new Lintian override styles for
 +    statically-linked-binary tag, since ftp-master has not yet been updated
 +    to 2.5.0~rc1.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 17 May 2011 01:36:10 +0100
 +
 +grub2 (1.99-1) unstable; urgency=low
 +
 +  * New upstream release.
 +    - Ensure uniqueness of RAID array numbers even if some elements have a
 +      name (closes: #609804).
 +    - Remove unnecessary brackets from tr arguments (closes: #612564).
 +    - Add grub-mkrescue info documentation (closes: #612585).
 +    - Avoid generating invalid configuration when something that looks like
 +      a Xen hypervisor is present without any Xen kernels (closes: #612898).
 +    - Fix memory alignment when calling 'linux' multiple times on EFI
 +      (closes: #616638).
 +    - Fix grub-install on amd64 EFI systems (closes: #617388).
 +    - Automatically export pager variable (closes: #612995).
 +    - Fix parser error with "time" (closes: #612991).
 +    - Ignore case of bitmap extensions (closes: #611123).
 +    - Skip vmlinux-* on x86 platforms (closes: #536846, #546008).
 +    - Accept old-style Xen kernels (closes: #610428).
 +    - Skip damaged LVM volumes (closes: #544731).
 +    - Handle LVM mirroring (closes: #598441).
 +    - Detect spares and report them as not RAID members (closes: #611561).
 +    - Don't enable localisation unless gfxterm is available (closes:
 +      #604609).
 +    - Fix partitioned RAID support (closes: #595071, #613444).
 +    - Dynamically count the number of lines for the lower banner (closes:
 +      #606494).
 +    - Improve quoting in grub-mkconfig, to support background image file
 +      names containing spaces (closes: #612417).
 +    - Flush BIOS disk devices more accurately (closes: #623124).
 +    - Identify RAID devices by their UUID rather than by their guessed name
 +      (closes: #624232).
 +    - Add "SEE ALSO" sections to most man pages (closes: #551428).
 +
 +  [ Christian Perrier ]
 +  * Drop extra word in French debconf translation. Thanks to David
 +    Prévôt.
 +  * Fix spelling error in French debconf translation. Thanks to David
 +    Prévôt.
 +
 +  [ Colin Watson ]
 +  * Set PACKAGE_VERSION and PACKAGE_STRING using configure arguments rather
 +    than sedding configure.ac in debian/rules (which sometimes has annoying
 +    interactions with quilt, etc.).
 +  * Update branch_embed-sectors.patch:
 +    - Detect sector used by HighPoint RAID controller (closes: #394868).
 +  * Add debian/README.source (from quilt).
 +  * Make debian/rules more explicit about when autogen.sh is run.  We need
 +    to be careful that all full builds run it, since we use GRUB extras.
 +  * Merge from Ubuntu:
 +    - Handle filesystems loop-mounted on file images.
 +    - On Wubi, don't ask for an install device, but just update wubildr
 +      using the diverted grub-install.
 +    - Add grub-mount-udeb, containing just grub-mount.  This can be used by
 +      os-prober and other parts of d-i.
 +    - Artificially bump Replaces: grub-common versioning to account for
 +      grub-reboot/grub-set-default movement in Ubuntu.
 +  * Don't do a separate build pass for grub-common.  It will be identical to
 +    the build for the default platform for the CPU architecture anyway, so
 +    reuse that.
 +  * Build with GCC 4.5 on all architectures.
 +  * Update Lintian overrides for changes in Lintian 2.5.0~rc1.
 +  * Invert how files are split among binary packages: rather than code in
 +    debian/rules to remove files we don't want, add dh_install configuration
 +    to declare the files we do want.  This means a little more repetition
 +    for platform-specific programs, but it seems less confusing and easier
 +    to extend.
 +  * Drop versioned dependencies on base-files.  GPL-3 has been there for two
 +    Debian releases now, and the dependency was never upgrade-critical
 +    anyway.
 +  * Create grub2-common package containing files that are common among GRUB
 +    platform packages but that would break GRUB Legacy, or that are too
 +    confusing when coinstalled with GRUB Legacy (closes: #564167).
 +  * Drop conflict on an ancient (pre-lenny/hardy) version of desktop-base.
 +  * Move /etc/grub.d/05_debian_theme to grub-common, to go with the other
 +    /etc/grub.d/* files.
 +  * Drop redundant Suggests: os-prober from several platform packages, as
 +    grub-common already Recommends: os-prober.
 +  * Create grub-<platform>-bin packages corresponding to all grub-<platform>
 +    packages (except for grub-emu).  These do not automatically install the
 +    boot loader or update grub.cfg, and they install their binaries to
 +    /usr/lib/grub/<cpu>-<platform>/; this means that they can be installed
 +    in parallel, making it easier to use them to build GRUB-based disk
 +    images (e.g. d-i).  The grub-<platform> packages now depend on these and
 +    include symlinks, so their behaviour will remain as before.
 +  * Make grub-emu depend on grub-common.
 +  * Make the documentation directory in most binary packages be a symlink to
 +    that in grub-common.
 +  * Drop lenny compatibility from grub2-common's dpkg/install-info
 +    dependency, since it produces a Lintian warning and using the current
 +    packaging on lenny is probably rather a stretch anyway.
 +
 +  [ Updated translations ]
 +  * Belarusian (Viktar Siarheichyk).  Closes: #606864
 +  * Danish (Joe Hansen).  Closes: #606879
 +  * Romanian (Andrei POPESCU).  Closes: #606888
 +  * Italian (Luca Monducci).  Closes: #606891
 +  * Brazilian Portuguese (Flamarion Jorge).  Closes: #610613
 +  * Greek (Emmanuel Galatoulas).  Closes: #604847
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 16 May 2011 17:42:07 +0100
 +
 +grub2 (1.99~rc1-13) unstable; urgency=low
 +
 +  * Cherry-pick from upstream:
 +    - Use correct limits for mips initrd.
 +  * Run grub-install on install or upgrade of grub-yeeloong.
 +  * Update branch_fuse.patch:
 +    - Tell FUSE to run single-threaded, since GRUB code is not thread-safe
 +      (LP: #756297).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 15 Apr 2011 12:11:21 +0100
 +
 +grub2 (1.99~rc1-12) unstable; urgency=low
 +
 +  * Update branch_butter.patch:
 +    - Fix filename comparison.
 +    - Take extent offset in account on uncompressed extents.
 +    - Use filled extent size if available.
 +  * Allow use of first sector on btrfs (LP: #757446).
 +  * Merge from Ubuntu:
 +    - Build part_msdos and vfat into EFI boot images (LP: #677758).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 11 Apr 2011 16:22:08 +0100
 +
 +grub2 (1.99~rc1-11) unstable; urgency=low
 +
 +  * Update branch_fuse.patch:
 +    - Make grub-mount exit non-zero if opening the device or filesystem
 +      fails.
 +    - Translate GRUB error codes into OS error codes for FUSE (LP: #756456).
 +  * Merge from Ubuntu:
 +    - Fix use of freed memory when replacing existing loopback device
 +      (LP: #742967).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 10 Apr 2011 21:52:26 +0100
 +
 +grub2 (1.99~rc1-10) unstable; urgency=low
 +
 +  * Update branch_butter.patch, fixing RAID1/duplicated chunk size
 +    calculation (thanks, Vladimir Serbinenko; LP: #732149).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 09 Apr 2011 21:22:15 +0100
 +
 +grub2 (1.99~rc1-9) unstable; urgency=low
 +
 +  * Update branch_parse-color.patch, to blend text when any background is
 +    set as opposed to only when a stretched background is set (closes:
 +    #613120).
 +  * Make update-grub2 a symlink to update-grub, rather than bothering with a
 +    wrapper script.
 +  * Cherry-pick from upstream:
 +    - Check RAID superblock offset (closes: #610184).
 +    - Flush buffer cache on close and not on open (closes: #620663).
 +    - Handle special naming of yeeloong directory (closes: #620420).
 +  * Add grub-mount utility, from the upstream 'fuse' branch.
 +  * efibootmgr is only available on Linux architectures, so only make
 +    grub-efi-ia32 and grub-efi-amd64 depend on it on Linux.
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 09 Apr 2011 03:39:56 +0100
 +
 +grub2 (1.99~rc1-8) unstable; urgency=low
 +
 +  * Cherry-pick from upstream:
 +    - Fix FreeBSD compilation problem.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 29 Mar 2011 15:13:51 +0100
 +
 +grub2 (1.99~rc1-7) unstable; urgency=low
 +
 +  * Add /proc/mdstat, LVM information, and listings of /dev/disk/by-id/ and
 +    /dev/disk/by-uuid/ to bug reports, by request of upstream.
 +  * Cherry-pick from upstream:
 +    - Use libgeom on FreeBSD to detect partitions (closes: #612128).
 +    - Copy the partition table zone if floppy support is disabled, even if
 +      no partition table is found (LP: #741867).
 +    - Fix an ext2 overflow affecting inodes past 2TiB.
 +    - Fix RAID-0 disk size calculation for metadata 1.x (LP: #743136).
 +  * Merge from Ubuntu:
 +    - Build with gcc-4.5 on ppc64.
 +    - Add apport hook for ProblemType = 'Package', thanks to Jean-Baptiste
 +      Lallement (LP: #591753).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 29 Mar 2011 12:30:36 +0100
 +
 +grub2 (1.99~rc1-6) unstable; urgency=low
 +
 +  * Cherry-pick from upstream:
 +    - Fix crash when extending menu entry line beyond 79 characters (closes:
 +      #615893).
 +    - Account for FreeBSD module headers when calculating allocation size.
 +    - Switch back to framebuffer page zero before loading the kernel
 +      (thanks, Felix Kuehling).
 +  * Merge from Ubuntu:
 +    - If we're upgrading and /boot/grub/core.img doesn't exist, then don't
 +      ask where to install GRUB, since it probably means we're in some kind
 +      of specialised environment such as a live USB stick (LP: #591202).
 +    - Drop the default priority of grub2/linux_cmdline to medium.  We only
 +      need to ask it if we're upgrading from GRUB Legacy and found an empty
 +      kopt in menu.lst (LP: #591202).
 +  * Update branch_embed-sectors.patch, avoiding consuming lots of space and
 +    time if the first partition is not near the start of the disk (closes:
 +    #619458, LP: #691569).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 25 Mar 2011 19:23:04 +0000
 +
 +grub2 (1.99~rc1-5) unstable; urgency=low
 +
 +  * Update debian/legacy/update-grub to the version from grub 0.97-65.
 +  * Mark binary packages as Multi-Arch: foreign (for example, an amd64
 +    kernel installed on an i386 system could use the native architecture's
 +    GRUB).
 +  * Rewrite find_root_device_from_mountinfo to cope with move-mounts
 +    (LP: #738345).
 +
 +  [ Updated translations ]
 +  * Esperanto (Felipe Castro).  Closes: #606524
 +  * Thai (Theppitak Karoonboonyanan).  Closes: #607706
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 23 Mar 2011 15:51:47 +0000
 +
 +grub2 (1.99~rc1-4) unstable; urgency=low
 +
 +  * Don't touch /boot/grub/grub2-installed if using the --root-directory
 +    option to grub-install (thanks, Nicolas George; closes: #614927).
 +  * Update branch_devmapper.patch, adding partitioned MD RAID support
 +    (untested) and support for probing multipath disks.
 +  * Update ntldr-img from grub-extras:
 +    - Only call ntfs_fix_mmft if the attribute to find is AT_DATA.  This
 +      matches GRUB's NTFS module.
 +    - Install grubinst as grub-ntldr-img.
 +  * Fix loading GRUB from lnxboot (LP: #693671).
 +  * Update branch_embed-sectors.patch to avoid straying into first partition
 +    when embedding-area sectors are in use (closes: #613409, LP: #730225).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 15 Mar 2011 11:01:48 +0000
 +
 +grub2 (1.99~rc1-3) unstable; urgency=low
 +
 +  * Build for ppc64 (except for grub-emu, which doesn't build cleanly yet).
 +  * Suppress output from debconf-communicate in upgrade-from-grub-legacy.
 +  * Refer to the info documentation at the top of /etc/default/grub (closes:
 +    #612538).
 +  * We need at least freebsd-utils (>= 8.0-4) on kFreeBSD architectures for
 +    camcontrol, so depend on it.
 +  * Tolerate camcontrol failing to read capacity of IDE devices, until such
 +    time as we know how to do this properly (see #612128).
 +  * Adjust /etc/default/grub for rename of GRUB_DISABLE_LINUX_RECOVERY to
 +    GRUB_DISABLE_RECOVERY (closes: #612777).
 +  * Update ntldr-img from grub-extras:
 +    - Install g2hdr.bin and g2ldr.mbr (closes: #613245).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 16 Feb 2011 13:11:11 +0000
 +
 +grub2 (1.99~rc1-2) unstable; urgency=low
 +
 +  * Merge 1.98+20100804-13 and 1.98+20100804-14, updating translations:
 +    - Kazakh (Baurzhan Muftakhidinov / Timur Birsh).
 +  * mkconfig_skip_dmcrypt.patch: Refer to GRUB_PRELOAD_MODULES rather than
 +    suggesting people write a /etc/grub.d/01_modules script (thanks, Jordan
 +    Uggla).
 +  * Handle empty dir passed to grub_find_root_device_from_mountinfo; fixes
 +    grub-mkrelpath on btrfs subvolumes (LP: #712029).
 +  * Add rootflags=subvol=<name> if / is on a btrfs subvolume (LP: #712029).
 +  * Upload to unstable.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 08 Feb 2011 11:39:26 +0000
 +
 +grub2 (1.99~rc1-1) experimental; urgency=low
 +
 +  [ Colin Watson ]
 +  * New upstream release candidate.
 +
 +  [ Alexander Kurtz ]
 +  * 05_debian_theme:
 +    - If we find a background image and no colours were specified, use
 +      upstream defaults for color_normal and color_highlight rather than
 +      setting color_normal to black/black.
 +    - Make the code more readable by replacing code for handling
 +      alternatives.
 +    - Make the code for searching for pictures in /boot/grub more readable
 +      and robust (for example against newlines in the filename).
 +    - Don't try the other alternatives when $GRUB_BACKGROUND is set; you can
 +      now add GRUB_BACKGROUND= to /etc/default/grub to force no background
 +      image (closes: #608263).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 17 Jan 2011 13:43:06 +0000
 +
 +grub2 (1.99~20110112-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Disable ieee1275_fb on sparc (closes: #560823).
 +    - Fix pf2 font generation on big-endian platforms (closes: #609818).
 +  * branch_butter.patch: Resolve the device returned by
 +    grub_find_root_device_from_mountinfo or find_root_device_from_libzfs
 +    using grub_find_device (closes: #609590, #609814, LP: #700147).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 13 Jan 2011 00:12:41 +0000
 +
 +grub2 (1.99~20110111-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Don't check amount of low memory, as reportedly INT 12h can be broken
 +      and if low memory is too low we wouldn't have gotten into
 +      grub_machine_init anyway (closes: #588293, LP: #513528).
 +    - Submenu default support (LP: #691878).
 +    - Fix optimisation-dependent grub-mklayout crash (closes: #609584).
 +  * branch_butter.patch: Don't free an uninitialised pointer if /proc is
 +    unmounted (LP: #697493).
 +  * Add a po/LINGUAS file listing the translations we've synced from the TP
 +    (closes: #609671).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 11 Jan 2011 17:11:44 +0000
 +
 +grub2 (1.99~20110106-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Check that named RAID array devices exist before using them (closes:
 +      #606035).
 +    - Clear terminfo output on initialisation (closes: #569678).
 +    - Fix grub-probe when btrfs is on / without a separate /boot.
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 06 Jan 2011 13:38:57 +0000
 +
 +grub2 (1.99~20110104-2) experimental; urgency=low
 +
 +  * Support long command lines as per the 2.06 Linux boot protocol, from the
 +    upstream 'longlinuxcmd' branch.
 +  * Add a background_color command, from the upstream 'parse-color' branch.
 +  * Update branch_devmapper.patch, adding a #include to fix a build failure
 +    on Ubuntu amd64.
 +  * When embedding the core image in a post-MBR gap, check for and avoid
 +    sectors matching any of a number of known signatures, from the upstream
 +    'embed-sectors' branch.
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 05 Jan 2011 13:31:05 +0000
 +
 +grub2 (1.99~20110104-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Don't emit drivemap directive for Windows Server 2008 (closes:
 +      #607687).
 +    - Don't add spurious RAID array members (closes: #605357).
 +    - Improve presentation of Xen menu entries (closes: #607867).
 +    - Fix PCI probing hangs by skipping remaining functions on devices that
 +      do not implement function 0 (closes: #594967).
 +    - Fix typo in descriptions of extract_legacy_entries_source and
 +      extract_legacy_entries_configfile (LP: #696721).
 +  * Merge 1.98+20100804-12:
 +    - Use semicolons rather than commas to separate size from model in
 +      debconf disk and partition descriptions.
 +  * Add full btrfs support, from the upstream 'butter' branch.
 +  * Support partitioned loop devices and improve devmapper support, from the
 +    upstream 'devmapper' branch.
 +  * Add squashfs 4 support, from the upstream 'squash' branch.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 04 Jan 2011 16:12:45 +0000
 +
 +grub2 (1.99~20101221-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Initialise next pointer when creating multiboot module (closes:
 +      #605567).
 +    - Fix gettext quoting to work with bash as /bin/sh, and make echo
 +      UTF-8-clean so that (at least) Catalan boot messages are displayed
 +      properly (closes: #605615).
 +    - Fix use of uninitialised memory in Reed-Solomon recovery code
 +      (LP: #686705).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 21 Dec 2010 17:43:52 +0000
 +
 +grub2 (1.99~20101210-2) experimental; urgency=low
 +
 +  * Automatically remove MD devices from device.map on upgrade, since the
 +    BIOS cannot read from these and including them in device.map will break
 +    GRUB's ability to read from such devices (LP: #690030).
 +  * Merge 1.98+20100804-9, 1.98+20100804-10, and 1.98+20100804-11:
 +    - Apply debconf template review by debian-l10n-english and mark several
 +      more strings for translation, thanks to David Prévot and Justin B Rye.
 +    - Incorporate rewritten 05_debian_theme by Alexander Kurtz, which works
 +      when /usr is inaccessible by GRUB.
 +
 + -- Colin Watson <cjwatson@debian.org>  Sun, 19 Dec 2010 13:25:14 +0000
 +
 +grub2 (1.99~20101210-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - ZFS moved into grub-core.
 +    - Extend gettext to fall back from ll_CC to ll, and set lang to include
 +      country part by default so that Chinese works (LP: #686788).
 +  * Remove grub-mknetdir from grub-emu.
 +  * Exit silently from zz-update-grub kernel hook if update-grub does not
 +    exist (e.g. if grub-pc has been removed but not purged; closes:
 +    #606184).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 11 Dec 2010 01:22:26 +0000
 +
 +grub2 (1.99~20101126-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot (mipsel build fix, LVM-on-RAID probing fix).
 +  * Fix comma-separation in handling of grub-pc/install_devices.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 26 Nov 2010 13:08:52 +0000
 +
 +grub2 (1.99~20101124-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot (command priorities, build fixes, grub-mkdevicemap
 +    segfault).
 +  * Don't try to build grub-efi-amd64 on kfreebsd-i386 or hurd-i386
 +    (requires gcc-4.4-multilib).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 24 Nov 2010 12:12:33 +0000
 +
 +grub2 (1.99~20101123-1) experimental; urgency=low
 +
 +  * New Bazaar snapshot (build fixes).
 +  * Build-depend on qemu-utils and parted on non-Hurd architectures.
 +  * qemu_img_exists.patch: Skip partmap test if qemu-img doesn't exist (as
 +    is the case on the Hurd).
 +  * Make grub-efi-ia32 and grub-efi-amd64 depend on efibootmgr so that
 +    grub-install works properly.
 +  * Upgrade the installed core image when upgrading grub-efi-ia32 or
 +    grub-efi-amd64, although only if /boot/efi/EFI/<id> (where <id> is an
 +    identifier based on GRUB_DISTRIBUTOR, e.g. 'debian') already exists.
 +  * Re-expand a couple of dpkg architecture wildcards to exclude certain
 +    special cases: gcc-4.4-multilib is not available on kfreebsd-i386 or
 +    hurd-i386, and qemu-system is not available on hurd-i386.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 23 Nov 2010 10:51:23 +0000
 +
 +grub2 (1.99~20101122-1) experimental; urgency=low
 +
 +  [ Colin Watson ]
 +  * New Bazaar snapshot.  Too many changes to list in full, but some of the
 +    more user-visible ones are as follows:
 +    - GRUB script:
 +      + Function parameters, "break", "continue", "shift", "setparams",
 +        "return", and "!".
 +      + "export" command supports multiple variable names.
 +      + Multi-line quoted strings support.
 +      + Wildcard expansion.
 +    - sendkey support.
 +    - USB hotunplugging and USB serial support.
 +    - Rename CD-ROM to cd on BIOS.
 +    - Add new --boot-directory option to grub-install, grub-reboot, and
 +      grub-set-default; the old --root-directory option is still accepted
 +      but was often confusing.
 +    - Basic btrfs detection/UUID support (but no file reading yet).
 +    - bash-completion for utilities.
 +    - If a device is listed in device.map, always assume that it is
 +      BIOS-visible rather than using extra layers such as LVM or RAID.
 +    - Add grub-mknetdir script (closes: #550658).
 +    - Remove deprecated "root" command.
 +    - Handle RAID devices containing virtio components.
 +    - GRUB Legacy configuration file support (via grub-menulst2cfg).
 +    - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
 +    - Check generated grub.cfg for syntax errors before saving.
 +    - Pause execution for at most ten seconds if any errors are displayed,
 +      so that the user has a chance to see them.
 +    - Support submenus.
 +    - Write embedding zone using Reed-Solomon, so that it's robust against
 +      being partially overwritten (closes: #550702, #591416, #593347).
 +    - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
 +      into a single GRUB_DISABLE_RECOVERY variable.
 +    - Fix loader memory allocation failure (closes: #551627).
 +    - Don't call savedefault on recovery entries (closes: #589325).
 +    - Support triple-indirect blocks on ext2 (closes: #543924).
 +    - Recognise DDF1 fake RAID (closes: #603354).
 +
 +  [ Robert Millan ]
 +  * Use dpkg architecture wildcards.
 +
 +  [ Updated translations ]
 +  * Slovenian (Vanja Cvelbar).  Closes: #604003
 +  * Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 22 Nov 2010 12:24:56 +0000
 +
 +grub2 (1.98+20100804-14) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Kazakh (Baurzhan Muftakhidinov / Timur Birsh).  Closes: #609187
 +
 +  [ Alexander Kurtz ]
 +  * 05_debian_theme:
 +    - If we find a background image and no colours were specified, use
 +      upstream defaults for color_normal and color_highlight rather than
 +      setting color_normal to black/black.
 +    - Don't try the other alternatives when $GRUB_BACKGROUND is set; you can
 +      now add GRUB_BACKGROUND= to /etc/default/grub to force no background
 +      image (closes: #608263).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 17 Jan 2011 23:19:38 +0000
 +
 +grub2 (1.98+20100804-13) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Don't add spurious RAID array members (closes: #605357).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 04 Jan 2011 14:07:14 +0000
 +
 +grub2 (1.98+20100804-12) unstable; urgency=low
 +
 +  * Backport from upstream:
 +    - Support big ext2 files (closes: #543924).
 +    - Fix gettext quoting to work with bash as /bin/sh, and make echo
 +      UTF-8-clean so that (at least) Catalan boot messages are displayed
 +      properly (closes: #605615).
 +    - Initialise next pointer when creating multiboot module (closes:
 +      #605567).
 +    - Fix PCI probing hangs by skipping remaining functions on devices that
 +      do not implement function 0 (closes: #594967).
 +  * Use semicolons rather than commas to separate size from model in debconf
 +    disk and partition descriptions; commas are too easily confused with the
 +    multiselect choice separator, and in particular make it impossible to
 +    answer questions properly in the editor frontend (closes: #608449).
 +    Unfuzzy all translations where possible.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 04 Jan 2011 00:42:29 +0000
 +
 +grub2 (1.98+20100804-11) unstable; urgency=low
 +
 +  * Exit silently from zz-update-grub kernel hook if update-grub does not
 +    exist (e.g. if grub-pc has been removed but not purged; closes:
 +    #606184).
 +  * Apply debconf template review by debian-l10n-english and mark several
 +    more strings for translation, thanks to David Prévot and Justin B Rye
 +    (closes: #605748).
 +  * Unfuzzy some translations that were not updated in this round (thanks,
 +    David Prévot; closes: #606921).
 +  * Incorporate rewritten 05_debian_theme by Alexander Kurtz, which works
 +    when /usr is inaccessible by GRUB (closes: #605705).
 +  * Backport from upstream:
 +    - Recognise DDF1 DM-RAID (closes: #603354).
 +
 +  [ Updated translations ]
 +  * Chinese (YunQiang Su).  Closes: #606426
 +  * Indonesian (Arief S Fitrianto).  Closes: #606431
 +  * Slovenian (Vanja Cvelbar).  Closes: #606445
 +  * Swedish (Martin Bagge / brother).  Closes: #606455
 +  * Ukrainian (Yatsenko Alexandr).  Closes: #606538
 +  * Basque (Iñaki Larrañaga Murgoitio).  Closes: #606644
 +  * Slovak (Slavko).  Closes: #606663
 +  * Catalan (Jordi Mallach).
 +  * Bulgarian (Damyan Ivanov).  Closes: #606452
 +  * Persian (Morteza Fakhraee).  Closes: #606672
 +  * Russian (Yuri Kozlov).  Closes: #606753
 +  * Dutch (Paul Gevers).  Closes: #606807
 +  * Japanese (Hideki Yamane).  Closes: #606836
 +  * French (Christian Perrier).  Closes: #606842
 +  * Czech (Miroslav Kure).  Closes: #606854
 +  * Spanish (Francisco Javier Cuadrado).  Closes: #606903
 +  * Portuguese (Tiago Fernandes / Miguel Figueiredo).  Closes: #606908
 +  * German (Martin Eberhard Schauer).  Closes: #606896
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 18 Dec 2010 17:20:09 +0000
 +
 +grub2 (1.98+20100804-10) unstable; urgency=low
 +
 +  * fix_crash_condition_in_kfreebsd_loader.patch: Import from upstream.
 +    Fixes crash condition in case kfreebsd_* commands are used after
 +    kfreebsd has (gracefully) failed.
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 30 Nov 2010 19:40:11 +0100
 +
 +grub2 (1.98+20100804-9) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * Import from upstream:
 +    - refuse_embedingless_cross_disk.patch: Refuse to do a cross-disk
 +      embeddingless install rather than creating a broken install.
 +    - fix_grub_install_error_msg.patch: Replace useless recomendation to
 +      pass --modules with a recomendation to report a bug.
 +    - message_refresh.patch: Make error messages visible again. (Closes: #605485)
 +
 +  [ Jordi Mallach ]
 +  * Update Catalan translation with latest file from the Translation Project.
 +
 +  [ Updated translations ]
 +  * Slovenian (Vanja Cvelbar).  Closes: #604003
 +  * Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 30 Nov 2010 15:44:02 +0100
 +
 +grub2 (1.98+20100804-8) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * increase_disk_limit.patch: Increase SCSI/IDE disk limits to cope with
 +    Sun Fire X4500.
 +  * linux_mdraid_1x.patch: Support for Linux MD RAID v1.x.  (Closes: #593652)
 +  * yeeloong_boot_info.patch: On Yeeloong, pass machine type information
 +    to Linux.
 +
 +  [ Updated translations ]
 +  * Portuguese fixed by Christian Perrier (variable names
 +    were translated)
 +
 + -- Robert Millan <rmh@debian.org>  Fri, 05 Nov 2010 23:43:15 +0100
 +
 +grub2 (1.98+20100804-7) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * zfs_fix_mkrelpath.patch: Replace with proper fix from upstream Bazaar.
 +    (Closes: #601087)
 +
 +  [ Updated translations ]
 +  * Vietnamese (Clytie Siddall). Closes: #598327
 +  * Icelandic (Sveinn í Felli).  Closes: #600126
 +
 + -- Robert Millan <rmh@debian.org>  Sun, 24 Oct 2010 16:35:37 +0200
 +
 +grub2 (1.98+20100804-6) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * zfs_v23.patch: Accept ZFS up to v23 (no changes required).
 +  * fix_usb_boot.patch: Fix boot on USB devices, for BIOSes that
 +    expose them as floppies.  (Closes: #600580)
 +  * zfs_fix_mkrelpath.patch: Fix grub-mkrelpath for non-root ZFS.
 +    (Closes: #600578)
 +
 +  [ Updated translations ]
 +  * Kazakh (kk.po) by Baurzhan Muftakhidinov via Timur Birsh (closes:
 +    #598188).
 +  * Portuguese (pt.po) by Tiago Fernandes via Rui Branco (closes: #599767).
 +  * Catalan (ca.po) by Jordi Mallach.
 +
 + -- Robert Millan <rmh@debian.org>  Thu, 21 Oct 2010 23:45:23 +0200
 +
 +grub2 (1.98+20100804-5) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Hebrew (he.po) by Omer Zak and Lior Kaplan (closes: #593855).
 +  * Romanian (ro.po) by ioan-eugen STAN (closes: #595727).
 +  * Esperanto (eo.po) by Felipe Castro (closes: #596171).
 +
 +  [ Colin Watson ]
 +  * Make grub-efi-amd64 conflict with grub-pc as well as the other way
 +    round.
 +  * Backport upstream patches to fix DM-RAID support (closes: #594221,
 +    LP: #634840).
 +
 +  [ Robert Millan ]
 +  * enable_zfs.patch: Fix grub-fstest build problem.
 +  * zfs_fix_label_arg.patch: Fix kfreebsd_device initialization on ZFS
 +    for non-main filesystems.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 17 Sep 2010 23:45:10 +0100
 +
 +grub2 (1.98+20100804-4) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Italian (it.po) by Luca Monducci (closes: #593685).
 +  * Finnish (fi.po) by Esko Arajärvi (closes: #593921).
 +
 +  [ Colin Watson ]
 +  * Run update-grub from kernel hooks if DEB_MAINT_PARAMS is unset, for
 +    compatibility with old kernel packages.  This may produce duplicate runs
 +    of update-grub, but that's better than not running it at all (closes:
 +    #594037).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 23 Aug 2010 12:11:55 +0100
 +
 +grub2 (1.98+20100804-3) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge (closes: #592156).
 +  * Asturian (ast.po) by Maacub (closes: #592313).
 +  * Galician (gl.po) by Jorge Barreiro (closes: #592816).
 +
 +  [ Robert Millan ]
 +  * Backport ZFS bugfixes from upstream Bazaar:
 +    - zfs_fix_chroot.patch: Fix breakage when running grub-probe inside chroot.
 +    - zfs_fix_label_arg.patch: Fix grub-probe fs_label argument.
 +    - zfs_fix_pathname.patch: Fix pathname for non-root ZFS filesystems.
 +    - zfs_fix_segfault.patch: Fix segfault when /dev is not mounted.
 +
 +  [ Colin Watson ]
 +  * Escape single quotes when removing them from $mode in zz-update-grub, so
 +    that this works when /bin/sh is bash (thanks, Will Dyson; closes:
 +    #593242).
 +  * Add support for ext2 root on GNU/kFreeBSD (thanks, Aurelien Jarno;
 +    closes: #593467).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 19 Aug 2010 18:21:45 +0100
 +
 +grub2 (1.98+20100804-2) unstable; urgency=low
 +
 +  [ Colin Watson ]
 +  * Make /etc/kernel/postrm.d/zz-update-grub a real file rather than a
 +    symlink (closes: #592076).
 +
 +  [ Updated translations ]
 +  * Norwegian Bokmål (nb.po) by Hans Nordhaug (closes: #591569).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 07 Aug 2010 17:53:34 +0100
 +
 +grub2 (1.98+20100804-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Fix grub-emu build on GNU/kFreeBSD (closes: #591490).
 +
 +  [ Colin Watson ]
 +  * Add kernel hook scripts and remove any uses of update-grub as a
 +    postinst_hook or postrm_hook in /etc/kernel-img.conf (closes: #554175).
 +    Thanks to Ben Hutchings for advice and to Harald Braumann for an early
 +    implementation.
 +  * Extend the existing GRUB_LEGACY_0_BASED_PARTITIONS handling to avoid
 +    new-style partition naming when generating output for GRUB Legacy
 +    (closes: #590554).
 +
 +  [ Updated translations ]
 +  * Slovak (sk.po) by Slavko (closes: #591458).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 04 Aug 2010 04:48:11 +0100
 +
 +grub2 (1.98+20100802-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Remove compatibility with terminal.mod prior to
 +      terminal_input/terminal_output separation (LP: #519358).
 +    - Enable `grub-probe -t device' resolution on ZFS.
 +    - Don't use UUID for LVM root when generating Xen entries (closes:
 +      #591093).
 +    - Restore missing whitespace to commands' --help output (closes:
 +      #590874).
 +    - Select unique numbers for named RAID arrays, for use as keys in the
 +      disk cache.
 +
 +  [ Updated translations ]
 +  * German (Martin Eberhard Schauer).  Closes: #590108
 +  * Spanish (Francisco Javier Cuadrado).  Closes: #590448
 +  * Traditional Chinese (Tetralet).  Closes: #591191
 +  * Danish (Joe Hansen).  Closes: #591223
 +  * Dutch (Paul Gevers).  Closes: #590864
 +  * Japanese (Hideki Yamane).  Closes: #591058
 +
 +  [ Robert Millan ]
 +  * postinst.in: Fill in device size and model information on GNU/kFreeBSD,
 +    using camcontrol.
 +  * patches/enable_zfs.patch: New patch. Link ZFS from grub-extras into
 +    grub-probe and grub-setup.
 +  * control: Build-Depend on libzfs-dev and libnvpair-dev on kfreebsd-*.
 +
 +  [ Colin Watson ]
 +  * Offer RAID devices as GRUB installation targets if they contain /,
 +    /boot, or /boot/grub.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 03 Aug 2010 02:13:07 +0100
 +
 +grub2 (1.98+20100722-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Don't count named RAID arrays when looking for unused array numbers.
 +
 +  [ Colin Watson ]
 +  * Merge from Ubuntu:
 +    - grub-common Breaks: lupin-support (<< 0.30) due to a grub-mkimage
 +      syntax change (lupin-support isn't in Debian, but this is harmless
 +      anyway).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 22 Jul 2010 14:33:34 +0100
 +
 +grub2 (1.98+20100720-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Link to Info documentation on changes from GRUB Legacy in README
 +      (closes: #502623).
 +    - Add support for mdadm metadata formats 1.x (closes: #492897).
 +
 +  [ Aaron M. Ucko ]
 +  * Compare -trunk kernels earlier than numeric ABIs (closes: #568160).
 +
 +  [ Colin Watson ]
 +  * Remove /boot/grub/device.map, /boot/grub/grubenv,
 +    /boot/grub/installed-version, and /boot/grub/locale/ on purge, if
 +    permitted (closes: #547679).
 +  * Convert from CDBS to dh.
 +  * Use exact-version dependencies in grub2 and grub-efi, to reduce
 +    potential confusion.
 +  * Raise priority of grub-common and grub-pc to optional (also done in
 +    archive overrides).
 +  * Copy-edit debian/presubj.
 +  * Use 'mktemp -t' rather than hardcoding /tmp (closes: #589537).
 +
 +  [ Mario 'BitKoenig' Holbe ]
 +  * Update /etc/grub.d/05_debian_theme to handle multiple entries in
 +    GRUB_TERMINAL_OUTPUT (closes: #589322).
 +
 +  [ Updated translations ]
 +  * Simplified Chinese (zh_CN.po) by YunQiang Su (closes: #589013).
 +  * Russian (ru.po) by Yuri Kozlov (closes: #589244).
 +  * Swedish (sv.po) by Martin Bagge / brother (closes: #589259).
 +  * Bulgarian (bg.po) by Damyan Ivanov (closes: #589272).
 +  * Indonesian (id.po) by Arief S Fitrianto (closes: #589318).
 +  * Arabic (ar.po) by Ossama M. Khayat.
 +  * Basque (eu.po) by Iñaki Larrañaga Murgoitio (closes: #589489).
 +  * Persian (fa.po) by Bersam Karbasion (closes: #589544).
 +  * Czech (cs.po) by Miroslav Kure (closes: #589568).
 +  * Belarusian (be.po) by Viktar Siarheichyk (closes: #589634).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 21 Jul 2010 09:11:14 +0100
 +
 +grub2 (1.98+20100710-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Handle degraded RAID arrays in grub-probe and grub-setup.
 +    - Fix gfxterm pager handling.
 +
 +  [ Fabian Greffrath ]
 +  * Get value of correct debconf question when deciding whether to purge
 +    /boot/grub (closes: #588331).
 +
 +  [ Colin Watson ]
 +  * Generate device.map in something closer to the old ordering (thanks,
 +    Vadim Solomin).
 +
 +  [ Updated translations ]
 +  * Croatian (hr.po) by Josip Rodin, closes: #588350.
 +  * French (fr.po) by Christian Perrier (closes: #588695).
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 12 Jul 2010 11:46:53 +0100
 +
 +grub2 (1.98+20100706-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - USB hub support.
 +    - Fix GRUB_BACKGROUND configuration ordering.
 +    - Fix corruption of first entry name in a reiserfs directory.
 +    - Don't include MD devices when generating device.map (if you're using
 +      RAID and upgraded through 1.98+20100702-1 or 1.98+20100705-1, you may
 +      need to fix this up manually).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 06 Jul 2010 18:06:40 +0100
 +
 +grub2 (1.98+20100705-1) unstable; urgency=medium
 +
 +  * New Bazaar snapshot.
 +    - Bidi and diacritics support.
 +      + Use terminfo for ieee1275 terminals (closes: #586953).
 +    - Don't use empty grub_device in EFI grub-install (closes: #587838).
 +    - Fix grub-setup core.img comparison when not embedding (thanks, Matt
 +      Kraai and M. Vefa Bicakci; closes: #586621).
 +
 +  * Update Source: in debian/copyright (thanks, Jörg Sommer).
 +  * Convert by-id disk device names from device.map to traditional device
 +    names for display (closes: #587951).
 +  * Set urgency=medium.  We've cleared out most of the apparent regressions
 +    at this point, and #550704 is getting more and more urgent to fix in
 +    testing.
 +
 + -- Colin Watson <cjwatson@debian.org>  Mon, 05 Jul 2010 02:09:58 +0100
 +
 +grub2 (1.98+20100702-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Use video functions in Linux loader rather than hardcoding UGA; load
 +      all available video backends (closes: #565576, probably).
 +    - Add support for initrd images on Fedora 13.
 +    - Output grub.cfg stanzas for Xen (closes: #505517).
 +    - Add 'cat --dos' option to treat DOS-style "\r\n" line endings as
 +      simple newlines (closes: #586358).
 +    - Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible
 +      on Linux.
 +    - Return CF correctly in mmap e820/e801 int15 hook (closes: #584846).
 +    - The info documentation now has no broken references, although of
 +      course it could still use more work (closes: #553460).
 +    - Support GRUB_BADRAM in grub-mkconfig.
 +    - Skip LVM snapshots (closes: #574863).
 +
 +  [ Colin Watson ]
 +  * Mention grub-rescue-usb.img in grub-rescue-pc description (closes:
 +    #586462).
 +  * Add instructions for using grub-rescue-usb.img (closes: #586463).
 +  * Remove /usr/lib/grub/mips-* from grub-common rather than the incorrect
 +    /usr/lib/grub/mipsel-*, so that it stops clashing with grub-yeeloong;
 +    add a versioned Replaces to grub-yeeloong just in case (closes:
 +    #586526).
 +  * Remove qemu-system build-dependency on hurd-i386, where it doesn't seem
 +    to exist.  Disable tests if qemu-system-i386 isn't available.
 +  * Mark "upgrade-from-grub-legacy" paragraph in
 +    grub-pc/chainload_from_menu.lst as untranslatable.
 +  * Update Homepage field (thanks, Sedat Dilek).
 +  * On Linux, if /boot/grub/device.map exists on upgrade to this version,
 +    regenerate it to use stable device names in /dev/disk/by-id/.  If it had
 +    more than one entry, then display a critical-priority debconf note
 +    (sorry, but it's better than silently breaking boot menu entries)
 +    advising people to check custom boot menu entries and update them if
 +    necessary (closes: #583271).
 +  * Use 'set -e' rather than '#! /bin/sh -e' or '#! /bin/bash -e', to avoid
 +    accidents when debugging with 'sh -x'.
 +  * Store grub-pc/install_devices as persistent device names under
 +    /dev/disk/by-id/ (closes: #554790).  Migrate previous device names to
 +    that, with explicit confirmation in non-trivial cases to make sure we
 +    got the right ones.  If the devices we were told to install to ever go
 +    away, ask again.  (This is based on the implementation in Ubuntu.)
 +  * If grub-install fails during upgrade-from-grub-legacy, allow the user to
 +    try again with a different device, but failing that cancel the upgrade
 +    (closes: #587790).
 +  * Remove numbering from patch files.  The order is now explicit in a quilt
 +    series file, and renumbering from time to time is tedious.
 +
 +  [ Updated translations ]
 +  * Ukrainian (uk.po) by Yatsenko Alexandr / Borys Yanovych (closes:
 +    #586611).
 +  * Indonesian (id.po) by Arief S Fitrianto (closes: #586799).
 +  * Swedish (sv.po) by Martin Bagge (closes: #586827).
 +  * Persian (fa.po) by Behrad Eslamifar (closes: #587085).
 +  * French (fr.po) by Christian Perrier (closes: #587383).
 +  * Galician (gl.po) by Jorge Barreiro (closes: #587796).
 +
 +  [ Robert Millan ]
 +  * Add commented GRUB_BADRAM example in debian/default/grub.
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 02 Jul 2010 17:42:56 +0100
 +
 +grub2 (1.98+20100617-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Fix i386-pc prefix handling with nested partitions (closes: #585068).
 +
 +  * When running grub-pc.postinst from upgrade-from-grub-legacy, tell it to
 +    disregard the fact that /boot/grub/stage2 and /boot/grub/menu.lst still
 +    exist (closes: #550477).
 +  * Touch a marker file when grub-install is run but GRUB Legacy files are
 +    still around.  If that marker file is present, pretend that GRUB Legacy
 +    files are missing when upgrading.
 +  * If GRUB Legacy files are present when upgrading, scan boot sectors of
 +    all disks for GRUB 2.  If we find GRUB 2 installed anywhere, then ask
 +    the user if they want to finish conversion to GRUB 2, and warn them that
 +    not doing so may render the system unbootable (closes: #586143).  Thanks
 +    to Sedat Dilek for helping to narrow down this bug.
 +  * Leaving grub-pc/install_devices empty makes sense in some situations,
 +    but more often than not is a mistake.  On the other hand, automatically
 +    selecting all disk devices would upset some people too.  Compromise by
 +    simply asking for explicit confirmation if grub-pc/install_devices is
 +    left empty, defaulting to false so that simply selecting all the
 +    defaults in debconf can't leave you with an unbootable system (closes:
 +    #547944, #557425).
 +
 + -- Colin Watson <cjwatson@debian.org>  Sat, 19 Jun 2010 01:31:40 +0100
 +
 +grub2 (1.98+20100614-2) unstable; urgency=low
 +
 +  * Build-depend on gcc-4.4-multilib on i386 and kopensolaris-i386 too, in
 +    order to build grub-efi-amd64.
 +  * Ignore non-option arguments in grub-mkconfig (closes: #586056).
 +
 + -- Colin Watson <cjwatson@debian.org>  Wed, 16 Jun 2010 17:58:48 +0100
 +
 +grub2 (1.98+20100614-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Make target-related error messages from grub-mkimage slightly more
 +      helpful (closes: #584415).
 +    - Fix underquoting that broke savedefault (thanks, Mario 'BitKoenig'
 +      Holbe; closes: #584812).
 +    - Expand 'info grub' substantially, including a new section on
 +      configuring authentication (closes: #584822).
 +    - Give all manual pages proper NAME sections (closes: #496706).
 +
 +  * Update 915resolution from grub-extras:
 +    - Fix a hang with 945GME (thanks, Sergio Perticone; closes: #582142).
 +
 +  [ Colin Watson ]
 +  * Disable grub-emu on sparc for the time being.  We're currently trying to
 +    use TARGET_* flags to build it, which won't work.
 +  * Don't build-depend on libsdl1.2-dev on hurd-i386.  Although
 +    libsdl1.2-dev exists there, it's currently uninstallable due to missing
 +    libpulse-dev, and we can happily live without it for now.
 +  * kfreebsd-amd64 needs gcc-4.4-multilib too (closes: #585668).
 +  * Warn and return without error from prepare_grub_to_access_device if
 +    /boot is a dm-crypt device (thanks, Marc Haber; closes: #542165).
 +  * Make /etc/grub.d/05_debian_theme usable by shells other than bash
 +    (thanks, Alex Chiang; closes: #585561).
 +  * Remove grub-mkisofs leftovers from debian/copyright.
 +  * Fix reversed sense of DEB_BUILD_OPTIONS=nocheck handling.
 +  * Build-depend on qemu-system for grub-pc tests.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 15 Jun 2010 12:45:35 +0100
 +
 +grub2 (1.98+20100602-2) unstable; urgency=low
 +
 +  * Only build-depend on libdevmapper-dev on Linux architectures.
 +  * Don't build-depend on libusb-dev on hurd-i386, where it doesn't seem to
 +    be available.
 +  * Fix printf format mismatch in disk/usbms.c (closes: #584474).
 +  * Fix verbose error output when device-mapper isn't supported by the
 +    running kernel (closes: #584196).
 +  * Prepend "part_" to partmap module names in grub-mkconfig, in line with
 +    grub-install (closes: #584426).
 +
 + -- Colin Watson <cjwatson@debian.org>  Fri, 04 Jun 2010 14:01:58 +0100
 +
 +grub2 (1.98+20100602-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Add btrfs probing support, currently only in the single-device case
 +      (closes: #540786).
 +    - Fix grub-emu build on mips/powerpc/sparc.
 +    - Add safety check to make sure that /boot/grub/locale exists before
 +      trying to probe it (closes: #567211).
 +    - Several 'info grub' improvements, including a new section on
 +      configuration file generation using grub-mkconfig which documents the
 +      available keys in /etc/default/grub (closes: #497085).
 +    - Many USB fixes.
 +
 +  [ Colin Watson ]
 +  * Reorganise configure and build targets in debian/rules to use stamp
 +    files.  configure/* never existed and build/* was always a directory, so
 +    make never considered either of them up to date (closes: #450505).
 +  * Remove config.h.in from AUTOGEN_FILES, since autoheader doesn't
 +    necessarily update it.
 +  * Remove conf/gcry.mk from AUTOGEN_FILES, and conf/gcry.rmk from their
 +    dependencies.  autogen.sh runs util/import_gcry.py after autoconf et al,
 +    so conf/gcry.rmk's timestamp will be later than some of the
 +    autogenerated outputs.
 +  * Go back to shipping rescue images in the grub-rescue-pc .deb itself
 +    rather than generating them in the postinst.  This means that (a) they
 +    get removed when the package is removed (closes: #584176); (b) they are
 +    listed in package metadata, as is proper for files in /usr (closes:
 +    #584218); (c) grub-rescue-pc can potentially be used as a
 +    build-dependency for other packages that need to build GRUB images into
 +    installation media etc., without having to build-depend on grub-pc which
 +    isn't coinstallable with other platform variants and does invasive
 +    things in its postinst.
 +  * Add grub-mkrescue patch from Thomas Schmitt to allow reducing the size
 +    of xorriso-created images.  Use this to ensure that
 +    grub-rescue-floppy.img fits well within size limits (closes: #548320).
 +
 + -- Colin Watson <cjwatson@debian.org>  Thu, 03 Jun 2010 11:24:41 +0100
 +
 +grub2 (1.98+20100527-2) unstable; urgency=low
 +
 +  * Always override statically-linked-binary Lintian tag for kernel.img;
 +    dynamic linking makes no sense here.
 +  * kernel.img is stripped upstream where it can be, but override Lintian's
 +    error for the cases where it can't.
 +  * Override binary-from-other-architecture for kernel.img as well as *.mod
 +    when building grub-efi-amd64 on i386.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 01 Jun 2010 13:48:14 +0100
 +
 +grub2 (1.98+20100527-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Support multiple terminals in grub-mkconfig, e.g.
 +      GRUB_TERMINAL='serial console' (closes: #506707).
 +    - Speed up consecutive hostdisk operations on the same device (closes:
 +      #508834, #574088).
 +    - Fix grammar error in grub-setup warning (closes: #559005).
 +    - Use xorriso for image creation rather than embedding a modified copy
 +      of mkisofs (closes: #570156).
 +    - Issue an error rather than segfaulting if only some LVM component
 +      devices are in device.map (closes: #577808).
 +    - Fix typo in make_device_name which caused grub-probe problems on
 +      systems with BSD disk labels (closes: #578201).
 +    - Add DM-RAID probe support (closes: #579919).
 +    - Include all gnumach kernels on Hurd, not just gnumach and gnumach.gz
 +      (closes: #581584).
 +
 +  [ Colin Watson ]
 +  * Restore TEXTDOMAINDIR correction in grub.d files, lost by mistake in a
 +    merge.  Noticed by Anthony Fok.
 +  * Don't fail on purge if the ucf association has already been taken over
 +    by a different grub package (closes: #574176).
 +  * Add debian/grub-extras/*/conf/*.mk to AUTOGEN_FILES.
 +  * Remove support for the lpia architecture, now removed from Ubuntu.
 +  * Conflict with grub (<< 0.97-54) as well as grub-legacy.
 +  * Build-depend on libdevmapper-dev for DM-RAID probe support.
 +  * Switch to quilt.
 +  * Suggest xorriso (>= 0.5.6.pl00) in grub-common, since grub-mkrescue now
 +    needs it.  Depend on it in grub-rescue-pc.
 +  * Move grub-mkimage to grub-common, now that it only has one
 +    implementation.
 +  * Clean up temporary files used while building grub-firmware-qemu.
 +  * Make grub-probe work with symlinks under /dev/mapper (closes: #550704).
 +  * When upgrading a system where GRUB 2 is chainloaded from GRUB Legacy and
 +    upgrade-from-grub-legacy has not been run, upgrade the chainloaded image
 +    rather than confusing the user by prompting them where they want to
 +    install GRUB (closes: #546822).
 +  * Build-depend on libsdl1.2-dev for SDL support in grub-emu.
 +  * Don't leak debconf's file descriptor to update-grub, so that the LVM
 +    tools called from os-prober don't complain about it (closes: #549976).
 +    Other leaks are not this package's fault, may not be bugs at all, and in
 +    any case os-prober 1.36 suppresses the warnings.
 +  * Build-depend on flex (>= 2.5.35).
 +  * Build-depend on gcc-4.4-multilib on amd64.
 +
 +  [ Updated translations ]
 +  * Slovenian (sl.po) by Vanja Cvelbar (closes: #570110).
 +  * Vietnamese (vi.po) by Clytie Siddall (closes: #574578).
 +  * Tamil (ta.po) by Tirumurti Vasudevan (closes: #578282).
 +  * Portuguese (pt.po) by Tiago Fernandes (closes: #580140).
 +  * Romanian (ro.po) by Eddy Petrișor / Andrei Popescu (closes: #583185).
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 01 Jun 2010 11:24:38 +0100
 +
 +grub2 (1.98-1) unstable; urgency=low
 +
 +  * New upstream release (closes: #572898).
 +    - Fix grub-script-check to handle empty lines (closes: #572302).
 +    - Fix offset computation when reading last sectors.  Partition reads and
 +      writes within and outside a partition (closes: #567469, #567884).
 +    - Fix script execution error handling bug that meant that an error in a
 +      menuentry's last statement caused the whole menuentry to fail (closes:
 +      #566538, LP: #464743).
 +    - Support GRUB_GFXPAYLOAD_LINUX (closes: #536453, LP: #416772).
 +
 +  [ Samuel Thibault ]
 +  * Add GRUB_INIT_TUNE example to /etc/default/grub (closes: #570340).
 +
 +  [ Colin Watson ]
 +  * Build-depend on libusb-dev so that grub-emu is reliably built with USB
 +    support (closes: #572854).
 +  * Update directions in debian/rules on exporting grub-extras to account
 +    for it being maintained in Bazaar nowadays.
 +  * Add myself to Uploaders.
 +  * Acknowledge NMUs, thanks to Torsten Landschoff and Julien Cristau.
 +
 + -- Colin Watson <cjwatson@debian.org>  Tue, 09 Mar 2010 13:25:35 +0000
 +
 +grub2 (1.98~20100128-1.2) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Stop setting gfxpayload=keep (closes: #567245).
 +
 + -- Julien Cristau <jcristau@debian.org>  Sun, 14 Feb 2010 20:37:51 +0100
 +
 +grub2 (1.98~20100128-1.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Apply trivial patch (already merged upstream) fixing the offset
 +    computation for non-cached reads (closes: #567637).
 +
 + -- Torsten Landschoff <torsten@debian.org>  Mon, 08 Feb 2010 22:15:01 +0100
 +
 +grub2 (1.98~20100128-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Fix corruption problem when reading files from CDROM.  (Closes: #567219)
 +
 +  [ Felix Zielcke ]
 +  * Never strip kernel.img in rules. Upstream already does it when it
 +    can be done. (Closes: #561933)
 +  * Bump Standards-Version to 3.8.4.
 +
 +  [ Robert Millan ]
 +  * rules: Run the testsuite (make check) when building grub-pc.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Thu, 28 Jan 2010 16:28:45 +0100
 +
 +grub2 (1.98~20100126-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Includes mipsel-yeeloong port.
 +
 +  [ Robert Millan ]
 +  * config.in: Lower priority of grub2/linux_cmdline_default.
 +
 +  [ Felix Zielcke ]
 +  * Drop `CFLAGS=-O0' workaround on powerpc. Should be fixed correctly now.
 +  * Ship grub-bin2h and grub-script-check in grub-common.
 +  * Terminate NEWS.Debian with a blank line like lintian would suggest
 +    if that check would be working correctly.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 26 Jan 2010 19:26:25 +0100
 +
 +grub2 (1.98~20100115-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Includes savedefault / grub-reboot branch.
 +    - Includes Multiboot video support (from latest 1.x draft).
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Fri, 15 Jan 2010 18:15:26 +0100
 +
 +grub2 (1.98~20100110-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +
 +  [ Robert Millan ]
 +  * grub-rescue-pc.postinst: Fix image generation during upgrades.
 +    (Closes: #564261)
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Sun, 10 Jan 2010 02:45:52 +0100
 +
 +grub2 (1.98~20100107-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +
 +  [ Robert Millan ]
 +  * grub-rescue-pc.postinst: Use grub-mkrescue for floppy as well.
 +
 +  [ Updated translations ]
 +  * Chinese (zh_TW.po) by Tetralet. (Closes: #564044)
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Thu, 07 Jan 2010 17:56:10 +0100
 +
 +grub2 (1.98~20100101-1) unstable; urgency=high
 +
 +  * New Bazaar snapshot.
 +    - Fix FTBS on sparc.
 +
 +  [ Robert Millan ]
 +  * rules: Auto-update version from debian/changelog.
 +
 +  [ Felix Zielcke ]
 +  * Add -O0 to CFLAGS on powerpc to avoid the `_restgpr_31_x in boot is
 +    not defined' FTBFS.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Fri, 01 Jan 2010 00:31:37 +0100
 +
 +grub2 (1.98~20091229-1) unstable; urgency=high
 +
 +  * New Bazaar snapshot.
 +    - Fix slowness when $prefix uses an UUID.
 +      (Closes: #541145, LP: #420933)
 +    - Correctly set TARGET_CFLAGS. (Closes: #562953)
 +
 +  [ Robert Millan ]
 +  * grub-rescue-pc.postinst: Build USB rescue image.
 +  * rules: Invoke configure with relative path.  This makes binaries smaller,
 +    since dprintf strings are constructed using this path.
 +
 +  [ Felix Zielcke ]
 +  * Urgency=high due to RC bug fix.
 +  * Fix version comparison in grub-common.preinst for handling obsolete
 +    /etc/grub.d/10_freebsd. (Closes: #562921)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 29 Dec 2009 16:05:00 +0100
 +
 +grub2 (1.98~20091222-1) unstable; urgency=low
 +
 +  * New Baazar snapshot.
 +    - Make 30_os-prober again dash compatible. (Closes: #562034) 
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 22 Dec 2009 12:50:57 +0100
 +
 +grub2 (1.98~20091221-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - Fix search command failing on some broken BIOSes. (Closes: #530357)
 +
 +  [ Felix Zielcke ]
 +  * Add Replaces:/Conflicts: grub-linuxbios to grub-coreboot. (Closes: #561811)
 +  * Delete obsolete /etc/grub.d/10_freebsd if it has not been modified,
 +    else disable it. (Closes: #560346)
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 21 Dec 2009 22:04:17 +0100
 +
 +grub2 (1.98~20091210-1) unstable; urgency=low
 +
 +  * Version bump.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 14 Dec 2009 14:52:59 +0100
 +
 +grub2 (1.97+20091210-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +    - patches/02_fix_mountpoints_in_mkrelpath.diff: Remove (merged). 
 +    - Fixes FTBFS on powerpc (again) and sparc.
 +    - patches/903_grub_legacy_0_based_partitions.diff: Resync (merged into
 +      debian branch).
 +
 +  * Fix dpkg dependency for lenny compatibility.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Thu, 10 Dec 2009 00:35:20 +0100
 +
 +grub2 (1.97+20091130-1) unstable; urgency=low
 +
 +  * New Bazaar snapshot.
 +  * Enable ntldr-img from grub-extras.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 30 Nov 2009 02:33:03 +0100
 +
 +grub2 (1.97+20091125-2) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Bulgarian (bg.po) by Damyan Ivanovi (Closes: #558039)
 +
 +  [ Robert Millan ]
 +  * control: Remove genisoimage from Build-Depends/Suggests (no longer
 +    used).
 +  * grub.d/05_debian_theme: Make output string distro-agnostic.
 +
 +  [ Felix Zielcke ]
 +  * patches/02_fix_mountpoints_in_mkrelpath.diff: New patch to handle
 +    mount points like the old shell function did. (Closes: #558042)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sun, 29 Nov 2009 21:38:00 +0100
 +
 +grub2 (1.97+20091125-1) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * New upstream snapshot.
 +    - Fixes script parser load error.
 +
 +  * Add gettext to Build-Depends and gettext-base to grub-common's
 +    Depends.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 25 Nov 2009 19:22:51 +0100
 +
 +grub2 (1.97+20091124-1) unstable; urgency=low
 +
 +  * New upstream snapshot.
 +    - Fix grub-mkisofs related FTBFS on powerpc. (Closes: #557704)
 +    - Create fake GRUB devices for devices not listed in device.map.
 +      This also makes dmraid and multipath work as long as
 +      search --fs-uuid works. (Closes: #442382, #540549, LP: #392136)
 +    - rules: grub-emu is now built as a port.
 +
 +  [ Felix Zielcke ]
 +  * Change the bt-utf-source build dependency to xfonts-unifont. It's
 +    more complete, better maintained and grub-mkfont supports actually
 +    more then BDF fonts as input, thanks to libfreetype.
 +  * Use grub-probe to get the GRUB device of /boot/grub instead of
 +    passing (hd0) to grub-install when creating the core.img with
 +    chainloading. This avoids the (UUID=) hack slowness in case
 +    /boot/grub is on a different disk then (hd0) in device.map.
 +  * patches/903_grub_legacy_0_based_partitions.diff: Update.
 +  * Add a build dependency on automake and python.
 +  * Set TARGET_CC=$(CC) to really use gcc-4.4 everywhere. Also pass it
 +    and CC as arguments to ./configure instead of env vars so they get
 +    preserved.
 +  * Ship grub-mkrelpath in grub-common.
 +  * Ship the locale files in grub-common.
 +  * Add a dependency on 'dpkg (>= 1.15.4) | install-info' for grub-common
 +    as recommended by Policy and lintian.
 +
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 24 Nov 2009 21:20:00 +0100
 +
 +grub2 (1.97+20091115-1) unstable; urgency=low
 +
 +  * New upstream snapshot.
 +    - Fix security problem with password checking.  (Closes: #555195)
 +    - Fix the generated GNU/Hurd menu entries and also add support for
 +      it in 30_os-prober. (Closes: #555188)
 +    - Same grub-mkrescue for grub-pc and grub-coreboot, used by
 +      grub-rescue-pc during postinst now. (Closes: #501867)
 +
 +  [ Felix Zielcke ]
 +  * Ship grub-mkisofs in grub-common.
 +  * patches/002_grub.d_freebsd.in.diff: Remove (merged upstream).
 +  * patches/906_grub_extras.diff: Remove. Superseded by GRUB_CONTRIB variable
 +    in recent upstream trunk.
 +  * rules: Export GRUB_CONTRIB to enable grub-extras add-ons.
 +  * Pass --force to grub-install in the postinst. (Closes: #553415) 
 +  * Don't strip debug symbols from grub-emu. It's meant for debugging
 +    and with them it's much more useful.
 +  * Ship grub-mkfloppy in grub-pc.
 +  * Revert the Replaces: grub-common to (<= 1.96+20080413-1) on the
 +    grub-pc package. It was wrongly modified long ago.
 +
 +  [ Robert Millan ]
 +  * copyright: Document mkisofs.
 +  * control: Update Vcs- fields (moved to Bazaar).
 +  * rules: Update debian/legacy/update-grub rule to Bazaar.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sun, 15 Nov 2009 19:13:31 +0100
 +
 +grub2 (1.97-1) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * patches/905_setup_force.diff: Remove, no longer needed as of
 +    grub-installer >= 1.47.
 +  * grub.d/05_debian_theme: Attempt to source grub_background.sh from
 +    desktop-base (Needed for #495282, #495616, #500134, see also
 +    #550984).
 +
 +  [ Felix Zielcke ]
 +  * Add a build dependency on texinfo.
 +  * Fix little typo in /etc/default/grub. (LP: #457703)
 +
 +  [ Updated translations ]
 +  * Finnish (fi.po) by Esko Arajärvi. (Closes: #551912)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sun, 25 Oct 2009 19:50:21 +0100
 +
 +grub2 (1.97~beta4-1) unstable; urgency=low
 +
 +  * New upstream beta release.
 +
 +  [ Felix Zielcke ]
 +  * Change the Recommends: os-prober to (>= 1.33).
 +  * patches/907_grub.cfg_400.diff: Really add it. Somehow it was a 0 byte file.
 +    (Closes: #547409)
 +  * Convert newlines back to spaces when parsing kopt from
 +    GRUB Legacy's menu.lst, before giving the value to Debconf.
 +    Thanks to Colin Watson. (Closes: #547649)
 +  * Ship the info docs in grub-common. (Closes: #484074)
 +  * Remove generated /usr/share/info/dir* files.
 +  * Update the presubj bug file and also install it for grub-common.
 +
 +  [ Robert Millan ]
 +  * Enable ZFS and 915resolution in grub-extras (now requires explicit
 +    switch).
 +  * grub-common conflicts with grub-doc (<< 0.97-32) and grub-legacy-doc
 +    (<< 0.97-59).
 +  * Move grub-emu to a separate package.
 +
 +  [ Updated translations ]
 +  * Japanese (ja.po) by Hideki Yamane. (Closes: #549599)
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 05 Oct 2009 20:03:04 +0200
 +
 +grub2 (1.97~beta3-1) unstable; urgency=high
 +
 +  * New upstream beta release.
 +    - Make it more clear how to use /etc/grub.d/40_custom. (Closes: #545153)
 +    - fix a serious memory corruption in the graphical subsystem.
 +      (Closes: #545364, #544155, #544639, #544822, LP: #424503)
 +    - patches/003_grub_probe_segfault.diff: Remove (merged).
 +
 +  * Change the watch file so upstream beta releases are recognized.
 +  * Include /etc/default/grub in bug reports.
 +  * Recommend os-prober (>= 1.32). (Closes: #491872)
 +  * Change the gcc-multilib [sparc] build dependency to gcc-4.4-multilib
 +    [sparc].
 +  * patches/907_grub.cfg_400.diff: New patch to make grub.cfg again mode
 +    444 if it does not contain a password line.
 +  * Use `su' in the bug reporting script to read grub.cfg in case the user
 +    is not allowed to read it.
 +  * Readd grub-pc/kopt-extracted template.
 +
 +  [ Updated translations ]
 +  * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge.
 +  * Japanese (ja.po) by Hideki Yamane. (Closes: #545331)
 +  * Spanish (es.po) by Francisco Javier Cuadrado. (Closes: #545566)
 +  * Italian (it.po) by Luca Monducci. (Closes: #546035)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sat, 12 Sep 2009 15:28:20 +0200
 +
 +grub2 (1.97~beta2-2) unstable; urgency=low
 +
 +  [ Updated translations ]
 +  * Dutch (nl.po) by Paul Gevers. (Closes: #545050)
 +
 +  [ Felix Zielcke ]
 +  * Move GRUB Legacy's grub-set-default to /usr/lib/grub-legacy in
 +    preparation for GRUB 2's grub-set-default.
 +  * Remove password lines in bug script.
 +
 +  [ Robert Millan ]
 +  * Do not conflict with `grub' dummy package (this prevented upgrades).
 +  * patches/003_grub_probe_segfault.diff: Disable file test codepath, which
 +    wasn't normally used before.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sat, 05 Sep 2009 00:27:22 +0200
 +
 +grub2 (1.97~beta2-1) unstable; urgency=low
 +
 +  * New upstream beta release.
 +    - Fix loading of FreeBSD modules. (Closes: #544305)
 +
 +  [ Updated translations ]
 +  * French (fr.po) by Christian Perrier. (Closes: #544320)
 +  * Czech (cs.po) by Miroslav Kure. (Closes: #544327)
 +  * Belarusian (be.po) by Hleb Rubanau.
 +  * Arabic (ar.po) by Ossama M. Khayat.
 +  * Catalan (ca.po) by Juan Andrés Gimeno Crespo.
 +  * Russian (ru.po) by Yuri Kozlov. (Closes: #544730)
 +  * Swedish (sv.po) by Martin Ågren. (Closes: #544759)
 +  * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge. (Closes: #544810)
 +  * German (de.po) by Helge Kreutzmann. (Closes: #544912)
 +
 +  [ Robert Millan ]
 +  * Build with GCC 4.4.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Fri, 04 Sep 2009 14:40:20 +0200
 +
 +grub2 (1.97~beta1-1) unstable; urgency=low
 +
 +  * New upstream beta release.
 +
 +  [ Updated translations ]
 +  * German (de.po) by Helge Kreutzmann. (Closes: #544261)
 +  * Asturian (ast.po) by Marcos.
 +  * Georgian (ka.po) by Aiet Kolkhi.
 +
 +  [ Robert Millan ]
 +  * Merge config, templates, postinst, postrm, dirs and install files
 +    into a single source.
 +  * Disable Linux-specific strings on GNU/kFreeBSD.  Enable translations
 +    in grub2/linux_cmdline_default.  Add grub2/kfreebsd_* strings (still
 +    unused).
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sun, 30 Aug 2009 18:01:40 +0200
 +
 +grub2 (1.96+20090829-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix filesystem mapping on GNU/kFreeBSD.  (Closes: #543950)
 +
 +  * New grub-extras SVN snapshot.
 +    - Add 915resolution support to the GMA500 (poulsbo) graphics chipset.
 +      Thanks to Pedro Bulach Gapski. (Closes: #543917)
 +
 +  * Use `cp -p' to copy /usr/share/grub/default/grub to the temporary
 +    file to preverse permissions.
 +  * Remove also efiemu files from /boot/grub on purge if requested.
 +  * Check that GRUB_CMDLINE_LINUX and GRUB_CMDLINUX_LINUX_DEFAULT is at
 +    the start of line in *.postinst.
 +  * Don't check that $GRUB_CMDLINE_LINUX{,DEFAULT} are non empty strings
 +    in *.config.
 +  * Add empty GRUB_CMDLINE_LINUX to /usr/share/grub/default/grub.
 +  * Factorise the editing of the temporary file. Thanks to Martin F
 +    Krafft.
 +  * Read in /etc/default/grub in *.config files.
 +
 +  [ Updated translations ]
 +  * French (fr.po) by Christian Perrier. (Closes: #544023)
 +  * Russian (ru.po) by Yuri Kozlov. (Closes: #544077)
 +  * Italian (it.po) by Luca Monducci. (Closes: #544200)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sat, 29 Aug 2009 17:01:17 +0200
 +
 +grub2 (1.96+20090826-3) unstable; urgency=low
 +
 +  * Add missing quotes in grub-pc.config and *.postinst.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 26 Aug 2009 19:14:23 +0200
 +
 +grub2 (1.96+20090826-2) unstable; urgency=low
 +
 +  * Really use the correct templates in grub-pc.config. ARGS.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 26 Aug 2009 14:10:41 +0200
 +
 +grub2 (1.96+20090826-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * Use the right templates in grub-pc.config. (Closes: #543615)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 26 Aug 2009 11:00:36 +0200
 +
 +grub2 (1.96+20090825-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Enable gfxterm only if there's a suitable video backend and don't
 +      print an error if not. (Closes: #520846)
 +
 +  [ Felix Zielcke ]
 +  * Copy unicode.pf2 instead of ascii.pf2 to /boot/grub in grub-pc
 +    postinst (Closes: #542314).
 +  * Update Standards version to 3.8.3.
 +  * Use DEB_HOST_ARCH_CPU for the generation of the lintian overrides.
 +  * Fix calling the grub-pc/postrm_purge_boot_grub template in
 +    grub-pc.postinst.
 +  * Handle GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT via
 +    debconf. Thanks to Martin F. Krafft and Colin Watson for idea and
 +    hints.
 +  * Use ucfr --force when /etc/default/grub is registered to a grub-* package.
 +  * Use #!/bin/sh in *.config and fix a small bashism in grub-pc.config.
 +
 +  [ Robert Millan ]
 +  * patches/907_terminal_output_workaround.diff: Remove.  It seems that
 +    it wasn't really necessary.
 +  * grub-pc.postinst: Avoid printing an error if /etc/kernel-img.conf
 +    doesn't exist, because it is misleading.  We simply refrain from
 +    fixing it and move along.
 +  * grub-pc.postinst: Don't schedule generation of grub.cfg via "grub-install"
 +    code path unless we actually run grub-install.
 +  * grub-pc.postinst: Only copy unicode.pf2 and moreblue-orbit-grub.png when
 +    /boot/grub/grub.cfg is scheduled to be generated.
 +  * legacy/upgrade-from-grub-legacy: Reset grub-pc/install_devices.
 +    Thanks Colin Watson.  (Closes: #541230)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 25 Aug 2009 21:45:24 +0200
 +
 +grub2 (1.96+20090808-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix XFS with inode size different then 256. (Closes: #528761)
 +    - Add support for multiple LVM metadata areas. (LP: #408580)
 +    - patches/008_dac_palette_width.diff: Remove. (merged)
 +    - Prefer unicode over ascii font. (LP: #352034)
 +
 +  [ Felix Zielcke ]
 +  * Fix the generation of the lintian override for efiemu64.o.
 +  * Remove the Conflicts dmsetup.
 +  * Use ?= for setting DEB_HOST_ARCH.
 +  * Document GRUB_DISABLE_LINUX_RECOVERY in /etc/default/grub.
 +    (Closes: #476536 LP: #190207)
 +  * Add docs/grub.cfg to examples.
 +  * patches/01_uuids_and_lvm_dont_play_along_nicely.diff: Updated to
 +    also disable UUIDs on LVM over RAID.
 +  * Add a debconf prompt to remove all grub2 files from /boot/grub on
 +    purge. (Closes: #527068, #470400)
 +  * Move the Suggests: os-prober from grub-pc to grub-common. 
 +  * patches/901_dpkg_version_comparison.diff: Updated.
 +  * Update the Replaces on grub-common for the other packages to (<<
 +    1.96+20080831-1). (Closes: #540492)
 +
 +  [ Robert Millan ]
 +  * Reorganize grub-pc.{config,postinst} logic.  The idea being that if there's
 +    no trace of GRUB Legacy, the grub-pc/install_devices template will be
 +    shown even if this is the first install.
 +  * When setting grub-pc/install_devices, obtain input dynamically from
 +    grub-mkdevicemap (rather than devices.map). (Closes: #535525)
 +  * Add a note to grub-pc/install_devices template that it's also possible
 +    to install GRUB to a partition boot record.
 +  * patches/002_grub.d_freebsd.in.diff: New patch.  Reimplement
 +    10_freebsd.in to handle multiple kernel versions & acpi.ko.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 10 Aug 2009 18:49:52 +0200
 +
 +grub2 (1.96+20090725-1) unstable; urgency=high
 +
 +  * New SVN snapshot.
 +    - Don't add drivemap call with Windows Vista/7. It breaks Win 7.
 +      (LP: #402154)
 +
 +  [ Felix Zielcke ]
 +  * Don't build grub-efi-amd64 on hurd-i386.
 +  * Change DEB_BUILD_ARCH to DEB_HOST_ARCH in the check for sparc.
 +  * Don't add the lintian override for kernel.img for sparc and grub-pc.
 +  * Add a lintian override for binary-from-other-architecture for
 +    grub-efi-amd64 and grub-pc on i386.
 +  * Use wildcards in the lintian overrides.
 +  * Add a Conflicts/Replaces for all packages except grub-common.
 +    (Closes: #538177)
 +
 +  [ Robert Millan ]
 +  * 008_dac_palette_width.diff: New patch.  Fix blank screen when booting
 +    Linux with vga= parameter set to a packed color mode (<= 8-bit).
 +    (Closes: #535026)
 +  * Set urgency=high because #535026 affects 1.96+20090709-1 which is in
 +    testing now.
 +  * patches/907_terminal_output_workaround.diff: Work around recent regression
 +    with terminal_output command (not critical, just breaks gfxterm).
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Sat, 25 Jul 2009 19:00:53 +0200
 +
 +grub2 (1.96+20090721-4) unstable; urgency=low
 +
 +  * Place grub-ofpathname only in grub-common. (Closes: #537999)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 22 Jul 2009 13:38:24 +0200
 +
 +grub2 (1.96+20090721-3) unstable; urgency=low
 +
 +  * Don't strip kernel.img on sparc.
 +  * Suggest efibootmgr on grub-efi-{amd64,ia32}.
 +  * Pass --disable-grub-fstest to configure. (Closes: #537897)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 21 Jul 2009 21:46:01 +0200
 +
 +grub2 (1.96+20090721-2) unstable; urgency=low
 +
 +  * Add back Conflicts/Replaces grub.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 21 Jul 2009 11:24:45 +0200
 +
 +grub2 (1.96+20090721-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * Change License of my update-grub(8) and update-grub2(8) manpages to
 +    GPL3+ to match new copyright file.
 +  * Merge from Ubuntu: Don't build grub-efi-amd64 on lpia.
 +  * Don't pass `--enable-efiemu' to configure. On kfreebsd-i386 it won't
 +    compile and it should be now auto detected if it's compilable.
 +    (Closes: #536783)
 +  * Don't build grub-efi-amd64 on kfreebsd-i386. It lacks 64bit compiler
 +    support.
 +  * Rename the lintian override for kernel.elf to kernel.img.
 +  * Strip kernel.img not kernel.elf, but not in the case of grub-pc.
 +  * Rename the Conflicts/Replaces grub to grub-legacy. (Closes: #537824)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 21 Jul 2009 10:50:20 +0200
 +
 +grub2 (1.96+20090709-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * control (Build-Depends): Add gcc-multilib [sparc].
 +  * copyright: Rewrite using DEP-5 format.
 +  * Merge grub-extras into the package, and integrate it with GRUB's
 +    build system.
 +    - patches/906_grub_extras.diff
 +    - rules
 +    - copyright
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Thu, 09 Jul 2009 00:26:49 +0200
 +
 +grub2 (1.96+20090702-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +  * rules: Remove duplicated files in sparc64-ieee1275 port.
 +  * rules: Comment out -DGRUB_ASSUME_LINUX_HAS_FB_SUPPORT=1 setting.  We'll
 +    re-evaluate using it when it's more mature.  (Closes: #535026).
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Thu, 02 Jul 2009 13:23:51 +0200
 +
 +grub2 (1.96+20090629-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Misc fixes in Linux loader.
 +
 +  * control (grub-firmware-qemu): Make it buildable only on i386/amd64.
 +  * control: Add sparc (grub-ieee1275), remove remnants of ppc64.
 +  * rules: Include all modules in grub-firmware-qemu build.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Mon, 29 Jun 2009 19:22:37 +0200
 +
 +grub2 (1.96+20090628-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +  * Re-enable QEMU port.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Sun, 28 Jun 2009 01:11:10 +0200
 +
 +grub2 (1.96+20090627-2) unstable; urgency=low
 +
 +  * Disable QEMU port untill it goes through NEW.
 +  * Upload to unstable.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Sat, 27 Jun 2009 18:40:17 +0200
 +
 +grub2 (1.96+20090627-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix parsing of --output in grub-mkconfig. (Closes: #532956)
 +
 +  [ Felix Zielcke ]
 +  * Use ucfr --force in grub-ieee1275.postinst in case we're upgrading
 +    from previous version. It registered /etc/default/grub wrongly with
 +    package iee1275.
 +  * Drop the build dependency on libc6-dev-i386.
 +  * Remove ppc64 from the Architectures. It's totally dead.
 +  * Add a note to /etc/default/grub that update-grub needs to be run to
 +    update grub.cfg. (Closes: #533026)
 +  * Fix the svn-snapshot rule.
 +  * Update Standards version to 3.8.2. No changes needed.
 +
 +  [ Robert Millan ]
 +  * legacy/upgrade-from-grub-legacy: Invoke grub-pc.postinst directly rather
 +    than dpkg-reconfigure.  Since we pretend we're upgrading, it will DTRT.
 +  * Add grub-firmware-qemu package.
 +    - patches/008_qemu.diff: QEMU port (patch from upstream).
 +    - control (grub-firmware-qemu): New package.
 +    - rules: Add grub-firmware-qemu targets.
 +    - debian/grub-firmware-qemu.dirs
 +    - debian/grub-firmware-qemu.install
 +  * patches/906_revert_to_linux16.diff: Remove, now that gfxpayload is
 +    supported.
 +
 + -- Robert Millan <rmh.debian@aybabtu.com>  Sat, 27 Jun 2009 00:46:23 +0200
 +
 +grub2 (1.96+20090611-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * Append .diff to patches/01_uuids_and_lvm_dont_play_along_nicely so
 +    it gets really applied.
 +  * Drop completely the build dependency on gcc-multilib.
 +  * Instead of arborting in the preinst if /etc/kernel-img.conf still
 +    contains /sbin/update-grub, change the file with sed. Policy allows
 +    thisi, because it's not a conffile, according to Colin Watson.
 +  * Change /etc/default/grub to an ucf managed file instead of dpkg
 +    conffile.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Fri, 12 Jun 2009 11:46:24 +0200
 +
 +grub2 (1.96+20090609-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix variable parsing inside strings. (Closes: #486180)
 +    - Add `true' command. (Closes: #530736)
 +
 +  [ Robert Millan ]
 +  * Split grub-efi in grub-efi-ia32 and grub-efi-amd64, both available
 +    on i386 and amd64.  (Closes: #524756)
 +  * Add kopensolaris-i386 to arch list.
 +
 +  [ Felix Zielcke ]
 +  * Add a NEWS entry about the grub-efi split. 
 +  * Drop the build dependency on gcc-multilib for all *i386.
 +  * Change upgrade-from-grub-legacy to use `dpkg-reconfigure grub-pc' to
 +    install grub2 into MBR.
 +
 +  [ New translations ]
 +  * Catalan (ca.po) by Jordi Mallach.
 +
 +  [ Updated translations ]
 +  * Spanish (es.po) by Francisco Javier Cuadrado. (Closes: #532407)
 +
 + -- Jordi Mallach <jordi@debian.org>  Tue, 09 Jun 2009 19:21:15 +0200
 +
 +grub2 (1.96+20090603-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * Abort the install of grub-pc if /etc/kernel-img.conf still contains
 +    /sbin/update-grub (Closes: #500631).
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 03 Jun 2009 20:01:11 +0200
 +
 +grub2 (1.96+20090602-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  [ Felix Zielcke ]
 +  * Skip floopies in the grub-install debconf prompt in grub-pc postinst.
 +    Patch by Fabian Greffrath. (Closes: #530848)
 +
 +  [ Robert Millan ]
 +  * Change Vcs-Browser field to viewsvn.
 +
 +  [ Felix Zielcke ]
 +  * Change Vcs-Svn field to point to the trunk. (Closes: #531391)
 +  * patches/01_uuids_and_lvm_dont_play_along_nicely: New patch.
 +    On Debian root=UUID= with lvm still doestn't work so disable it.
 +    (Closes: #530357)
 +  * Remove Otavio Salvador from Uploaders with his permission.
 +  * add grub-pc.preinst
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Wed, 03 Jun 2009 14:42:11 +0200
 +
 +grub2 (1.96+20090523-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Add drivemap command, similar to grub-legacy's map command.
 +      (Closes: 503630)
 +    - Export GRUB_TERMINAL_INPUT in grub-mkconfig. (Closes: #526741)
 +
 +  [ Robert Millan ]
 +  * rules: Set GRUB_ASSUME_LINUX_HAS_FB_SUPPORT=1 in CFLAGS.
 +  * patches/905_setup_force.diff: Relax blocklist warnings.
 +  * patches/906_revert_to_linux16.diff: Keep using linux16 for now.
 +
 +  [ Felix Zielcke ]
 +  * patches/07_core_in_fs.diff: Updated.
 +  * Remove /etc/grub.d/10_hurd on non-Hurd systems in the grub-common
 +    preinst. Likewise for 10_freebsd for non kFreebsd and 10_linux on
 +    kFreebsd and Hurd. (Closes: #523777)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sat, 23 May 2009 20:05:10 +0200
 +
 +grub2 (1.96+20090504-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Add support for parttool command, which can be used to hide partitions.
 +      (Closes: #505905)
 +    - Fix a segfault with LVM on RAID. (Closes: #520637)
 +    - Add support for char devices on (k)FreeBSD. (Closes: #521292)
 +    - patches/08_powerpc-ieee1275_build_fix.patch: Remove (merged).
 +
 +  [ Updated translations ]
 +  * Basque (eu.po) by Piarres Beobide. (Closes: #522457)
 +  * German (de.po) by Helge Kreutzmann. (Closes: #522815)
 +
 +  [ Robert Millan ]
 +  * Update my email address.
 +  * Remove 04_uuids_and_abstraction_dont_play_along_nicely.diff now that
 +    bugs #435983 and #455746 in mdadm and dmsetup have been fixed.
 +
 +  [ Felix Zielcke ]
 +  * Place new grub-dumpbios in grub-common.
 +  * Add lpia to the archictectures to reduce the ubuntu delta.
 +  * Add a manpage for the update-grub and update-grub2 stubs, written by
 +    me. (Closes: #523876)
 +  * Suggest genisoimage on grub-pc and grub-ieee1275, because grub-mkrescue
 +    needs it to create a cd image. (Closes: #525845)
 +  * Add a dependency on $(AUTOGEN_FILES) for the configure/grub-common target,
 +    this is needed now that upstream removed the autogenerated files from SVN.
 +  * Add `--enable-efiemu to' `./configure' flags.
 +  * Add a build dependency on gcc-multilib for i386.
 +  * Drop alternate build dependency on gcc-4.1 (<< 4.1.2).
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Mon, 04 May 2009 21:01:22 +0200
 +
 +grub2 (1.96+20090402-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix regression in disk/raid.c.  (Closes: #521897, #514338)
 +    - Fix handling of filename string lengths in HFS.
 +      (Really closes: #516458).
 +  * Add myself to Uploaders.
 +  * Add patch 08_powerpc-ieee1275_build_fix.patch to fix powerpc-ieee1275
 +    builds which were lacking header files for kernel_elf_HEADERS. Thanks
 +    Vladimir Serbinenko.
 +
 + -- Jordi Mallach <jordi@debian.org>  Fri, 03 Apr 2009 20:58:37 +0200
 +
 +grub2 (1.96+20090401-1) experimental; urgency=low
 +
 +  [ Felix Zielcke ]
 +  * New SVN snapshot.
 +    - Pass grub's gfxterm mode to Linux kernel. (Closes: #519506)
 +    - Fix ext4 extents on powerpc. (Closes: #520286)
 +
 +  [ Robert Millan ]
 +  * Remove grub-of transitional package (Lenny had grub-ieee1275 already).
 +  * Fix kopt parsing in grub-pc.config. Thanks Marcus Obst. (Closes: #514837)
 +  * Add debconf template to automatically run grub-install during upgrades
 +    (prior user confirmation).  (Closes: #514705)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 01 Apr 2009 01:19:45 +0200
 +
 +grub2 (1.96+20090317-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Fix loading of files with underscore in HFS. (Closes: #516458)
 +
 +  * Update Standards version to 3.8.1. No changes needed.
 +
 +  [ Updated translations ]
 +  * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge. (Closes: #519417)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 17 Mar 2009 14:42:10 +0100
 +
 +grub2 (1.96+20090309-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Mon, 09 Mar 2009 10:03:13 +0100
 +
 +grub2 (1.96+20090307-1) unstable; urgency=low
 +
 +  * New SVN snapshot.
 +    - Add support for /dev/md/dNNpNN mdraid devices. (Closes: #509960)
 +    - Add new PF2 fontengine. (Closes: #510344)
 +    - Avoid mounting ext2 partitions with backward-incompatible features.
 +      (Closes: #502333)
 +    - Try to avoid false positives with FAT. (Closes: #514263)
 +
 +  [ Felix Zielcke ]
 +  * Remove build-dependency on unifont package and add one for bf-utf-source
 +    package and libfreetype6-dev
 +  * grub-pc.postinst: Copy new ascii.pf2 instead of old ascii.pff to /boot/grub.
 +  * Add `--enable-grub-mkfont' to configure flags.
 +  * Put new grub-mkfont in grub-common package.
 +  * Add a dependency for ${misc:Depends} to all packages to make lintian a bit
 +    more happy.
 +  * Detect when grub-setup leaves core.img in filesystem, and include that
 +    info in bug report templates.
 +    - debian/patches/07_core_in_fs.diff
 +    - debian/script
 +  * Add myself to Uploads and add `DM-Upload-Allowed: yes' tag.
 +
 +  [ Updated translations ]
 +  * Asturian (ast.po) by Marcos Alvarez Costales. (Closes: #511144)
 +  * Traditional Chinese (zh_TW.po) by Tetralet. (Closes: #513918)
 +  * Belarusian (be.po) by Pavel Piatruk. (Closes: #516243)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Sat, 07 Mar 2009 11:54:43 +0100
 +
 +grub2 (1.96+20081201-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon,  1 Dec 2008 00:07:31 +0100
 +
 +grub2 (1.96+20081120-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +
 +  * Update to new debian theme.
 +    - grub-pc.postinst: Switch to moreblue-orbit-grub.png.
 +    - grub.d/05_debian_theme: Likewise.
 +  * grub.d/05_debian_theme:
 +      - Update to use new grub-mkconfig_lib instead of the deprecated
 +        update-grub_lib.
 +      - Update to check if `GRUB_TERMINAL_OUTPUT' is `gfxterm' instead of
 +        `GRUB_TERMINAL'.
 +
 +   [ Updated translations ]
 +  * Romanien (ro.po) by Eddy Petrișor. (Closes: #506039)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Thu, 20 Nov 2008 20:25:56 +0100
 +
 +grub2 (1.96+20081108-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Add support for /dev/md/N style mdraid devices. (Closes: #475585)
 +    - Handle LVM dash escaping. (Closes: #464215)
 +    - Use case insensitive match in NTFS. (Closes: #497889)
 +    - Use hd%d drive names in grub-mkdevicemap for all architectures.
 +      (Closes: #465365)
 +    - Handle LVM circular metadata. (Closes: #462835, #502953)
 +    - Fix NULL dereference and failure paths in LVM.  Thanks Guillem Jover.
 +      (Closes: #500482)
 +    - Provides GRUB header files (only in grub-common).
 +
 +  [ Updated translations ]
 +  * Dutch (nl.po) by Paul Gevers. (Closes: #500514)
 +  * French (fr.po) by Christian Perrier. (Closes: #503708)
 +  * Georgian (ka.po) by Aiet Kolkhi. (Closes: #503715)
 +  * Czech (cs.po) by Miroslav Kure. (Closes: #503809)
 +  * German (de.po) by Helge Kreutzmann. (Closes: #503841)
 +  * Japanese (ja.po) by Hideki Yamane. (Closes: #503869)
 +  * Italian (it.po) by Luca Monducci. (Closes: #504076)
 +  * Swedish (sv.po) by Martin Ågren. (Closes: #504207)
 +  * Arabic (ar.po) by Ossama Khayat. (Closes: #504254)
 +  * Portuguese (pt.po) by Miguel Figueiredo. (Closes: #504280)
 +  * Russian (ru.po) by Yuri Kozlov. (Closes: #504324)
 +  * Finnish (fi.po) by Esko Arajärvi. (Closes: #504310)
 +  * Basque (eu.po) by Piarres Beobide. (Closes: #504466)
 +  * Dutch (nl.po) by Paul Gevers. (Closes: #504683)
 +
 +  [ Felix Zielcke ]
 +  * patches/01_grub_legacy_0_based_partitions.diff: Rename to
 +  * patches/903_grub_legacy_0_based_partitions.diff: this and adapt for
 +    s/biosdisk.c/hostdisk.c/ rename upstream.
 +  * patches/03_disable_floppies.diff
 +    patches/904_disable_floppies.diff: Likewise.
 +  * update-grub has been renamed to grub-mkconfig, so provide a stub for
 +    compatibility.
 +  * Make grub-pc/linux_cmdline debconf template translatable. (Closes: #503478)
 +  * Remove ro.po and ta.po. They don't contain a single translated
 +    message.
 +
 +  [ Robert Millan ]
 +  * control: Make grub-common dependency = ${binary:Version}.
 +  * default/grub: Set GRUB_CMDLINE_LINUX=quiet to syncronize with
 +    default D-I settings.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat,  8 Nov 2008 13:54:10 +0100
 +
 +grub2 (1.96+20080831-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +   - patches/00_fix_double_prefix.diff: Remove (merged). (Closes: #487565)
 +   - patches/00_getline.diff: Remove (merged). (Closes: #493289)
 +   - Handle errors in RAID/LVM scan routine (rather than letting the upper
 +     layer cope with them).  (Closes: #494501, #495049)
 +   - patches/901_linux_coreboot.diff: Remove (replaced).
 +   - Add support for GFXMODE variable (Closes: #493106)
 +   - Skips /dev/.* in grub-probe.  (Closes: #486624)
 +   - RAID code has various fixes. (Closes: #496573)
 +   - Buffered file read is now used to read the background image faster.
 +     (Closes: #490584)
 +
 +  * We are already using LZMA, because upstream includes it's own lzma encoder,
 +    so drop completely the liblzo handling in control and rules files.
 +
 +  [ Felix Zielcke ]
 +  * Remove the 1.95 partition numbering transition debconf warning
 +    from grub2 package and removed it from all languages (*.po).
 +    (Closes: #493744)
 +  * Add a comment for the new GFXMODE in default/grub.
 +  * debian/rules:
 +      - Remove 2 ./configure options which it didn't understand.
 +      - New grub-mkelfimage belongs to grub-common.
 +  * debian/control:
 +      - Change debhelper compat level to 7 and build depend on it >= 7.
 +      - Remove ${misc:Depend} dependency on all packages except grub-pc which is
 +        the only one using debconf.
 +      - Replace deprecated ${Source-Version} with ${source:Version} for <<
 +        dependency and with ${build:Version} for = ones.
 +      - Remove versioned dependency of Build-Depends patchutils and cdbs,
 +        because etch has newer versions then the one used.
 +      - Remove dpkg-dev completely from Build-Depends because it's
 +        build-essentail and a non versioned dependency results in a lintian error.
 +      - Remove Conflict/Replaces pupa, it has been removed from Debian 2004.
 +      - Change build-dependency of unifont-bin to unifont (>= 1:5.1.20080820),
 +        it's the new package containing unifont.hex and that version to avoid
 +        licensing problems (Closes: #496061)
 +      - Remove Jason Thomas from Uploaders with his permission.
 +  * Preserve arguments in update-grub2 stub. (Closes: #496610)
 +
 +  [ Updated translations ]
 +  * Japanese (ja.po) by Hideki Yamane (Closes: #493347)
 +
 +  [ Robert Millan ]
 +  * Move a few files to grub-common and remove them from the arch-
 +    specific packages.
 +  * patches/02_old_linux_version_comparison.diff: Replace with ...
 +  * patches/901_dpkg_version_comparison.diff: ... this.
 +    Use dpkg --compare-versions in update-grub. (Closes: #494158)
 +  * patches/03_disable_floppies.diff: Free .drive struct member when skipping
 +    floppy drives.  (Closes: #496040)
 +  * patches/902_boot_blocklist_hack.diff: Support separate /boot when using
 +    blocklists.  (Closes: #496820, #489287, #494589)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun, 31 Aug 2008 18:40:09 +0200
 +
 +grub2 (1.96+20080730-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - patches/00_fix_overflow.diff: Remove (merged).
 +    - patches/00_uuid_boot.diff: Remove (merged).
 +    - patches/00_raid_duped_disks.diff: Remove (merged).
 +    - patches/00_xfs.diff: Remove (merged).
 +    - patches/00_strengthen_apple_partmap_check.diff: Remove (merged).
 +    - patches/00_skip_dev_dm.diff: Remove (merged).
 +
 +  * patches/901_linux_coreboot.diff: Implements Linux load on Coreboot
 +    (patch from Coresystems).
 +
 +  * grub-linuxbios -> grub-coreboot rename again.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 30 Jul 2008 22:12:07 +0200
 +
 +grub2 (1.96+20080724-4) unstable; urgency=high
 +
 +  * patches/00_fix_overflow.diff: fix overflow with a big grub.cfg.
 +    (Closes: #473543)
 +
 + -- Felix Zielcke <fzielcke@z-51.de>  Tue, 29 Jul 2008 17:10:59 +0200
 +
 +grub2 (1.96+20080724-3) unstable; urgency=low
 +
 +  [ Felix Zielcke ]
 +  * changed dependency for debconf to also support debconf-2.0. (Closes: #492543)
 +  * patches/00_xfs.diff: Fix "out of partition" error with XFS.
 +    (Closes: #436943)
 +
 +  [ Robert Millan ]
 +  * patches/00_raid_duped_disks.diff: Do not abort when two RAID disks with
 +    the same number are found.  (Closes: #492656)
 +  * patches/00_strengthen_apple_partmap_check.diff: Be more strict when probing
 +    for Apple partition maps (this prevents false positives on i386-pc
 +    installs).  (Closes: #475718)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue, 29 Jul 2008 00:48:01 +0200
 +
 +grub2 (1.96+20080724-2) unstable; urgency=high
 +
 +  [ Felix Zielcke ]
 +  * fixed lintian override for kernel.elf
 +  * debian/rules: changed cvs targets to use svn
 +
 +  [ Robert Millan ]
 +  * patches/00_skip_dev_dm.diff: Skip /dev/dm-[0-9] devices also (implicitly)
 +    for RAID.  (Closes: #491977)
 +  * patches/00_uuid_boot.diff: Fix cross-disk installs by using UUIDs.
 +    (Closes: #492204)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 26 Jul 2008 01:06:07 +0200
 +
 +grub2 (1.96+20080724-1) unstable; urgency=high
 +
 +  * New SVN snapshot.
 +    - Support for ext4dev extents.
 +    - patches/00_speed_up_font_load.diff: Remove (merged).
 +
 +  [ Felix Zielcke ]
 +  * upgrade-from-grub-legacy now calls update-grub if grub.cfg doestn't exist
 +    and prints a big warning if it failed.
 +  * Update Standards version to 3.8.0. No changes need.
 +  * Added Build-Dep for po-debconf and a lintian override, to make it happy.
 +
 +  [ Updated translations ]
 +  * Swedish (sv.po) by Martin Ågren (Closes: #492056)
 +
 +  [ Robert Millan ]
 +  * Revert r844.  grub-coreboot is stuck on NEW, and it was too early
 +    for branching.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Thu, 24 Jul 2008 13:27:53 +0200
 +
 +grub2 (1.96+20080717-1) experimental; urgency=low
 +
 +  * New SVN snapshot.
 +    - Provides LZMA support (not yet used in the package).
 +    - Fix grub-mkrescue manpage generation.  (Closes: #489440)
 +
 +  * Rename grub-linuxbios to grub-coreboot (and leave a dummy grub-linuxbios
 +    package to handle upgrades).
 +
 +  [ Updated translations ]
 +  * Spanish (es.po) by Maria Germana Oliveira Blazetic  (Closes: #489877)
 +  * Portuguese (pt.po) by Ricardo Silva  (Closes: #489807)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 12 Jul 2008 17:47:09 +0200
 +
 +grub2 (1.96+20080704-2) unstable; urgency=high
 +
 +  * patches/02_old_linux_version_comparison.diff: Set interpreter to /bin/bash.
 +    (Closes: #489426, #489446)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon,  7 Jul 2008 15:17:58 +0200
 +
 +grub2 (1.96+20080704-1) unstable; urgency=high
 +
 +  * New SVN snapshot.
 +  * default/grub: Add commented example to disable graphical terminal.
 +  * Use substvars to support linking with liblzo1.
 +  * Bring 03_disable_floppies.diff to pre-r805 state.  (Closes: #488375)
 +  * patches/02_old_linux_version_comparison.diff: New patch.  Steal version
 +    comparison code from GRUB Legacy's update-grub.  (Closes: #464086, #489133)
 +  * patches/00_speed_up_font_load.diff: New patch.  Generate font files with
 +    only the needed characters.  (Closes: #476479, #477083)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Fri,  4 Jul 2008 21:39:07 +0200
 +
 +grub2 (1.96+20080626-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Avoids passing UUID to Linux when not using initrd.  (Closes: #484228)
 +    - patches/04_uuids_and_abstraction_dont_play_along_nicely.diff: Resync.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Thu, 26 Jun 2008 16:43:48 +0200
 +
 +grub2 (1.96+20080621-1) unstable; urgency=high
 +
 +  * Urgency set to "high" because of #482688.
 +  * New CVS snapshot.
 +    - Fix module load hook in prepare_grub_to_access_device().
 +      (Closes: #486804)
 +    - Call prepare_grub_to_access_device() before accessing devices, never
 +      afterwards.  (Closes: #487198)
 +  * grub.d/05_debian_theme: Prefer /boot/grub over /usr for image
 +    loading, since chances are it's less LVMed.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 21 Jun 2008 15:52:48 +0200
 +
 +grub2 (1.96+20080617-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Supports IDA block devices.  (Closes: #483858)
 +    - Fixes some problems in ext2/ext3.  (Closes: #485068, #485065)
 +    - Uses EUID instead of UID in update-grub.  (Closes: #486043, #486039,
 +      #486040, #486041).
 +    - Fixes incomplete I2O device support.  Thanks Sven Mueller.
 +      (Closes: #486505)
 +    - Fixes recent regressions in fs/ext2.c.  (Closes: #485279)
 +    - Only use UUIDs when requested device is not the same as the one
 +      providing /boot.  (Closes: #486119)
 +    - patches/02_libgcc_powerpc_hack.diff: Remove.  Probably not needed
 +      anymore.
 +    - patches/04_uuids_and_abstraction_dont_play_along_nicely.diff: Update.
 +  * patches/06_olpc_prefix_hack.diff: Hardcode prefix to (sd,1) on OLPC.
 +  * Refurbish 03_disable_floppy_support_in_util_biosdisk.diff into
 +    03_disable_floppies.diff.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue, 17 Jun 2008 01:07:52 +0200
 +
 +grub2 (1.96+20080601-2) unstable; urgency=low
 +
 +  * 04_run_grub_mkdevicemap_when_grub_probe_fails.diff: Remove.  Argueably
 +    makes grub-probe unreliable and is quite annoying.
 +  * 04_uuids_and_abstraction_dont_play_along_nicely.diff: New patch.  Disable
 +    UUID parameter to Linux when LVM or dmRAID is in use.  (Closes: #484228)
 +    This is a workaround for bug #484297 in udev.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue,  3 Jun 2008 16:29:53 +0200
 +
 +grub2 (1.96+20080601-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - patches/06_backward_compat_in_uuid_support.diff: Merged.
 +    - Fixes NULL pointer dereference in biosdisk.c.  (Closes: #483895, #483900)
 +    - Extends UUID support for XFS and ReiserFS.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun,  1 Jun 2008 15:44:08 +0200
 +
 +grub2 (1.96+20080531-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Work around BIOS bug affecting keyboard on macbooks.  (Closes: #482860)
 +    - Adjust grub.d/05_debian_theme to use the new UUID-compatible API.
 +    - default/grub: Add commented GRUB_DISABLE_LINUX_UUID variable.
 +    - patches/06_backward_compat_in_uuid_support.diff: New.  Make update-grub
 +      generate code that is compatible with older GRUB installs.
 +    - util/biosdisk.c no longer complains about duplicated device.map entries.
 +      (Closes: #481236)
 +
 +  [ Updated translations ]
 +  * Galician (gl.po) by Jacobo Tarrio  (Closes: #480977)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 31 May 2008 00:02:54 +0200
 +
 +grub2 (1.96+20080512-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Adds support for default-only Linux cmdline options.  (Closes: #460843)
 +    - Supports Xen virtual block devices.  (Closes: #456777)
 +    - Supports Virtio block devices.  (Closes: #479056)
 +    - Supports CCISS block devices.  (Closes: #479735)
 +    - Fixes handling of more LVM abnormal conditions.  (Closes: #474343,
 +      #474931, #477175)
 +
 +  * Switch to liblzo2 now that it's GPLv3-compatible.  (Closes: #466375)
 +  * grub-pc.postinst: Escape \ and / in cmdline sed invokation.
 +    (Closes: #479279)
 +
 +  [ Updated translations ]
 +  * Italian (it.po) by Luca Monducci  (Closes: #480740)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon, 12 May 2008 17:46:38 +0200
 +
 +grub2 (1.96+20080429-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Includes sample grub.cfg file; we use it for grub-rescue-pc.
 +      (Closes: #478324)
 +  * grub-common: Upgrade Replaces to << 1.96+20080426-3.  (Closes: #478224,
 +    #478353, #478144)
 +
 +  [ Updated translations ]
 +  * French (fr.po) by Christian Perrier  (Closes: #471291)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue, 29 Apr 2008 13:27:52 +0200
 +
 +grub2 (1.96+20080426-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Fixes syntax error when setting GRUB_PRELOAD_MODULES.  (Closes: #476517)
 +  * Move os-prober to Suggests, to avoid trouble with #476184.
 +    (Closes: #476684)
 +  * patches/04_run_grub_mkdevicemap_when_grub_probe_fails.diff: New patch,
 +    does what its name says.  (Closes: #467127)
 +    - Also move grub-mkdevicemap from grub-pc to grub-common, so that GRUB
 +      Legacy can use it.
 +
 +  [ Updated translations ]
 +  * Basque (eu.po) by Piarres Beobide  (Closes: #476708)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 26 Apr 2008 20:06:55 +0200
 +
 +grub2 (1.96+20080413-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Provides 30_os-prober update-grub add-on.  Thanks Fabian Greffrath.
 +      (Closes: #461442)
 +    - Improves robustness when handling LVM.
 +      (Closes: #474931, #474343)
 +  * patches/03_disable_floppy_support_in_util_biosdisk.diff: New.  Does
 +    what its name says.  (Closes: #475177)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun, 13 Apr 2008 13:53:28 +0200
 +
 +grub2 (1.96+20080408-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - grub-probe skips non-existant devices when processing device.map.
 +    (Closes: #473209)
 +  * control: Fix syntax error.
 +
 +  [ Updated translations ]
 +  * Finnish (fi.po) by Esko Arajärvi (Closes: #468641)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue,  8 Apr 2008 15:45:25 +0200
 +
 +grub2 (1.96+20080228-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +  * Split grub-probe into grub-common package.  Make all flavours depend on it.
 +    (Closes: #241972)
 +  * Suggest multiboot-doc.
 +  * patches/01_grub_legacy_0_based_partitions.diff: New patch.  Add a hack that
 +    tells grub-probe you want 0-based partition count
 +    (GRUB_LEGACY_0_BASED_PARTITIONS variable)
 +  * Stop depending on lsb-release (too heavy! we don't need python in base).
 +    Instead of assuming it's there, try calling it and otherwise just echo
 +    Debian.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Thu, 28 Feb 2008 16:43:40 +0100
 +
 +grub2 (1.96+20080219-3) unstable; urgency=low
 +
 +  * default/grub: Use lsb_release to support Debian derivatives.
 +    (Closes: #466561)
 +  * grub.d/05_debian_theme: Only setup background image when a reader for it
 +    is present in /boot/grub.  (Closes: #467111)
 +
 +  [ Updated translations ]
 +  * Russian (ru.po) by Yuri Kozlov (Closes: #467181)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun, 24 Feb 2008 15:39:50 +0100
 +
 +grub2 (1.96+20080219-2) unstable; urgency=high
 +
 +  * grub-pc.postinst: Create /boot/grub if it doesn't exist.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 20 Feb 2008 07:15:14 +0100
 +
 +grub2 (1.96+20080219-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Improves GPT support, allowing it to work without blocklists.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue, 19 Feb 2008 15:05:10 +0100
 +
 +grub2 (1.96+20080216-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Fixes offset calculation issue when installing on GPT (urgency set
 +      to high because of this).
 +  * Fix Vcs-Browser tag.  Thanks James.  (Closes: #465697)
 +  * Only process grub-pc/linux_cmdline if /boot/grub/menu.lst exists.
 +    (Closes: #465708)
 +
 +  [ Updated translations ]
 +  * French (fr.po) by Christian Perrier  (Closes: #465706)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 16 Feb 2008 23:30:55 +0100
 +
 +grub2 (1.96+20080213-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Failure to read one device in a RAID-1 array no longer causes boot
 +      to fail (so long as there's a member that works).  (Closes: #426341)
 +  * script: For /proc/mounts, only report lines that start with /dev/.
 +  * Add new upgrade-from-grub-legacy script for the user to complete the upgrade
 +    process from GRUB Legacy, and advertise it prominently in menu.lst.
 +    (Closes: #464912)
 +  * Add a hack to support gfxterm / background_image on systems where /usr
 +    isn't accessible.  (Closes: #464911, #463144)
 +    - grub-pc.postinst
 +    - grub.d/05_debian_theme
 +  * Fix a pair of spelling mistakes in debconf.  (Closes: #465296)
 +  * Migrate kopt from menu.lst.  (Closes: #461164, #464918)
 +
 +  [ Updated translations ]
 +  * Portuguese (pt.po) by Ricardo Silva (Closes: #465137)
 +  * German (de.po) by Helge Kreutzmann (Closes: #465295)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 13 Feb 2008 16:37:13 +0100
 +
 +grub2 (1.96+20080210-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Errors that cause GRUB to enter rescue mode are displayed now.
 +      (Closes: #425149)
 +    - Build LVM/RAID modules into a few commands that were missing them
 +      (notably, grub-setup).  (Closes: #465033)
 +  * Fix license violation (incompatibility between GRUB and LZO2).
 +    (Closes: #465056)
 +    - Urgency set to high.
 +    - control: Move liblzo2-dev from Build-Depends to Build-Conflicts
 +      (leaving liblzo-dev as the only option).
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun, 10 Feb 2008 17:09:15 +0100
 +
 +grub2 (1.96+20080209-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Fix a root device setting issue in grub-setup.  (Closes: #463391)
 +    - Fix partmap detection under LVM/RAID.
 +    - Add scripting commands that would allow user to implement hiddenmenu-like
 +      functionality (http://grub.enbug.org/Hiddenmenu).
 +    - Provide manpages for grub-setup, grub-emu, grub-mkimage and others.
 +      (Closes: #333516, #372890)
 +  * Fix a pair of spelling errors in debconf templates.  Thanks Christian
 +    Perrier.  (Closes: #464133)
 +  * Run debconf-updatepo.  (Closes: #463918)
 +  * Lower base-files versioned dependency to >= 4.0.1~bpo40+1.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat,  9 Feb 2008 13:43:49 +0100
 +
 +grub2 (1.96+20080203-1) unstable; urgency=low
 +
 +  * New CVS snapshot (and release, but we skipped that ;-))
 +    - patches/01_regparm.diff: Delete.
 +    - Improved XFS support.
 +    - util/grub.d/00_header.in: Add runtime error detection (for gfxterm).
 +    - Fixes problem when chainloading to Vista.
 +  * Fix po-debconf errors.  Thanks Thomas Huriaux.  (Closes: #402972)
 +  * grub.d/05_debian_theme:
 +    - Add runtime error detection.
 +    - Detect/Enable PNG background when it is present.
 +  * control (grub-ieee1275): Remove versioned dependency on powerpc-ibm-utils.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun,  3 Feb 2008 19:31:23 +0100
 +
 +grub2 (1.95+20080201-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +  * presubj: Improve notice.
 +  * patches/01_regparm.diff: Fix CPU context corruption affecting fs/xfs.c.
 +    (Closes: #463081, #419766, #462159)
 +  * patches/02_libgcc_powerpc_hack.diff: Fix FTBFS on powerpc. (Closes: #457491)
 +  * patches/disable_xfs.diff: Actually remove this time...
 +
 + -- Robert Millan <rmh@aybabtu.com>  Fri,  1 Feb 2008 17:06:00 +0100
 +
 +grub2 (1.95+20080128-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Fixes bogus CLAIM problems on Apple firmware.  (Closes: #449135, #422729)
 +    - grub-probe performs sanity checks to make sure our filesystem drivers
 +      are usable.  (Closes: #462449)
 +    - patches/disable_ata.diff: Remove.  ATA module isn't auto-loaded in
 +      rescue floppies now.
 +    - patches/disable_xfs.diff: Remove.  See above (about grub-probe).
 +  * Bring back grub-emu; it can help a lot with debugging feedback.
 +    - control
 +    - rules
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon, 28 Jan 2008 00:01:11 +0100
 +
 +grub2 (1.95+20080116-2) unstable; urgency=low
 +
 +  * grub.d/05_debian_theme: Enable swirlish beauty.
 +  * rules: Obtain debian/legacy/update-grub dynamicaly from GRUB Legacy svn.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 19 Jan 2008 13:16:18 +0100
 +
 +grub2 (1.95+20080116-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - update-grub ignores stale *.dpkg-* files.  (Closes: #422708, #424223)
 +    - LVM/RAID now working properly (except when it affects /boot).
 +      (Closes: #425666)
 +    - Fixes flickery in timeout message.  (Closes: #437275)
 +  * grub-pc.postinst: Use `--no-floppy' whenever possible.  Die, floppies,
 +    die!
 +  * Resync with latest version of GRUB Legacy's update-grub.  This time,
 +    using the $LET_US_TRY_GRUB_2 hack to reuse the same script both for
 +    addition of core.img and its removal.
 +  * grub-*.install: Add update-grub2 stub.  Packages providing /etc/grub.d/
 +    scripts should invoke update-grub2 in both postinst and postrm (whenever
 +    it is found, of course).
 +  * control: Reorganize a bit, including a complete rewrite of the
 +    package descriptions.
 +  * control (grub-ieee1275): Enable for i386/amd64.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 16 Jan 2008 15:00:54 +0100
 +
 +grub2 (1.95+20080107-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Supports ReiserFS.  (Closes: #430742)
 +    - patches/disable_ata.diff: Resync.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon,  7 Jan 2008 12:46:39 +0100
 +
 +grub2 (1.95+20080105-2) unstable; urgency=low
 +
 +  * grub-pc.postinst: Fix covered assumption that menu.lst exists.
 +    (Closes: #459247)
 +  * copyright: Fix copyright/license reference.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun,  6 Jan 2008 18:02:28 +0100
 +
 +grub2 (1.95+20080105-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Fixes install on non-devfs systems with devfs-style paths (ouch).
 +      (Closes: #450709).
 +    - Fixes boot of "Linux" zImages (including memtest86+).  (Closes: #436113).
 +    - Corrects usage message in grub-setup.  (Closes: #458600).
 +    - patches/menu_color.diff: Remove.  Made obsolete by `menu_color_normal'
 +      and `menu_color_highlight' variables.  Add/install grub.d/05_debian_theme
 +      to make use of them.
 +  * Reestructure grub-pc.postinst.  Notably:
 +    - Do not touch menu.lst unless user has confirmed it (via debconf).
 +      (Closes: #459247)
 +    - When we do, keep a backup in /boot/grub/menu.lst_backup_by_grub2_postinst.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat,  5 Jan 2008 17:55:37 +0100
 +
 +grub2 (1.95+20080101-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - patches/disable_xfs.diff: Rewrite in a way that won't collide with
 +      upstream changes so often.
 +    - unifont.hex now processed by upstream.
 +      - rules: Disable build of unifont.pff.
 +      - *.install: Remove build/unifont.pff line.
 +    - patches/menu_color.diff: Change menu color to our traditional blue theme.
 +  * Support new dpkg fields (Homepage, Vcs-Svn, Vcs-Browser).
 +  * patches/disable_ata.diff: Prevent ATA module from being built on i386-pc.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue,  1 Jan 2008 19:45:30 +0100
 +
 +grub2 (1.95+20071101-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - patches/linuxbios.diff: Remove (supported in upstream now).
 +
 + -- Robert Millan <rmh@aybabtu.com>  Thu,  1 Nov 2007 13:18:51 +0100
 +
 +grub2 (1.95+20071004-2) unstable; urgency=low
 +
 +  * Rename debian/grub-of.* to debian/grub-ieee1275.*.
 +  * Add debian/grub-linuxbios.{postinst,dirs,install}.
 +  * rules: Fix/Overrride lintian warnings (unstripped-binary-or-object).
 +  * Remove grub-linuxbios.postinst.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Wed, 10 Oct 2007 23:56:35 +0200
 +
 +grub2 (1.95+20071004-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +  * Add grub-linuxbios package.
 +    - patches/linuxbios.diff
 +    - control
 +    - rules
 +  * Rename grub-of to grub-ieee1275 to match with upstream conventions.
 +    - control
 +    - rules
 +
 + -- Robert Millan <rmh@aybabtu.com>  Thu,  4 Oct 2007 14:42:30 +0200
 +
 +grub2 (1.95+20070829-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Includes fix for parallel builds.
 +  * rules: Append -j flag to $(MAKE) to take advantage of >1 processors.
 +  * Add reference to /usr/share/common-licenses.
 +    - debian/copyright
 +    - debian/control (all packages): Add base-files (>= 4.0.1) dependency.
 +
 + -- Robert Millan <rmh@debian.org>  Sat,  1 Sep 2007 19:00:22 +0200
 +
 +grub2 (1.95+20070828-2) unstable; urgency=low
 +
 +  * control (grub-of): Make depends on powerpc-ibm-utils versioned as
 +    >= 1.0.6 (older versions don't have -a flag).
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 28 Aug 2007 23:32:32 +0200
 +
 +grub2 (1.95+20070828-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Adds ntfs support.
 +    - Fixes a pair of issues indirectly breaking grub-probe on powerpc.
 +      (Closes: #431488)
 +    - patches/disable_xfs.diff: Resync.
 +    - copyright: License upgraded to GPLv3.
 +  * control (grub-of Depends): Add powerpc-utils (for nvsetenv) and bc.
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 28 Aug 2007 21:24:14 +0200
 +
 +grub2 (1.95+20070626-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - More fixes to cope with unreadable /.  (Closes: #427289)
 +    - update-grub supports multiple terminals.
 +  * control (Build-Depends): Add genisoimage.
 +  * patches/partmap_fallback.diff: Remove.  It didn't archieve anything as
 +    it also needs support for proper identification of raid / lvm (this is
 +    being worked on).
 +  * patches/disable_xfs.diff: Disable xfs in grub-probe.
 +  * grub-rescue-pc.README.Debian: New.  Explain how to use the rescue
 +    images.
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 26 Jun 2007 08:39:14 +0200
 +
 +grub2 (1.95+20070614-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - update-grub is tollerant to unreadable / (as long as /boot is
 +    accessible). (Closes: #427289)
 +  * grub-pc.postinst: Generate new grub.cfg when menu.lst exists.
 +  * New package grub-rescue-pc.
 +    - control: Add it.
 +    - README.Debian.in: Remove obsolete documentation.
 +    - rules: Build rescue images using grub-mkrescue.
 +    - grub-rescue-pc.dirs: Prepare their directory.
 +    - grub-rescue-pc.install: Install them.
 +  * legacy/update-grub: Fix core.img detection on separate /boot.
 +
 + -- Robert Millan <rmh@debian.org>  Thu, 14 Jun 2007 08:17:21 +0200
 +
 +grub2 (1.95+20070604-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - patches/grub_probe_for_everyone.diff: Remove (merged).
 +    - update-grub exports user-defined GRUB_CMDLINE_LINUX.  (Closes: #425453)
 +    - Fix those nasty powerpc bugs.  (Closes: #422729)
 +
 + -- Robert Millan <rmh@aybabtu.com>  Mon,  4 Jun 2007 21:30:55 +0200
 +
 +grub2 (1.95+20070520-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - LVM / RAID fixes.  (Closes: #423648, #381150)
 +    - Fix memory management bug.  (Closes: #423409)
 +    - patches/efi.diff: Remove (merged).
 +    - patches/grub_probe_for_everyone.diff: Use the new paths for
 +      util/grub-probe.c, util/biosdisk.c, util/getroot.c.  Enable
 +      grub-mkdevicemap.  (Closes: #424985)
 +  * legacy/update-grub: Get rid of all grub-set-default calls.  (Closes: #425054)
 +  * grub-{pc,efi,of}.postinst: Only run update-grub if grub.cfg already exists.
 +  * grub-pc.postinst: Only run GRUB Legacy compat stuff if menu.lst is found.
 +  * patches/partmap_fallback.diff: New.  Implement fallback "pc gpt" for partmap
 +    detection failures.  (Closes: #423022)
 +  * control: Update XS-Vcs-* fields.  Thanks Sam Morris <sam@robots.org.uk>.
 +    (Closes: #425146)
 +  * grub-{pc,efi,of}.{dirs,postinst}: Move unifont.pff to /usr/share/grub.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun, 20 May 2007 11:13:03 +0200
 +
 +grub2 (1.95+20070515-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Fix assumptions about /, /boot and /boot/grub being the same device.
 +    (Closes: #423268, #422459)
 +    - Proper sorting of Linux images.  (Closes: #422580)
 +    - update-grub lets /etc/default/grub override its variables now.
 +    (Closes: #423649)
 +    - update-grub mentions /etc/default/grub in the grub.cfg header.
 +    (Closes: #423651)
 +    - update-grub sets 800x600x16 as the default gfxmode.  (Closes: #422794)
 +    - update-grub runs grub-mkdevicemap before attempting to use grub-probe
 +    (part of #423217)
 +
 +  [ Otavio Salvador ]
 +  * Add support to DEB_BUILD_OPTIONS=noopt. Thanks to Sam Morris
 +    <sam@robots.org.uk> for the patch. (Closes: #423005)
 +  * Add Robert Millan as uploader.
 +  * Change build-dependency from liblzo-dev to liblzo2-dev. (Closes: #423358)
 +
 +  [ Robert Millan ]
 +  * grub-pc.postinst:
 +    - Remove /boot/grub/device.map before running grub-install.
 +      (Closes: #422851)
 +    - Always run update-grub after grub-install. (part of #423217)
 +    - Use grub-mkdevicemap instead of removing device.map, since update-grub
 +      needs it but grub-install is not run unconditionaly.
 +    - Redirect grub-install invocation to /dev/null, since it can mislead
 +      users into thinking that MBR was overwritten.  (part of #423217)
 +  * default/grub: Stop exporting the variables (update-grub does that now).
 +  * Misc EFI fixes, including new grub-install.
 +    - patches/efi.diff: New.
 +    - patches/grub_probe_for_everyone.diff: Move some bits to efi.diff.
 +    - grub-efi.install: Stop installing dummy grub-install.
 +    - grub-install: Remove.
 +  * grub-pc.postinst: Avoid generating core.img when menu.lst is not present,
 +    to avoid duplicated work (this is specialy important for d-i).  (part of
 +    #423217).
 +  * See multiple references above.  (Closes: #423217)
 +  * grub-{pc,efi,of}.{dirs,install}: Install presubj in the right directory
 +    to make it work again (oops).
 +  * Add reportbug script to gather debugging information.  (Closes: #423218)
 +    - script: New.
 +    - grub-{pc,efi,of}.install: Install it.
 +  * Install the reportbug scripts for grub2 too, since users might still use
 +    it for bugfiling.
 +    - grub2.dirs
 +    - grub2.install
 +  * Fix some lintian warnings.
 +    - control (grub2): Depend on debconf.
 +    - README.Debian.in: Fix mispell.
 +    - grub2.templates: Remove extra dot.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Tue, 15 May 2007 22:08:53 +0200
 +
 +grub2 (1.95+20070507-1) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * New CVS snapshot.
 +    - patches/build_neq_src.diff: Remove (merged).
 +  * Fix debhelper files to ensure each package gets the right thing.
 +  * Enable gfxterm/unifont support.
 +  * On grub-pc, if there's no core.img setup, create one (but do not
 +    risk writing to MBR).
 +  * On grub-pc, if menu.lst is found, regenerate it to include our
 +    core.img.
 +
 +  [ Otavio Salvador ]
 +  * Move debian/update-grub to debian/legacy/update-grub otherwise the
 +    source gets messy.
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Mon, 07 May 2007 18:48:14 -0300
 +
 +grub2 (1.95+20070505.1-3) unstable; urgency=low
 +
 +  * Split postinst into grub2.postinst (with the transition warning) and
 +    postinst.in, with update-grub invocation for grub-{pc,efi,of}.
 +    - postinst.in
 +    - grub2.postinst
 +    - rules
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun,  6 May 2007 01:20:04 +0200
 +
 +grub2 (1.95+20070505.1-2) unstable; urgency=low
 +
 +  * Add EFI build of GRUB.
 +  - control: Restructure to provide 3 packages: grub-pc (x86),
 +    grub-efi (x86) and grub-of (powerpc).
 +  - rules: Handle a separate build for each package.
 +  - patches/build_neq_src.diff: Fix builddir == srcdir assumptions.
 +  - patches/grub_probe_for_everyone.diff: New (superceds
 +    powerpc_probe.diff).  Enable grub-probe on powerpc and i386-efi.
 +  - grub-install: Dummy informational grub-install for EFI.
 +  - grub-efi.install: Installs it.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sun,  6 May 2007 00:23:56 +0200
 +
 +grub2 (1.95+20070505.1-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +  * patches/powerpc_probe.diff: Add partmap/gpt.c to grub-probe.
 +  * control (Architecture): Temporarily disable powerpc.  Sorry, but runtime
 +    is currently broken and we don't have the hardware to debug it.  Will be
 +    re-enabled in next upload.
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat,  5 May 2007 21:52:49 +0200
 +
 +grub2 (1.95+20070505-1) unstable; urgency=low
 +
 +  * New CVS snapshot.
 +    - Improved grub.cfg parser.  (Closes: #381215)
 +    - patches/fix-grub-install.diff: Remove (merged).
 +    - control (Build-Depends): Remove libncurses5-dev (no longer needed).
 +    - provides update-grub2.  (Closes: #419151)
 +    - Supports GPT in PC/BIOS systems.  (Closes: #409073)
 +  * control (Build-Depends): Add gcc-multilib to fix FTBFS.
 +  * control (Description): Make it less scary, and more informative.
 +  * postinst: Run update-grub to ensure the latest improvements always are
 +    applied.
 +  * patches/powerpc_probe.diff: Attempt at making grub-probe build/install
 +    on powerpc (and hopefuly update-grub).
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat,  5 May 2007 01:49:07 +0200
 +
 +grub2 (1.95-5) unstable; urgency=low
 +
 +  * Fix FTBFS on kFreeBSD. Thanks to Aurelien Jarno <aurel32@debian.org>
 +    by providing the patch. Closes: #416408
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Fri, 30 Mar 2007 19:20:48 -0300
 +
 +grub2 (1.95-4) unstable; urgency=low
 +
 +  * Fix powerpc grub-install binary path. Closes: #402838
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Thu, 22 Mar 2007 23:45:56 -0300
 +
 +grub2 (1.95-3) unstable; urgency=low
 +
 +  [ Christian Perrier ]
 +  * Switch to po-debconf for debconf templates. Closes: #402972
 +  * Depend on ${misc:Depends} and not "debconf" to allow cdebconf to be used
 +  * Debconf translations:
 +    - French
 +    - Czech. Closes: #413327
 +    - Galician. Closes: #413323
 +    - Swedish. Closes: #413325
 +    - Portuguese. Closes: #413332
 +    - German. Closes: #413365
 +    - Tamil. Closes: #413478
 +    - Russian. Closes: #413542
 +    - Italian. Closes: #413904
 +    - Romanian. Closes: #414443
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Tue, 20 Mar 2007 23:46:38 -0300
 +
 +grub2 (1.95-2) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * update-grub: Fix for Xen hypervisor entries, thanks Aaron Schrab.
 +    (Closes: #394706)
 +  * Transition to new numbering scheme for partitions. (Closes: #395019)
 +    - update-grub: Don't substract 1 when converting partition device names to
 +      grub drives.
 +    - Add debconf warning explaining the situation.
 +  * Rewrite Architecture line back to hardcoded list :(.  (Closes: #398060)
 +
 + -- Otavio Salvador <otavio@debian.org>  Mon, 11 Dec 2006 05:08:41 -0200
 +
 +grub2 (1.95-1) unstable; urgency=low
 +
 +  * New upstream release.
 +    - patches/03_revert_partition_numbering.diff: Delete (obsoleted).
 +
 + -- Robert Millan <rmh@aybabtu.com>  Sat, 14 Oct 2006 21:19:21 +0200
 +
 +grub2 (1.94+20061003-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +
 +  [ Otavio Salvador ]
 +  * Change debhelper compatibility mode to 5:
 +    - debian/compat: setted to 5;
 +  * control (Build-Depends): Add lib32ncurses5-dev for ppc64.
 +    Closes: #389873
 +  * Set urgency=high since it's experimental stuff and tagged likewise. It
 +    also solved a serious bug on PowerPC that leave users with a black
 +    screen.
 +
 +  [ Robert Millan ]
 +  * control (Depends):  Add powerpc-ibm-utils for powerpc/ppc64.
 +    (Closes: #372186)
 +
 + -- Otavio Salvador <otavio@debian.org>  Tue,  3 Oct 2006 16:49:32 -0300
 +
 +grub2 (1.94+20060926-1) unstable; urgency=high
 +
 +  * New CVS snapshot.
 +    - Command-line editting fix (Closes: #381214).
 +    - Fixes runtime breakage on amd64 (not in BTS).
 +    - Delete a few patches (merged).
 +
 +  [ Robert Millan ]
 +  * Set urgency=high.  Might seem like a rush, but it can't possibly be worse than
 +    1.94-5 (broken on systems that use udev, broken on amd64...).
 +  * Pure ppc64 support.
 +    - control (Architecture): Add any-ppc64.
 +    - control (Build-Depends): Add libc6-dev-powerpc [ppc64].
 +  * rules: Remove moddep.lst install command (no longer needed).
 +  * patches/03_revert_partition_numbering.diff:  New.  Revert a commit that
 +    broke grub-probefs.
 +  * Add bug template to encourage sending upstream stuff directly to
 +    upstream.
 +    - presubj: New.
 +
 +  [ Otavio Salvador ]
 +  * Add XS-X-Vcs-Svn on control file and point it to our current svn
 +    repository.
 +  * Add cvs-snapshot to rules.
 +
 + -- Otavio Salvador <otavio@debian.org>  Tue, 26 Sep 2006 16:14:36 -0300
 +
 +grub2 (1.94-6) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * update-grub:  Set interpreter to /bin/bash to cope with non-POSIX
 +    extensions.  (mentioned in #361929)
 +  * patches/03_avoid_recursing_into_dot_static.diff:  New.  Avoid recursing into
 +    dotdirs (e.g. ".static").
 +  * patches/04_mkdevicemap_dont_assume_floppies.diff:  New.  Don't assume
 +    /dev/fd0 exists when generating device.map.
 +
 + -- Otavio Salvador <otavio@debian.org>  Thu, 14 Sep 2006 16:07:30 -0300
 +
 +grub2 (1.94-5) unstable; urgency=low
 +
 +  [ Robert Millan ]
 +  * control (Build-Depends): s/any-amd64/amd64 kfreebsd-amd64/g (this seems to
 +    confuse buildds).
 +  * 02_not_remove_menu_lst.patch: New patch.  Skip menu.lst removal in
 +    grub-install.  (Closes: #372934)
 +
 + -- Otavio Salvador <otavio@debian.org>  Sun, 20 Aug 2006 12:02:13 -0300
 +
 +grub2 (1.94-4) unstable; urgency=low
 +
 +  [ Otavio Salvador ]
 +  * 01_fix_amd64_building.patch: dropped since it now supports amd64
 +    native building.
 +  * Remove convert_kernel26 usage since it's not necessary anymore and due
 +    initramfs-tools changes it's bug too.
 +  
 +  [ Robert Millan ]
 +  * Fork update-grub from grub legacy, and tweak a few commands in output to
 +    make it work for grub2.
 +  * Update README.Debian.in with more recent (and easier) install instructions.
 +  * Add grub to Conflicts/Replaces.  Too many commands with the same name,
 +    even if they don't use the same path yet (but will likely do in the
 +    future, see #361929).
 +  * Get rid of control.in, which I introduced in 0.6+20040805-1 and turned out
 +    to be an endless source of problems (and forbidden by policy as well).
 +  * Fix FTBFS on amd64. Really closes: #372548.
 +
 + -- Otavio Salvador <otavio@debian.org>  Fri, 18 Aug 2006 15:38:25 -0300
 +
 +grub2 (1.94-3) unstable; urgency=low
 +
 +  * Fix FTBFS in amd64. Closes: 372548
 +
 + -- Otavio Salvador <otavio@debian.org>  Sat, 10 Jun 2006 19:57:01 -0300
 +
 +grub2 (1.94-2) unstable; urgency=low
 +
 +  * Update grub images paths in README.Debian
 +  * 01_fix_grub-install.patch: add to fix a problem with PowerPC
 +    installation. Refs: #371069
 +  * Fix FTBFS in amd64. Closes: #370803
 +
 + -- Otavio Salvador <otavio@debian.org>  Fri,  9 Jun 2006 09:29:40 -0300
 +
 +grub2 (1.94-1) unstable; urgency=low
 +
 +  * New upstream release.
 +    - Fix powerpc building. Closes: #370259
 +    - 01_fix_grub-install.patch: merged upstream.
 +    - Moved modules to /usr/lib/grub since they are architecture 
 +      dependent.
 +  * Leave CDBS set debhelper compatibility level.
 +  * Allow amd64 build to happen. Closes: #364956
 +  * Enforce building in 32bits while running in x86_64 machines.
 +  * Update Standards version to 3.7.2. No changes need.
 +
 + -- Otavio Salvador <otavio@debian.org>  Mon,  5 Jun 2006 12:49:09 -0300
 +
 +grub2 (1.93-1) unstable; urgency=low
 +
 +  * New upstream release.
 +    - Added support to PowerPC. Closes: #357853
 +    - 01_fix_grub-install.patch: rediff.
 +  * Update Standards version to 3.6.2. No changes need.
 +  * Start to use new dpkg architecture definition. Closes: #360134
 +
 + -- Otavio Salvador <otavio@debian.org>  Sat,  1 Apr 2006 10:07:17 -0300
 +
 +grub2 (1.92-2) unstable; urgency=low
 +
 +  * Add bison on build-depends field. Closes: #346178
 +  * Add more fixes in 01_fix_grub-install.patch. Closes: #346177
 +
 + -- Otavio Salvador <otavio@debian.org>  Fri,  6 Jan 2006 09:48:08 -0200
 +
 +grub2 (1.92-1) unstable; urgency=low
 +
 +  * New upstream release.
 +    - Add support for GPT partition table format.
 +    - Add a new command "play" to play an audio file on PC.
 +    - Add support for Linux/ADFS partition table format.
 +    - Add support for BASH-like scripting.
 +    - Add support for Apple HFS+ filesystems.
 +  * 01_fix_grub-install.patch: Added. Fix grub-install to use
 +    /bin/grub-mkimage instead of /sbin/grub-mkimage. Closes: #338824
 +  * Do not use CDBS tarball mode anymore. Closes: #344272  
 +  
 + -- Otavio Salvador <otavio@debian.org>  Thu,  5 Jan 2006 15:20:40 -0200
 +
 +grub2 (1.91-0) unstable; urgency=low
 +
 +  * New upstream release. Closes: #331211
 +  * debian/watch: added.
 +  * debian/control.in, debian/control: Add libncurses5-dev in
 +    Build-Depends. Closes: #304638
 +  * Remove Robert Millan as uploader;
 +  * Add myself as uploader;
 +
 + -- Otavio Salvador <otavio@debian.org>  Sat, 12 Nov 2005 16:35:18 -0200
 +
 +grub2 (0.6+20050203-2) unstable; urgency=low
 +
 +  * Disable for powerpc.  Reportedly it fails to boot.
 +
 + -- Robert Millan <rmh@debian.org>  Fri,  4 Feb 2005 01:52:09 +0100
 +
 +grub2 (0.6+20050203-1) unstable; urgency=low
 +
 +  * New upstream snapshot.
 +  * Install moddep.lst properly in a cpu-independant way. (Closes: #264115)
 +  * Use cdbs debian/control autogeneration.
 +    - Set DEB_AUTO_UPDATE_DEBIAN_CONTROL = yes.
 +    - Move control to control.in.
 +    - Add a @cdbs@ tag and replace Architecture with Cpu/System.
 +  * control.in (Build-Depends):  Add ruby.
 +
 + -- Robert Millan <rmh@debian.org>  Thu,  3 Feb 2005 22:33:39 +0100
 +
 +grub2 (0.6+20040805-1) unstable; urgency=low
 +
 +  * New upstream snapshot.
 +  * Uploading to unstable so that powerpc users can be blessed by GRUB too.
 +  * Use type-handling to generate dpkg arch list.
 +    - control.in
 +    - rules
 +
 + -- Robert Millan <rmh@debian.org>  Thu,  5 Aug 2004 20:50:16 +0200
 +
 +grub2 (0.6+20040502-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +    - Fix FTBFS on powerpc.
 +
 + -- Robert Millan <rmh@debian.org>  Sun,  2 May 2004 18:16:29 +0200
 +
 +grub2 (0.6+20040429-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +    - control (Architecture): Add powerpc.
 +
 + -- Robert Millan <rmh@debian.org>  Thu, 29 Apr 2004 20:41:31 +0200
 +
 +grub2 (0.6+20031125-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +    - patches/multiboot.diff: Nuked.
 +    - install,docs: Update directory name.
 +  * control (Maintainer): Set to pkg-grub-devel mailing list.
 +  * control (Uploaders): Add myself.
 +  * control (Architecture): Add freebsd-i386 and netbsd-i386.
 +
 + -- Robert Millan <rmh@debian.org>  Tue, 25 Nov 2003 23:48:18 +0100
 +
 +grub2 (0.6+20031114-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +    - README.Debian: s/fat/ext2/g (We now have ext2fs support).
 +  * Add multiboot support, thanks to Jeroen Dekkers for his patch.
 +    - patches/multiboot.diff: New.
 +    - control (Architecture): Add hurd-i386 (which needed multiboot).
 +  * Rename package to grub2 (to follow upstream tendency).
 +    - control: Ditto.
 +    - README.Debian: Likewise.
 +  * Switch to tarball mode.
 +    - rules: Ditto.
 +    - docs: Prefix paths in order to workaround dh_installdocs bug.
 +    - install: Likewise, but not because of bug (should be in rules, actualy).
 +  * Fix FTBFS. (Closes: #213868)
 +    - control (Build-Depends): Add autoconf.
 +    - control (Build-Conflicts): Add autoconf2.13.
 +
 + -- Robert Millan <rmh@debian.org>  Fri, 14 Nov 2003 13:16:12 +0100
 +
 +pupa (0.6+20031008-1) experimental; urgency=low
 +
 +  * New upstream snapshot.
 +  * Uploading to experimental.
 +  * debian/control: Add Jason Thomas to Uploaders.
 +
 + -- Robert Millan <rmh@debian.org>  Wed,  8 Oct 2003 13:22:50 +0000
 +
 +pupa (0.6+20030915-1) unstable; urgency=low
 +
 +  * Initial Release. (Closes: #211030)
 +
 + -- Robert Millan <rmh@debian.org>  Mon, 15 Sep 2003 14:58:42 +0000
index cb4669c50e59965afca095c6dcb9d35910216348,0000000000000000000000000000000000000000..342de5f6aaeef912f5858459b547dce80c0e997f
mode 100644,000000..100644
--- /dev/null
@@@ -1,1117 -1,0 +1,1117 @@@
-  grub-core/net/bootp.c | 908 +++++++++++++++++++++++++++++++++++++++++-
-  grub-core/net/ip.c    |  39 ++
 +From 7c754fff55f261e39d25da72413213600b2577c3 Mon Sep 17 00:00:00 2001
 +From: Michael Chang <mchang@suse.com>
 +Date: Thu, 27 Oct 2016 17:41:04 -0400
 +Subject: bootp: New net_bootp6 command
 +
 +Implement new net_bootp6 command for IPv6 network auto configuration via the
 +DHCPv6 protocol (RFC3315).
 +
 +Signed-off-by: Michael Chang <mchang@suse.com>
 +Signed-off-by: Ken Lin <ken.lin@hpe.com>
 +
 +Patch-Name: bootp_new_net_bootp6_command.patch
 +---
++ grub-core/net/bootp.c | 908 +++++++++++++++++++++++++++++++++++++++++++++++++-
++ grub-core/net/ip.c    |  39 +++
 + include/grub/net.h    |  72 ++++
 + 3 files changed, 1018 insertions(+), 1 deletion(-)
 +
 +diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
 +index 9e2fdb795..172528ee8 100644
 +--- a/grub-core/net/bootp.c
 ++++ b/grub-core/net/bootp.c
 +@@ -24,6 +24,98 @@
 + #include <grub/net/netbuff.h>
 + #include <grub/net/udp.h>
 + #include <grub/datetime.h>
 ++#include <grub/time.h>
 ++#include <grub/list.h>
 ++
 ++static int
 ++dissect_url (const char *url, char **proto, char **host, char **path)
 ++{
 ++  const char *p, *ps;
 ++  grub_size_t l;
 ++
 ++  *proto = *host = *path = NULL;
 ++  ps = p = url;
 ++
 ++  while ((p = grub_strchr (p, ':')))
 ++    {
 ++      if (grub_strlen (p) < sizeof ("://") - 1)
 ++     break;
 ++      if (grub_memcmp (p, "://", sizeof ("://") - 1) == 0)
 ++     {
 ++       l = p - ps;
 ++       *proto = grub_malloc (l + 1);
 ++       if (!*proto)
 ++         {
 ++           grub_print_error ();
 ++           return 0;
 ++         }
 ++
 ++       grub_memcpy (*proto, ps, l);
 ++       (*proto)[l] = '\0';
 ++       p +=  sizeof ("://") - 1;
 ++       break;
 ++     }
 ++      ++p;
 ++    }
 ++
 ++  if (!*proto)
 ++    {
 ++      grub_dprintf ("bootp", "url: %s is not valid, protocol not found\n", url);
 ++      return 0;
 ++    }
 ++
 ++  ps = p;
 ++  p = grub_strchr (p, '/');
 ++
 ++  if (!p)
 ++    {
 ++      grub_dprintf ("bootp", "url: %s is not valid, host/path not found\n", url);
 ++      grub_free (*proto);
 ++      *proto = NULL;
 ++      return 0;
 ++    }
 ++
 ++  l = p - ps;
 ++
 ++  if (l > 2 && ps[0] == '[' && ps[l - 1] == ']')
 ++    {
 ++      *host = grub_malloc (l - 1);
 ++      if (!*host)
 ++     {
 ++       grub_print_error ();
 ++       grub_free (*proto);
 ++       *proto = NULL;
 ++       return 0;
 ++     }
 ++      grub_memcpy (*host, ps + 1, l - 2);
 ++      (*host)[l - 2] = 0;
 ++    }
 ++  else
 ++    {
 ++      *host = grub_malloc (l + 1);
 ++      if (!*host)
 ++     {
 ++       grub_print_error ();
 ++       grub_free (*proto);
 ++       *proto = NULL;
 ++       return 0;
 ++     }
 ++      grub_memcpy (*host, ps, l);
 ++      (*host)[l] = 0;
 ++    }
 ++
 ++  *path = grub_strdup (p);
 ++  if (!*path)
 ++    {
 ++      grub_print_error ();
 ++      grub_free (*host);
 ++      grub_free (*proto);
 ++      *host = NULL;
 ++      *proto = NULL;
 ++      return 0;
 ++    }
 ++  return 1;
 ++}
 + 
 + static void
 + parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
 +@@ -270,6 +362,578 @@ grub_net_configure_by_dhcp_ack (const char *name,
 +   return inter;
 + }
 + 
 ++/* The default netbuff size for sending DHCPv6 packets which should be
 ++   large enough to hold the information */
 ++#define GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE 512
 ++
 ++struct grub_dhcp6_options
 ++{
 ++  grub_uint8_t *client_duid;
 ++  grub_uint16_t client_duid_len;
 ++  grub_uint8_t *server_duid;
 ++  grub_uint16_t server_duid_len;
 ++  grub_uint32_t iaid;
 ++  grub_uint32_t t1;
 ++  grub_uint32_t t2;
 ++  grub_net_network_level_address_t *ia_addr;
 ++  grub_uint32_t preferred_lifetime;
 ++  grub_uint32_t valid_lifetime;
 ++  grub_net_network_level_address_t *dns_server_addrs;
 ++  grub_uint16_t num_dns_server;
 ++  char *boot_file_proto;
 ++  char *boot_file_server_ip;
 ++  char *boot_file_path;
 ++};
 ++
 ++typedef struct grub_dhcp6_options *grub_dhcp6_options_t;
 ++
 ++struct grub_dhcp6_session
 ++{
 ++  struct grub_dhcp6_session *next;
 ++  struct grub_dhcp6_session **prev;
 ++  grub_uint32_t iaid;
 ++  grub_uint32_t transaction_id:24;
 ++  grub_uint64_t start_time;
 ++  struct grub_net_dhcp6_option_duid_ll duid;
 ++  struct grub_net_network_level_interface *iface;
 ++
 ++  /* The associated dhcpv6 options */
 ++  grub_dhcp6_options_t adv;
 ++  grub_dhcp6_options_t reply;
 ++};
 ++
 ++typedef struct grub_dhcp6_session *grub_dhcp6_session_t;
 ++
 ++typedef void (*dhcp6_option_hook_fn) (const struct grub_net_dhcp6_option *opt, void *data);
 ++
 ++static void
 ++foreach_dhcp6_option (const struct grub_net_dhcp6_option *opt, grub_size_t size,
 ++                   dhcp6_option_hook_fn hook, void *hook_data);
 ++
 ++static void
 ++parse_dhcp6_iaaddr (const struct grub_net_dhcp6_option *opt, void *data)
 ++{
 ++  grub_dhcp6_options_t dhcp6 = (grub_dhcp6_options_t )data;
 ++
 ++  grub_uint16_t code = grub_be_to_cpu16 (opt->code);
 ++  grub_uint16_t len = grub_be_to_cpu16 (opt->len);
 ++
 ++  if (code == GRUB_NET_DHCP6_OPTION_IAADDR)
 ++    {
 ++      const struct grub_net_dhcp6_option_iaaddr *iaaddr;
 ++      iaaddr = (const struct grub_net_dhcp6_option_iaaddr *)opt->data;
 ++
 ++      if (len < sizeof (*iaaddr))
 ++     {
 ++       grub_dprintf ("bootp", "DHCPv6: code %u with insufficient length %u\n", code, len);
 ++       return;
 ++     }
 ++      if (!dhcp6->ia_addr)
 ++     {
 ++       dhcp6->ia_addr = grub_malloc (sizeof(*dhcp6->ia_addr));
 ++       dhcp6->ia_addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
 ++       dhcp6->ia_addr->ipv6[0] = grub_get_unaligned64 (iaaddr->addr);
 ++       dhcp6->ia_addr->ipv6[1] = grub_get_unaligned64 (iaaddr->addr + 8);
 ++       dhcp6->preferred_lifetime = grub_be_to_cpu32 (iaaddr->preferred_lifetime);
 ++       dhcp6->valid_lifetime = grub_be_to_cpu32 (iaaddr->valid_lifetime);
 ++     }
 ++    }
 ++}
 ++
 ++static void
 ++parse_dhcp6_option (const struct grub_net_dhcp6_option *opt, void *data)
 ++{
 ++  grub_dhcp6_options_t dhcp6 = (grub_dhcp6_options_t)data;
 ++  grub_uint16_t code = grub_be_to_cpu16 (opt->code);
 ++  grub_uint16_t len = grub_be_to_cpu16 (opt->len);
 ++
 ++  switch (code)
 ++    {
 ++      case GRUB_NET_DHCP6_OPTION_CLIENTID:
 ++
 ++     if (dhcp6->client_duid || !len)
 ++       {
 ++         grub_dprintf ("bootp", "Skipped DHCPv6 CLIENTID with length %u\n", len);
 ++         break;
 ++       }
 ++     dhcp6->client_duid = grub_malloc (len);
 ++     grub_memcpy (dhcp6->client_duid, opt->data, len);
 ++     dhcp6->client_duid_len = len;
 ++     break;
 ++
 ++      case GRUB_NET_DHCP6_OPTION_SERVERID:
 ++
 ++     if (dhcp6->server_duid || !len)
 ++       {
 ++         grub_dprintf ("bootp", "Skipped DHCPv6 SERVERID with length %u\n", len);
 ++         break;
 ++       }
 ++     dhcp6->server_duid = grub_malloc (len);
 ++     grub_memcpy (dhcp6->server_duid, opt->data, len);
 ++     dhcp6->server_duid_len = len;
 ++     break;
 ++
 ++      case GRUB_NET_DHCP6_OPTION_IA_NA:
 ++     {
 ++       const struct grub_net_dhcp6_option_iana *ia_na;
 ++       grub_uint16_t data_len;
 ++
 ++       if (dhcp6->iaid || len < sizeof (*ia_na))
 ++         {
 ++           grub_dprintf ("bootp", "Skipped DHCPv6 IA_NA with length %u\n", len);
 ++           break;
 ++         }
 ++       ia_na = (const struct grub_net_dhcp6_option_iana *)opt->data;
 ++       dhcp6->iaid = grub_be_to_cpu32 (ia_na->iaid);
 ++       dhcp6->t1 = grub_be_to_cpu32 (ia_na->t1);
 ++       dhcp6->t2 = grub_be_to_cpu32 (ia_na->t2);
 ++
 ++       data_len = len - sizeof (*ia_na);
 ++       if (data_len)
 ++         foreach_dhcp6_option ((const struct grub_net_dhcp6_option *)ia_na->data, data_len, parse_dhcp6_iaaddr, dhcp6);
 ++     }
 ++     break;
 ++
 ++      case GRUB_NET_DHCP6_OPTION_DNS_SERVERS:
 ++     {
 ++       const grub_uint8_t *po;
 ++       grub_uint16_t ln;
 ++       grub_net_network_level_address_t *la;
 ++
 ++       if (!len || len & 0xf)
 ++         {
 ++           grub_dprintf ("bootp", "Skip invalid length DHCPv6 DNS_SERVERS \n");
 ++           break;
 ++         }
 ++       dhcp6->num_dns_server = ln = len >> 4;
 ++       dhcp6->dns_server_addrs = la = grub_zalloc (ln * sizeof (*la));
 ++
 ++       for (po = opt->data; ln > 0; po += 0x10, la++, ln--)
 ++         {
 ++           la->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
 ++           la->ipv6[0] = grub_get_unaligned64 (po);
 ++           la->ipv6[1] = grub_get_unaligned64 (po + 8);
 ++           la->option = DNS_OPTION_PREFER_IPV6;
 ++         }
 ++     }
 ++     break;
 ++
 ++      case GRUB_NET_DHCP6_OPTION_BOOTFILE_URL:
 ++     dissect_url ((const char *)opt->data,
 ++                   &dhcp6->boot_file_proto,
 ++                   &dhcp6->boot_file_server_ip,
 ++                   &dhcp6->boot_file_path);
 ++     break;
 ++
 ++      default:
 ++     break;
 ++    }
 ++}
 ++
 ++static void
 ++foreach_dhcp6_option (const struct grub_net_dhcp6_option *opt, grub_size_t size, dhcp6_option_hook_fn hook, void *hook_data)
 ++{
 ++  while (size)
 ++    {
 ++      grub_uint16_t code, len;
 ++
 ++      if (size < sizeof (*opt))
 ++     {
 ++       grub_dprintf ("bootp", "DHCPv6: Options stopped with remaining size %" PRIxGRUB_SIZE "\n", size);
 ++       break;
 ++     }
 ++      size -= sizeof (*opt);
 ++      len = grub_be_to_cpu16 (opt->len);
 ++      code = grub_be_to_cpu16 (opt->code);
 ++      if (size < len)
 ++     {
 ++       grub_dprintf ("bootp", "DHCPv6: Options stopped at out of bound length %u for option %u\n", len, code);
 ++       break;
 ++     }
 ++      if (!len)
 ++     {
 ++       grub_dprintf ("bootp", "DHCPv6: Options stopped at zero length option %u\n", code);
 ++       break;
 ++     }
 ++      else
 ++     {
 ++       if (hook)
 ++         hook (opt, hook_data);
 ++       size -= len;
 ++       opt = (const struct grub_net_dhcp6_option *)((grub_uint8_t *)opt + len + sizeof (*opt));
 ++     }
 ++    }
 ++}
 ++
 ++static grub_dhcp6_options_t
 ++grub_dhcp6_options_get (const struct grub_net_dhcp6_packet *v6h,
 ++                     grub_size_t size)
 ++{
 ++  grub_dhcp6_options_t options;
 ++
 ++  if (size < sizeof (*v6h))
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_RANGE, N_("DHCPv6 packet size too small"));
 ++      return NULL;
 ++    }
 ++
 ++  options = grub_zalloc (sizeof(*options));
 ++  if (!options)
 ++    return NULL;
 ++
 ++  foreach_dhcp6_option ((const struct grub_net_dhcp6_option *)v6h->dhcp_options,
 ++                    size - sizeof (*v6h), parse_dhcp6_option, options);
 ++
 ++  return options;
 ++}
 ++
 ++static void
 ++grub_dhcp6_options_free (grub_dhcp6_options_t options)
 ++{
 ++  if (options->client_duid)
 ++    grub_free (options->client_duid);
 ++  if (options->server_duid)
 ++    grub_free (options->server_duid);
 ++  if (options->ia_addr)
 ++    grub_free (options->ia_addr);
 ++  if (options->dns_server_addrs)
 ++    grub_free (options->dns_server_addrs);
 ++  if (options->boot_file_proto)
 ++    grub_free (options->boot_file_proto);
 ++  if (options->boot_file_server_ip)
 ++    grub_free (options->boot_file_server_ip);
 ++  if (options->boot_file_path)
 ++    grub_free (options->boot_file_path);
 ++
 ++  grub_free (options);
 ++}
 ++
 ++static grub_dhcp6_session_t grub_dhcp6_sessions;
 ++#define FOR_DHCP6_SESSIONS(var) FOR_LIST_ELEMENTS (var, grub_dhcp6_sessions)
 ++
 ++static void
 ++grub_net_configure_by_dhcp6_info (const char *name,
 ++       struct grub_net_card *card,
 ++       grub_dhcp6_options_t dhcp6,
 ++       int is_def,
 ++       int flags,
 ++       struct grub_net_network_level_interface **ret_inf)
 ++{
 ++  grub_net_network_level_netaddress_t netaddr;
 ++  struct grub_net_network_level_interface *inf;
 ++
 ++  if (dhcp6->ia_addr)
 ++    {
 ++      inf = grub_net_add_addr (name, card, dhcp6->ia_addr, &card->default_address, flags);
 ++
 ++      netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
 ++      netaddr.ipv6.base[0] = dhcp6->ia_addr->ipv6[0];
 ++      netaddr.ipv6.base[1] = 0;
 ++      netaddr.ipv6.masksize = 64;
 ++      grub_net_add_route (name, netaddr, inf);
 ++
 ++      if (ret_inf)
 ++     *ret_inf = inf;
 ++    }
 ++
 ++  if (dhcp6->dns_server_addrs)
 ++    {
 ++      grub_uint16_t i;
 ++
 ++      for (i = 0; i < dhcp6->num_dns_server; ++i)
 ++     grub_net_add_dns_server (dhcp6->dns_server_addrs + i);
 ++    }
 ++
 ++  if (dhcp6->boot_file_path)
 ++    grub_env_set_net_property (name, "boot_file", dhcp6->boot_file_path,
 ++                       grub_strlen (dhcp6->boot_file_path));
 ++
 ++  if (is_def && dhcp6->boot_file_server_ip)
 ++    {
 ++      grub_net_default_server = grub_strdup (dhcp6->boot_file_server_ip);
 ++      grub_env_set ("net_default_interface", name);
 ++      grub_env_export ("net_default_interface");
 ++    }
 ++}
 ++
 ++static void
 ++grub_dhcp6_session_add (struct grub_net_network_level_interface *iface,
 ++                     grub_uint32_t iaid)
 ++{
 ++  grub_dhcp6_session_t se;
 ++  struct grub_datetime date;
 ++  grub_err_t err;
 ++  grub_int32_t t = 0;
 ++
 ++  se = grub_malloc (sizeof (*se));
 ++
 ++  err = grub_get_datetime (&date);
 ++  if (err || !grub_datetime2unixtime (&date, &t))
 ++    {
 ++      grub_errno = GRUB_ERR_NONE;
 ++      t = 0;
 ++    }
 ++
 ++  se->iface = iface;
 ++  se->iaid = iaid;
 ++  se->transaction_id = t;
 ++  se->start_time = grub_get_time_ms ();
 ++  se->duid.type = grub_cpu_to_be16_compile_time (3) ;
 ++  se->duid.hw_type = grub_cpu_to_be16_compile_time (1);
 ++  grub_memcpy (&se->duid.hwaddr, &iface->hwaddress.mac, sizeof (se->duid.hwaddr));
 ++  se->adv = NULL;
 ++  se->reply = NULL;
 ++  grub_list_push (GRUB_AS_LIST_P (&grub_dhcp6_sessions), GRUB_AS_LIST (se));
 ++}
 ++
 ++static void
 ++grub_dhcp6_session_remove (grub_dhcp6_session_t se)
 ++{
 ++  grub_list_remove (GRUB_AS_LIST (se));
 ++  if (se->adv)
 ++    grub_dhcp6_options_free (se->adv);
 ++  if (se->reply)
 ++    grub_dhcp6_options_free (se->reply);
 ++  grub_free (se);
 ++}
 ++
 ++static void
 ++grub_dhcp6_session_remove_all (void)
 ++{
 ++  grub_dhcp6_session_t se;
 ++
 ++  FOR_DHCP6_SESSIONS (se)
 ++    {
 ++      grub_dhcp6_session_remove (se);
 ++      se = grub_dhcp6_sessions;
 ++    }
 ++}
 ++
 ++static grub_err_t
 ++grub_dhcp6_session_configure_network (grub_dhcp6_session_t se)
 ++{
 ++  char *name;
 ++
 ++  name = grub_xasprintf ("%s:dhcp6", se->iface->card->name);
 ++  if (!name)
 ++    return grub_errno;
 ++
 ++  grub_net_configure_by_dhcp6_info (name, se->iface->card, se->reply, 1, 0, 0);
 ++  grub_free (name);
 ++
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 ++static grub_err_t
 ++grub_dhcp6_session_send_request (grub_dhcp6_session_t se)
 ++{
 ++  struct grub_net_buff *nb;
 ++  struct grub_net_dhcp6_option *opt;
 ++  struct grub_net_dhcp6_packet *v6h;
 ++  struct grub_net_dhcp6_option_iana *ia_na;
 ++  struct grub_net_dhcp6_option_iaaddr *iaaddr;
 ++  struct udphdr *udph;
 ++  grub_net_network_level_address_t multicast;
 ++  grub_net_link_level_address_t ll_multicast;
 ++  grub_uint64_t elapsed;
 ++  struct grub_net_network_level_interface *inf = se->iface;
 ++  grub_dhcp6_options_t dhcp6 = se->adv;
 ++  grub_err_t err = GRUB_ERR_NONE;
 ++
 ++  multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
 ++  multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48);
 ++  multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL);
 ++
 ++  err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast);
 ++  if (err)
 ++    return err;
 ++
 ++  nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE);
 ++
 ++  if (!nb)
 ++    return grub_errno;
 ++
 ++  err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE);
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++
 ++  err = grub_netbuff_push (nb, dhcp6->client_duid_len + sizeof (*opt));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++  opt = (struct grub_net_dhcp6_option *)nb->data;
 ++  opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID);
 ++  opt->len = grub_cpu_to_be16 (dhcp6->client_duid_len);
 ++  grub_memcpy (opt->data, dhcp6->client_duid , dhcp6->client_duid_len);
 ++
 ++  err = grub_netbuff_push (nb, dhcp6->server_duid_len + sizeof (*opt));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++  opt = (struct grub_net_dhcp6_option *)nb->data;
 ++  opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_SERVERID);
 ++  opt->len = grub_cpu_to_be16 (dhcp6->server_duid_len);
 ++  grub_memcpy (opt->data, dhcp6->server_duid , dhcp6->server_duid_len);
 ++
 ++  err = grub_netbuff_push (nb, sizeof (*ia_na) + sizeof (*opt));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++
 ++  if (dhcp6->ia_addr)
 ++    {
 ++      err = grub_netbuff_push (nb, sizeof(*iaaddr) + sizeof (*opt));
 ++      if (err)
 ++     {
 ++       grub_netbuff_free (nb);
 ++       return err;
 ++     }
 ++    }
 ++  opt = (struct grub_net_dhcp6_option *)nb->data;
 ++  opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA);
 ++  opt->len = grub_cpu_to_be16 (sizeof (*ia_na));
 ++  if (dhcp6->ia_addr)
 ++    opt->len += grub_cpu_to_be16 (sizeof(*iaaddr) + sizeof (*opt));
 ++
 ++  ia_na = (struct grub_net_dhcp6_option_iana *)opt->data;
 ++  ia_na->iaid = grub_cpu_to_be32 (dhcp6->iaid);
 ++
 ++  ia_na->t1 = grub_cpu_to_be32 (dhcp6->t1);
 ++  ia_na->t2 = grub_cpu_to_be32 (dhcp6->t2);
 ++
 ++  if (dhcp6->ia_addr)
 ++    {
 ++      opt = (struct grub_net_dhcp6_option *)ia_na->data;
 ++      opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR);
 ++      opt->len = grub_cpu_to_be16 (sizeof (*iaaddr));
 ++      iaaddr = (struct grub_net_dhcp6_option_iaaddr *)opt->data;
 ++      grub_set_unaligned64 (iaaddr->addr, dhcp6->ia_addr->ipv6[0]);
 ++      grub_set_unaligned64 (iaaddr->addr + 8, dhcp6->ia_addr->ipv6[1]);
 ++
 ++      iaaddr->preferred_lifetime = grub_cpu_to_be32 (dhcp6->preferred_lifetime);
 ++      iaaddr->valid_lifetime = grub_cpu_to_be32 (dhcp6->valid_lifetime);
 ++    }
 ++
 ++  err = grub_netbuff_push (nb, sizeof (*opt) + 2 * sizeof (grub_uint16_t));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++
 ++  opt = (struct grub_net_dhcp6_option*) nb->data;
 ++  opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ORO);
 ++  opt->len = grub_cpu_to_be16_compile_time (2 * sizeof (grub_uint16_t));
 ++  grub_set_unaligned16 (opt->data, grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL));
 ++  grub_set_unaligned16 (opt->data + 2, grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS));
 ++
 ++  err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++  opt = (struct grub_net_dhcp6_option*) nb->data;
 ++  opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME);
 ++  opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t));
 ++
 ++  /* the time is expressed in hundredths of a second */
 ++  elapsed = grub_divmod64 (grub_get_time_ms () - se->start_time, 10, 0);
 ++
 ++  if (elapsed > 0xffff)
 ++    elapsed = 0xffff;
 ++
 ++  grub_set_unaligned16 (opt->data,  grub_cpu_to_be16 ((grub_uint16_t)elapsed));
 ++
 ++  err = grub_netbuff_push (nb, sizeof (*v6h));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++
 ++  v6h = (struct grub_net_dhcp6_packet *) nb->data;
 ++  v6h->message_type = GRUB_NET_DHCP6_REQUEST;
 ++  v6h->transaction_id = se->transaction_id;
 ++
 ++  err = grub_netbuff_push (nb, sizeof (*udph));
 ++  if (err)
 ++    {
 ++      grub_netbuff_free (nb);
 ++      return err;
 ++    }
 ++
 ++  udph = (struct udphdr *) nb->data;
 ++  udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT);
 ++  udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT);
 ++  udph->chksum = 0;
 ++  udph->len = grub_cpu_to_be16 (nb->tail - nb->data);
 ++
 ++  udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP,
 ++                                              &inf->address,
 ++                                              &multicast);
 ++  err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb,
 ++                              GRUB_NET_IP_UDP);
 ++
 ++  grub_netbuff_free (nb);
 ++
 ++  return err;
 ++}
 ++
 ++struct grub_net_network_level_interface *
 ++grub_net_configure_by_dhcpv6_reply (const char *name,
 ++     struct grub_net_card *card,
 ++     grub_net_interface_flags_t flags,
 ++     const struct grub_net_dhcp6_packet *v6h,
 ++     grub_size_t size,
 ++     int is_def,
 ++     char **device, char **path)
 ++{
 ++  struct grub_net_network_level_interface *inf;
 ++  grub_dhcp6_options_t dhcp6;
 ++
 ++  dhcp6 = grub_dhcp6_options_get (v6h, size);
 ++  if (!dhcp6)
 ++    {
 ++      grub_print_error ();
 ++      return NULL;
 ++    }
 ++
 ++  grub_net_configure_by_dhcp6_info (name, card, dhcp6, is_def, flags, &inf);
 ++
 ++  if (device && dhcp6->boot_file_proto && dhcp6->boot_file_server_ip)
 ++    {
 ++      *device = grub_xasprintf ("%s,%s", dhcp6->boot_file_proto, dhcp6->boot_file_server_ip);
 ++      grub_print_error ();
 ++    }
 ++  if (path && dhcp6->boot_file_path)
 ++    {
 ++      *path = grub_strdup (dhcp6->boot_file_path);
 ++      grub_print_error ();
 ++      if (*path)
 ++     {
 ++       char *slash;
 ++       slash = grub_strrchr (*path, '/');
 ++       if (slash)
 ++         *slash = 0;
 ++       else
 ++         **path = 0;
 ++     }
 ++    }
 ++
 ++  grub_dhcp6_options_free (dhcp6);
 ++  return inf;
 ++}
 ++
 + void
 + grub_net_process_dhcp (struct grub_net_buff *nb,
 +                     struct grub_net_card *card)
 +@@ -302,6 +966,77 @@ grub_net_process_dhcp (struct grub_net_buff *nb,
 +     }
 + }
 + 
 ++grub_err_t
 ++grub_net_process_dhcp6 (struct grub_net_buff *nb,
 ++                     struct grub_net_card *card __attribute__ ((unused)))
 ++{
 ++  const struct grub_net_dhcp6_packet *v6h;
 ++  grub_dhcp6_session_t se;
 ++  grub_size_t size;
 ++  grub_dhcp6_options_t options;
 ++
 ++  v6h = (const struct grub_net_dhcp6_packet *) nb->data;
 ++  size = nb->tail - nb->data;
 ++
 ++  options = grub_dhcp6_options_get (v6h, size);
 ++  if (!options)
 ++    return grub_errno;
 ++
 ++  if (!options->client_duid || !options->server_duid || !options->ia_addr)
 ++    {
 ++      grub_dhcp6_options_free (options);
 ++      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Bad DHCPv6 Packet");
 ++    }
 ++
 ++  FOR_DHCP6_SESSIONS (se)
 ++    {
 ++      if (se->transaction_id == v6h->transaction_id &&
 ++       grub_memcmp (options->client_duid, &se->duid, sizeof (se->duid)) == 0 &&
 ++       se->iaid == options->iaid)
 ++     break;
 ++    }
 ++
 ++  if (!se)
 ++    {
 ++      grub_dprintf ("bootp", "DHCPv6 session not found\n");
 ++      grub_dhcp6_options_free (options);
 ++      return GRUB_ERR_NONE;
 ++    }
 ++
 ++  if (v6h->message_type == GRUB_NET_DHCP6_ADVERTISE)
 ++    {
 ++      if (se->adv)
 ++     {
 ++       grub_dprintf ("bootp", "Skipped DHCPv6 Advertised .. \n");
 ++       grub_dhcp6_options_free (options);
 ++       return GRUB_ERR_NONE;
 ++     }
 ++
 ++      se->adv = options;
 ++      return grub_dhcp6_session_send_request (se);
 ++    }
 ++  else if (v6h->message_type == GRUB_NET_DHCP6_REPLY)
 ++    {
 ++      if (!se->adv)
 ++     {
 ++       grub_dprintf ("bootp", "Skipped DHCPv6 Reply .. \n");
 ++       grub_dhcp6_options_free (options);
 ++       return GRUB_ERR_NONE;
 ++     }
 ++
 ++      se->reply = options;
 ++      grub_dhcp6_session_configure_network (se);
 ++      grub_dhcp6_session_remove (se);
 ++      return GRUB_ERR_NONE;
 ++    }
 ++  else
 ++    {
 ++      grub_dhcp6_options_free (options);
 ++    }
 ++
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 + static char
 + hexdigit (grub_uint8_t val)
 + {
 +@@ -582,7 +1317,174 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
 +   return err;
 + }
 + 
 +-static grub_command_t cmd_getdhcp, cmd_bootp;
 ++static grub_err_t
 ++grub_cmd_bootp6 (struct grub_command *cmd __attribute__ ((unused)),
 ++               int argc, char **args)
 ++{
 ++  struct grub_net_card *card;
 ++  grub_uint32_t iaid = 0;
 ++  int interval;
 ++  grub_err_t err;
 ++  grub_dhcp6_session_t se;
 ++
 ++  err = GRUB_ERR_NONE;
 ++
 ++  FOR_NET_CARDS (card)
 ++  {
 ++    struct grub_net_network_level_interface *iface;
 ++
 ++    if (argc > 0 && grub_strcmp (card->name, args[0]) != 0)
 ++      continue;
 ++
 ++    iface = grub_net_ipv6_get_link_local (card, &card->default_address);
 ++    if (!iface)
 ++      {
 ++     grub_dhcp6_session_remove_all ();
 ++     return grub_errno;
 ++      }
 ++
 ++    grub_dhcp6_session_add (iface, iaid++);
 ++  }
 ++
 ++  for (interval = 200; interval < 10000; interval *= 2)
 ++    {
 ++      int done = 1;
 ++
 ++      FOR_DHCP6_SESSIONS (se)
 ++     {
 ++       struct grub_net_buff *nb;
 ++       struct grub_net_dhcp6_option *opt;
 ++       struct grub_net_dhcp6_packet *v6h;
 ++       struct grub_net_dhcp6_option_duid_ll *duid;
 ++       struct grub_net_dhcp6_option_iana *ia_na;
 ++       grub_net_network_level_address_t multicast;
 ++       grub_net_link_level_address_t ll_multicast;
 ++       struct udphdr *udph;
 ++
 ++       multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
 ++       multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48);
 ++       multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL);
 ++
 ++       err = grub_net_link_layer_resolve (se->iface,
 ++                 &multicast, &ll_multicast);
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           return err;
 ++         }
 ++
 ++       nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE);
 ++
 ++       if (!nb)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           return grub_errno;
 ++         }
 ++
 ++       err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE);
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           grub_netbuff_free (nb);
 ++           return err;
 ++         }
 ++
 ++       err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t));
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           grub_netbuff_free (nb);
 ++           return err;
 ++         }
 ++
 ++       opt = (struct grub_net_dhcp6_option *)nb->data;
 ++       opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME);
 ++       opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t));
 ++       grub_set_unaligned16 (opt->data, 0);
 ++
 ++       err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*duid));
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           grub_netbuff_free (nb);
 ++           return err;
 ++         }
 ++
 ++       opt = (struct grub_net_dhcp6_option *)nb->data;
 ++       opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID);
 ++       opt->len = grub_cpu_to_be16 (sizeof (*duid));
 ++
 ++       duid = (struct grub_net_dhcp6_option_duid_ll *) opt->data;
 ++       grub_memcpy (duid, &se->duid, sizeof (*duid));
 ++
 ++       err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*ia_na));
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           grub_netbuff_free (nb);
 ++           return err;
 ++         }
 ++
 ++       opt = (struct grub_net_dhcp6_option *)nb->data;
 ++       opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA);
 ++       opt->len = grub_cpu_to_be16 (sizeof (*ia_na));
 ++       ia_na = (struct grub_net_dhcp6_option_iana *)opt->data;
 ++       ia_na->iaid = grub_cpu_to_be32 (se->iaid);
 ++       ia_na->t1 = 0;
 ++       ia_na->t2 = 0;
 ++
 ++       err = grub_netbuff_push (nb, sizeof (*v6h));
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           grub_netbuff_free (nb);
 ++           return err;
 ++         }
 ++
 ++       v6h = (struct grub_net_dhcp6_packet *)nb->data;
 ++       v6h->message_type = GRUB_NET_DHCP6_SOLICIT;
 ++       v6h->transaction_id = se->transaction_id;
 ++
 ++       grub_netbuff_push (nb, sizeof (*udph));
 ++
 ++       udph = (struct udphdr *) nb->data;
 ++       udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT);
 ++       udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT);
 ++       udph->chksum = 0;
 ++       udph->len = grub_cpu_to_be16 (nb->tail - nb->data);
 ++
 ++       udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP,
 ++                         &se->iface->address, &multicast);
 ++
 ++       err = grub_net_send_ip_packet (se->iface, &multicast,
 ++                 &ll_multicast, nb, GRUB_NET_IP_UDP);
 ++       done = 0;
 ++       grub_netbuff_free (nb);
 ++
 ++       if (err)
 ++         {
 ++           grub_dhcp6_session_remove_all ();
 ++           return err;
 ++         }
 ++     }
 ++      if (!done)
 ++     grub_net_poll_cards (interval, 0);
 ++    }
 ++
 ++  FOR_DHCP6_SESSIONS (se)
 ++    {
 ++      grub_error_push ();
 ++      err = grub_error (GRUB_ERR_FILE_NOT_FOUND,
 ++                     N_("couldn't autoconfigure %s"),
 ++                     se->iface->card->name);
 ++    }
 ++
 ++  grub_dhcp6_session_remove_all ();
 ++
 ++  return err;
 ++}
 ++
 ++static grub_command_t cmd_getdhcp, cmd_bootp, cmd_bootp6;
 + 
 + void
 + grub_bootp_init (void)
 +@@ -593,6 +1495,9 @@ grub_bootp_init (void)
 +   cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt,
 +                                     N_("VAR INTERFACE NUMBER DESCRIPTION"),
 +                                     N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value."));
 ++  cmd_bootp6 = grub_register_command ("net_bootp6", grub_cmd_bootp6,
 ++                                  N_("[CARD]"),
 ++                                  N_("perform a DHCPv6 autoconfiguration"));
 + }
 + 
 + void
 +@@ -600,4 +1505,5 @@ grub_bootp_fini (void)
 + {
 +   grub_unregister_command (cmd_getdhcp);
 +   grub_unregister_command (cmd_bootp);
 ++  grub_unregister_command (cmd_bootp6);
 + }
 +diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
 +index aba4f8908..59970ab74 100644
 +--- a/grub-core/net/ip.c
 ++++ b/grub-core/net/ip.c
 +@@ -238,6 +238,45 @@ handle_dgram (struct grub_net_buff *nb,
 +   {
 +     struct udphdr *udph;
 +     udph = (struct udphdr *) nb->data;
 ++
 ++    if (proto == GRUB_NET_IP_UDP && udph->dst == grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT))
 ++      {
 ++     if (udph->chksum)
 ++       {
 ++         grub_uint16_t chk, expected;
 ++         chk = udph->chksum;
 ++         udph->chksum = 0;
 ++         expected = grub_net_ip_transport_checksum (nb,
 ++                                                    GRUB_NET_IP_UDP,
 ++                                                    source,
 ++                                                    dest);
 ++         if (expected != chk)
 ++           {
 ++             grub_dprintf ("net", "Invalid UDP checksum. "
 ++                           "Expected %x, got %x\n",
 ++                           grub_be_to_cpu16 (expected),
 ++                           grub_be_to_cpu16 (chk));
 ++             grub_netbuff_free (nb);
 ++             return GRUB_ERR_NONE;
 ++           }
 ++         udph->chksum = chk;
 ++       }
 ++
 ++     err = grub_netbuff_pull (nb, sizeof (*udph));
 ++     if (err)
 ++       {
 ++         grub_netbuff_free (nb);
 ++         return err;
 ++       }
 ++
 ++     err = grub_net_process_dhcp6 (nb, card);
 ++     if (err)
 ++       grub_print_error ();
 ++
 ++     grub_netbuff_free (nb);
 ++     return GRUB_ERR_NONE;
 ++      }
 ++
 +     if (proto == GRUB_NET_IP_UDP && grub_be_to_cpu16 (udph->dst) == 68)
 +       {
 +      const struct grub_net_bootp_packet *bootp;
 +diff --git a/include/grub/net.h b/include/grub/net.h
 +index ccc169c2d..38a3973f3 100644
 +--- a/include/grub/net.h
 ++++ b/include/grub/net.h
 +@@ -442,6 +442,66 @@ struct grub_net_bootp_packet
 +   grub_uint8_t vendor[0];
 + } GRUB_PACKED;
 + 
 ++struct grub_net_dhcp6_packet
 ++{
 ++  grub_uint32_t message_type:8;
 ++  grub_uint32_t transaction_id:24;
 ++  grub_uint8_t dhcp_options[0];
 ++} GRUB_PACKED;
 ++
 ++struct grub_net_dhcp6_option {
 ++  grub_uint16_t code;
 ++  grub_uint16_t len;
 ++  grub_uint8_t data[0];
 ++} GRUB_PACKED;
 ++
 ++struct grub_net_dhcp6_option_iana {
 ++  grub_uint32_t iaid;
 ++  grub_uint32_t t1;
 ++  grub_uint32_t t2;
 ++  grub_uint8_t data[0];
 ++} GRUB_PACKED;
 ++
 ++struct grub_net_dhcp6_option_iaaddr {
 ++  grub_uint8_t addr[16];
 ++  grub_uint32_t preferred_lifetime;
 ++  grub_uint32_t valid_lifetime;
 ++  grub_uint8_t data[0];
 ++} GRUB_PACKED;
 ++
 ++struct grub_net_dhcp6_option_duid_ll
 ++{
 ++  grub_uint16_t type;
 ++  grub_uint16_t hw_type;
 ++  grub_uint8_t hwaddr[6];
 ++} GRUB_PACKED;
 ++
 ++enum
 ++  {
 ++    GRUB_NET_DHCP6_SOLICIT = 1,
 ++    GRUB_NET_DHCP6_ADVERTISE = 2,
 ++    GRUB_NET_DHCP6_REQUEST = 3,
 ++    GRUB_NET_DHCP6_REPLY = 7
 ++  };
 ++
 ++enum
 ++  {
 ++    DHCP6_CLIENT_PORT = 546,
 ++    DHCP6_SERVER_PORT = 547
 ++  };
 ++
 ++enum
 ++  {
 ++    GRUB_NET_DHCP6_OPTION_CLIENTID = 1,
 ++    GRUB_NET_DHCP6_OPTION_SERVERID = 2,
 ++    GRUB_NET_DHCP6_OPTION_IA_NA = 3,
 ++    GRUB_NET_DHCP6_OPTION_IAADDR = 5,
 ++    GRUB_NET_DHCP6_OPTION_ORO = 6,
 ++    GRUB_NET_DHCP6_OPTION_ELAPSED_TIME = 8,
 ++    GRUB_NET_DHCP6_OPTION_DNS_SERVERS = 23,
 ++    GRUB_NET_DHCP6_OPTION_BOOTFILE_URL = 59
 ++  };
 ++
 + #define      GRUB_NET_BOOTP_RFC1048_MAGIC_0  0x63
 + #define      GRUB_NET_BOOTP_RFC1048_MAGIC_1  0x82
 + #define      GRUB_NET_BOOTP_RFC1048_MAGIC_2  0x53
 +@@ -468,6 +528,14 @@ grub_net_configure_by_dhcp_ack (const char *name,
 +                              grub_size_t size,
 +                              int is_def, char **device, char **path);
 + 
 ++struct grub_net_network_level_interface *
 ++grub_net_configure_by_dhcpv6_reply (const char *name,
 ++                                 struct grub_net_card *card,
 ++                                 grub_net_interface_flags_t flags,
 ++                                 const struct grub_net_dhcp6_packet *v6,
 ++                                 grub_size_t size,
 ++                                 int is_def, char **device, char **path);
 ++
 + grub_err_t
 + grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf,
 +                       int mask);
 +@@ -476,6 +544,10 @@ void
 + grub_net_process_dhcp (struct grub_net_buff *nb,
 +                     struct grub_net_card *card);
 + 
 ++grub_err_t
 ++grub_net_process_dhcp6 (struct grub_net_buff *nb,
 ++                     struct grub_net_card *card);
 ++
 + int
 + grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a,
 +                   const grub_net_link_level_address_t *b);
index 1f81a26298313c2ddeec35ee736a593b799c3d72,0000000000000000000000000000000000000000..1a461a7b5defd5ce6c7d3ee2a824b18d12679832
mode 100644,000000..100644
--- /dev/null
@@@ -1,129 -1,0 +1,129 @@@
-  grub-core/net/bootp.c | 67 +++++++++++++++++++++++++++++++++++++++++--
 +From 74c824f2b0d39b6fb5645fd55f9726d5aabc81f1 Mon Sep 17 00:00:00 2001
 +From: Michael Chang <mchang@suse.com>
 +Date: Thu, 27 Oct 2016 17:42:19 -0400
 +Subject: bootp: Add processing DHCPACK packet from HTTP Boot
 +
 +The vendor class identifier with the string "HTTPClient" is used to denote the
 +packet as responding to HTTP boot request. In DHCP4 config, the filename for
 +HTTP boot is the URL of the boot file while for PXE boot it is the path to the
 +boot file. As a consequence, the next-server becomes obseleted because the HTTP
 +URL already contains the server address for the boot file. For DHCP6 config,
 +there's no difference definition in existing config as dhcp6.bootfile-url can
 +be used to specify URL for both HTTP and PXE boot file.
 +
 +This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK
 +packet by treating it as HTTP format, not as the PXE format.
 +
 +Signed-off-by: Michael Chang <mchang@suse.com>
 +Signed-off-by: Ken Lin <ken.lin@hpe.com>
 +
 +Patch-Name: bootp_process_dhcpack_http_boot.patch
 +---
++ grub-core/net/bootp.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++--
 + include/grub/net.h    |  1 +
 + 2 files changed, 66 insertions(+), 2 deletions(-)
 +
 +diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
 +index 172528ee8..de9239c16 100644
 +--- a/grub-core/net/bootp.c
 ++++ b/grub-core/net/bootp.c
 +@@ -207,6 +207,11 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
 +                                      taglength);
 +           break;
 + 
 ++        case GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER:
 ++          grub_env_set_net_property (name, "vendor_class_identifier", (const char *) ptr,
 ++                                     taglength);
 ++       break;
 ++
 +      case GRUB_NET_BOOTP_EXTENSIONS_PATH:
 +           grub_env_set_net_property (name, "extensionspath", (const char *) ptr,
 +                                      taglength);
 +@@ -282,6 +287,66 @@ grub_net_configure_by_dhcp_ack (const char *name,
 +     }
 + #endif
 + 
 ++  if (size > OFFSET_OF (vendor, bp))
 ++    {
 ++      char *cidvar;
 ++      const char *cid;
 ++
 ++      parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
 ++      cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier");
 ++      cid = grub_env_get (cidvar);
 ++      grub_free (cidvar);
 ++
 ++      if (cid && grub_strcmp (cid, "HTTPClient") == 0)
 ++     {
 ++       char *proto, *ip, *pa;
 ++
 ++       if (!dissect_url (bp->boot_file, &proto, &ip, &pa))
 ++         return inter;
 ++
 ++       grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa));
 ++       if (is_def)
 ++         {
 ++           grub_net_default_server = grub_strdup (ip);
 ++           grub_env_set ("net_default_interface", name);
 ++           grub_env_export ("net_default_interface");
 ++         }
 ++       if (device && !*device)
 ++         {
 ++           *device = grub_xasprintf ("%s,%s", proto, ip);
 ++           grub_print_error ();
 ++         }
 ++       if (path)
 ++         {
 ++           *path = grub_strdup (pa);
 ++           grub_print_error ();
 ++           if (*path)
 ++             {
 ++               char *slash;
 ++               slash = grub_strrchr (*path, '/');
 ++               if (slash)
 ++                 *slash = 0;
 ++               else
 ++                 **path = 0;
 ++             }
 ++         }
 ++       grub_net_add_ipv4_local (inter, mask);
 ++       inter->dhcp_ack = grub_malloc (size);
 ++       if (inter->dhcp_ack)
 ++         {
 ++           grub_memcpy (inter->dhcp_ack, bp, size);
 ++           inter->dhcp_acklen = size;
 ++         }
 ++       else
 ++         grub_errno = GRUB_ERR_NONE;
 ++
 ++       grub_free (proto);
 ++       grub_free (ip);
 ++       grub_free (pa);
 ++       return inter;
 ++     }
 ++    }
 ++
 +   if (size > OFFSET_OF (boot_file, bp))
 +     grub_env_set_net_property (name, "boot_file", bp->boot_file,
 +                                sizeof (bp->boot_file));
 +@@ -346,8 +411,6 @@ grub_net_configure_by_dhcp_ack (const char *name,
 +          **path = 0;
 +      }
 +     }
 +-  if (size > OFFSET_OF (vendor, bp))
 +-    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
 +   grub_net_add_ipv4_local (inter, mask);
 +   
 +   inter->dhcp_ack = grub_malloc (size);
 +diff --git a/include/grub/net.h b/include/grub/net.h
 +index 38a3973f3..e4bf678db 100644
 +--- a/include/grub/net.h
 ++++ b/include/grub/net.h
 +@@ -517,6 +517,7 @@ enum
 +     GRUB_NET_BOOTP_DOMAIN = 0x0f,
 +     GRUB_NET_BOOTP_ROOT_PATH = 0x11,
 +     GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
 ++    GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 0x3C,
 +     GRUB_NET_BOOTP_END = 0xff
 +   };
 + 
index c4a5d8c502f94e7bd5fd695f2a9270536e6ec11d,0000000000000000000000000000000000000000..2a3748c08eaab2aef5f4f96396f600c4d88c274b
mode 100644,000000..100644
--- /dev/null
@@@ -1,195 -1,0 +1,195 @@@
-  grub-core/osdep/unix/config.c | 114 +++++++++++++++++++++++++++-------
 +From 0c9b39ffe82f8946dce58ff0e45fcf122ed64fe3 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:10 +0000
 +Subject: Read /etc/default/grub.d/*.cfg after /etc/default/grub
 +
 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/901600
 +Forwarded: no
 +Last-Update: 2014-01-28
 +
 +Patch-Name: default_grub_d.patch
 +---
++ grub-core/osdep/unix/config.c | 114 ++++++++++++++++++++++++++++++++++--------
 + util/grub-mkconfig.in         |   5 ++
 + 2 files changed, 98 insertions(+), 21 deletions(-)
 +
 +diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c
 +index 65effa9f3..5478030fd 100644
 +--- a/grub-core/osdep/unix/config.c
 ++++ b/grub-core/osdep/unix/config.c
 +@@ -24,6 +24,8 @@
 + #include <grub/emu/config.h>
 + #include <grub/util/install.h>
 + #include <grub/util/misc.h>
 ++#include <grub/list.h>
 ++#include <assert.h>
 + #include <string.h>
 + #include <sys/types.h>
 + #include <sys/wait.h>
 +@@ -61,13 +63,27 @@ grub_util_get_localedir (void)
 +   return LOCALEDIR;
 + }
 + 
 ++struct cfglist
 ++{
 ++  struct cfglist *next;
 ++  struct cfglist *prev;
 ++  char *path;
 ++};
 ++
 + void
 + grub_util_load_config (struct grub_util_config *cfg)
 + {
 +   pid_t pid;
 +   const char *argv[4];
 +-  char *script, *ptr;
 ++  char *script = NULL, *ptr;
 +   const char *cfgfile, *iptr;
 ++  char *cfgdir;
 ++  grub_util_fd_dir_t d;
 ++  struct cfglist *cfgpaths = NULL, *cfgpath, *next_cfgpath;
 ++  int num_cfgpaths = 0;
 ++  size_t len_cfgpaths = 0;
 ++  char **sorted_cfgpaths = NULL;
 ++  int i;
 +   FILE *f = NULL;
 +   int fd;
 +   const char *v;
 +@@ -83,29 +99,75 @@ grub_util_load_config (struct grub_util_config *cfg)
 +     cfg->grub_distributor = xstrdup (v);
 + 
 +   cfgfile = grub_util_get_config_filename ();
 +-  if (!grub_util_is_regular (cfgfile))
 +-    return;
 ++  if (grub_util_is_regular (cfgfile))
 ++    {
 ++      ++num_cfgpaths;
 ++      len_cfgpaths += strlen (cfgfile) * 4 + sizeof (". ''; ") - 1;
 ++    }
 ++
 ++  cfgdir = xasprintf ("%s.d", cfgfile);
 ++  d = grub_util_fd_opendir (cfgdir);
 ++  if (d)
 ++    {
 ++      grub_util_fd_dirent_t de;
 ++
 ++      while ((de = grub_util_fd_readdir (d)))
 ++     {
 ++       const char *ext = strrchr (de->d_name, '.');
 ++
 ++       if (!ext || strcmp (ext, ".cfg") != 0)
 ++         continue;
 ++
 ++       cfgpath = xmalloc (sizeof (*cfgpath));
 ++       cfgpath->path = grub_util_path_concat (2, cfgdir, de->d_name);
 ++       grub_list_push (GRUB_AS_LIST_P (&cfgpaths), GRUB_AS_LIST (cfgpath));
 ++       ++num_cfgpaths;
 ++       len_cfgpaths += strlen (cfgpath->path) * 4 + sizeof (". ''; ") - 1;
 ++     }
 ++      grub_util_fd_closedir (d);
 ++    }
 ++
 ++  if (num_cfgpaths == 0)
 ++    goto out;
 ++
 ++  sorted_cfgpaths = xmalloc (num_cfgpaths * sizeof (*sorted_cfgpaths));
 ++  i = 0;
 ++  if (grub_util_is_regular (cfgfile))
 ++    sorted_cfgpaths[i++] = xstrdup (cfgfile);
 ++  FOR_LIST_ELEMENTS_SAFE (cfgpath, next_cfgpath, cfgpaths)
 ++    {
 ++      sorted_cfgpaths[i++] = cfgpath->path;
 ++      free (cfgpath);
 ++    }
 ++  assert (i == num_cfgpaths);
 ++  qsort (sorted_cfgpaths + 1, num_cfgpaths - 1, sizeof (*sorted_cfgpaths),
 ++      (int (*) (const void *, const void *)) strcmp);
 + 
 +   argv[0] = "sh";
 +   argv[1] = "-c";
 + 
 +-  script = xmalloc (4 * strlen (cfgfile) + 300);
 ++  script = xmalloc (len_cfgpaths + 300);
 + 
 +   ptr = script;
 +-  memcpy (ptr, ". '", 3);
 +-  ptr += 3;
 +-  for (iptr = cfgfile; *iptr; iptr++)
 ++  for (i = 0; i < num_cfgpaths; i++)
 +     {
 +-      if (*iptr == '\\')
 ++      memcpy (ptr, ". '", 3);
 ++      ptr += 3;
 ++      for (iptr = sorted_cfgpaths[i]; *iptr; iptr++)
 +      {
 +-       memcpy (ptr, "'\\''", 4);
 +-       ptr += 4;
 +-       continue;
 ++       if (*iptr == '\\')
 ++         {
 ++           memcpy (ptr, "'\\''", 4);
 ++           ptr += 4;
 ++           continue;
 ++         }
 ++       *ptr++ = *iptr;
 +      }
 +-      *ptr++ = *iptr;
 ++      memcpy (ptr, "'; ", 3);
 ++      ptr += 3;
 +     }
 + 
 +-  strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
 ++  strcpy (ptr, "printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
 +        "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\"");
 + 
 +   argv[2] = script;
 +@@ -125,15 +187,25 @@ grub_util_load_config (struct grub_util_config *cfg)
 +       waitpid (pid, NULL, 0);
 +     }
 +   if (f)
 +-    return;
 ++    goto out;
 + 
 +-  f = grub_util_fopen (cfgfile, "r");
 +-  if (f)
 ++  for (i = 0; i < num_cfgpaths; i++)
 +     {
 +-      grub_util_parse_config (f, cfg, 0);
 +-      fclose (f);
 ++      f = grub_util_fopen (sorted_cfgpaths[i], "r");
 ++      if (f)
 ++     {
 ++       grub_util_parse_config (f, cfg, 0);
 ++       fclose (f);
 ++     }
 ++      else
 ++     grub_util_warn (_("cannot open configuration file `%s': %s"),
 ++                     cfgfile, strerror (errno));
 +     }
 +-  else
 +-    grub_util_warn (_("cannot open configuration file `%s': %s"),
 +-                 cfgfile, strerror (errno));
 ++
 ++out:
 ++  free (script);
 ++  for (i = 0; i < num_cfgpaths; i++)
 ++    free (sorted_cfgpaths[i]);
 ++  free (sorted_cfgpaths);
 ++  free (cfgdir);
 + }
 +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
 +index 99ba7acba..b4f0011b5 100644
 +--- a/util/grub-mkconfig.in
 ++++ b/util/grub-mkconfig.in
 +@@ -157,6 +157,11 @@ fi
 + if test -f ${sysconfdir}/default/grub ; then
 +   . ${sysconfdir}/default/grub
 + fi
 ++for x in ${sysconfdir}/default/grub.d/*.cfg ; do
 ++  if [ -e "${x}" ]; then
 ++    . "${x}"
 ++  fi
 ++done
 + 
 + # XXX: should this be deprecated at some point?
 + if [ "x${GRUB_TERMINAL}" != "x" ] ; then
index 44b6a82fc489f60c0950a22203eab5b891404f1a,0000000000000000000000000000000000000000..10540835d465c1fb9a5e1a38e8d074e82fa6027d
mode 100644,000000..100644
--- /dev/null
@@@ -1,339 -1,0 +1,339 @@@
-  grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++
-  include/grub/efi/api.h             |  76 ++++++++++++++
 +From ca0032fc42ff1ee941a77b5b6fdca866c3b94b5b Mon Sep 17 00:00:00 2001
 +From: Michael Chang <mchang@suse.com>
 +Date: Thu, 27 Oct 2016 17:43:21 -0400
 +Subject: efinet: Setting DNS server from UEFI protocol
 +
 +In the URI device path node, any name rahter than address can be used for
 +looking up the resources so that DNS service become needed to get answer of the
 +name's address. Unfortunately the DNS is not defined in any of the device path
 +nodes so that we use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL
 +to obtain it.
 +
 +These two protcols are defined the sections of UEFI specification.
 +
 + 27.5 EFI IPv4 Configuration II Protocol
 + 27.7 EFI IPv6 Configuration Protocol
 +
 +include/grub/efi/api.h:
 +Add new structure and protocol UUID of EFI_IP4_CONFIG2_PROTOCOL and
 +EFI_IP6_CONFIG_PROTOCOL.
 +
 +grub-core/net/drivers/efi/efinet.c:
 +Use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL to obtain the list
 +of DNS server address for IPv4 and IPv6 respectively. The address of DNS
 +servers is structured into DHCPACK packet and feed into the same DHCP packet
 +processing functions to ensure the network interface is setting up the same way
 +it used to be.
 +
 +Signed-off-by: Michael Chang <mchang@suse.com>
 +Signed-off-by: Ken Lin <ken.lin@hpe.com>
 +
 +Patch-Name: efinet_set_dns_from_uefi_proto.patch
 +---
++ grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++++++++++
++ include/grub/efi/api.h             |  76 +++++++++++++++++
 + 2 files changed, 239 insertions(+)
 +
 +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
 +index 2d3b00f0e..82a28fb6e 100644
 +--- a/grub-core/net/drivers/efi/efinet.c
 ++++ b/grub-core/net/drivers/efi/efinet.c
 +@@ -30,6 +30,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
 + /* GUID.  */
 + static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID;
 + static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID;
 ++static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID;
 ++static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID;
 + 
 + static grub_err_t
 + send_card_buffer (struct grub_net_card *dev,
 +@@ -325,6 +327,125 @@ grub_efinet_findcards (void)
 +   grub_free (handles);
 + }
 + 
 ++static grub_efi_handle_t
 ++grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path,
 ++                         grub_efi_device_path_t **r_device_path)
 ++{
 ++  grub_efi_handle_t handle;
 ++  grub_efi_status_t status;
 ++
 ++  status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path,
 ++                   protocol, &device_path, &handle);
 ++
 ++  if (status != GRUB_EFI_SUCCESS)
 ++    return 0;
 ++
 ++  if (r_device_path)
 ++    *r_device_path = device_path;
 ++
 ++  return handle;
 ++}
 ++
 ++static grub_efi_ipv4_address_t *
 ++grub_dns_server_ip4_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns)
 ++{
 ++  grub_efi_handle_t hnd;
 ++  grub_efi_status_t status;
 ++  grub_efi_ip4_config2_protocol_t *conf;
 ++  grub_efi_ipv4_address_t *addrs;
 ++  grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv4_address_t);
 ++
 ++  hnd = grub_efi_locate_device_path (&ip4_config_guid, dp, NULL);
 ++
 ++  if (!hnd)
 ++    return 0;
 ++
 ++  conf = grub_efi_open_protocol (hnd, &ip4_config_guid,
 ++                             GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 ++
 ++  if (!conf)
 ++    return 0;
 ++
 ++  addrs  = grub_malloc (data_size);
 ++  if (!addrs)
 ++    return 0;
 ++
 ++  status = efi_call_4 (conf->get_data, conf,
 ++                   GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
 ++                   &data_size, addrs);
 ++
 ++  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
 ++    {
 ++      grub_free (addrs);
 ++      addrs  = grub_malloc (data_size);
 ++      if (!addrs)
 ++     return 0;
 ++
 ++      status = efi_call_4 (conf->get_data,  conf,
 ++                       GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
 ++                       &data_size, addrs);
 ++    }
 ++
 ++  if (status != GRUB_EFI_SUCCESS)
 ++    {
 ++      grub_free (addrs);
 ++      return 0;
 ++    }
 ++
 ++  *num_dns = data_size / sizeof (grub_efi_ipv4_address_t);
 ++  return addrs;
 ++}
 ++
 ++static grub_efi_ipv6_address_t *
 ++grub_dns_server_ip6_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns)
 ++{
 ++  grub_efi_handle_t hnd;
 ++  grub_efi_status_t status;
 ++  grub_efi_ip6_config_protocol_t *conf;
 ++  grub_efi_ipv6_address_t *addrs;
 ++  grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv6_address_t);
 ++
 ++  hnd = grub_efi_locate_device_path (&ip6_config_guid, dp, NULL);
 ++
 ++  if (!hnd)
 ++    return 0;
 ++
 ++  conf = grub_efi_open_protocol (hnd, &ip6_config_guid,
 ++                             GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 ++
 ++  if (!conf)
 ++    return 0;
 ++
 ++  addrs  = grub_malloc (data_size);
 ++  if (!addrs)
 ++    return 0;
 ++
 ++  status = efi_call_4 (conf->get_data, conf,
 ++                   GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
 ++                   &data_size, addrs);
 ++
 ++  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
 ++    {
 ++      grub_free (addrs);
 ++      addrs  = grub_malloc (data_size);
 ++      if (!addrs)
 ++     return 0;
 ++
 ++      status = efi_call_4 (conf->get_data,  conf,
 ++                       GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
 ++                       &data_size, addrs);
 ++    }
 ++
 ++  if (status != GRUB_EFI_SUCCESS)
 ++    {
 ++      grub_free (addrs);
 ++      return 0;
 ++    }
 ++
 ++  *num_dns = data_size / sizeof (grub_efi_ipv6_address_t);
 ++  return addrs;
 ++}
 ++
 + static struct grub_net_buff *
 + grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6)
 + {
 +@@ -377,6 +498,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u
 +       grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp;
 +       struct grub_net_bootp_packet *bp;
 +       grub_uint8_t *ptr;
 ++      grub_efi_ipv4_address_t *dns;
 ++      grub_efi_uintn_t num_dns;
 + 
 +       bp = (struct grub_net_bootp_packet *) nb->tail;
 +       err = grub_netbuff_put (nb, sizeof (*bp) + 4);
 +@@ -438,6 +561,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u
 +       *ptr++ = sizeof ("HTTPClient") - 1;
 +       grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1);
 + 
 ++      dns = grub_dns_server_ip4_address (dp, &num_dns);
 ++      if (dns)
 ++     {
 ++       grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns;
 ++
 ++       ptr = nb->tail;
 ++       err = grub_netbuff_put (nb, size_dns + 2);
 ++       if (err)
 ++         {
 ++           grub_free (ddp);
 ++           grub_netbuff_free (nb);
 ++           return NULL;
 ++         }
 ++       *ptr++ = GRUB_NET_BOOTP_DNS;
 ++       *ptr++ = size_dns;
 ++       grub_memcpy (ptr, dns, size_dns);
 ++       grub_free (dns);
 ++     }
 ++
 +       ptr = nb->tail;
 +       err = grub_netbuff_put (nb, 1);
 +       if (err)
 +@@ -470,6 +612,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u
 +       struct grub_net_dhcp6_option *opt;
 +       struct grub_net_dhcp6_option_iana *iana;
 +       struct grub_net_dhcp6_option_iaaddr *iaaddr;
 ++      grub_efi_ipv6_address_t *dns;
 ++      grub_efi_uintn_t num_dns;
 + 
 +       d6p = (struct grub_net_dhcp6_packet *)nb->tail;
 +       err = grub_netbuff_put (nb, sizeof(*d6p));
 +@@ -533,6 +677,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u
 +       opt->len = grub_cpu_to_be16 (uri_len);
 +       grub_memcpy (opt->data, uri_dp->uri, uri_len);
 + 
 ++      dns = grub_dns_server_ip6_address (dp, &num_dns);
 ++      if (dns)
 ++     {
 ++       grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns;
 ++
 ++       opt = (struct grub_net_dhcp6_option *)nb->tail;
 ++       err = grub_netbuff_put (nb, sizeof(*opt) + size_dns);
 ++       if (err)
 ++       {
 ++         grub_free (ddp);
 ++         grub_netbuff_free (nb);
 ++         return NULL;
 ++       }
 ++       opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS);
 ++       opt->len = grub_cpu_to_be16 (size_dns);
 ++       grub_memcpy (opt->data, dns, size_dns);
 ++       grub_free (dns);
 ++     }
 ++
 +       *use_ipv6 = 1;
 +     }
 + 
 +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
 +index d5a12569b..99ba068e3 100644
 +--- a/include/grub/efi/api.h
 ++++ b/include/grub/efi/api.h
 +@@ -334,6 +334,16 @@
 +       { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
 +   }
 + 
 ++#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \
 ++  { 0x5b446ed1, 0xe30b, 0x4faa, \
 ++      { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \
 ++  }
 ++
 ++#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \
 ++  { 0x937fe521, 0x95ae, 0x4d1a, \
 ++      { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
 ++  }
 ++
 + struct grub_efi_sal_system_table
 + {
 +   grub_uint32_t signature;
 +@@ -1749,6 +1759,72 @@ struct grub_efi_block_io
 + };
 + typedef struct grub_efi_block_io grub_efi_block_io_t;
 + 
 ++enum grub_efi_ip4_config2_data_type {
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO,
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY,
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY,
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
 ++  GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MAXIMUM
 ++};
 ++typedef enum grub_efi_ip4_config2_data_type grub_efi_ip4_config2_data_type_t;
 ++
 ++struct grub_efi_ip4_config2_protocol
 ++{
 ++  grub_efi_status_t (*set_data) (struct grub_efi_ip4_config2_protocol *this,
 ++                              grub_efi_ip4_config2_data_type_t data_type,
 ++                              grub_efi_uintn_t data_size,
 ++                              void *data);
 ++
 ++  grub_efi_status_t (*get_data) (struct grub_efi_ip4_config2_protocol *this,
 ++                              grub_efi_ip4_config2_data_type_t data_type,
 ++                              grub_efi_uintn_t *data_size,
 ++                              void *data);
 ++
 ++  grub_efi_status_t (*register_data_notify) (struct grub_efi_ip4_config2_protocol *this,
 ++                                          grub_efi_ip4_config2_data_type_t data_type,
 ++                                          grub_efi_event_t event);
 ++
 ++  grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this,
 ++                                          grub_efi_ip4_config2_data_type_t data_type,
 ++                                          grub_efi_event_t event);
 ++};
 ++typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t;
 ++
 ++enum grub_efi_ip6_config_data_type {
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_DUP_ADDR_DETECT_TRANSMITS,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
 ++  GRUB_EFI_IP6_CONFIG_DATA_TYPE_MAXIMUM
 ++};
 ++typedef enum grub_efi_ip6_config_data_type grub_efi_ip6_config_data_type_t;
 ++
 ++struct grub_efi_ip6_config_protocol
 ++{
 ++  grub_efi_status_t (*set_data) (struct grub_efi_ip6_config_protocol *this,
 ++                              grub_efi_ip6_config_data_type_t data_type,
 ++                              grub_efi_uintn_t data_size,
 ++                              void *data);
 ++
 ++  grub_efi_status_t (*get_data) (struct grub_efi_ip6_config_protocol *this,
 ++                              grub_efi_ip6_config_data_type_t data_type,
 ++                              grub_efi_uintn_t *data_size,
 ++                              void *data);
 ++
 ++  grub_efi_status_t (*register_data_notify) (struct grub_efi_ip6_config_protocol *this,
 ++                                          grub_efi_ip6_config_data_type_t data_type,
 ++                                          grub_efi_event_t event);
 ++
 ++  grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip6_config_protocol *this,
 ++                                          grub_efi_ip6_config_data_type_t data_type,
 ++                                          grub_efi_event_t event);
 ++};
 ++typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t;
 ++
 + #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
 +   || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__)
 + 
index 50218e0500b9f5f37c51aa47f2cc181c177e73da,0000000000000000000000000000000000000000..125beb0da8152fec20116ba495be566f1ca4e518
mode 100644,000000..100644
--- /dev/null
@@@ -1,388 -1,0 +1,388 @@@
-  grub-core/net/drivers/efi/efinet.c | 268 ++++++++++++++++++++++++++++-
 +From e03383171dce3d640bf78109f633274f5936f1df Mon Sep 17 00:00:00 2001
 +From: Michael Chang <mchang@suse.com>
 +Date: Thu, 27 Oct 2016 17:43:05 -0400
 +Subject: efinet: Setting network from UEFI device path
 +
 +The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no
 +longer provided for HTTP Boot. Instead, we have to get the HTTP boot
 +information from the device path nodes defined in following UEFI Specification
 +sections.
 +
 + 9.3.5.12 IPv4 Device Path
 + 9.3.5.13 IPv6 Device Path
 + 9.3.5.23 Uniform Resource Identifiers (URI) Device Path
 +
 +This patch basically does:
 +
 +include/grub/efi/api.h:
 +Add new structure of Uniform Resource Identifiers (URI) Device Path
 +
 +grub-core/net/drivers/efi/efinet.c:
 +Check if PXE Base Code is available, if not it will try to obtain the netboot
 +information from the device path where the image booted from. The DHCPACK
 +packet is recoverd from the information in device patch and feed into the same
 +DHCP packet processing functions to ensure the network interface is setting up
 +the same way it used to be.
 +
 +Signed-off-by: Michael Chang <mchang@suse.com>
 +Signed-off-by: Ken Lin <ken.lin@hpe.com>
 +
 +Patch-Name: efinet_set_network_from_uefi_devpath.patch
 +---
++ grub-core/net/drivers/efi/efinet.c | 268 +++++++++++++++++++++++++++++++++++--
 + include/grub/efi/api.h             |  11 ++
 + 2 files changed, 270 insertions(+), 9 deletions(-)
 +
 +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
 +index fc90415f2..2d3b00f0e 100644
 +--- a/grub-core/net/drivers/efi/efinet.c
 ++++ b/grub-core/net/drivers/efi/efinet.c
 +@@ -23,6 +23,7 @@
 + #include <grub/efi/api.h>
 + #include <grub/efi/efi.h>
 + #include <grub/i18n.h>
 ++#include <grub/net/netbuff.h>
 + 
 + GRUB_MOD_LICENSE ("GPLv3+");
 + 
 +@@ -324,6 +325,221 @@ grub_efinet_findcards (void)
 +   grub_free (handles);
 + }
 + 
 ++static struct grub_net_buff *
 ++grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6)
 ++{
 ++  grub_efi_uint16_t uri_len;
 ++  grub_efi_device_path_t *ldp, *ddp;
 ++  grub_efi_uri_device_path_t *uri_dp;
 ++  struct grub_net_buff *nb;
 ++  grub_err_t err;
 ++
 ++  ddp = grub_efi_duplicate_device_path (dp);
 ++  ldp = grub_efi_find_last_device_path (ddp);
 ++
 ++  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
 ++      || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)
 ++    {
 ++      grub_free (ddp);
 ++      return NULL;
 ++    }
 ++
 ++  uri_len = GRUB_EFI_DEVICE_PATH_LENGTH (ldp) > 4 ? GRUB_EFI_DEVICE_PATH_LENGTH (ldp) - 4  : 0;
 ++
 ++  if (!uri_len)
 ++    {
 ++      grub_free (ddp);
 ++      return NULL;
 ++    }
 ++
 ++  uri_dp = (grub_efi_uri_device_path_t *) ldp;
 ++
 ++  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
 ++  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
 ++  ldp->length = sizeof (*ldp);
 ++
 ++  ldp = grub_efi_find_last_device_path (ddp);
 ++
 ++  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
 ++      || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
 ++          && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
 ++    {
 ++      grub_free (ddp);
 ++      return NULL;
 ++    }
 ++
 ++  nb = grub_netbuff_alloc (512);
 ++  if (!nb)
 ++    return NULL;
 ++
 ++  if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE)
 ++    {
 ++      grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp;
 ++      struct grub_net_bootp_packet *bp;
 ++      grub_uint8_t *ptr;
 ++
 ++      bp = (struct grub_net_bootp_packet *) nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof (*bp) + 4);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++
 ++      if (sizeof(bp->boot_file) < uri_len)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      grub_memcpy (bp->boot_file, uri_dp->uri, uri_len);
 ++      grub_memcpy (&bp->your_ip, ipv4->local_ip_address, sizeof (bp->your_ip));
 ++      grub_memcpy (&bp->server_ip, ipv4->remote_ip_address, sizeof (bp->server_ip));
 ++
 ++      bp->vendor[0] = GRUB_NET_BOOTP_RFC1048_MAGIC_0;
 ++      bp->vendor[1] = GRUB_NET_BOOTP_RFC1048_MAGIC_1;
 ++      bp->vendor[2] = GRUB_NET_BOOTP_RFC1048_MAGIC_2;
 ++      bp->vendor[3] = GRUB_NET_BOOTP_RFC1048_MAGIC_3;
 ++
 ++      ptr = nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof (ipv4->subnet_mask) + 2);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      *ptr++ = GRUB_NET_BOOTP_NETMASK;
 ++      *ptr++ = sizeof (ipv4->subnet_mask);
 ++      grub_memcpy (ptr, ipv4->subnet_mask, sizeof (ipv4->subnet_mask));
 ++
 ++      ptr = nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof (ipv4->gateway_ip_address) + 2);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      *ptr++ = GRUB_NET_BOOTP_ROUTER;
 ++      *ptr++ = sizeof (ipv4->gateway_ip_address);
 ++      grub_memcpy (ptr, ipv4->gateway_ip_address, sizeof (ipv4->gateway_ip_address));
 ++
 ++      ptr = nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof ("HTTPClient") + 1);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      *ptr++ = GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER;
 ++      *ptr++ = sizeof ("HTTPClient") - 1;
 ++      grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1);
 ++
 ++      ptr = nb->tail;
 ++      err = grub_netbuff_put (nb, 1);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      *ptr = GRUB_NET_BOOTP_END;
 ++      *use_ipv6 = 0;
 ++
 ++      ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
 ++      ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
 ++      ldp->length = sizeof (*ldp);
 ++      ldp = grub_efi_find_last_device_path (ddp);
 ++
 ++      if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) ==  GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
 ++     {
 ++       grub_efi_mac_address_device_path_t *mac = (grub_efi_mac_address_device_path_t *) ldp;
 ++       bp->hw_type = mac->if_type;
 ++       bp->hw_len = sizeof (bp->mac_addr);
 ++       grub_memcpy (bp->mac_addr, mac->mac_address, bp->hw_len);
 ++     }
 ++    }
 ++  else
 ++    {
 ++      grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) ldp;
 ++
 ++      struct grub_net_dhcp6_packet *d6p;
 ++      struct grub_net_dhcp6_option *opt;
 ++      struct grub_net_dhcp6_option_iana *iana;
 ++      struct grub_net_dhcp6_option_iaaddr *iaaddr;
 ++
 ++      d6p = (struct grub_net_dhcp6_packet *)nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof(*d6p));
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      d6p->message_type = GRUB_NET_DHCP6_REPLY;
 ++
 ++      opt = (struct grub_net_dhcp6_option *)nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof(*opt));
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA);
 ++      opt->len = grub_cpu_to_be16_compile_time (sizeof(*iana) + sizeof(*opt) + sizeof(*iaaddr));
 ++
 ++      err = grub_netbuff_put (nb, sizeof(*iana));
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++
 ++      opt = (struct grub_net_dhcp6_option *)nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof(*opt));
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR);
 ++      opt->len = grub_cpu_to_be16_compile_time (sizeof (*iaaddr));
 ++
 ++      iaaddr = (struct grub_net_dhcp6_option_iaaddr *)nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof(*iaaddr));
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      grub_memcpy (iaaddr->addr, ipv6->local_ip_address, sizeof(ipv6->local_ip_address));
 ++
 ++      opt = (struct grub_net_dhcp6_option *)nb->tail;
 ++      err = grub_netbuff_put (nb, sizeof(*opt) + uri_len);
 ++      if (err)
 ++     {
 ++       grub_free (ddp);
 ++       grub_netbuff_free (nb);
 ++       return NULL;
 ++     }
 ++      opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL);
 ++      opt->len = grub_cpu_to_be16 (uri_len);
 ++      grub_memcpy (opt->data, uri_dp->uri, uri_len);
 ++
 ++      *use_ipv6 = 1;
 ++    }
 ++
 ++  grub_free (ddp);
 ++  return nb;
 ++}
 ++
 + static void
 + grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +                        char **path)
 +@@ -340,6 +556,11 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +     grub_efi_device_path_t *cdp;
 +     struct grub_efi_pxe *pxe;
 +     struct grub_efi_pxe_mode *pxe_mode;
 ++    grub_uint8_t *packet_buf;
 ++    grub_size_t packet_bufsz ;
 ++    int ipv6;
 ++    struct grub_net_buff *nb = NULL;
 ++
 +     if (card->driver != &efidriver)
 +       continue;
 +     cdp = grub_efi_get_device_path (card->efi_handle);
 +@@ -359,11 +580,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +      ldp = grub_efi_find_last_device_path (dp);
 +      if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
 +          || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
 +-             && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
 ++             && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
 ++             && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE))
 +        continue;
 +      dup_dp = grub_efi_duplicate_device_path (dp);
 +      if (!dup_dp)
 +        continue;
 ++
 ++     if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)
 ++       {
 ++         dup_ldp = grub_efi_find_last_device_path (dup_dp);
 ++         dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
 ++         dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
 ++         dup_ldp->length = sizeof (*dup_ldp);
 ++       }
 ++
 +      dup_ldp = grub_efi_find_last_device_path (dup_dp);
 +      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
 +      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
 +@@ -375,16 +606,31 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +       }
 +     pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
 +                                GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 +-    if (! pxe)
 +-      continue;
 +-    pxe_mode = pxe->mode;
 ++    if (!pxe)
 ++      {
 ++     nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6);
 ++     if (!nb)
 ++       {
 ++         grub_print_error ();
 ++         continue;
 ++       }
 ++     packet_buf = nb->head;
 ++     packet_bufsz = nb->tail - nb->head;
 ++      }
 ++    else
 ++      {
 ++     pxe_mode = pxe->mode;
 ++     packet_buf = (grub_uint8_t *) &pxe_mode->dhcp_ack;
 ++     packet_bufsz = sizeof (pxe_mode->dhcp_ack);
 ++     ipv6 = pxe_mode->using_ipv6;
 ++      }
 + 
 +-    if (pxe_mode->using_ipv6)
 ++    if (ipv6)
 +       {
 +      grub_net_configure_by_dhcpv6_reply (card->name, card, 0,
 +                                          (struct grub_net_dhcp6_packet *)
 +-                                         &pxe_mode->dhcp_ack,
 +-                                         sizeof (pxe_mode->dhcp_ack),
 ++                                         packet_buf,
 ++                                         packet_bufsz,
 +                                          1, device, path);
 +      if (grub_errno)
 +        grub_print_error ();
 +@@ -393,10 +639,14 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +       {
 +      grub_net_configure_by_dhcp_ack (card->name, card, 0,
 +                                      (struct grub_net_bootp_packet *)
 +-                                     &pxe_mode->dhcp_ack,
 +-                                     sizeof (pxe_mode->dhcp_ack),
 ++                                     packet_buf,
 ++                                     packet_bufsz,
 +                                      1, device, path);
 +       }
 ++
 ++    if (nb)
 ++      grub_netbuff_free (nb);
 ++
 +     return;
 +   }
 + }
 +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
 +index 92f9b5a6f..d5a12569b 100644
 +--- a/include/grub/efi/api.h
 ++++ b/include/grub/efi/api.h
 +@@ -825,6 +825,8 @@ struct grub_efi_ipv4_device_path
 +   grub_efi_uint16_t remote_port;
 +   grub_efi_uint16_t protocol;
 +   grub_efi_uint8_t static_ip_address;
 ++  grub_efi_ipv4_address_t gateway_ip_address;
 ++  grub_efi_ipv4_address_t subnet_mask;
 + } GRUB_PACKED;
 + typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
 + 
 +@@ -879,6 +881,15 @@ struct grub_efi_sata_device_path
 + } GRUB_PACKED;
 + typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t;
 + 
 ++#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE             24
 ++
 ++struct grub_efi_uri_device_path
 ++{
 ++  grub_efi_device_path_t header;
 ++  grub_efi_uint8_t uri[0];
 ++} GRUB_PACKED;
 ++typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t;
 ++
 + #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE        10
 + 
 + /* Media Device Path.  */
index e631856583bdacef1ac3958b6f247f3ab86763e9,0000000000000000000000000000000000000000..d77cabd38bcd2b93b831a8af465b91e05c490e9d
mode 100644,000000..100644
--- /dev/null
@@@ -1,126 -1,0 +1,126 @@@
-  grub-core/net/drivers/efi/efinet.c | 24 ++++++++++---
-  include/grub/efi/api.h             | 55 +++++++++++++++++++++++++++++-
 +From d948a72a7c909b18c424ea732aec2788705646b5 Mon Sep 17 00:00:00 2001
 +From: Michael Chang <mchang@suse.com>
 +Date: Thu, 27 Oct 2016 17:41:21 -0400
 +Subject: efinet: UEFI IPv6 PXE support
 +
 +When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is
 +cached in firmware buffer which can be obtained by PXE Base Code protocol. The
 +network interface can be setup through the parameters in that obtained packet.
 +
 +Signed-off-by: Michael Chang <mchang@suse.com>
 +Signed-off-by: Ken Lin <ken.lin@hpe.com>
 +
 +Patch-Name: efinet_uefi_ipv6_pxe_support.patch
 +---
++ grub-core/net/drivers/efi/efinet.c | 24 +++++++++++++----
++ include/grub/efi/api.h             | 55 +++++++++++++++++++++++++++++++++++++-
 + 2 files changed, 73 insertions(+), 6 deletions(-)
 +
 +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
 +index 5388f952b..fc90415f2 100644
 +--- a/grub-core/net/drivers/efi/efinet.c
 ++++ b/grub-core/net/drivers/efi/efinet.c
 +@@ -378,11 +378,25 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
 +     if (! pxe)
 +       continue;
 +     pxe_mode = pxe->mode;
 +-    grub_net_configure_by_dhcp_ack (card->name, card, 0,
 +-                                 (struct grub_net_bootp_packet *)
 +-                                 &pxe_mode->dhcp_ack,
 +-                                 sizeof (pxe_mode->dhcp_ack),
 +-                                 1, device, path);
 ++
 ++    if (pxe_mode->using_ipv6)
 ++      {
 ++     grub_net_configure_by_dhcpv6_reply (card->name, card, 0,
 ++                                         (struct grub_net_dhcp6_packet *)
 ++                                         &pxe_mode->dhcp_ack,
 ++                                         sizeof (pxe_mode->dhcp_ack),
 ++                                         1, device, path);
 ++     if (grub_errno)
 ++       grub_print_error ();
 ++      }
 ++    else
 ++      {
 ++     grub_net_configure_by_dhcp_ack (card->name, card, 0,
 ++                                     (struct grub_net_bootp_packet *)
 ++                                     &pxe_mode->dhcp_ack,
 ++                                     sizeof (pxe_mode->dhcp_ack),
 ++                                     1, device, path);
 ++      }
 +     return;
 +   }
 + }
 +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
 +index c7c9f0e1d..92f9b5a6f 100644
 +--- a/include/grub/efi/api.h
 ++++ b/include/grub/efi/api.h
 +@@ -1452,14 +1452,67 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
 + 
 + typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
 + 
 ++typedef struct {
 ++  grub_uint8_t addr[4];
 ++} grub_efi_pxe_ipv4_address_t;
 ++
 ++typedef struct {
 ++  grub_uint8_t addr[16];
 ++} grub_efi_pxe_ipv6_address_t;
 ++
 ++typedef struct {
 ++  grub_uint8_t addr[32];
 ++} grub_efi_pxe_mac_address_t;
 ++
 ++typedef union {
 ++    grub_uint32_t addr[4];
 ++    grub_efi_pxe_ipv4_address_t v4;
 ++    grub_efi_pxe_ipv6_address_t v6;
 ++} grub_efi_pxe_ip_address_t;
 ++
 ++#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8
 ++typedef struct {
 ++    grub_uint8_t filters;
 ++    grub_uint8_t ip_cnt;
 ++    grub_uint16_t reserved;
 ++    grub_efi_pxe_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT];
 ++} grub_efi_pxe_ip_filter_t;
 ++
 ++typedef struct {
 ++    grub_efi_pxe_ip_address_t ip_addr;
 ++    grub_efi_pxe_mac_address_t mac_addr;
 ++} grub_efi_pxe_arp_entry_t;
 ++
 ++typedef struct {
 ++    grub_efi_pxe_ip_address_t ip_addr;
 ++    grub_efi_pxe_ip_address_t subnet_mask;
 ++    grub_efi_pxe_ip_address_t gw_addr;
 ++} grub_efi_pxe_route_entry_t;
 ++
 ++
 ++#define GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8
 ++#define GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8
 ++
 + typedef struct grub_efi_pxe_mode
 + {
 +-  grub_uint8_t unused[52];
 ++  grub_uint8_t started;
 ++  grub_uint8_t ipv6_available;
 ++  grub_uint8_t ipv6_supported;
 ++  grub_uint8_t using_ipv6;
 ++  grub_uint8_t unused[16];
 ++  grub_efi_pxe_ip_address_t station_ip;
 ++  grub_efi_pxe_ip_address_t subnet_mask;
 +   grub_efi_pxe_packet_t dhcp_discover;
 +   grub_efi_pxe_packet_t dhcp_ack;
 +   grub_efi_pxe_packet_t proxy_offer;
 +   grub_efi_pxe_packet_t pxe_discover;
 +   grub_efi_pxe_packet_t pxe_reply;
 ++  grub_efi_pxe_packet_t pxe_bis_reply;
 ++  grub_efi_pxe_ip_filter_t ip_filter;
 ++  grub_uint32_t arp_cache_entries;
 ++  grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES];
 ++  grub_uint32_t route_table_entries;
 ++  grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES];
 + } grub_efi_pxe_mode_t;
 + 
 + typedef struct grub_efi_pxe
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7710e9976a7d748ff8c15b0e83c82cf751d82be3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,43 @@@
++From bd06522c349270c5142ad4837a2d5163c2c78138 Mon Sep 17 00:00:00 2001
++From: Luca Boccassi <bluca@debian.org>
++Date: Tue, 15 May 2018 11:36:46 +0100
++Subject: Add patch to fix lockdown mode
++
++Description: do not overwrite sentinel byte in boot_params, breaks lockdown
++ grub currently copies the entire boot_params, which includes setting sentinel
++ byte to 0xff, which triggers sanitize_boot_params in the kernel which in
++ turn clears various boot_params variables, including the indication that
++ the booloader chain is verified and thus the kernel disables lockdown mode.
++ According to the information on the Fedora bug tracker, only the information
++ from byte 0x1f1 is necessary, so start copying from there instead.
++Author: Luca Boccassi <bluca@debian.org>
++Bug-Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1418360
++Forwarded: no
++Patch-Name: fix_lockdown.patch
++---
++ grub-core/loader/i386/efi/linux.c | 5 ++++-
++ 1 file changed, 4 insertions(+), 1 deletion(-)
++
++diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
++index de4471bc8..0e2796763 100644
++--- a/grub-core/loader/i386/efi/linux.c
+++++ b/grub-core/loader/i386/efi/linux.c
++@@ -27,6 +27,7 @@
++ #include <grub/i18n.h>
++ #include <grub/lib/cmdline.h>
++ #include <grub/efi/efi.h>
+++#include <stddef.h>
++ 
++ GRUB_MOD_LICENSE ("GPLv3+");
++ 
++@@ -346,7 +347,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
++       lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
++     }
++ 
++-  grub_memcpy (params, &lh, 2 * 512);
+++  /* do not overwrite below boot_params->hdr to avoid setting the sentinel byte */
+++  start = offsetof (struct linux_kernel_params, setup_sects);
+++  grub_memcpy ((grub_uint8_t *)params + start, (grub_uint8_t *)&lh + start, 2 * 512 - start);
++ 
++   params->type_of_loader = 0x21;
++ 
index 8acc59d6eb879ae8463240f894bfdfb7eda12c3f,0000000000000000000000000000000000000000..94437f073c4f65e18fd7d8a2a272d3dde750bb43
mode 100644,000000..100644
--- /dev/null
@@@ -1,194 -1,0 +1,194 @@@
-  INSTALL      | 11 ++++----
-  configure.ac | 74 ++++++++++++++++++++++------------------------------
 +From 3eec911197081a63d9dae28f1784ad01a06fb60a Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Tue, 30 Jan 2018 21:54:17 +0000
 +Subject: build: Use pkg-config to find FreeType
 +
 +pkg-config is apparently preferred over freetype-config these days (see
 +the BUGS section of freetype-config(1)).  pkg-config support was added
 +to FreeType in version 2.1.5, which was released in 2003, so it should
 +comfortably be available everywhere by now.
 +
 +We no longer need to explicitly substitute FREETYPE_CFLAGS and
 +FREETYPE_LIBS, since PKG_CHECK_MODULES does that automatically.
 +
 +Fixes Debian bug #887721.
 +
 +Reported-by: Hugh McMaster <hugh.mcmaster@outlook.com>
 +Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
 +
 +Bug-Debian: https://bugs.debian.org/887721
 +Last-Update: 2018-02-11
 +
 +Patch-Name: freetype-pkg-config.patch
 +---
++ INSTALL      | 11 +++++----
++ configure.ac | 74 +++++++++++++++++++++++++-----------------------------------
 + 2 files changed, 37 insertions(+), 48 deletions(-)
 +
 +diff --git a/INSTALL b/INSTALL
 +index f3c20edc8..b370d7753 100644
 +--- a/INSTALL
 ++++ b/INSTALL
 +@@ -37,6 +37,7 @@ configuring the GRUB.
 + * GNU gettext 0.17 or later
 + * GNU binutils 2.9.1.0.23 or later
 + * Flex 2.5.35 or later
 ++* pkg-config
 + * Other standard GNU/Unix tools
 + * a libc with large file support (e.g. glibc 2.1 or later)
 + 
 +@@ -52,7 +53,7 @@ For optional grub-emu features, you need:
 + 
 + To build GRUB's graphical terminal (gfxterm), you need:
 + 
 +-* FreeType 2 or later
 ++* FreeType 2.1.5 or later
 + * GNU Unifont
 + 
 + If you use a development snapshot or want to hack on GRUB you may
 +@@ -158,8 +159,8 @@ For this example the configure line might look like (more details below)
 + (some options are optional and included here for completeness but some rarely
 + used options are omitted):
 + 
 +-./configure BUILD_CC=gcc BUILD_FREETYPE=freetype-config --host=amd64-linux-gnu
 +-CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" FREETYPE=amd64-linux-gnu-freetype-config
 ++./configure BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config --host=amd64-linux-gnu
 ++CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" PKG_CONFIG=amd64-linux-gnu-pkg-config
 + --target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc
 + TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6"
 + TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip"
 +@@ -176,7 +177,7 @@ corresponding platform are not needed for the platform in question.
 +     2. BUILD_CFLAGS= for C options for build.
 +     3. BUILD_CPPFLAGS= for C preprocessor options for build.
 +     4. BUILD_LDFLAGS= for linker options for build.
 +-    5. BUILD_FREETYPE= for freetype-config for build (optional).
 ++    5. BUILD_PKG_CONFIG= for pkg-config for build (optional).
 + 
 +   - For host
 +     1. --host= to autoconf name of host.
 +@@ -184,7 +185,7 @@ corresponding platform are not needed for the platform in question.
 +     3. HOST_CFLAGS= for C options for host.
 +     4. HOST_CPPFLAGS= for C preprocessor options for host.
 +     5. HOST_LDFLAGS= for linker options for host.
 +-    6. FREETYPE= for freetype-config for host (optional).
 ++    6. PKG_CONFIG= for pkg-config for host (optional).
 +     7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
 +     8. Libfuse if any must be in standard linker folders (-lfuse) (optional).
 +     9. Libzfs if any must be in standard linker folders (-lzfs) (optional).
 +diff --git a/configure.ac b/configure.ac
 +index 85c23bd62..f102b7024 100644
 +--- a/configure.ac
 ++++ b/configure.ac
 +@@ -50,6 +50,10 @@ AC_PREREQ(2.60)
 + AC_CONFIG_SRCDIR([include/grub/dl.h])
 + AC_CONFIG_HEADER([config-util.h])
 + 
 ++# Explicitly check for pkg-config early on, since otherwise conditional
 ++# calls are problematic.
 ++PKG_PROG_PKG_CONFIG
 ++
 + # Program name transformations
 + AC_ARG_PROGRAM
 + grub_TRANSFORM([grub-bios-setup])
 +@@ -1493,29 +1497,22 @@ if test x"$enable_grub_mkfont" = xno ; then
 +   grub_mkfont_excuse="explicitly disabled"
 + fi
 + 
 +-if test x"$grub_mkfont_excuse" = x ; then
 +-  # Check for freetype libraries.
 +-  AC_CHECK_TOOLS([FREETYPE], [freetype-config])
 +-  if test "x$FREETYPE" = x ; then
 +-    grub_mkfont_excuse=["need freetype2 library"]
 +-  fi
 +-fi
 +-
 + unset ac_cv_header_ft2build_h
 + 
 + if test x"$grub_mkfont_excuse" = x ; then
 +   # Check for freetype libraries.
 +-  FREETYPE_CFLAGS=`$FREETYPE --cflags`
 +-  FREETYPE_LIBS=`$FREETYPE --libs`
 +-  SAVED_CPPFLAGS="$CPPFLAGS"
 +-  SAVED_LIBS="$LIBS"
 +-  CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS"
 +-  LIBS="$LIBS $FREETYPE_LIBS"
 +-  AC_CHECK_HEADERS([ft2build.h], [],
 +-     [grub_mkfont_excuse=["need freetype2 headers"]])
 +-  AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_mkfont_excuse=["freetype2 library unusable"]])
 +-  CPPFLAGS="$SAVED_CPPFLAGS"
 +-  LIBS="$SAVED_LIBS"
 ++  PKG_CHECK_MODULES([FREETYPE], [freetype2], [
 ++    SAVED_CPPFLAGS="$CPPFLAGS"
 ++    SAVED_LIBS="$LIBS"
 ++    CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS"
 ++    LIBS="$LIBS $FREETYPE_LIBS"
 ++    AC_CHECK_HEADERS([ft2build.h], [],
 ++      [grub_mkfont_excuse=["need freetype2 headers"]])
 ++    AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [],
 ++      [grub_mkfont_excuse=["freetype2 library unusable"]])
 ++    CPPFLAGS="$SAVED_CPPFLAGS"
 ++    LIBS="$SAVED_LIBS"
 ++  ], [grub_mkfont_excuse=["need freetype2 library"]])
 + fi
 + 
 + if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
 +@@ -1527,8 +1524,6 @@ else
 + enable_grub_mkfont=no
 + fi
 + AC_SUBST([enable_grub_mkfont])
 +-AC_SUBST([FREETYPE_CFLAGS])
 +-AC_SUBST([FREETYPE_LIBS])
 + 
 + SAVED_CC="$CC"
 + SAVED_CPP="$CPP"
 +@@ -1558,25 +1553,21 @@ AC_SUBST([BUILD_WORDS_BIGENDIAN])
 + 
 + if test x"$grub_build_mkfont_excuse" = x ; then
 +   # Check for freetype libraries.
 +-  AC_CHECK_PROGS([BUILD_FREETYPE], [freetype-config])
 +-  if test "x$BUILD_FREETYPE" = x ; then
 +-    grub_build_mkfont_excuse=["need freetype2 library"]
 +-  fi
 +-fi
 +-
 +-if test x"$grub_build_mkfont_excuse" = x ; then
 +-  # Check for freetype libraries.
 +-  BUILD_FREETYPE_CFLAGS=`$BUILD_FREETYPE --cflags`
 +-  BUILD_FREETYPE_LIBS=`$BUILD_FREETYPE --libs`
 +-  SAVED_CPPFLAGS_2="$CPPFLAGS"
 +-  SAVED_LIBS="$LIBS"
 +-  CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS"
 +-  LIBS="$LIBS $BUILD_FREETYPE_LIBS"
 +-  AC_CHECK_HEADERS([ft2build.h], [],
 +-     [grub_build_mkfont_excuse=["need freetype2 headers"]])
 +-  AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_build_mkfont_excuse=["freetype2 library unusable"]])
 +-  LIBS="$SAVED_LIBS"
 +-  CPPFLAGS="$SAVED_CPPFLAGS_2"
 ++  SAVED_PKG_CONFIG="$PKG_CONFIG"
 ++  test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG"
 ++  PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [
 ++    SAVED_CPPFLAGS_2="$CPPFLAGS"
 ++    SAVED_LIBS="$LIBS"
 ++    CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS"
 ++    LIBS="$LIBS $BUILD_FREETYPE_LIBS"
 ++    AC_CHECK_HEADERS([ft2build.h], [],
 ++      [grub_build_mkfont_excuse=["need freetype2 headers"]])
 ++    AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [],
 ++      [grub_build_mkfont_excuse=["freetype2 library unusable"]])
 ++    LIBS="$SAVED_LIBS"
 ++    CPPFLAGS="$SAVED_CPPFLAGS_2"
 ++  ], [grub_build_mkfont_excuse=["need freetype2 library"]])
 ++  PKG_CONFIG="$SAVED_PKG_CONFIG"
 + fi
 + 
 + if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then
 +@@ -1595,9 +1586,6 @@ if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || tes
 +   fi
 + fi
 + 
 +-AC_SUBST([BUILD_FREETYPE_CFLAGS])
 +-AC_SUBST([BUILD_FREETYPE_LIBS])
 +-
 + CC="$SAVED_CC"
 + CPP="$SAVED_CPP"
 + CFLAGS="$SAVED_CFLAGS"
index c1fc1348dc866e9403a301fdab6ca73a3dc02af7,0000000000000000000000000000000000000000..f226b126aed163f07c597d4b4b367156b0108303
mode 100644,000000..100644
--- /dev/null
@@@ -1,278 -1,0 +1,278 @@@
-  configure.ac                         |  11 ++
-  grub-core/Makefile.core.def          |   9 ++
-  grub-core/commands/i386/pc/hwmatch.c | 146 +++++++++++++++++++++++++++
-  util/grub.d/10_linux.in              |  37 ++++++-
 +From 9cccd7167b2bd4e6198903674a186cf657ef13bd Mon Sep 17 00:00:00 2001
 +From: Evan Broder <evan@ebroder.net>
 +Date: Mon, 13 Jan 2014 12:13:29 +0000
 +Subject: Add configure option to enable gfxpayload=keep dynamically
 +
 +Set GRUB_GFXPAYLOAD_LINUX=keep unless it's known to be unsupported on
 +the current hardware.  See
 +https://blueprints.launchpad.net/ubuntu/+spec/packageselection-foundations-n-grub2-boot-framebuffer.
 +
 +Author: Colin Watson <cjwatson@ubuntu.com>
 +Forwarded: no
 +Last-Update: 2013-12-25
 +
 +Patch-Name: gfxpayload_dynamic.patch
 +---
- @@ -889,6 +889,15 @@ module = {
-    common = lib/hexdump.c;
++ configure.ac                         |  11 +++
++ grub-core/Makefile.core.def          |   9 +++
++ grub-core/commands/i386/pc/hwmatch.c | 146 +++++++++++++++++++++++++++++++++++
++ util/grub.d/10_linux.in              |  37 ++++++++-
 + 4 files changed, 200 insertions(+), 3 deletions(-)
 + create mode 100644 grub-core/commands/i386/pc/hwmatch.c
 +
 +diff --git a/configure.ac b/configure.ac
 +index e508f9c43..7f1431352 100644
 +--- a/configure.ac
 ++++ b/configure.ac
 +@@ -1852,6 +1852,17 @@ else
 + fi
 + AC_SUBST([QUICK_BOOT])
 + 
 ++AC_ARG_ENABLE([gfxpayload-dynamic],
 ++              [AS_HELP_STRING([--enable-gfxpayload-dynamic],
 ++                              [use GRUB_GFXPAYLOAD_LINUX=keep unless explicitly unsupported on current hardware (default=no)])],
 ++              [], [enable_gfxpayload_dynamic=no])
 ++if test x"$enable_gfxpayload_dynamic" = xyes ; then
 ++  GFXPAYLOAD_DYNAMIC=1
 ++else
 ++  GFXPAYLOAD_DYNAMIC=0
 ++fi
 ++AC_SUBST([GFXPAYLOAD_DYNAMIC])
 ++
 + LIBS=""
 + 
 + AC_SUBST([FONT_SOURCE])
 +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
 +index 68e47a727..3b389277c 100644
 +--- a/grub-core/Makefile.core.def
 ++++ b/grub-core/Makefile.core.def
- +module = {
++@@ -890,6 +890,15 @@ module = {
 + };
 + 
-  module = {
++ module = {
 ++  name = hwmatch;
 ++  i386_pc = commands/i386/pc/hwmatch.c;
 ++  enable = i386_pc;
 ++  common = gnulib/regex.c;
 ++  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
 ++  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
 ++};
 ++
+++module = {
 +   name = keystatus;
 +   common = commands/keystatus.c;
++ };
 +diff --git a/grub-core/commands/i386/pc/hwmatch.c b/grub-core/commands/i386/pc/hwmatch.c
 +new file mode 100644
 +index 000000000..c9f7c9f19
 +--- /dev/null
 ++++ b/grub-core/commands/i386/pc/hwmatch.c
 +@@ -0,0 +1,146 @@
 ++/* hwmatch.c - Match hardware against a whitelist/blacklist.  */
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 2011  Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#include <grub/dl.h>
 ++#include <grub/misc.h>
 ++#include <grub/command.h>
 ++#include <grub/pci.h>
 ++#include <grub/normal.h>
 ++#include <grub/file.h>
 ++#include <grub/env.h>
 ++#include <grub/i18n.h>
 ++#include <regex.h>
 ++
 ++GRUB_MOD_LICENSE ("GPLv3+");
 ++
 ++/* Context for grub_cmd_hwmatch.  */
 ++struct hwmatch_ctx
 ++{
 ++  grub_file_t matches_file;
 ++  int class_match;
 ++  int match;
 ++};
 ++
 ++/* Helper for grub_cmd_hwmatch.  */
 ++static int
 ++hwmatch_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
 ++{
 ++  struct hwmatch_ctx *ctx = data;
 ++  grub_pci_address_t addr;
 ++  grub_uint32_t class, baseclass, vendor, device;
 ++  grub_pci_id_t subpciid;
 ++  grub_uint32_t subvendor, subdevice, subclass;
 ++  char *id, *line;
 ++
 ++  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
 ++  class = grub_pci_read (addr);
 ++  baseclass = class >> 24;
 ++
 ++  if (ctx->class_match != baseclass)
 ++    return 0;
 ++
 ++  vendor = pciid & 0xffff;
 ++  device = pciid >> 16;
 ++
 ++  addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR);
 ++  subpciid = grub_pci_read (addr);
 ++
 ++  subclass = (class >> 16) & 0xff;
 ++  subvendor = subpciid & 0xffff;
 ++  subdevice = subpciid >> 16;
 ++
 ++  id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x",
 ++                    vendor, device, subvendor, subdevice,
 ++                    baseclass, subclass);
 ++
 ++  grub_file_seek (ctx->matches_file, 0);
 ++  while ((line = grub_file_getline (ctx->matches_file)) != NULL)
 ++    {
 ++      char *anchored_line;
 ++      regex_t regex;
 ++      int ret;
 ++
 ++      if (! *line || *line == '#')
 ++     {
 ++       grub_free (line);
 ++       continue;
 ++     }
 ++
 ++      anchored_line = grub_xasprintf ("^%s$", line);
 ++      ret = regcomp (&regex, anchored_line, REG_EXTENDED | REG_NOSUB);
 ++      grub_free (anchored_line);
 ++      if (ret)
 ++     {
 ++       grub_free (line);
 ++       continue;
 ++     }
 ++
 ++      ret = regexec (&regex, id, 0, NULL, 0);
 ++      regfree (&regex);
 ++      grub_free (line);
 ++      if (! ret)
 ++     {
 ++       ctx->match = 1;
 ++       return 1;
 ++     }
 ++    }
 ++
 ++  return 0;
 ++}
 ++
 ++static grub_err_t
 ++grub_cmd_hwmatch (grub_command_t cmd __attribute__ ((unused)),
 ++               int argc, char **args)
 ++{
 ++  struct hwmatch_ctx ctx = { .match = 0 };
 ++  char *match_str;
 ++
 ++  if (argc < 2)
 ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, "list file and class required");
 ++
 ++  ctx.matches_file = grub_file_open (args[0]);
 ++  if (! ctx.matches_file)
 ++    return grub_errno;
 ++
 ++  ctx.class_match = grub_strtol (args[1], 0, 10);
 ++
 ++  grub_pci_iterate (hwmatch_iter, &ctx);
 ++
 ++  match_str = grub_xasprintf ("%d", ctx.match);
 ++  grub_env_set ("match", match_str);
 ++  grub_free (match_str);
 ++
 ++  grub_file_close (ctx.matches_file);
 ++
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 ++static grub_command_t cmd;
 ++\f
 ++GRUB_MOD_INIT(hwmatch)
 ++{
 ++  cmd = grub_register_command ("hwmatch", grub_cmd_hwmatch,
 ++                            N_("MATCHES-FILE CLASS"),
 ++                            N_("Match PCI devices."));
 ++}
 ++
 ++GRUB_MOD_FINI(hwmatch)
 ++{
 ++  grub_unregister_command (cmd);
 ++}
 +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
 +index 0f8a16837..2983b515f 100644
 +--- a/util/grub.d/10_linux.in
 ++++ b/util/grub.d/10_linux.in
 +@@ -23,6 +23,7 @@ datarootdir="@datarootdir@"
 + ubuntu_recovery="@UBUNTU_RECOVERY@"
 + quiet_boot="@QUIET_BOOT@"
 + quick_boot="@QUICK_BOOT@"
 ++gfxpayload_dynamic="@GFXPAYLOAD_DYNAMIC@"
 + 
 + . "$pkgdatadir/grub-mkconfig_lib"
 + 
 +@@ -135,9 +136,10 @@ linux_entry ()
 +       if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
 +        echo "        load_video" | sed "s/^/$submenu_indentation/"
 +       fi
 +-      if [ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]; then
 +-       echo "        set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/"
 +-      fi
 ++  fi
 ++  if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \
 ++     ([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then
 ++      echo " set gfxpayload=\$linux_gfx_mode" | sed "s/^/$submenu_indentation/"
 +   fi
 + 
 +   echo "     insmod gzio" | sed "s/^/$submenu_indentation/"
 +@@ -212,6 +214,35 @@ prepare_root_cache=
 + boot_device_id=
 + title_correction_code=
 + 
 ++# Use ELILO's generic "efifb" when it's known to be available.
 ++# FIXME: We need an interface to select vesafb in case efifb can't be used.
 ++if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then
 ++  echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX"
 ++else
 ++  cat << EOF
 ++if [ "\${recordfail}" != 1 ]; then
 ++  if [ -e \${prefix}/gfxblacklist.txt ]; then
 ++    if hwmatch \${prefix}/gfxblacklist.txt 3; then
 ++      if [ \${match} = 0 ]; then
 ++        set linux_gfx_mode=keep
 ++      else
 ++        set linux_gfx_mode=text
 ++      fi
 ++    else
 ++      set linux_gfx_mode=text
 ++    fi
 ++  else
 ++    set linux_gfx_mode=keep
 ++  fi
 ++else
 ++  set linux_gfx_mode=text
 ++fi
 ++EOF
 ++fi
 ++cat << EOF
 ++export linux_gfx_mode
 ++EOF
 ++
 + # Extra indentation to add to menu entries in a submenu. We're not in a submenu
 + # yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
 + submenu_indentation=""
index 15721a3412951bf3a3d2e4c3ad1b60ce568492b4,0000000000000000000000000000000000000000..3102895d0494c3f080ab8bea719a2d778d510791
mode 100644,000000..100644
--- /dev/null
@@@ -1,202 -1,0 +1,202 @@@
-  util/grub-install.c | 110 +++++++++++++++++++++++++++++++++++++++++++-
 +From c009126d6256205355a392dc7002ed1dac2dc59f Mon Sep 17 00:00:00 2001
 +From: Steve McIntyre <93sam@debian.org>
 +Date: Wed, 3 Dec 2014 01:25:12 +0000
 +Subject: Add support for forcing EFI installation to the removable media path
 +
 +Add an extra option to grub-install "--force-extra-removable". On EFI
 +platforms, this will cause an extra copy of the grub-efi image to be
 +written to the appropriate removable media patch
 +/boot/efi/EFI/BOOT/BOOT$ARCH.EFI as well. This will help with broken
 +UEFI implementations where the firmware does not work when configured
 +with new boot paths.
 +
 +Signed-off-by: Steve McIntyre <93sam@debian.org>
 +
 +Bug-Debian: https://bugs.debian.org/767037 https://bugs.debian.org/773092
 +Forwarded: Not yet
 +Last-Update: 2014-12-20
 +
 +Patch-Name: grub-install-extra-removable.patch
 +---
++ util/grub-install.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 + 1 file changed, 108 insertions(+), 2 deletions(-)
 +
 +diff --git a/util/grub-install.c b/util/grub-install.c
 +index 7a24767c1..1fbb4c7da 100644
 +--- a/util/grub-install.c
 ++++ b/util/grub-install.c
 +@@ -56,6 +56,7 @@
 + 
 + static char *target;
 + static int removable = 0;
 ++static int force_extra_removable = 0;
 + static int recheck = 0;
 + static int update_nvram = 1;
 + static char *install_device = NULL;
 +@@ -113,7 +114,8 @@ enum
 +     OPTION_LABEL_BGCOLOR,
 +     OPTION_PRODUCT_VERSION,
 +     OPTION_UEFI_SECURE_BOOT,
 +-    OPTION_NO_UEFI_SECURE_BOOT
 ++    OPTION_NO_UEFI_SECURE_BOOT,
 ++    OPTION_FORCE_EXTRA_REMOVABLE
 +   };
 + 
 + static int fs_probe = 1;
 +@@ -216,6 +218,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
 +       removable = 1;
 +       return 0;
 + 
 ++    case OPTION_FORCE_EXTRA_REMOVABLE:
 ++      force_extra_removable = 1;
 ++      return 0;
 ++
 +     case OPTION_ALLOW_FLOPPY:
 +       allow_floppy = 1;
 +       return 0;
 +@@ -322,6 +328,9 @@ static struct argp_option options[] = {
 +    N_("do not install an image usable with UEFI Secure Boot, even if the "
 +       "system was currently started using it. "
 +       "This option is only available on EFI."), 2},
 ++  {"force-extra-removable", OPTION_FORCE_EXTRA_REMOVABLE, 0, 0,
 ++   N_("force installation to the removable media path also. "
 ++      "This option is only available on EFI."), 2},
 +   {0, 0, 0, 0, 0, 0}
 + };
 + 
 +@@ -835,6 +844,91 @@ fill_core_services (const char *core_services)
 +   free (sysv_plist);
 + }
 + 
 ++/* Helper routine for also_install_removable() below. Walk through the
 ++   specified dir, looking to see if there is a file/dir that matches
 ++   the search string exactly, but in a case-insensitive manner. If so,
 ++   return a copy of the exact file/dir that *does* exist. If not,
 ++   return NULL */
 ++static char *
 ++check_component_exists(const char *dir,
 ++                    const char *search)
 ++{
 ++  grub_util_fd_dir_t d;
 ++  grub_util_fd_dirent_t de;
 ++  char *found = NULL;
 ++
 ++  d = grub_util_fd_opendir (dir);
 ++  if (!d)
 ++    grub_util_error (_("cannot open directory `%s': %s"),
 ++                  dir, grub_util_fd_strerror ());
 ++
 ++  while ((de = grub_util_fd_readdir (d)))
 ++    {
 ++      if (strcasecmp (de->d_name, search) == 0)
 ++     {
 ++       found = xstrdup (de->d_name);
 ++       break;
 ++     }
 ++    }
 ++  grub_util_fd_closedir (d);
 ++  return found;
 ++}
 ++
 ++/* Some complex directory-handling stuff in here, to cope with
 ++ * case-insensitive FAT/VFAT filesystem semantics. Ugh. */
 ++static void
 ++also_install_removable(const char *src,
 ++                    const char *base_efidir,
 ++                    const char *efi_suffix_upper)
 ++{
 ++  char *efi_file = NULL;
 ++  char *dst = NULL;
 ++  char *cur = NULL;
 ++  char *found = NULL;
 ++
 ++  if (!efi_suffix_upper)
 ++    grub_util_error ("%s", _("efi_suffix_upper not set"));
 ++  efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper);
 ++
 ++  /* We need to install in $base_efidir/EFI/BOOT/$efi_file, but we
 ++   * need to cope with case-insensitive stuff here. Build the path one
 ++   * component at a time, checking for existing matches each time. */
 ++
 ++  /* Look for "EFI" in base_efidir. Make it if it does not exist in
 ++   * some form. */
 ++  found = check_component_exists(base_efidir, "EFI");
 ++  if (found == NULL)
 ++    found = xstrdup("EFI");
 ++  dst = grub_util_path_concat (2, base_efidir, found);
 ++  cur = xstrdup (dst);
 ++  free (dst);
 ++  free (found);
 ++  grub_install_mkdir_p (cur);
 ++
 ++  /* Now BOOT */
 ++  found = check_component_exists(cur, "BOOT");
 ++  if (found == NULL)
 ++    found = xstrdup("BOOT");
 ++  dst = grub_util_path_concat (2, cur, found);
 ++  cur = xstrdup (dst);
 ++  free (dst);
 ++  free (found);
 ++  grub_install_mkdir_p (cur);
 ++
 ++  /* Now $efi_file */
 ++  found = check_component_exists(cur, efi_file);
 ++  if (found == NULL)
 ++    found = xstrdup(efi_file);
 ++  dst = grub_util_path_concat (2, cur, found);
 ++  cur = xstrdup (dst);
 ++  free (dst);
 ++  free (found);
 ++  grub_install_copy_file (src, cur, 1);
 ++
 ++  free (cur);
 ++  free (efi_file);
 ++}
 ++
 + int
 + main (int argc, char *argv[])
 + {
 +@@ -852,6 +946,7 @@ main (int argc, char *argv[])
 +   char *relative_grubdir;
 +   char **efidir_device_names = NULL;
 +   grub_device_t efidir_grub_dev = NULL;
 ++  char *base_efidir = NULL;
 +   char *efidir_grub_devname;
 +   int efidir_is_mac = 0;
 +   int is_prep = 0;
 +@@ -884,6 +979,9 @@ main (int argc, char *argv[])
 +       bootloader_id = xstrdup ("grub");
 +     }
 + 
 ++  if (removable && force_extra_removable)
 ++    grub_util_error (_("Invalid to use both --removable and --force_extra_removable"));
 ++
 +   if (!grub_install_source_directory)
 +     {
 +       if (!target)
 +@@ -1093,6 +1191,8 @@ main (int argc, char *argv[])
 +       if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
 +      grub_util_error (_("%s doesn't look like an EFI partition"), efidir);
 + 
 ++      base_efidir = xstrdup(efidir);
 ++
 +       /* The EFI specification requires that an EFI System Partition must
 +       contain an "EFI" subdirectory, and that OS loaders are stored in
 +       subdirectories below EFI.  Vendors are expected to pick names that do
 +@@ -1980,9 +2080,15 @@ main (int argc, char *argv[])
 +          fprintf (config_dst_f, "configfile $prefix/grub.cfg\n");
 +          fclose (config_dst_f);
 +          free (config_dst);
 ++         if (force_extra_removable)
 ++           also_install_removable(efi_signed, base_efidir, efi_suffix_upper);
 +        }
 +      else
 +-       grub_install_copy_file (imgfile, dst, 1);
 ++       {
 ++         grub_install_copy_file (imgfile, dst, 1);
 ++         if (force_extra_removable)
 ++           also_install_removable(imgfile, base_efidir, efi_suffix_upper);
 ++       }
 +      free (dst);
 +       }
 +       if (!removable && update_nvram)
index ce0b380ad66a7ca150b8c66caa709148c0e0c797,0000000000000000000000000000000000000000..c4bd12de32828d210f8d3d5c34ec242b25ddba30
mode 100644,000000..100644
--- /dev/null
@@@ -1,118 -1,0 +1,118 @@@
-  util/grub-install-common.c | 40 +++++++++++++++++++++++++++++++-------
 +From 03ca727beff305cee6e925af0ec9d37f8f5046f8 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:07 +0000
 +Subject: Prefer translations from Ubuntu language packs if available
 +
 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/537998
 +Forwarded: not-needed
 +Last-Update: 2013-12-25
 +
 +Patch-Name: install_locale_langpack.patch
 +---
- @@ -816,6 +827,19 @@ grub_install_copy_files (const char *src,
-             continue;
++ util/grub-install-common.c | 40 +++++++++++++++++++++++++++++++++-------
 + 1 file changed, 33 insertions(+), 7 deletions(-)
 +
 +diff --git a/util/grub-install-common.c b/util/grub-install-common.c
 +index 452b230da..c9d5e3d0f 100644
 +--- a/util/grub-install-common.c
 ++++ b/util/grub-install-common.c
 +@@ -595,17 +595,25 @@ get_localedir (void)
 + }
 + 
 + static void
 +-copy_locales (const char *dstd)
 ++copy_locales (const char *dstd, int langpack)
 + {
 +   grub_util_fd_dir_t d;
 +   grub_util_fd_dirent_t de;
 +   const char *locale_dir = get_localedir ();
 ++  char *dir;
 + 
 +-  d = grub_util_fd_opendir (locale_dir);
 ++  if (langpack)
 ++    dir = xasprintf ("%s-langpack", locale_dir);
 ++  else
 ++    dir = xstrdup (locale_dir);
 ++
 ++  d = grub_util_fd_opendir (dir);
 +   if (!d)
 +     {
 +-      grub_util_warn (_("cannot open directory `%s': %s"),
 +-                   locale_dir, grub_util_fd_strerror ());
 ++      if (!langpack)
 ++     grub_util_warn (_("cannot open directory `%s': %s"),
 ++                     dir, grub_util_fd_strerror ());
 ++      free (dir);
 +       return;
 +     }
 + 
 +@@ -622,14 +630,14 @@ copy_locales (const char *dstd)
 +       if (ext && (grub_strcmp (ext, ".mo") == 0
 +                || grub_strcmp (ext, ".gmo") == 0))
 +      {
 +-       srcf = grub_util_path_concat (2, locale_dir, de->d_name);
 ++       srcf = grub_util_path_concat (2, dir, de->d_name);
 +        dstf = grub_util_path_concat (2, dstd, de->d_name);
 +        ext = grub_strrchr (dstf, '.');
 +        grub_strcpy (ext, ".mo");
 +      }
 +       else
 +      {
 +-       srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name,
 ++       srcf = grub_util_path_concat_ext (4, dir, de->d_name,
 +                                          "LC_MESSAGES", PACKAGE, ".mo");
 +        dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo");
 +      }
 +@@ -638,6 +646,7 @@ copy_locales (const char *dstd)
 +       free (dstf);
 +     }
 +   grub_util_fd_closedir (d);
 ++  free (dir);
 + }
 + 
 + static struct
 +@@ -793,12 +802,14 @@ grub_install_copy_files (const char *src,
 +     {
 +       char *srcd = grub_util_path_concat (2, src, "po");
 +       copy_by_ext (srcd, dst_locale, ".mo", 0);
 +-      copy_locales (dst_locale);
 ++      copy_locales (dst_locale, 0);
 ++      copy_locales (dst_locale, 1);
 +       free (srcd);
 +     }
 +   else
 +     {
 +       const char *locale_dir = get_localedir ();
 ++      char *locale_langpack_dir = xasprintf ("%s-langpack", locale_dir);
 + 
 +       for (i = 0; i < install_locales.n_entries; i++)
 +      {
- +       srcf = grub_util_path_concat_ext (4,
++@@ -817,6 +828,19 @@ grub_install_copy_files (const char *src,
 +          }
 +        free (srcf);
-         srcf = grub_util_path_concat_ext (4,
++        srcf = grub_util_path_concat_ext (4,
 ++                                              locale_langpack_dir,
 ++                                              install_locales.entries[i],
 ++                                              "LC_MESSAGES",
 ++                                              PACKAGE,
 ++                                              ".mo");
 ++       if (grub_install_compress_file (srcf, dstf, 0))
 ++         {
 ++           free (srcf);
 ++           free (dstf);
 ++           continue;
 ++         }
 ++       free (srcf);
+++       srcf = grub_util_path_concat_ext (4,
 +                                               locale_dir,
 +                                               install_locales.entries[i],
++                                               "LC_MESSAGES",
 +@@ -831,6 +855,8 @@ grub_install_copy_files (const char *src,
 +        grub_util_error (_("cannot find locale `%s'"),
 +                         install_locales.entries[i]);
 +      }
 ++
 ++      free (locale_langpack_dir);
 +     }
 + 
 +   if (install_themes.is_default)
index ab8bf083825a46fe81cedf29371ca2d587b5ea82,0000000000000000000000000000000000000000..5acb9bca202069dcc2ebbc83ae8f7adb962cf482
mode 100644,000000..100644
--- /dev/null
@@@ -1,220 -1,0 +1,220 @@@
-  grub-core/osdep/linux/platform.c   | 72 ++++++++++++++++++++++++++++++
-  grub-core/osdep/unix/platform.c    | 28 +++++++++---
-  grub-core/osdep/windows/platform.c |  6 +++
 +From 4ee18c4a571e455f1a14762006f91d6f0ae76f41 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@debian.org>
 +Date: Tue, 28 Jan 2014 14:40:02 +0000
 +Subject: Port yaboot logic for various powerpc machine types
 +
 +Some powerpc machines require not updating the NVRAM.  This can be handled
 +by existing grub-install command-line options, but it's friendlier to detect
 +this automatically.
 +
 +On chrp_ibm machines, use the nvram utility rather than nvsetenv.  (This
 +is possibly suitable for other machines too, but that needs to be
 +verified.)
 +
 +Forwarded: no
 +Last-Update: 2014-10-15
 +
 +Patch-Name: install_powerpc_machtypes.patch
 +---
 + grub-core/osdep/basic/platform.c   |  5 +++
-  util/grub-install.c                | 11 +++++
++ grub-core/osdep/linux/platform.c   | 72 ++++++++++++++++++++++++++++++++++++++
++ grub-core/osdep/unix/platform.c    | 28 +++++++++++----
++ grub-core/osdep/windows/platform.c |  6 ++++
 + include/grub/util/install.h        |  3 ++
++ util/grub-install.c                | 11 ++++++
 + 6 files changed, 119 insertions(+), 6 deletions(-)
 +
 +diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c
 +index 4b5502aeb..2ab907976 100644
 +--- a/grub-core/osdep/basic/platform.c
 ++++ b/grub-core/osdep/basic/platform.c
 +@@ -24,3 +24,8 @@ grub_install_get_default_x86_platform (void)
 +   return "i386-pc";
 + }
 + 
 ++const char *
 ++grub_install_get_default_powerpc_machtype (void)
 ++{
 ++  return "generic";
 ++}
 +diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c
 +index 35f1bcc0e..9805c36d4 100644
 +--- a/grub-core/osdep/linux/platform.c
 ++++ b/grub-core/osdep/linux/platform.c
 +@@ -24,6 +24,7 @@
 + #include <grub/emu/misc.h>
 + #include <sys/types.h>
 + #include <dirent.h>
 ++#include <stdio.h>
 + #include <stdlib.h>
 + #include <string.h>
 + 
 +@@ -145,3 +146,74 @@ grub_install_get_default_x86_platform (void)
 +   grub_util_info ("... not found");
 +   return "i386-pc";
 + }
 ++
 ++const char *
 ++grub_install_get_default_powerpc_machtype (void)
 ++{
 ++  FILE *fp;
 ++  char *buf = NULL;
 ++  size_t len = 0;
 ++  const char *machtype = "generic";
 ++
 ++  fp = grub_util_fopen ("/proc/cpuinfo", "r");
 ++  if (! fp)
 ++    return machtype;
 ++
 ++  while (getline (&buf, &len, fp) > 0)
 ++    {
 ++      if (strncmp (buf, "pmac-generation",
 ++                sizeof ("pmac-generation") - 1) == 0)
 ++     {
 ++       if (strstr (buf, "NewWorld"))
 ++         {
 ++           machtype = "pmac_newworld";
 ++           break;
 ++         }
 ++       if (strstr (buf, "OldWorld"))
 ++         {
 ++           machtype = "pmac_oldworld";
 ++           break;
 ++         }
 ++     }
 ++
 ++      if (strncmp (buf, "motherboard", sizeof ("motherboard") - 1) == 0 &&
 ++       strstr (buf, "AAPL"))
 ++     {
 ++       machtype = "pmac_oldworld";
 ++       break;
 ++     }
 ++
 ++      if (strncmp (buf, "machine", sizeof ("machine") - 1) == 0 &&
 ++       strstr (buf, "CHRP IBM"))
 ++     {
 ++       if (strstr (buf, "qemu"))
 ++         {
 ++           machtype = "chrp_ibm_qemu";
 ++           break;
 ++         }
 ++       else
 ++         {
 ++           machtype = "chrp_ibm";
 ++           break;
 ++         }
 ++     }
 ++
 ++      if (strncmp (buf, "platform", sizeof ("platform") - 1) == 0)
 ++     {
 ++       if (strstr (buf, "Maple"))
 ++         {
 ++           machtype = "maple";
 ++           break;
 ++         }
 ++       if (strstr (buf, "Cell"))
 ++         {
 ++           machtype = "cell";
 ++           break;
 ++         }
 ++     }
 ++    }
 ++
 ++  free (buf);
 ++  fclose (fp);
 ++  return machtype;
 ++}
 +diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
 +index a3fcfcaca..28cb37e15 100644
 +--- a/grub-core/osdep/unix/platform.c
 ++++ b/grub-core/osdep/unix/platform.c
 +@@ -212,13 +212,29 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
 +   else
 +     boot_device = get_ofpathname (install_device);
 + 
 +-  if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
 +-       boot_device, NULL }))
 ++  if (strcmp (grub_install_get_default_powerpc_machtype (), "chrp_ibm") == 0)
 +     {
 +-      char *cmd = xasprintf ("setenv boot-device %s", boot_device);
 +-      grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually.  At the IEEE1275 prompt, type:\n  %s\n"),
 +-                    cmd);
 +-      free (cmd);
 ++      char *arg = xasprintf ("boot-device=%s", boot_device);
 ++      if (grub_util_exec ((const char * []){ "nvram",
 ++       "--update-config", arg, NULL }))
 ++     {
 ++       char *cmd = xasprintf ("setenv boot-device %s", boot_device);
 ++       grub_util_error (_("`nvram' failed. \nYou will have to set `boot-device' variable manually.  At the IEEE1275 prompt, type:\n  %s\n"),
 ++                        cmd);
 ++       free (cmd);
 ++     }
 ++      free (arg);
 ++    }
 ++  else
 ++    {
 ++      if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
 ++           boot_device, NULL }))
 ++     {
 ++       char *cmd = xasprintf ("setenv boot-device %s", boot_device);
 ++       grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually.  At the IEEE1275 prompt, type:\n  %s\n"),
 ++                        cmd);
 ++       free (cmd);
 ++     }
 +     }
 + 
 +   free (boot_device);
 +diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
 +index 912269191..c30025b13 100644
 +--- a/grub-core/osdep/windows/platform.c
 ++++ b/grub-core/osdep/windows/platform.c
 +@@ -128,6 +128,12 @@ grub_install_get_default_x86_platform (void)
 +     return "i386-efi";
 + }
 + 
 ++const char *
 ++grub_install_get_default_powerpc_machtype (void)
 ++{
 ++  return "generic";
 ++}
 ++
 + static void *
 + get_efi_variable (const wchar_t *varname, ssize_t *len)
 + {
 +diff --git a/include/grub/util/install.h b/include/grub/util/install.h
 +index 5ca4811cd..9f517a1bb 100644
 +--- a/include/grub/util/install.h
 ++++ b/include/grub/util/install.h
 +@@ -206,6 +206,9 @@ grub_install_create_envblk_file (const char *name);
 + const char *
 + grub_install_get_default_x86_platform (void);
 + 
 ++const char *
 ++grub_install_get_default_powerpc_machtype (void);
 ++
 + void
 + grub_install_register_efi (grub_device_t efidir_grub_dev,
 +                         const char *efifile_path,
 +diff --git a/util/grub-install.c b/util/grub-install.c
 +index a73d12e87..57d6aab76 100644
 +--- a/util/grub-install.c
 ++++ b/util/grub-install.c
 +@@ -1155,7 +1155,18 @@ main (int argc, char *argv[])
 + 
 +   if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
 +     {
 ++      const char *machtype = grub_install_get_default_powerpc_machtype ();
 +       int is_guess = 0;
 ++
 ++      if (strcmp (machtype, "pmac_oldworld") == 0)
 ++     update_nvram = 0;
 ++      else if (strcmp (machtype, "cell") == 0)
 ++     update_nvram = 0;
 ++      else if (strcmp (machtype, "generic") == 0)
 ++     update_nvram = 0;
 ++      else if (strcmp (machtype, "chrp_ibm_qemu") == 0)
 ++     update_nvram = 0;
 ++
 +       if (!macppcdir)
 +      {
 +        char *d;
index 24f1b72d00fc758bc04d050a074418542738fc9c,0000000000000000000000000000000000000000..93860808fb00e3ca7bb7621c942b8164f44b48ed
mode 100644,000000..100644
--- /dev/null
@@@ -1,291 -1,0 +1,291 @@@
-  util/grub-install.c | 192 +++++++++++++++++++++++++++++++++-----------
 +From 1917ef9042066380b9839501f7ccc598617847ae Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:22 +0000
 +Subject: Install signed images if UEFI Secure Boot is enabled
 +MIME-Version: 1.0
 +Content-Type: text/plain; charset=UTF-8
 +Content-Transfer-Encoding: 8bit
 +
 +Author: Stéphane Graber <stgraber@ubuntu.com>
 +Author: Steve Langasek <steve.langasek@ubuntu.com>
 +Author: Linn Crosetto <linn@hpe.com>
 +Author: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
 +Forwarded: no
 +Last-Update: 2016-11-01
 +
 +Patch-Name: install_signed.patch
 +---
++ util/grub-install.c | 192 +++++++++++++++++++++++++++++++++++++++-------------
 + 1 file changed, 145 insertions(+), 47 deletions(-)
 +
 +diff --git a/util/grub-install.c b/util/grub-install.c
 +index 0e1303ee5..260dabcfb 100644
 +--- a/util/grub-install.c
 ++++ b/util/grub-install.c
 +@@ -80,6 +80,7 @@ static char *label_color;
 + static char *label_bgcolor;
 + static char *product_version;
 + static int add_rs_codes = 1;
 ++static int uefi_secure_boot = 1;
 + 
 + enum
 +   {
 +@@ -110,7 +111,9 @@ enum
 +     OPTION_LABEL_FONT,
 +     OPTION_LABEL_COLOR,
 +     OPTION_LABEL_BGCOLOR,
 +-    OPTION_PRODUCT_VERSION
 ++    OPTION_PRODUCT_VERSION,
 ++    OPTION_UEFI_SECURE_BOOT,
 ++    OPTION_NO_UEFI_SECURE_BOOT
 +   };
 + 
 + static int fs_probe = 1;
 +@@ -234,6 +237,14 @@ argp_parser (int key, char *arg, struct argp_state *state)
 +       bootloader_id = xstrdup (arg);
 +       return 0;
 + 
 ++    case OPTION_UEFI_SECURE_BOOT:
 ++      uefi_secure_boot = 1;
 ++      return 0;
 ++
 ++    case OPTION_NO_UEFI_SECURE_BOOT:
 ++      uefi_secure_boot = 0;
 ++      return 0;
 ++
 +     case ARGP_KEY_ARG:
 +       if (install_device)
 +      grub_util_error ("%s", _("More than one install device?"));
 +@@ -303,6 +314,14 @@ static struct argp_option options[] = {
 +   {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
 +   {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
 +   {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
 ++  {"uefi-secure-boot", OPTION_UEFI_SECURE_BOOT, 0, 0,
 ++   N_("install an image usable with UEFI Secure Boot. "
 ++      "This option is only available on EFI and if the grub-efi-amd64-signed "
 ++      "package is installed."), 2},
 ++  {"no-uefi-secure-boot", OPTION_NO_UEFI_SECURE_BOOT, 0, 0,
 ++   N_("do not install an image usable with UEFI Secure Boot, even if the "
 ++      "system was currently started using it. "
 ++      "This option is only available on EFI."), 2},
 +   {0, 0, 0, 0, 0, 0}
 + };
 + 
 +@@ -821,7 +840,8 @@ main (int argc, char *argv[])
 + {
 +   int is_efi = 0;
 +   const char *efi_distributor = NULL;
 +-  const char *efi_file = NULL;
 ++  const char *efi_suffix = NULL, *efi_suffix_upper = NULL;
 ++  char *efi_file = NULL;
 +   char **grub_devices;
 +   grub_fs_t grub_fs;
 +   grub_device_t grub_dev = NULL;
 +@@ -1081,6 +1101,31 @@ main (int argc, char *argv[])
 +       */
 +       char *t;
 +       efi_distributor = bootloader_id;
 ++      switch (platform)
 ++     {
 ++     case GRUB_INSTALL_PLATFORM_I386_EFI:
 ++       efi_suffix = "ia32";
 ++       efi_suffix_upper = "IA32";
 ++       break;
 ++     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
 ++       efi_suffix = "x64";
 ++       efi_suffix_upper = "X64";
 ++       break;
 ++     case GRUB_INSTALL_PLATFORM_IA64_EFI:
 ++       efi_suffix = "ia64";
 ++       efi_suffix_upper = "IA64";
 ++       break;
 ++     case GRUB_INSTALL_PLATFORM_ARM_EFI:
 ++       efi_suffix = "arm";
 ++       efi_suffix_upper = "ARM";
 ++       break;
 ++     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 ++       efi_suffix = "aa64";
 ++       efi_suffix_upper = "AA64";
 ++       break;
 ++     default:
 ++       break;
 ++     }
 +       if (removable)
 +      {
 +        /* The specification makes stricter requirements of removable
 +@@ -1089,54 +1134,16 @@ main (int argc, char *argv[])
 +           must have a specific file name depending on the architecture.
 +        */
 +        efi_distributor = "BOOT";
 +-       switch (platform)
 +-         {
 +-         case GRUB_INSTALL_PLATFORM_I386_EFI:
 +-           efi_file = "BOOTIA32.EFI";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_X86_64_EFI:
 +-           efi_file = "BOOTX64.EFI";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_IA64_EFI:
 +-           efi_file = "BOOTIA64.EFI";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_ARM_EFI:
 +-           efi_file = "BOOTARM.EFI";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 +-           efi_file = "BOOTAA64.EFI";
 +-           break;
 +-         default:
 +-           grub_util_error ("%s", _("You've found a bug"));
 +-           break;
 +-         }
 ++       if (!efi_suffix)
 ++         grub_util_error ("%s", _("You've found a bug"));
 ++       efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper);
 +      }
 +       else
 +      {
 +        /* It is convenient for each architecture to have a different
 +           efi_file, so that different versions can be installed in parallel.
 +        */
 +-       switch (platform)
 +-         {
 +-         case GRUB_INSTALL_PLATFORM_I386_EFI:
 +-           efi_file = "grubia32.efi";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_X86_64_EFI:
 +-           efi_file = "grubx64.efi";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_IA64_EFI:
 +-           efi_file = "grubia64.efi";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_ARM_EFI:
 +-           efi_file = "grubarm.efi";
 +-           break;
 +-         case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 +-           efi_file = "grubaa64.efi";
 +-           break;
 +-         default:
 +-           efi_file = "grub.efi";
 +-           break;
 +-         }
 ++       efi_file = xasprintf ("grub%s.efi", efi_suffix);
 +      }
 +       t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
 +       free (efidir);
 +@@ -1342,14 +1349,41 @@ main (int argc, char *argv[])
 +      }
 +     }
 + 
 +-  if (!have_abstractions)
 ++  char *efi_signed = NULL;
 ++  switch (platform)
 ++    {
 ++    case GRUB_INSTALL_PLATFORM_I386_EFI:
 ++    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
 ++    case GRUB_INSTALL_PLATFORM_ARM_EFI:
 ++    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 ++    case GRUB_INSTALL_PLATFORM_IA64_EFI:
 ++      {
 ++     char *dir = xasprintf ("%s-signed", grub_install_source_directory);
 ++     char *signed_image;
 ++     if (removable)
 ++       signed_image = xasprintf ("gcd%s.efi.signed", efi_suffix);
 ++     else
 ++       signed_image = xasprintf ("grub%s.efi.signed", efi_suffix);
 ++     efi_signed = grub_util_path_concat (2, dir, signed_image);
 ++     break;
 ++      }
 ++
 ++    default:
 ++      break;
 ++    }
 ++
 ++  if (!efi_signed || !grub_util_is_regular (efi_signed))
 ++    uefi_secure_boot = 0;
 ++
 ++  if (!have_abstractions || uefi_secure_boot)
 +     {
 +       if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
 +        || grub_drives[1]
 +        || (!install_drive
 +            && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
 +        || (install_drive && !is_same_disk (grub_drives[0], install_drive))
 +-       || !have_bootdev (platform))
 ++       || !have_bootdev (platform)
 ++       || uefi_secure_boot)
 +      {
 +        char *uuid = NULL;
 +        /*  generic method (used on coreboot and ata mod).  */
 +@@ -1871,7 +1905,71 @@ main (int argc, char *argv[])
 +     case GRUB_INSTALL_PLATFORM_IA64_EFI:
 +       {
 +      char *dst = grub_util_path_concat (2, efidir, efi_file);
 +-     grub_install_copy_file (imgfile, dst, 1);
 ++     if (uefi_secure_boot)
 ++       {
 ++         char *shim_signed = NULL;
 ++         char *mok_signed = NULL, *mok_file = NULL;
 ++         char *fb_signed = NULL, *fb_file = NULL;
 ++         char *config_dst;
 ++         FILE *config_dst_f;
 ++
 ++         shim_signed = xasprintf ("/usr/lib/shim/shim%s.efi.signed", efi_suffix);
 ++         mok_signed = xasprintf ("mm%s.efi.signed", efi_suffix);
 ++         mok_file = xasprintf ("mm%s.efi", efi_suffix);
 ++         fb_signed = xasprintf ("fb%s.efi.signed", efi_suffix);
 ++         fb_file = xasprintf ("fb%s.efi", efi_suffix);
 ++
 ++         if (grub_util_is_regular (shim_signed))
 ++           {
 ++             char *chained_base, *chained_dst;
 ++             char *mok_src, *mok_dst, *fb_src, *fb_dst;
 ++             if (!removable)
 ++               {
 ++                 free (efi_file);
 ++                 efi_file = xasprintf ("shim%s.efi", efi_suffix);
 ++                 free (dst);
 ++                 dst = grub_util_path_concat (2, efidir, efi_file);
 ++               }
 ++             grub_install_copy_file (shim_signed, dst, 1);
 ++             chained_base = xasprintf ("grub%s.efi", efi_suffix);
 ++             chained_dst = grub_util_path_concat (2, efidir, chained_base);
 ++             grub_install_copy_file (efi_signed, chained_dst, 1);
 ++             free (chained_dst);
 ++             free (chained_base);
 ++
 ++             /* Not critical, so not an error if they are not present (as it
 ++                won't be for older releases); but if we have them, make
 ++                sure they are installed.  */
 ++             mok_src = grub_util_path_concat (2, "/usr/lib/shim/",
 ++                                                 mok_signed);
 ++             mok_dst = grub_util_path_concat (2, efidir,
 ++                                                 mok_file);
 ++             grub_install_copy_file (mok_src,
 ++                                     mok_dst, 0);
 ++             free (mok_src);
 ++             free (mok_dst);
 ++
 ++             fb_src = grub_util_path_concat (2, "/usr/lib/shim/",
 ++                                                 fb_signed);
 ++             fb_dst = grub_util_path_concat (2, efidir,
 ++                                                 fb_file);
 ++             grub_install_copy_file (fb_src,
 ++                                     fb_dst, 0);
 ++             free (fb_src);
 ++             free (fb_dst);
 ++           }
 ++         else
 ++           grub_install_copy_file (efi_signed, dst, 1);
 ++
 ++         config_dst = grub_util_path_concat (2, efidir, "grub.cfg");
 ++         grub_install_copy_file (load_cfg, config_dst, 1);
 ++         config_dst_f = grub_util_fopen (config_dst, "ab");
 ++         fprintf (config_dst_f, "configfile $prefix/grub.cfg\n");
 ++         fclose (config_dst_f);
 ++         free (config_dst);
 ++       }
 ++     else
 ++       grub_install_copy_file (imgfile, dst, 1);
 +      free (dst);
 +       }
 +       if (!removable && update_nvram)
index fbe446aac088dd2dc8ed07aab7d8e98177d6b189,0000000000000000000000000000000000000000..98f99d41bd191e1d490284c2ed44b8ef4abcb4b4
mode 100644,000000..100644
--- /dev/null
@@@ -1,484 -1,0 +1,484 @@@
-  grub-core/kern/efi/mm.c           |  32 +++
-  grub-core/loader/i386/efi/linux.c | 371 ++++++++++++++++++++++++++++++
 +From 72da0de7449b8eada6a23f9a5e4b48f07955a368 Mon Sep 17 00:00:00 2001
 +From: Matthew Garrett <mjg@redhat.com>
 +Date: Mon, 13 Jan 2014 12:13:15 +0000
 +Subject: Add "linuxefi" loader which avoids ExitBootServices
 +
 +Origin: vendor, http://pkgs.fedoraproject.org/cgit/grub2.git/tree/grub2-linuxefi.patch
 +Forwarded: no
 +Last-Update: 2016-09-19
 +
 +Patch-Name: linuxefi.patch
 +---
 + grub-core/Makefile.core.def       |   8 +
- @@ -1733,6 +1733,14 @@ module = {
-    enable = x86_64_efi;
++ grub-core/kern/efi/mm.c           |  32 ++++
++ grub-core/loader/i386/efi/linux.c | 371 ++++++++++++++++++++++++++++++++++++++
 + include/grub/efi/efi.h            |   3 +
 + include/grub/i386/linux.h         |   1 +
 + 5 files changed, 415 insertions(+)
 + create mode 100644 grub-core/loader/i386/efi/linux.c
 +
 +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
 +index 2dfa22a92..68e47a727 100644
 +--- a/grub-core/Makefile.core.def
 ++++ b/grub-core/Makefile.core.def
- +module = {
++@@ -1734,6 +1734,14 @@ module = {
 + };
 + 
-  module = {
++ module = {
 ++  name = linuxefi;
 ++  efi = loader/i386/efi/linux.c;
 ++  efi = lib/cmdline.c;
 ++  enable = i386_efi;
 ++  enable = x86_64_efi;
 ++};
 ++
+++module = {
 +   name = chain;
 +   efi = loader/efi/chainloader.c;
++   i386_pc = loader/i386/pc/chainloader.c;
 +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
 +index 20a47aaf5..efb15cc1b 100644
 +--- a/grub-core/kern/efi/mm.c
 ++++ b/grub-core/kern/efi/mm.c
 +@@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size;
 + static grub_efi_uint32_t finish_desc_version;
 + int grub_efi_is_finished = 0;
 + 
 ++/* Allocate pages below a specified address */
 ++void *
 ++grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
 ++                          grub_efi_uintn_t pages)
 ++{
 ++  grub_efi_status_t status;
 ++  grub_efi_boot_services_t *b;
 ++  grub_efi_physical_address_t address = max;
 ++
 ++  if (max > 0xffffffff)
 ++    return 0;
 ++
 ++  b = grub_efi_system_table->boot_services;
 ++  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
 ++
 ++  if (status != GRUB_EFI_SUCCESS)
 ++    return 0;
 ++
 ++  if (address == 0)
 ++    {
 ++      /* Uggh, the address 0 was allocated... This is too annoying,
 ++      so reallocate another one.  */
 ++      address = max;
 ++      status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
 ++      grub_efi_free_pages (0, pages);
 ++      if (status != GRUB_EFI_SUCCESS)
 ++     return 0;
 ++    }
 ++
 ++  return (void *) ((grub_addr_t) address);
 ++}
 ++
 + /* Allocate pages. Return the pointer to the first of allocated pages.  */
 + void *
 + grub_efi_allocate_pages (grub_efi_physical_address_t address,
 +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
 +new file mode 100644
 +index 000000000..b622b3b71
 +--- /dev/null
 ++++ b/grub-core/loader/i386/efi/linux.c
 +@@ -0,0 +1,371 @@
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 2012  Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#include <grub/loader.h>
 ++#include <grub/file.h>
 ++#include <grub/err.h>
 ++#include <grub/types.h>
 ++#include <grub/mm.h>
 ++#include <grub/cpu/linux.h>
 ++#include <grub/command.h>
 ++#include <grub/i18n.h>
 ++#include <grub/lib/cmdline.h>
 ++#include <grub/efi/efi.h>
 ++
 ++GRUB_MOD_LICENSE ("GPLv3+");
 ++
 ++static grub_dl_t my_mod;
 ++static int loaded;
 ++static void *kernel_mem;
 ++static grub_uint64_t kernel_size;
 ++static grub_uint8_t *initrd_mem;
 ++static grub_uint32_t handover_offset;
 ++struct linux_kernel_params *params;
 ++static char *linux_cmdline;
 ++
 ++#define BYTES_TO_PAGES(bytes)   (((bytes) + 0xfff) >> 12)
 ++
 ++#define SHIM_LOCK_GUID \
 ++  { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
 ++
 ++struct grub_efi_shim_lock
 ++{
 ++  grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
 ++};
 ++typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
 ++
 ++static grub_efi_boolean_t
 ++grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
 ++{
 ++  grub_efi_guid_t guid = SHIM_LOCK_GUID;
 ++  grub_efi_shim_lock_t *shim_lock;
 ++
 ++  shim_lock = grub_efi_locate_protocol(&guid, NULL);
 ++
 ++  if (!shim_lock)
 ++    return 1;
 ++
 ++  if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
 ++    return 1;
 ++
 ++  return 0;
 ++}
 ++
 ++typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
 ++
 ++static grub_err_t
 ++grub_linuxefi_boot (void)
 ++{
 ++  handover_func hf;
 ++  int offset = 0;
 ++
 ++#ifdef __x86_64__
 ++  offset = 512;
 ++#endif
 ++
 ++  hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
 ++
 ++  asm volatile ("cli");
 ++
 ++  hf (grub_efi_image_handle, grub_efi_system_table, params);
 ++
 ++  /* Not reached */
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 ++static grub_err_t
 ++grub_linuxefi_unload (void)
 ++{
 ++  grub_dl_unref (my_mod);
 ++  loaded = 0;
 ++  if (initrd_mem)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size));
 ++  if (linux_cmdline)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1));
 ++  if (kernel_mem)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
 ++  if (params)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384));
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 ++static grub_err_t
 ++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 ++                 int argc, char *argv[])
 ++{
 ++  grub_file_t *files = 0;
 ++  int i, nfiles = 0;
 ++  grub_size_t size = 0;
 ++  grub_uint8_t *ptr;
 ++
 ++  if (argc == 0)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 ++      goto fail;
 ++    }
 ++
 ++  if (!loaded)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
 ++      goto fail;
 ++    }
 ++
 ++  files = grub_zalloc (argc * sizeof (files[0]));
 ++  if (!files)
 ++    goto fail;
 ++
 ++  for (i = 0; i < argc; i++)
 ++    {
 ++      grub_file_filter_disable_compression ();
 ++      files[i] = grub_file_open (argv[i]);
 ++      if (! files[i])
 ++        goto fail;
 ++      nfiles++;
 ++      size += ALIGN_UP (grub_file_size (files[i]), 4);
 ++    }
 ++
 ++  initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
 ++
 ++  if (!initrd_mem)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
 ++      goto fail;
 ++    }
 ++
 ++  params->ramdisk_size = size;
 ++  params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem;
 ++
 ++  ptr = initrd_mem;
 ++
 ++  for (i = 0; i < nfiles; i++)
 ++    {
 ++      grub_ssize_t cursize = grub_file_size (files[i]);
 ++      if (grub_file_read (files[i], ptr, cursize) != cursize)
 ++        {
 ++          if (!grub_errno)
 ++            grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
 ++                        argv[i]);
 ++          goto fail;
 ++        }
 ++      ptr += cursize;
 ++      grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
 ++      ptr += ALIGN_UP_OVERHEAD (cursize, 4);
 ++    }
 ++
 ++  params->ramdisk_size = size;
 ++
 ++ fail:
 ++  for (i = 0; i < nfiles; i++)
 ++    grub_file_close (files[i]);
 ++  grub_free (files);
 ++
 ++  if (initrd_mem && grub_errno)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size));
 ++
 ++  return grub_errno;
 ++}
 ++
 ++static grub_err_t
 ++grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 ++             int argc, char *argv[])
 ++{
 ++  grub_file_t file = 0;
 ++  struct linux_kernel_header lh;
 ++  grub_ssize_t len, start, filelen;
 ++  void *kernel;
 ++
 ++  grub_dl_ref (my_mod);
 ++
 ++  if (argc == 0)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 ++      goto fail;
 ++    }
 ++
 ++  file = grub_file_open (argv[0]);
 ++  if (! file)
 ++    goto fail;
 ++
 ++  filelen = grub_file_size (file);
 ++
 ++  kernel = grub_malloc(filelen);
 ++
 ++  if (!kernel)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
 ++      goto fail;
 ++    }
 ++
 ++  if (grub_file_read (file, kernel, filelen) != filelen)
 ++    {
 ++      grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
 ++      goto fail;
 ++    }
 ++
 ++  if (! grub_linuxefi_secure_validate (kernel, filelen))
 ++    {
 ++      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
 ++      grub_free (kernel);
 ++      goto fail;
 ++    }
 ++
 ++  grub_file_seek (file, 0);
 ++
 ++  grub_free(kernel);
 ++
 ++  params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
 ++
 ++  if (! params)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
 ++      goto fail;
 ++    }
 ++
 ++  grub_memset (params, 0, 16384);
 ++
 ++  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
 ++    {
 ++      if (!grub_errno)
 ++     grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
 ++                 argv[0]);
 ++      goto fail;
 ++    }
 ++
 ++  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
 ++      goto fail;
 ++    }
 ++
 ++  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
 ++      goto fail;
 ++    }
 ++
 ++  if (lh.version < grub_cpu_to_le16 (0x020b))
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
 ++      goto fail;
 ++    }
 ++
 ++  if (!lh.handover_offset)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
 ++      goto fail;
 ++    }
 ++
 ++  linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
 ++                                      BYTES_TO_PAGES(lh.cmdline_size + 1));
 ++
 ++  if (!linux_cmdline)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
 ++      goto fail;
 ++    }
 ++
 ++  grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
 ++  grub_create_loader_cmdline (argc, argv,
 ++                              linux_cmdline + sizeof (LINUX_IMAGE) - 1,
 ++                           lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1));
 ++
 ++  lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline;
 ++
 ++  handover_offset = lh.handover_offset;
 ++
 ++  start = (lh.setup_sects + 1) * 512;
 ++  len = grub_file_size(file) - start;
 ++
 ++  kernel_mem = grub_efi_allocate_pages(lh.pref_address,
 ++                                    BYTES_TO_PAGES(lh.init_size));
 ++
 ++  if (!kernel_mem)
 ++    kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
 ++                                          BYTES_TO_PAGES(lh.init_size));
 ++
 ++  if (!kernel_mem)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
 ++      goto fail;
 ++    }
 ++
 ++  if (grub_file_seek (file, start) == (grub_off_t) -1)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
 ++               argv[0]);
 ++      goto fail;
 ++    }
 ++
 ++  if (grub_file_read (file, kernel_mem, len) != len && !grub_errno)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
 ++               argv[0]);
 ++    }
 ++
 ++  if (grub_errno == GRUB_ERR_NONE)
 ++    {
 ++      grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
 ++      loaded = 1;
 ++      lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
 ++    }
 ++
 ++  grub_memcpy (params, &lh, 2 * 512);
 ++
 ++  params->type_of_loader = 0x21;
 ++
 ++ fail:
 ++
 ++  if (file)
 ++    grub_file_close (file);
 ++
 ++  if (grub_errno != GRUB_ERR_NONE)
 ++    {
 ++      grub_dl_unref (my_mod);
 ++      loaded = 0;
 ++    }
 ++
 ++  if (linux_cmdline && !loaded)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1));
 ++
 ++  if (kernel_mem && !loaded)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
 ++
 ++  if (params && !loaded)
 ++    grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384));
 ++
 ++  return grub_errno;
 ++}
 ++
 ++static grub_command_t cmd_linux, cmd_initrd;
 ++
 ++GRUB_MOD_INIT(linuxefi)
 ++{
 ++  cmd_linux =
 ++    grub_register_command ("linuxefi", grub_cmd_linux,
 ++                           0, N_("Load Linux."));
 ++  cmd_initrd =
 ++    grub_register_command ("initrdefi", grub_cmd_initrd,
 ++                           0, N_("Load initrd."));
 ++  my_mod = mod;
 ++}
 ++
 ++GRUB_MOD_FINI(linuxefi)
 ++{
 ++  grub_unregister_command (cmd_linux);
 ++  grub_unregister_command (cmd_initrd);
 ++}
 +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
 +index 5e87950fd..62a3d9726 100644
 +--- a/include/grub/efi/efi.h
 ++++ b/include/grub/efi/efi.h
 +@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
 + void *
 + EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
 +                                    grub_efi_uintn_t pages);
 ++void *
 ++EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max,
 ++                                       grub_efi_uintn_t pages);
 + void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
 +                                     grub_efi_uintn_t pages);
 + int
 +diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
 +index da0ca3b83..fc36bdaf3 100644
 +--- a/include/grub/i386/linux.h
 ++++ b/include/grub/i386/linux.h
 +@@ -139,6 +139,7 @@ struct linux_kernel_header
 +   grub_uint64_t setup_data;
 +   grub_uint64_t pref_address;
 +   grub_uint32_t init_size;
 ++  grub_uint32_t handover_offset;
 + } GRUB_PACKED;
 + 
 + /* Boot parameters for Linux based on 2.6.12. This is used by the setup
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cf6b6e0d27c3d3624c177f8f4e751aab7128fdc7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,43 @@@
++From 3627951693d3e40b5d263ca567ef990edf7b7c2f Mon Sep 17 00:00:00 2001
++From: Linn Crosetto <linn@hpe.com>
++Date: Tue, 5 Apr 2016 11:49:05 -0600
++Subject: Disallow unsigned kernels if UEFI Secure Boot is enabled
++
++If UEFI Secure Boot is enabled and kernel signature verification fails, do not
++boot the kernel. Before this change, if kernel signature verification failed
++then GRUB would fall back to calling ExitBootServices() and continuing the
++boot.
++
++Patch-Name: linuxefi_disable_sb_fallback.patch
++
++Signed-off-by: Linn Crosetto <linn@hpe.com>
++---
++ grub-core/loader/i386/linux.c | 8 +++-----
++ 1 file changed, 3 insertions(+), 5 deletions(-)
++
++diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
++index 4dcd213b6..59b88ca18 100644
++--- a/grub-core/loader/i386/linux.c
+++++ b/grub-core/loader/i386/linux.c
++@@ -695,10 +695,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
++   using_linuxefi = 0;
++   if (grub_efi_secure_boot ())
++     {
++-      /* Try linuxefi first, which will require a successful signature check
++-      and then hand over to the kernel without calling ExitBootServices.
++-      If that fails, however, fall back to calling ExitBootServices
++-      ourselves and then booting an unsigned kernel.  */
+++      /* linuxefi requires a successful signature check and then hand over
+++      to the kernel without calling ExitBootServices. */
++       grub_dl_t mod;
++       grub_command_t linuxefi_cmd;
++ 
++@@ -720,7 +718,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
++                return GRUB_ERR_NONE;
++              }
++            grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
++-           grub_errno = GRUB_ERR_NONE;
+++           goto fail;
++          }
++      }
++     }
index cc71e659b66e180432aad55ccbba9d3f5970ca85,0000000000000000000000000000000000000000..38ef8565acfe6cd782c41f223259374f8bb06371
mode 100644,000000..100644
--- /dev/null
@@@ -1,96 -1,0 +1,96 @@@
-  grub-core/loader/i386/linux.c     | 43 +++++++++++++++++++++++++++++++
 +From 6da8e840ec0878e1bbdf549ac09afe016409fcb8 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:20 +0000
 +Subject: If running under UEFI secure boot, attempt to use linuxefi loader
 +
 +Author: Steve Langasek <steve.langasek@canonical.com>
 +Forwarded: no
 +Last-Update: 2013-12-20
 +
 +Patch-Name: linuxefi_non_sb_fallback.patch
 +---
 + grub-core/loader/i386/efi/linux.c |  2 +-
++ grub-core/loader/i386/linux.c     | 43 +++++++++++++++++++++++++++++++++++++++
 + 2 files changed, 44 insertions(+), 1 deletion(-)
 +
 +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
 +index ff293166c..de4471bc8 100644
 +--- a/grub-core/loader/i386/efi/linux.c
 ++++ b/grub-core/loader/i386/efi/linux.c
 +@@ -234,7 +234,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 + 
 +   if (! grub_linuxefi_secure_validate (kernel, filelen))
 +     {
 +-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
 ++      grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]);
 +       grub_free (kernel);
 +       goto fail;
 +     }
 +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
 +index 083f9417c..4dcd213b6 100644
 +--- a/grub-core/loader/i386/linux.c
 ++++ b/grub-core/loader/i386/linux.c
 +@@ -75,6 +75,8 @@ static grub_size_t maximal_cmdline_size;
 + static struct linux_kernel_params linux_params;
 + static char *linux_cmdline;
 + #ifdef GRUB_MACHINE_EFI
 ++static int using_linuxefi;
 ++static grub_command_t initrdefi_cmd;
 + static grub_efi_uintn_t efi_mmap_size;
 + #else
 + static const grub_size_t efi_mmap_size = 0;
 +@@ -689,6 +691,41 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 + 
 +   grub_dl_ref (my_mod);
 + 
 ++#ifdef GRUB_MACHINE_EFI
 ++  using_linuxefi = 0;
 ++  if (grub_efi_secure_boot ())
 ++    {
 ++      /* Try linuxefi first, which will require a successful signature check
 ++      and then hand over to the kernel without calling ExitBootServices.
 ++      If that fails, however, fall back to calling ExitBootServices
 ++      ourselves and then booting an unsigned kernel.  */
 ++      grub_dl_t mod;
 ++      grub_command_t linuxefi_cmd;
 ++
 ++      grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n");
 ++
 ++      mod = grub_dl_load ("linuxefi");
 ++      if (mod)
 ++     {
 ++       grub_dl_ref (mod);
 ++       linuxefi_cmd = grub_command_find ("linuxefi");
 ++       initrdefi_cmd = grub_command_find ("initrdefi");
 ++       if (linuxefi_cmd && initrdefi_cmd)
 ++         {
 ++           (linuxefi_cmd->func) (linuxefi_cmd, argc, argv);
 ++           if (grub_errno == GRUB_ERR_NONE)
 ++             {
 ++               grub_dprintf ("linux", "Handing off to linuxefi\n");
 ++               using_linuxefi = 1;
 ++               return GRUB_ERR_NONE;
 ++             }
 ++           grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
 ++           grub_errno = GRUB_ERR_NONE;
 ++         }
 ++     }
 ++    }
 ++#endif
 ++
 +   if (argc == 0)
 +     {
 +       grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 +@@ -1054,6 +1091,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 +   grub_err_t err;
 +   struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
 + 
 ++#ifdef GRUB_MACHINE_EFI
 ++  /* If we're using linuxefi, just forward to initrdefi.  */
 ++  if (using_linuxefi && initrdefi_cmd)
 ++    return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv);
 ++#endif
 ++
 +   if (argc == 0)
 +     {
 +       grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
index cd59051d7483352ecbd00fe900a1765755b4c363,0000000000000000000000000000000000000000..881445fdca78a59bbad4ecdd49df9b91c5b0be14
mode 100644,000000..100644
--- /dev/null
@@@ -1,254 -1,0 +1,254 @@@
-  grub-core/net/http.c | 21 ++++++++--
-  grub-core/net/net.c  | 93 +++++++++++++++++++++++++++++++++++++++++---
-  grub-core/net/tftp.c |  6 ++-
 +From 8fef2df852f48b22897dd016186cc2d9f996c0da Mon Sep 17 00:00:00 2001
 +From: Aaron Miller <aaronmiller@fb.com>
 +Date: Thu, 27 Oct 2016 17:39:49 -0400
 +Subject: net: read bracketed ipv6 addrs and port numbers
 +
 +Allow specifying port numbers for http and tftp paths, and allow ipv6 addresses
 +to be recognized with brackets around them, which is required to specify a port
 +number
 +
 +Patch-Name: net_read_bracketed_ipv6_addr.patch
 +---
++ grub-core/net/http.c | 21 +++++++++---
++ grub-core/net/net.c  | 93 ++++++++++++++++++++++++++++++++++++++++++++++++----
++ grub-core/net/tftp.c |  6 +++-
 + include/grub/net.h   |  1 +
 + 4 files changed, 110 insertions(+), 11 deletions(-)
 +
 +diff --git a/grub-core/net/http.c b/grub-core/net/http.c
 +index 5aa4ad3be..f182d7b87 100644
 +--- a/grub-core/net/http.c
 ++++ b/grub-core/net/http.c
 +@@ -312,12 +312,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
 +   int i;
 +   struct grub_net_buff *nb;
 +   grub_err_t err;
 ++  char* server = file->device->net->server;
 ++  int port = file->device->net->port;
 + 
 +   nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE
 +                         + sizeof ("GET ") - 1
 +                         + grub_strlen (data->filename)
 +                         + sizeof (" HTTP/1.1\r\nHost: ") - 1
 +-                        + grub_strlen (file->device->net->server)
 ++                        + grub_strlen (server) + sizeof (":XXXXXXXXXX")
 +                         + sizeof ("\r\nUser-Agent: " PACKAGE_STRING
 +                                   "\r\n") - 1
 +                         + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX"
 +@@ -356,7 +358,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
 +             sizeof (" HTTP/1.1\r\nHost: ") - 1);
 + 
 +   ptr = nb->tail;
 +-  err = grub_netbuff_put (nb, grub_strlen (file->device->net->server));
 ++  err = grub_netbuff_put (nb, grub_strlen (server));
 +   if (err)
 +     {
 +       grub_netbuff_free (nb);
 +@@ -365,6 +367,15 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
 +   grub_memcpy (ptr, file->device->net->server,
 +             grub_strlen (file->device->net->server));
 + 
 ++  if (port)
 ++    {
 ++      ptr = nb->tail;
 ++      grub_snprintf ((char *) ptr,
 ++       sizeof (":XXXXXXXXXX"),
 ++       ":%d",
 ++       port);
 ++    }
 ++
 +   ptr = nb->tail;
 +   err = grub_netbuff_put (nb, 
 +                        sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n")
 +@@ -390,8 +401,10 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
 +   grub_netbuff_put (nb, 2);
 +   grub_memcpy (ptr, "\r\n", 2);
 + 
 +-  data->sock = grub_net_tcp_open (file->device->net->server,
 +-                               HTTP_PORT, http_receive,
 ++  grub_dprintf ("http", "opening path %s on host %s TCP port %d\n",
 ++             data->filename, server, port ? port : HTTP_PORT);
 ++  data->sock = grub_net_tcp_open (server,
 ++                               port ? port : HTTP_PORT, http_receive,
 +                                http_err, http_err,
 +                                file);
 +   if (!data->sock)
 +diff --git a/grub-core/net/net.c b/grub-core/net/net.c
 +index 10773fc34..fbac15e0f 100644
 +--- a/grub-core/net/net.c
 ++++ b/grub-core/net/net.c
 +@@ -437,6 +437,12 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
 +   grub_uint16_t newip[8];
 +   const char *ptr = val;
 +   int word, quaddot = -1;
 ++  int bracketed = 0;
 ++
 ++  if (ptr[0] == '[') {
 ++    bracketed = 1;
 ++    ptr++;
 ++  }
 + 
 +   if (ptr[0] == ':' && ptr[1] != ':')
 +     return 0;
 +@@ -475,6 +481,9 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
 +       grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0]));
 +     }
 +   grub_memcpy (ip, newip, 16);
 ++  if (bracketed && *ptr == ']') {
 ++    ptr++;
 ++  }
 +   if (rest)
 +     *rest = ptr;
 +   return 1;
 +@@ -1260,8 +1269,10 @@ grub_net_open_real (const char *name)
 + {
 +   grub_net_app_level_t proto;
 +   const char *protname, *server;
 ++  char *host;
 +   grub_size_t protnamelen;
 +   int try;
 ++  int port = 0;
 + 
 +   if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
 +     {
 +@@ -1299,6 +1310,72 @@ grub_net_open_real (const char *name)
 +       return NULL;
 +     }  
 + 
 ++  char* port_start;
 ++  /* ipv6 or port specified? */
 ++  if ((port_start = grub_strchr (server, ':')))
 ++  {
 ++      char* ipv6_begin;
 ++      if((ipv6_begin = grub_strchr (server, '[')))
 ++     {
 ++       char* ipv6_end = grub_strchr (server, ']');
 ++       if(!ipv6_end)
 ++         {
 ++           grub_error (GRUB_ERR_NET_BAD_ADDRESS,
 ++                   N_("mismatched [ in address"));
 ++           return NULL;
 ++         }
 ++       /* port number after bracketed ipv6 addr */
 ++       if(ipv6_end[1] == ':')
 ++         {
 ++           port = grub_strtoul (ipv6_end + 2, NULL, 10);
 ++           if(port > 65535)
 ++             {
 ++               grub_error (GRUB_ERR_NET_BAD_ADDRESS,
 ++                       N_("bad port number"));
 ++               return NULL;
 ++             }
 ++         }
 ++       host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1);
 ++     }
 ++      else
 ++     {
 ++       if (grub_strchr (port_start + 1, ':'))
 ++         {
 ++           int iplen = grub_strlen (server);
 ++           /* bracket bare ipv6 addrs */
 ++           host = grub_malloc (iplen + 3);
 ++           if(!host)
 ++             {
 ++               return NULL;
 ++             }
 ++           host[0] = '[';
 ++           grub_memcpy (host + 1, server, iplen);
 ++           host[iplen + 1] = ']';
 ++           host[iplen + 2] = '\0';
 ++         }
 ++       else
 ++         {
 ++           /* hostname:port or ipv4:port */
 ++           port = grub_strtol (port_start + 1, NULL, 10);
 ++           if(port > 65535)
 ++             {
 ++               grub_error (GRUB_ERR_NET_BAD_ADDRESS,
 ++                       N_("bad port number"));
 ++               return NULL;
 ++             }
 ++           host = grub_strndup (server, port_start - server);
 ++         }
 ++     }
 ++    }
 ++  else
 ++    {
 ++      host = grub_strdup (server);
 ++    }
 ++  if (!host)
 ++    {
 ++      return NULL;
 ++    }
 ++
 +   for (try = 0; try < 2; try++)
 +     {
 +       FOR_NET_APP_LEVEL (proto)
 +@@ -1308,15 +1385,19 @@ grub_net_open_real (const char *name)
 +        {
 +          grub_net_t ret = grub_zalloc (sizeof (*ret));
 +          if (!ret)
 +-           return NULL;
 +-         ret->protocol = proto;
 +-         ret->server = grub_strdup (server);
 +-         if (!ret->server)
 ++             grub_free (host);
 ++         if (host)
 +            {
 +-             grub_free (ret);
 +-             return NULL;
 ++             ret->server = grub_strdup (host);
 ++             if (!ret->server)
 ++               {
 ++                 grub_free (ret);
 ++                 return NULL;
 ++               }
 +            }
 +          ret->fs = &grub_net_fs;
 ++         ret->protocol = proto;
 ++         ret->port = port;
 +          return ret;
 +        }
 +       }
 +diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
 +index 7d90bf66e..a0817a075 100644
 +--- a/grub-core/net/tftp.c
 ++++ b/grub-core/net/tftp.c
 +@@ -314,6 +314,7 @@ tftp_open (struct grub_file *file, const char *filename)
 +   grub_err_t err;
 +   grub_uint8_t *nbd;
 +   grub_net_network_level_address_t addr;
 ++  int port = file->device->net->port;
 + 
 +   data = grub_zalloc (sizeof (*data));
 +   if (!data)
 +@@ -382,13 +383,16 @@ tftp_open (struct grub_file *file, const char *filename)
 +   err = grub_net_resolve_address (file->device->net->server, &addr);
 +   if (err)
 +     {
 ++      grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n",
 ++                 (unsigned long long)data->file_size,
 ++                 (unsigned long long)data->block_size);
 +       destroy_pq (data);
 +       grub_free (data);
 +       return err;
 +     }
 + 
 +   data->sock = grub_net_udp_open (addr,
 +-                               TFTP_SERVER_PORT, tftp_receive,
 ++                               port ? port : TFTP_SERVER_PORT, tftp_receive,
 +                                file);
 +   if (!data->sock)
 +     {
 +diff --git a/include/grub/net.h b/include/grub/net.h
 +index 2192fa186..ccc169c2d 100644
 +--- a/include/grub/net.h
 ++++ b/include/grub/net.h
 +@@ -270,6 +270,7 @@ typedef struct grub_net
 + {
 +   char *server;
 +   char *name;
 ++  int port;
 +   grub_net_app_level_t protocol;
 +   grub_net_packets_t packs;
 +   grub_off_t offset;
index e8290d6848dee4864f17bf1a1bf7a98b434f4869,0000000000000000000000000000000000000000..14bb0497169c6dc5a999f49c51f488e081a9513b
mode 100644,000000..100644
--- /dev/null
@@@ -1,358 -1,0 +1,358 @@@
-  configure.ac                | 11 ++++++
-  docs/grub.texi              | 14 +++++++
-  grub-core/normal/menu.c     | 24 ++++++++++++
 +From 82480176b8b1404acb7aec08d108cb7517d4fb23 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:28 +0000
 +Subject: Add configure option to bypass boot menu if possible
 +
 +If other operating systems are installed, then automatically unhide the
 +menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus if
 +available to check whether Shift is pressed.  If it is, show the menu,
 +otherwise boot immediately.  If keystatus is not available, then fall
 +back to a short delay interruptible with Escape.
 +
 +This may or may not remain Ubuntu-specific, although it's not obviously
 +wanted upstream.  It implements a requirement of
 +https://wiki.ubuntu.com/DesktopExperienceTeam/KarmicBootExperienceDesignSpec#Bootloader.
 +
 +If the previous boot failed (defined as failing to get to the end of one
 +of the normal runlevels), then show the boot menu regardless.
 +
 +Author: Richard Laager <rlaager@wiktel.com>
 +Author: Robie Basak <robie.basak@ubuntu.com>
 +Forwarded: no
 +Last-Update: 2015-09-04
 +
 +Patch-Name: quick_boot.patch
 +---
-  util/grub.d/00_header.in    | 77 +++++++++++++++++++++++++++++++------
-  util/grub.d/10_linux.in     |  4 ++
-  util/grub.d/30_os-prober.in | 21 ++++++++++
++ configure.ac                | 11 +++++++
++ docs/grub.texi              | 14 +++++++++
++ grub-core/normal/menu.c     | 24 ++++++++++++++
 + util/grub-mkconfig.in       |  3 +-
++ util/grub.d/00_header.in    | 77 ++++++++++++++++++++++++++++++++++++++-------
++ util/grub.d/10_linux.in     |  4 +++
++ util/grub.d/30_os-prober.in | 21 +++++++++++++
 + 7 files changed, 141 insertions(+), 13 deletions(-)
 +
 +diff --git a/configure.ac b/configure.ac
 +index dd2fbd01c..e508f9c43 100644
 +--- a/configure.ac
 ++++ b/configure.ac
 +@@ -1841,6 +1841,17 @@ else
 + fi
 + AC_SUBST([QUIET_BOOT])
 + 
 ++AC_ARG_ENABLE([quick-boot],
 ++              [AS_HELP_STRING([--enable-quick-boot],
 ++                              [bypass boot menu if possible (default=no)])],
 ++              [], [enable_quick_boot=no])
 ++if test x"$enable_quick_boot" = xyes ; then
 ++  QUICK_BOOT=1
 ++else
 ++  QUICK_BOOT=0
 ++fi
 ++AC_SUBST([QUICK_BOOT])
 ++
 + LIBS=""
 + 
 + AC_SUBST([FONT_SOURCE])
 +diff --git a/docs/grub.texi b/docs/grub.texi
 +index e935af33e..5b2a7bbb2 100644
 +--- a/docs/grub.texi
 ++++ b/docs/grub.texi
 +@@ -1490,6 +1490,20 @@ This option may be set to a list of GRUB module names separated by spaces.
 + Each module will be loaded as early as possible, at the start of
 + @file{grub.cfg}.
 + 
 ++@item GRUB_RECORDFAIL_TIMEOUT
 ++If this option is set, it overrides the default recordfail setting.  A
 ++setting of -1 causes GRUB to wait for user input indefinitely.  However, a
 ++false positive in the recordfail mechanism may occur if power is lost during
 ++boot before boot success is recorded in userspace.  The default setting is
 ++30, which causes GRUB to wait for user input for thirty seconds before
 ++continuing.  This default allows interactive users the opportunity to switch
 ++to a different, working kernel, while avoiding a false positive causing the
 ++boot to block indefinitely on headless and appliance systems where access to
 ++a console is restricted or limited.
 ++
 ++This option is only effective when GRUB was configured with the
 ++@option{--enable-quick-boot} option.
 ++
 + @end table
 + 
 + The following options are still accepted for compatibility with existing
 +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
 +index 1f3447ad3..906a480a2 100644
 +--- a/grub-core/normal/menu.c
 ++++ b/grub-core/normal/menu.c
 +@@ -604,6 +604,30 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
 +       static struct grub_term_coordinate *pos;
 +       int entry = -1;
 + 
 ++      if (timeout == 0)
 ++     {
 ++       /* If modifier key statuses can't be detected without a delay,
 ++          then a hidden timeout of zero cannot be interrupted in any way,
 ++          which is not very helpful.  Bump it to three seconds in this
 ++          case to give the user a fighting chance.  */
 ++       grub_term_input_t term;
 ++       int nterms = 0;
 ++       int mods_detectable = 1;
 ++
 ++       FOR_ACTIVE_TERM_INPUTS(term)
 ++       {
 ++         if (!term->getkeystatus)
 ++           {
 ++             mods_detectable = 0;
 ++             break;
 ++           }
 ++         else
 ++           nterms++;
 ++       }
 ++       if (!mods_detectable || !nterms)
 ++         timeout = 3;
 ++     }
 ++
 +       if (timeout_style == TIMEOUT_STYLE_COUNTDOWN && timeout)
 +      {
 +        pos = grub_term_save_pos ();
 +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
 +index b4f0011b5..fac560464 100644
 +--- a/util/grub-mkconfig.in
 ++++ b/util/grub-mkconfig.in
 +@@ -239,7 +239,8 @@ export GRUB_DEFAULT \
 +   GRUB_ENABLE_CRYPTODISK \
 +   GRUB_BADRAM \
 +   GRUB_OS_PROBER_SKIP_LIST \
 +-  GRUB_DISABLE_SUBMENU
 ++  GRUB_DISABLE_SUBMENU \
 ++  GRUB_RECORDFAIL_TIMEOUT
 + 
 + if test "x${grub_cfg}" != "x"; then
 +   rm -f "${grub_cfg}.new"
 +diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
 +index 93a90233e..674a76140 100644
 +--- a/util/grub.d/00_header.in
 ++++ b/util/grub.d/00_header.in
 +@@ -21,6 +21,8 @@ prefix="@prefix@"
 + exec_prefix="@exec_prefix@"
 + datarootdir="@datarootdir@"
 + grub_lang=`echo $LANG | cut -d . -f 1`
 ++grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`"
 ++quick_boot="@QUICK_BOOT@"
 + 
 + export TEXTDOMAIN=@PACKAGE@
 + export TEXTDOMAINDIR="@localedir@"
 +@@ -44,6 +46,7 @@ if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT
 + 
 + cat << EOF
 + if [ -s \$prefix/grubenv ]; then
 ++  set have_grubenv=true
 +   load_env
 + fi
 + EOF
 +@@ -96,7 +99,50 @@ function savedefault {
 +     save_env saved_entry
 +   fi
 + }
 ++EOF
 ++
 ++if [ "$quick_boot" = 1 ]; then
 ++    cat <<EOF
 ++function recordfail {
 ++  set recordfail=1
 ++EOF
 ++
 ++  check_writable () {
 ++    abstractions="$(grub-probe --target=abstraction "${grubdir}")"
 ++    for abstraction in $abstractions; do
 ++      case "$abstraction" in
 ++        diskfilter | lvm)
 ++          cat <<EOF
 ++  # GRUB lacks write support for $abstraction, so recordfail support is disabled.
 ++EOF
 ++          return
 ++          ;;
 ++      esac
 ++    done
 ++
 ++    FS="$(grub-probe --target=fs "${grubdir}")"
 ++    case "$FS" in
 ++      btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
 ++     cat <<EOF
 ++  # GRUB lacks write support for $FS, so recordfail support is disabled.
 ++EOF
 ++     return
 ++     ;;
 ++    esac
 ++
 ++    cat <<EOF
 ++  if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
 ++EOF
 ++  }
 ++
 ++  check_writable
 + 
 ++  cat <<EOF
 ++}
 ++EOF
 ++fi
 ++
 ++cat <<EOF
 + function load_video {
 + EOF
 + if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
 +@@ -282,10 +328,16 @@ fi
 + 
 + make_timeout ()
 + {
 ++    cat << EOF
 ++if [ "\${recordfail}" = 1 ] ; then
 ++  set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
 ++else
 ++EOF
 +     if [ "x${3}" != "x" ] ; then
 +      timeout="${2}"
 +      style="${3}"
 +-    elif [ "x${1}" != "x" ] && [ "x${1}" != "x0" ] ; then
 ++    elif [ "x${1}" != "x" ] && \
 ++      ([ "$quick_boot" = 1 ] || [ "x${1}" != "x0" ]) ; then
 +      # Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
 +      timeout="${1}"
 +      if [ "x${2}" != "x0" ] ; then
 +@@ -304,26 +356,27 @@ make_timeout ()
 +      style="menu"
 +     fi
 +     cat << EOF
 +-if [ x\$feature_timeout_style = xy ] ; then
 +-  set timeout_style=${style}
 +-  set timeout=${timeout}
 ++  if [ x\$feature_timeout_style = xy ] ; then
 ++    set timeout_style=${style}
 ++    set timeout=${timeout}
 + EOF
 +     if [ "x${style}" = "xmenu" ] ; then
 +      cat << EOF
 +-# Fallback normal timeout code in case the timeout_style feature is
 +-# unavailable.
 +-else
 +-  set timeout=${timeout}
 ++  # Fallback normal timeout code in case the timeout_style feature is
 ++  # unavailable.
 ++  else
 ++    set timeout=${timeout}
 + EOF
 +     else
 +      cat << EOF
 +-# Fallback hidden-timeout code in case the timeout_style feature is
 +-# unavailable.
 +-elif sleep${verbose} --interruptible ${timeout} ; then
 +-  set timeout=0
 ++  # Fallback hidden-timeout code in case the timeout_style feature is
 ++  # unavailable.
 ++  elif sleep${verbose} --interruptible ${timeout} ; then
 ++    set timeout=0
 + EOF
 +     fi
 +     cat << EOF
 ++  fi
 + fi
 + EOF
 + }
 +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
 +index 67d57ecfd..0f8a16837 100644
 +--- a/util/grub.d/10_linux.in
 ++++ b/util/grub.d/10_linux.in
 +@@ -22,6 +22,7 @@ exec_prefix="@exec_prefix@"
 + datarootdir="@datarootdir@"
 + ubuntu_recovery="@UBUNTU_RECOVERY@"
 + quiet_boot="@QUIET_BOOT@"
 ++quick_boot="@QUICK_BOOT@"
 + 
 + . "$pkgdatadir/grub-mkconfig_lib"
 + 
 +@@ -119,6 +120,9 @@ linux_entry ()
 +   else
 +       echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
 +   fi      
 ++  if [ "$quick_boot" = 1 ]; then
 ++      echo " recordfail" | sed "s/^/$submenu_indentation/"
 ++  fi
 +   if [ x$type != xrecovery ] ; then
 +       save_default_entry | grub_add_tab
 +   fi
 +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in
 +index 271044f59..da5f28876 100644
 +--- a/util/grub.d/30_os-prober.in
 ++++ b/util/grub.d/30_os-prober.in
 +@@ -20,12 +20,26 @@ set -e
 + prefix="@prefix@"
 + exec_prefix="@exec_prefix@"
 + datarootdir="@datarootdir@"
 ++quick_boot="@QUICK_BOOT@"
 + 
 + export TEXTDOMAIN=@PACKAGE@
 + export TEXTDOMAINDIR="@localedir@"
 + 
 + . "$pkgdatadir/grub-mkconfig_lib"
 + 
 ++found_other_os=
 ++
 ++adjust_timeout () {
 ++  if [ "$quick_boot" = 1 ] && [ "x${found_other_os}" != "x" ]; then
 ++    cat << EOF
 ++set timeout_style=menu
 ++if [ "\${timeout}" = 0 ]; then
 ++  set timeout=10
 ++fi
 ++EOF
 ++  fi
 ++}
 ++
 + if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
 +   exit 0
 + fi
 +@@ -42,6 +56,7 @@ if [ -z "${OSPROBED}" ] ; then
 + fi
 + 
 + osx_entry() {
 ++    found_other_os=1
 +     if [ x$2 = x32 ]; then
 +         # TRANSLATORS: it refers to kernel architecture (32-bit)
 +      bitstr="$(gettext "(32-bit)")"
 +@@ -165,6 +180,7 @@ for OS in ${OSPROBED} ; do
 +        ;;
 +       esac
 + 
 ++      found_other_os=1
 +        onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
 +       cat << EOF
 + menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
 +@@ -195,6 +211,7 @@ EOF
 +     ;;
 +     efi)
 + 
 ++     found_other_os=1
 +      EFIPATH=${DEVICE#*@}
 +      DEVICE=${DEVICE%@*}
 +      onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
 +@@ -243,6 +260,7 @@ EOF
 +        [ "${prepare_boot_cache}" ] || continue
 +      fi
 + 
 ++     found_other_os=1
 +      onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
 +      recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true
 +      counter=1
 +@@ -311,6 +329,7 @@ EOF
 +       fi
 +     ;;
 +     hurd)
 ++      found_other_os=1
 +       onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
 +       cat << EOF
 + menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
 +@@ -353,3 +372,5 @@ EOF
 +     ;;
 +   esac
 + done
 ++
 ++adjust_timeout
index 5ca4c485480750a76e050b042d2c97c86545f543,0000000000000000000000000000000000000000..3b003b0ab676e9cd1ff865ba9aef00e43125fee2
mode 100644,000000..100644
--- /dev/null
@@@ -1,2538 -1,0 +1,2538 @@@
-  grub-core/lib/libgcrypt-grub/cipher/bufhelp.h | 435 +++++++++
-  grub-core/lib/libgcrypt-grub/cipher/crc.c     | 826 ++++++++++++++++++
-  grub-core/lib/libgcrypt/cipher/bufhelp.h      | 432 +++++++++
-  grub-core/lib/libgcrypt/cipher/crc.c          | 793 +++++++++++++++++
 +From 4ddac1bc51d1c784d48ad8c890f9cbe2e4c7b1f4 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@debian.org>
 +Date: Fri, 16 Feb 2018 11:02:19 +0000
 +Subject: Import replacement CRC operations from libgcrypt
 +
 +Mostly backported from
 +https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=06e122baa3321483a47bbf82fd2a4540becfa0c9,
 +but importing bufhelp.h from libgcrypt 1.7.0 as well.  We can drop this
 +once GRUB updates to a newer import of libgcrypt.
 +
 +The new implementation is not encumbered by the restrictive Internet
 +Society licence on RFCs.
 +
 +Bug-Debian: https://bugs.debian.org/745409
 +Last-Update: 2018-02-16
 +
 +Patch-Name: replace-libgcrypt-crc.patch
 +---
++ grub-core/lib/libgcrypt-grub/cipher/bufhelp.h | 435 ++++++++++++++
++ grub-core/lib/libgcrypt-grub/cipher/crc.c     | 826 ++++++++++++++++++++++++++
++ grub-core/lib/libgcrypt/cipher/bufhelp.h      | 432 ++++++++++++++
++ grub-core/lib/libgcrypt/cipher/crc.c          | 793 +++++++++++++++++++++++++
 + 4 files changed, 2486 insertions(+)
 + create mode 100644 grub-core/lib/libgcrypt-grub/cipher/bufhelp.h
 + create mode 100644 grub-core/lib/libgcrypt-grub/cipher/crc.c
 + create mode 100644 grub-core/lib/libgcrypt/cipher/bufhelp.h
 + create mode 100644 grub-core/lib/libgcrypt/cipher/crc.c
 +
 +diff --git a/grub-core/lib/libgcrypt-grub/cipher/bufhelp.h b/grub-core/lib/libgcrypt-grub/cipher/bufhelp.h
 +new file mode 100644
 +index 000000000..89471e65f
 +--- /dev/null
 ++++ b/grub-core/lib/libgcrypt-grub/cipher/bufhelp.h
 +@@ -0,0 +1,435 @@
 ++/* This file was automatically imported with 
 ++   import_gcry.py. Please don't modify it */
 ++#include <grub/dl.h>
 ++/* bufhelp.h  -  Some buffer manipulation helpers
 ++ * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 ++ *
 ++ * This file is part of Libgcrypt.
 ++ *
 ++ * Libgcrypt is free software; you can redistribute it and/or modify
 ++ * it under the terms of the GNU Lesser General Public License as
 ++ * published by the Free Software Foundation; either version 2.1 of
 ++ * the License, or (at your option) any later version.
 ++ *
 ++ * Libgcrypt 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 Lesser General Public License for more details.
 ++ *
 ++ * You should have received a copy of the GNU Lesser General Public
 ++ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++#ifndef GCRYPT_BUFHELP_H
 ++#define GCRYPT_BUFHELP_H
 ++
 ++
 ++#include "bithelp.h"
 ++
 ++
 ++#undef BUFHELP_FAST_UNALIGNED_ACCESS
 ++#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
 ++    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
 ++    (defined(__i386__) || defined(__x86_64__) || \
 ++     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
 ++     defined(__aarch64__))
 ++/* These architectures are able of unaligned memory accesses and can
 ++   handle those fast.
 ++ */
 ++# define BUFHELP_FAST_UNALIGNED_ACCESS 1
 ++#endif
 ++
 ++
 ++#ifdef BUFHELP_FAST_UNALIGNED_ACCESS
 ++/* Define type with one-byte alignment on architectures with fast unaligned
 ++   memory accesses.
 ++ */
 ++typedef struct bufhelp_int_s
 ++{
 ++  uintptr_t a;
 ++} __attribute__((packed, aligned(1))) bufhelp_int_t;
 ++#else
 ++/* Define type with default alignment for other architectures (unaligned
 ++   accessed handled in per byte loops).
 ++ */
 ++typedef struct bufhelp_int_s
 ++{
 ++  uintptr_t a;
 ++} bufhelp_int_t;
 ++#endif
 ++
 ++
 ++/* Optimized function for small buffer copying */
 ++static inline void
 ++buf_cpy(void *_dst, const void *_src, size_t len)
 ++{
 ++#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__))
 ++  /* For AMD64 and i386, memcpy is faster.  */
 ++  memcpy(_dst, _src, len);
 ++#else
 ++  byte *dst = _dst;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a = (lsrc++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ = *src++;
 ++#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/
 ++}
 ++
 ++
 ++/* Optimized function for buffer xoring */
 ++static inline void
 ++buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
 ++{
 ++  byte *dst = _dst;
 ++  const byte *src1 = _src1;
 ++  const byte *src2 = _src2;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc1, *lsrc2;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc1 = (const bufhelp_int_t *)(const void *)src1;
 ++  lsrc2 = (const bufhelp_int_t *)(const void *)src2;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src1 = (const byte *)lsrc1;
 ++  src2 = (const byte *)lsrc2;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ = *src1++ ^ *src2++;
 ++}
 ++
 ++
 ++/* Optimized function for in-place buffer xoring. */
 ++static inline void
 ++buf_xor_1(void *_dst, const void *_src, size_t len)
 ++{
 ++  byte *dst = _dst;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a ^= (lsrc++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ ^= *src++;
 ++}
 ++
 ++
 ++/* Optimized function for buffer xoring with two destination buffers.  Used
 ++   mainly by CFB mode encryption.  */
 ++static inline void
 ++buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
 ++{
 ++  byte *dst1 = _dst1;
 ++  byte *dst2 = _dst2;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst1, *ldst2;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst1 = (bufhelp_int_t *)(void *)dst1;
 ++  ldst2 = (bufhelp_int_t *)(void *)dst2;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a);
 ++
 ++  dst1 = (byte *)ldst1;
 ++  dst2 = (byte *)ldst2;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst1++ = (*dst2++ ^= *src++);
 ++}
 ++
 ++
 ++/* Optimized function for combined buffer xoring and copying.  Used by mainly
 ++   CBC mode decryption.  */
 ++static inline void
 ++buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
 ++              const void *_src_cpy, size_t len)
 ++{
 ++  byte *dst_xor = _dst_xor;
 ++  byte *srcdst_cpy = _srcdst_cpy;
 ++  const byte *src_xor = _src_xor;
 ++  const byte *src_cpy = _src_cpy;
 ++  byte temp;
 ++  bufhelp_int_t *ldst_xor, *lsrcdst_cpy;
 ++  const bufhelp_int_t *lsrc_cpy, *lsrc_xor;
 ++  uintptr_t ltemp;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
 ++       (uintptr_t)srcdst_cpy) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst_xor = (bufhelp_int_t *)(void *)dst_xor;
 ++  lsrc_xor = (const bufhelp_int_t *)(void *)src_xor;
 ++  lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy;
 ++  lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    {
 ++      ltemp = (lsrc_cpy++)->a;
 ++      (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a;
 ++      (lsrcdst_cpy++)->a = ltemp;
 ++    }
 ++
 ++  dst_xor = (byte *)ldst_xor;
 ++  src_xor = (const byte *)lsrc_xor;
 ++  srcdst_cpy = (byte *)lsrcdst_cpy;
 ++  src_cpy = (const byte *)lsrc_cpy;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    {
 ++      temp = *src_cpy++;
 ++      *dst_xor++ = *srcdst_cpy ^ *src_xor++;
 ++      *srcdst_cpy++ = temp;
 ++    }
 ++}
 ++
 ++
 ++/* Optimized function for combined buffer xoring and copying.  Used by mainly
 ++   CFB mode decryption.  */
 ++static inline void
 ++buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
 ++{
 ++  buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len);
 ++}
 ++
 ++
 ++/* Constant-time compare of two buffers.  Returns 1 if buffers are equal,
 ++   and 0 if buffers differ.  */
 ++static inline int
 ++buf_eq_const(const void *_a, const void *_b, size_t len)
 ++{
 ++  const byte *a = _a;
 ++  const byte *b = _b;
 ++  size_t diff, i;
 ++
 ++  /* Constant-time compare. */
 ++  for (i = 0, diff = 0; i < len; i++)
 ++    diff -= !!(a[i] - b[i]);
 ++
 ++  return !diff;
 ++}
 ++
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++
 ++/* Functions for loading and storing unaligned u32 values of different
 ++   endianness.  */
 ++static inline u32 buf_get_be32(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \
 ++         ((u32)in[2] << 8) | (u32)in[3];
 ++}
 ++
 ++static inline u32 buf_get_le32(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \
 ++         ((u32)in[1] << 8) | (u32)in[0];
 ++}
 ++
 ++static inline void buf_put_be32(void *_buf, u32 val)
 ++{
 ++  byte *out = _buf;
 ++  out[0] = val >> 24;
 ++  out[1] = val >> 16;
 ++  out[2] = val >> 8;
 ++  out[3] = val;
 ++}
 ++
 ++static inline void buf_put_le32(void *_buf, u32 val)
 ++{
 ++  byte *out = _buf;
 ++  out[3] = val >> 24;
 ++  out[2] = val >> 16;
 ++  out[1] = val >> 8;
 ++  out[0] = val;
 ++}
 ++
 ++
 ++/* Functions for loading and storing unaligned u64 values of different
 ++   endianness.  */
 ++static inline u64 buf_get_be64(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \
 ++         ((u64)in[2] << 40) | ((u64)in[3] << 32) | \
 ++         ((u64)in[4] << 24) | ((u64)in[5] << 16) | \
 ++         ((u64)in[6] << 8) | (u64)in[7];
 ++}
 ++
 ++static inline u64 buf_get_le64(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \
 ++         ((u64)in[5] << 40) | ((u64)in[4] << 32) | \
 ++         ((u64)in[3] << 24) | ((u64)in[2] << 16) | \
 ++         ((u64)in[1] << 8) | (u64)in[0];
 ++}
 ++
 ++static inline void buf_put_be64(void *_buf, u64 val)
 ++{
 ++  byte *out = _buf;
 ++  out[0] = val >> 56;
 ++  out[1] = val >> 48;
 ++  out[2] = val >> 40;
 ++  out[3] = val >> 32;
 ++  out[4] = val >> 24;
 ++  out[5] = val >> 16;
 ++  out[6] = val >> 8;
 ++  out[7] = val;
 ++}
 ++
 ++static inline void buf_put_le64(void *_buf, u64 val)
 ++{
 ++  byte *out = _buf;
 ++  out[7] = val >> 56;
 ++  out[6] = val >> 48;
 ++  out[5] = val >> 40;
 ++  out[4] = val >> 32;
 ++  out[3] = val >> 24;
 ++  out[2] = val >> 16;
 ++  out[1] = val >> 8;
 ++  out[0] = val;
 ++}
 ++
 ++#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 ++
 ++typedef struct bufhelp_u32_s
 ++{
 ++  u32 a;
 ++} __attribute__((packed, aligned(1))) bufhelp_u32_t;
 ++
 ++/* Functions for loading and storing unaligned u32 values of different
 ++   endianness.  */
 ++static inline u32 buf_get_be32(const void *_buf)
 ++{
 ++  return be_bswap32(((const bufhelp_u32_t *)_buf)->a);
 ++}
 ++
 ++static inline u32 buf_get_le32(const void *_buf)
 ++{
 ++  return le_bswap32(((const bufhelp_u32_t *)_buf)->a);
 ++}
 ++
 ++static inline void buf_put_be32(void *_buf, u32 val)
 ++{
 ++  bufhelp_u32_t *out = _buf;
 ++  out->a = be_bswap32(val);
 ++}
 ++
 ++static inline void buf_put_le32(void *_buf, u32 val)
 ++{
 ++  bufhelp_u32_t *out = _buf;
 ++  out->a = le_bswap32(val);
 ++}
 ++
 ++
 ++typedef struct bufhelp_u64_s
 ++{
 ++  u64 a;
 ++} __attribute__((packed, aligned(1))) bufhelp_u64_t;
 ++
 ++/* Functions for loading and storing unaligned u64 values of different
 ++   endianness.  */
 ++static inline u64 buf_get_be64(const void *_buf)
 ++{
 ++  return be_bswap64(((const bufhelp_u64_t *)_buf)->a);
 ++}
 ++
 ++static inline u64 buf_get_le64(const void *_buf)
 ++{
 ++  return le_bswap64(((const bufhelp_u64_t *)_buf)->a);
 ++}
 ++
 ++static inline void buf_put_be64(void *_buf, u64 val)
 ++{
 ++  bufhelp_u64_t *out = _buf;
 ++  out->a = be_bswap64(val);
 ++}
 ++
 ++static inline void buf_put_le64(void *_buf, u64 val)
 ++{
 ++  bufhelp_u64_t *out = _buf;
 ++  out->a = le_bswap64(val);
 ++}
 ++
 ++
 ++#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 ++
 ++#endif /*GCRYPT_BUFHELP_H*/
 +diff --git a/grub-core/lib/libgcrypt-grub/cipher/crc.c b/grub-core/lib/libgcrypt-grub/cipher/crc.c
 +new file mode 100644
 +index 000000000..a92943213
 +--- /dev/null
 ++++ b/grub-core/lib/libgcrypt-grub/cipher/crc.c
 +@@ -0,0 +1,826 @@
 ++/* This file was automatically imported with 
 ++   import_gcry.py. Please don't modify it */
 ++#include <grub/dl.h>
 ++GRUB_MOD_LICENSE ("GPLv3+");
 ++/* crc.c - Cyclic redundancy checks.
 ++ * Copyright (C) 2003 Free Software Foundation, Inc.
 ++ *
 ++ * This file is part of Libgcrypt.
 ++ *
 ++ * Libgcrypt is free software; you can redistribute it and/or modify
 ++ * it under the terms of the GNU Lesser General Public License as
 ++ * published by the Free Software Foundation; either version 2.1 of
 ++ * the License, or (at your option) any later version.
 ++ *
 ++ * Libgcrypt 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 Lesser General Public License for more details.
 ++ *
 ++ * You should have received a copy of the GNU Lesser General Public
 ++ * License along with this program; if not, write to the Free Software
 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 ++ *
 ++ */
 ++
 ++
 ++#include "g10lib.h"
 ++#include "cipher.h"
 ++
 ++#include "bithelp.h"
 ++#include "bufhelp.h"
 ++
 ++
 ++typedef struct
 ++{
 ++  u32 CRC;
 ++  byte buf[4];
 ++}
 ++CRC_CONTEXT;
 ++
 ++
 ++/*
 ++ * Code generated by universal_crc by Danjel McGougan
 ++ *
 ++ * CRC parameters used:
 ++ *   bits:       32
 ++ *   poly:       0x04c11db7
 ++ *   init:       0xffffffff
 ++ *   xor:        0xffffffff
 ++ *   reverse:    true
 ++ *   non-direct: false
 ++ *
 ++ * CRC of the string "123456789" is 0xcbf43926
 ++ */
 ++
 ++static const u32 crc32_table[1024] = {
 ++  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
 ++  0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
 ++  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
 ++  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
 ++  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
 ++  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
 ++  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
 ++  0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
 ++  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
 ++  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
 ++  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
 ++  0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
 ++  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
 ++  0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
 ++  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
 ++  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
 ++  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
 ++  0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
 ++  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
 ++  0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
 ++  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
 ++  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
 ++  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
 ++  0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
 ++  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
 ++  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
 ++  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
 ++  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
 ++  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
 ++  0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 ++  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
 ++  0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
 ++  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
 ++  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
 ++  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
 ++  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
 ++  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
 ++  0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
 ++  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
 ++  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
 ++  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
 ++  0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
 ++  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
 ++  0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
 ++  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 ++  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
 ++  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
 ++  0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
 ++  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
 ++  0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
 ++  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
 ++  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
 ++  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
 ++  0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
 ++  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
 ++  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
 ++  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
 ++  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
 ++  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
 ++  0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 ++  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
 ++  0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
 ++  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
 ++  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
 ++  0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,
 ++  0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
 ++  0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,
 ++  0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
 ++  0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
 ++  0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
 ++  0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,
 ++  0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
 ++  0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,
 ++  0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
 ++  0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,
 ++  0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
 ++  0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,
 ++  0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
 ++  0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
 ++  0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
 ++  0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,
 ++  0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
 ++  0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,
 ++  0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
 ++  0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,
 ++  0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
 ++  0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,
 ++  0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
 ++  0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
 ++  0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
 ++  0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,
 ++  0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
 ++  0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,
 ++  0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
 ++  0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,
 ++  0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
 ++  0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,
 ++  0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
 ++  0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
 ++  0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
 ++  0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,
 ++  0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
 ++  0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,
 ++  0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
 ++  0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,
 ++  0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
 ++  0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,
 ++  0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
 ++  0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
 ++  0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
 ++  0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,
 ++  0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
 ++  0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,
 ++  0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
 ++  0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,
 ++  0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
 ++  0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,
 ++  0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
 ++  0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
 ++  0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
 ++  0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,
 ++  0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
 ++  0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,
 ++  0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
 ++  0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,
 ++  0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
 ++  0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,
 ++  0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,
 ++  0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,
 ++  0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
 ++  0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,
 ++  0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
 ++  0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
 ++  0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
 ++  0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,
 ++  0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
 ++  0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,
 ++  0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
 ++  0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,
 ++  0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
 ++  0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,
 ++  0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
 ++  0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
 ++  0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
 ++  0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,
 ++  0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
 ++  0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,
 ++  0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
 ++  0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,
 ++  0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
 ++  0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,
 ++  0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
 ++  0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
 ++  0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
 ++  0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,
 ++  0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
 ++  0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,
 ++  0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
 ++  0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,
 ++  0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
 ++  0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,
 ++  0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
 ++  0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
 ++  0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
 ++  0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,
 ++  0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
 ++  0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,
 ++  0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
 ++  0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,
 ++  0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
 ++  0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,
 ++  0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
 ++  0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
 ++  0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
 ++  0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,
 ++  0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
 ++  0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,
 ++  0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
 ++  0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,
 ++  0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
 ++  0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,
 ++  0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
 ++  0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
 ++  0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
 ++  0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,
 ++  0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
 ++  0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,
 ++  0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
 ++  0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,
 ++  0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
 ++  0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,
 ++  0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,
 ++  0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,
 ++  0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
 ++  0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,
 ++  0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
 ++  0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
 ++  0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
 ++  0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,
 ++  0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
 ++  0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,
 ++  0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
 ++  0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,
 ++  0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
 ++  0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,
 ++  0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
 ++  0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
 ++  0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
 ++  0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,
 ++  0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
 ++  0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,
 ++  0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
 ++  0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,
 ++  0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
 ++  0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,
 ++  0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
 ++  0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
 ++  0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
 ++  0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,
 ++  0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
 ++  0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,
 ++  0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
 ++  0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,
 ++  0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
 ++  0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,
 ++  0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
 ++  0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
 ++  0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
 ++  0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,
 ++  0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
 ++  0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,
 ++  0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
 ++  0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,
 ++  0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
 ++  0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,
 ++  0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
 ++  0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
 ++  0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
 ++  0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,
 ++  0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
 ++  0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,
 ++  0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
 ++  0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,
 ++  0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
 ++  0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,
 ++  0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
 ++  0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
 ++  0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
 ++  0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,
 ++  0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
 ++  0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,
 ++  0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
 ++  0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,
 ++  0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
 ++  0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,
 ++  0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
 ++};
 ++
 ++/* CRC32 */
 ++
 ++static inline u32
 ++crc32_next (u32 crc, byte data)
 ++{
 ++  return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data];
 ++}
 ++
 ++/*
 ++ * Process 4 bytes in one go
 ++ */
 ++static inline u32
 ++crc32_next4 (u32 crc, u32 data)
 ++{
 ++  crc ^= data;
 ++  crc = crc32_table[(crc & 0xff) + 0x300] ^
 ++        crc32_table[((crc >> 8) & 0xff) + 0x200] ^
 ++        crc32_table[((crc >> 16) & 0xff) + 0x100] ^
 ++        crc32_table[(crc >> 24) & 0xff];
 ++  return crc;
 ++}
 ++
 ++static void
 ++crc32_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = 0 ^ 0xffffffffL;
 ++}
 ++
 ++static void
 ++crc32_write (void *context, const void *inbuf_arg, size_t inlen)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  const byte *inbuf = inbuf_arg;
 ++  u32 crc;
 ++
 ++  if (!inbuf || !inlen)
 ++    return;
 ++
 ++  crc = ctx->CRC;
 ++
 ++  while (inlen >= 16)
 ++    {
 ++      inlen -= 16;
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[0]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[4]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[8]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[12]));
 ++      inbuf += 16;
 ++    }
 ++
 ++  while (inlen >= 4)
 ++    {
 ++      inlen -= 4;
 ++      crc = crc32_next4(crc, buf_get_le32(inbuf));
 ++      inbuf += 4;
 ++    }
 ++
 ++  while (inlen--)
 ++    {
 ++      crc = crc32_next(crc, *inbuf++);
 ++    }
 ++
 ++  ctx->CRC = crc;
 ++}
 ++
 ++static byte *
 ++crc32_read (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  return ctx->buf;
 ++}
 ++
 ++static void
 ++crc32_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC ^= 0xffffffffL;
 ++  buf_put_be32 (ctx->buf, ctx->CRC);
 ++}
 ++
 ++/* CRC32 a'la RFC 1510 */
 ++/* CRC of the string "123456789" is 0x2dfd2d88 */
 ++
 ++static void
 ++crc32rfc1510_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = 0;
 ++}
 ++
 ++static void
 ++crc32rfc1510_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  buf_put_be32(ctx->buf, ctx->CRC);
 ++}
 ++
 ++/* CRC24 a'la RFC 2440 */
 ++/*
 ++ * Code generated by universal_crc by Danjel McGougan
 ++ *
 ++ * CRC parameters used:
 ++ *   bits:       24
 ++ *   poly:       0x864cfb
 ++ *   init:       0xb704ce
 ++ *   xor:        0x000000
 ++ *   reverse:    false
 ++ *   non-direct: false
 ++ *
 ++ * CRC of the string "123456789" is 0x21cf02
 ++ */
 ++
 ++static const u32 crc24_table[1024] =
 ++{
 ++  0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c,
 ++  0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f,
 ++  0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad,
 ++  0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e,
 ++  0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9,
 ++  0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a,
 ++  0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668,
 ++  0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb,
 ++  0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800,
 ++  0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93,
 ++  0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1,
 ++  0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32,
 ++  0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5,
 ++  0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056,
 ++  0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764,
 ++  0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7,
 ++  0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15,
 ++  0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86,
 ++  0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4,
 ++  0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27,
 ++  0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0,
 ++  0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243,
 ++  0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571,
 ++  0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2,
 ++  0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19,
 ++  0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a,
 ++  0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8,
 ++  0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b,
 ++  0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc,
 ++  0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f,
 ++  0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d,
 ++  0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee,
 ++  0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f,
 ++  0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac,
 ++  0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e,
 ++  0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d,
 ++  0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa,
 ++  0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669,
 ++  0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b,
 ++  0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8,
 ++  0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33,
 ++  0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0,
 ++  0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92,
 ++  0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801,
 ++  0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6,
 ++  0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765,
 ++  0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057,
 ++  0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4,
 ++  0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26,
 ++  0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5,
 ++  0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87,
 ++  0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14,
 ++  0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3,
 ++  0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570,
 ++  0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242,
 ++  0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1,
 ++  0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a,
 ++  0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9,
 ++  0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b,
 ++  0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18,
 ++  0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef,
 ++  0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c,
 ++  0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e,
 ++  0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd,
 ++  0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab,
 ++  0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7,
 ++  0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293,
 ++  0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f,
 ++  0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da,
 ++  0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6,
 ++  0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2,
 ++  0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe,
 ++  0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48,
 ++  0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54,
 ++  0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70,
 ++  0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c,
 ++  0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839,
 ++  0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925,
 ++  0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01,
 ++  0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d,
 ++  0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea,
 ++  0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6,
 ++  0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2,
 ++  0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce,
 ++  0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b,
 ++  0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687,
 ++  0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3,
 ++  0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf,
 ++  0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09,
 ++  0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15,
 ++  0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31,
 ++  0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d,
 ++  0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978,
 ++  0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864,
 ++  0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40,
 ++  0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c,
 ++  0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329,
 ++  0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235,
 ++  0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011,
 ++  0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d,
 ++  0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458,
 ++  0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544,
 ++  0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760,
 ++  0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c,
 ++  0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca,
 ++  0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6,
 ++  0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2,
 ++  0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee,
 ++  0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb,
 ++  0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7,
 ++  0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983,
 ++  0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f,
 ++  0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268,
 ++  0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374,
 ++  0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150,
 ++  0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c,
 ++  0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519,
 ++  0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405,
 ++  0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621,
 ++  0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d,
 ++  0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b,
 ++  0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97,
 ++  0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3,
 ++  0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf,
 ++  0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa,
 ++  0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6,
 ++  0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2,
 ++  0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de,
 ++  0x00000000, 0x00d70983, 0x00555f80, 0x00825603,
 ++  0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485,
 ++  0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88,
 ++  0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e,
 ++  0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92,
 ++  0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814,
 ++  0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219,
 ++  0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f,
 ++  0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7,
 ++  0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021,
 ++  0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c,
 ++  0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa,
 ++  0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36,
 ++  0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0,
 ++  0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd,
 ++  0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b,
 ++  0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd,
 ++  0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b,
 ++  0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46,
 ++  0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0,
 ++  0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c,
 ++  0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda,
 ++  0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7,
 ++  0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451,
 ++  0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669,
 ++  0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef,
 ++  0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2,
 ++  0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64,
 ++  0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8,
 ++  0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e,
 ++  0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273,
 ++  0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5,
 ++  0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218,
 ++  0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e,
 ++  0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93,
 ++  0x00a15e16, 0x00765795, 0x00f40196, 0x00230815,
 ++  0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89,
 ++  0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f,
 ++  0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602,
 ++  0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484,
 ++  0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc,
 ++  0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a,
 ++  0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37,
 ++  0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1,
 ++  0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d,
 ++  0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab,
 ++  0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6,
 ++  0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020,
 ++  0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6,
 ++  0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450,
 ++  0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d,
 ++  0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb,
 ++  0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47,
 ++  0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1,
 ++  0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc,
 ++  0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a,
 ++  0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272,
 ++  0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4,
 ++  0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9,
 ++  0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f,
 ++  0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3,
 ++  0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65,
 ++  0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668,
 ++  0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee,
 ++  0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a,
 ++  0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82,
 ++  0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c,
 ++  0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4,
 ++  0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736,
 ++  0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee,
 ++  0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100,
 ++  0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8,
 ++  0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282,
 ++  0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a,
 ++  0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4,
 ++  0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c,
 ++  0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee,
 ++  0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36,
 ++  0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8,
 ++  0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00,
 ++  0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c,
 ++  0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4,
 ++  0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a,
 ++  0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782,
 ++  0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800,
 ++  0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8,
 ++  0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36,
 ++  0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee,
 ++  0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4,
 ++  0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c,
 ++  0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82,
 ++  0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a,
 ++  0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8,
 ++  0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400,
 ++  0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee,
 ++  0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236,
 ++  0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436,
 ++  0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee,
 ++  0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200,
 ++  0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8,
 ++  0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a,
 ++  0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82,
 ++  0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c,
 ++  0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4,
 ++  0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee,
 ++  0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836,
 ++  0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8,
 ++  0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00,
 ++  0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182,
 ++  0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a,
 ++  0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4,
 ++  0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c,
 ++  0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00,
 ++  0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8,
 ++  0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36,
 ++  0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee,
 ++  0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c,
 ++  0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4,
 ++  0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a,
 ++  0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482,
 ++  0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8,
 ++  0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700,
 ++  0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee,
 ++  0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136,
 ++  0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4,
 ++  0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c,
 ++  0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882,
 ++  0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a
 ++};
 ++
 ++static inline
 ++u32 crc24_init (void)
 ++{
 ++  return 0xce04b7;
 ++}
 ++
 ++static inline
 ++u32 crc24_next (u32 crc, byte data)
 ++{
 ++  return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data];
 ++}
 ++
 ++/*
 ++ * Process 4 bytes in one go
 ++ */
 ++static inline
 ++u32 crc24_next4 (u32 crc, u32 data)
 ++{
 ++  crc ^= data;
 ++  crc = crc24_table[(crc & 0xff) + 0x300] ^
 ++        crc24_table[((crc >> 8) & 0xff) + 0x200] ^
 ++        crc24_table[((crc >> 16) & 0xff) + 0x100] ^
 ++        crc24_table[(crc >> 24) & 0xff];
 ++  return crc;
 ++}
 ++
 ++static inline
 ++u32 crc24_final (u32 crc)
 ++{
 ++  return crc & 0xffffff;
 ++}
 ++
 ++static void
 ++crc24rfc2440_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = crc24_init();
 ++}
 ++
 ++static void
 ++crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
 ++{
 ++  const unsigned char *inbuf = inbuf_arg;
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  u32 crc;
 ++
 ++  if (!inbuf || !inlen)
 ++    return;
 ++
 ++  crc = ctx->CRC;
 ++
 ++  while (inlen >= 16)
 ++    {
 ++      inlen -= 16;
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[0]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[4]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[8]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[12]));
 ++      inbuf += 16;
 ++    }
 ++
 ++  while (inlen >= 4)
 ++    {
 ++      inlen -= 4;
 ++      crc = crc24_next4(crc, buf_get_le32(inbuf));
 ++      inbuf += 4;
 ++    }
 ++
 ++  while (inlen--)
 ++    {
 ++      crc = crc24_next(crc, *inbuf++);
 ++    }
 ++
 ++  ctx->CRC = crc;
 ++}
 ++
 ++static void
 ++crc24rfc2440_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = crc24_final(ctx->CRC);
 ++  buf_put_le32 (ctx->buf, ctx->CRC);
 ++}
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc32 =
 ++  {
 ++    "CRC32", NULL, 0, NULL, 4,
 ++    crc32_init, crc32_write, crc32_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++    ,
 ++#ifdef GRUB_UTIL
 ++    .modname = "gcry_crc",
 ++#endif
 ++    .blocksize = 64
 ++  };
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
 ++  {
 ++    "CRC32RFC1510", NULL, 0, NULL, 4,
 ++    crc32rfc1510_init, crc32_write,
 ++    crc32rfc1510_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++    ,
 ++#ifdef GRUB_UTIL
 ++    .modname = "gcry_crc",
 ++#endif
 ++    .blocksize = 64
 ++  };
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
 ++  {
 ++    "CRC24RFC2440", NULL, 0, NULL, 3,
 ++    crc24rfc2440_init, crc24rfc2440_write,
 ++    crc24rfc2440_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++    ,
 ++#ifdef GRUB_UTIL
 ++    .modname = "gcry_crc",
 ++#endif
 ++    .blocksize = 64
 ++  };
 ++
 ++
 ++GRUB_MOD_INIT(gcry_crc)
 ++{
 ++  COMPILE_TIME_ASSERT(sizeof (CRC_CONTEXT) <= GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);
 ++  COMPILE_TIME_ASSERT(sizeof (CRC_CONTEXT) <= GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);
 ++  COMPILE_TIME_ASSERT(sizeof (CRC_CONTEXT) <= GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);
 ++  grub_md_register (&_gcry_digest_spec_crc32);
 ++  grub_md_register (&_gcry_digest_spec_crc32_rfc1510);
 ++  grub_md_register (&_gcry_digest_spec_crc24_rfc2440);
 ++}
 ++
 ++GRUB_MOD_FINI(gcry_crc)
 ++{
 ++  grub_md_unregister (&_gcry_digest_spec_crc32);
 ++  grub_md_unregister (&_gcry_digest_spec_crc32_rfc1510);
 ++  grub_md_unregister (&_gcry_digest_spec_crc24_rfc2440);
 ++}
 +diff --git a/grub-core/lib/libgcrypt/cipher/bufhelp.h b/grub-core/lib/libgcrypt/cipher/bufhelp.h
 +new file mode 100644
 +index 000000000..df3559472
 +--- /dev/null
 ++++ b/grub-core/lib/libgcrypt/cipher/bufhelp.h
 +@@ -0,0 +1,432 @@
 ++/* bufhelp.h  -  Some buffer manipulation helpers
 ++ * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 ++ *
 ++ * This file is part of Libgcrypt.
 ++ *
 ++ * Libgcrypt is free software; you can redistribute it and/or modify
 ++ * it under the terms of the GNU Lesser General Public License as
 ++ * published by the Free Software Foundation; either version 2.1 of
 ++ * the License, or (at your option) any later version.
 ++ *
 ++ * Libgcrypt 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 Lesser General Public License for more details.
 ++ *
 ++ * You should have received a copy of the GNU Lesser General Public
 ++ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++#ifndef GCRYPT_BUFHELP_H
 ++#define GCRYPT_BUFHELP_H
 ++
 ++
 ++#include "bithelp.h"
 ++
 ++
 ++#undef BUFHELP_FAST_UNALIGNED_ACCESS
 ++#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
 ++    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
 ++    (defined(__i386__) || defined(__x86_64__) || \
 ++     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
 ++     defined(__aarch64__))
 ++/* These architectures are able of unaligned memory accesses and can
 ++   handle those fast.
 ++ */
 ++# define BUFHELP_FAST_UNALIGNED_ACCESS 1
 ++#endif
 ++
 ++
 ++#ifdef BUFHELP_FAST_UNALIGNED_ACCESS
 ++/* Define type with one-byte alignment on architectures with fast unaligned
 ++   memory accesses.
 ++ */
 ++typedef struct bufhelp_int_s
 ++{
 ++  uintptr_t a;
 ++} __attribute__((packed, aligned(1))) bufhelp_int_t;
 ++#else
 ++/* Define type with default alignment for other architectures (unaligned
 ++   accessed handled in per byte loops).
 ++ */
 ++typedef struct bufhelp_int_s
 ++{
 ++  uintptr_t a;
 ++} bufhelp_int_t;
 ++#endif
 ++
 ++
 ++/* Optimized function for small buffer copying */
 ++static inline void
 ++buf_cpy(void *_dst, const void *_src, size_t len)
 ++{
 ++#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__))
 ++  /* For AMD64 and i386, memcpy is faster.  */
 ++  memcpy(_dst, _src, len);
 ++#else
 ++  byte *dst = _dst;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a = (lsrc++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ = *src++;
 ++#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/
 ++}
 ++
 ++
 ++/* Optimized function for buffer xoring */
 ++static inline void
 ++buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
 ++{
 ++  byte *dst = _dst;
 ++  const byte *src1 = _src1;
 ++  const byte *src2 = _src2;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc1, *lsrc2;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc1 = (const bufhelp_int_t *)(const void *)src1;
 ++  lsrc2 = (const bufhelp_int_t *)(const void *)src2;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src1 = (const byte *)lsrc1;
 ++  src2 = (const byte *)lsrc2;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ = *src1++ ^ *src2++;
 ++}
 ++
 ++
 ++/* Optimized function for in-place buffer xoring. */
 ++static inline void
 ++buf_xor_1(void *_dst, const void *_src, size_t len)
 ++{
 ++  byte *dst = _dst;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst = (bufhelp_int_t *)(void *)dst;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst++)->a ^= (lsrc++)->a;
 ++
 ++  dst = (byte *)ldst;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst++ ^= *src++;
 ++}
 ++
 ++
 ++/* Optimized function for buffer xoring with two destination buffers.  Used
 ++   mainly by CFB mode encryption.  */
 ++static inline void
 ++buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
 ++{
 ++  byte *dst1 = _dst1;
 ++  byte *dst2 = _dst2;
 ++  const byte *src = _src;
 ++  bufhelp_int_t *ldst1, *ldst2;
 ++  const bufhelp_int_t *lsrc;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst1 = (bufhelp_int_t *)(void *)dst1;
 ++  ldst2 = (bufhelp_int_t *)(void *)dst2;
 ++  lsrc = (const bufhelp_int_t *)(const void *)src;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a);
 ++
 ++  dst1 = (byte *)ldst1;
 ++  dst2 = (byte *)ldst2;
 ++  src = (const byte *)lsrc;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    *dst1++ = (*dst2++ ^= *src++);
 ++}
 ++
 ++
 ++/* Optimized function for combined buffer xoring and copying.  Used by mainly
 ++   CBC mode decryption.  */
 ++static inline void
 ++buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
 ++              const void *_src_cpy, size_t len)
 ++{
 ++  byte *dst_xor = _dst_xor;
 ++  byte *srcdst_cpy = _srcdst_cpy;
 ++  const byte *src_xor = _src_xor;
 ++  const byte *src_cpy = _src_cpy;
 ++  byte temp;
 ++  bufhelp_int_t *ldst_xor, *lsrcdst_cpy;
 ++  const bufhelp_int_t *lsrc_cpy, *lsrc_xor;
 ++  uintptr_t ltemp;
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 ++
 ++  /* Skip fast processing if buffers are unaligned.  */
 ++  if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
 ++       (uintptr_t)srcdst_cpy) & longmask)
 ++    goto do_bytes;
 ++#endif
 ++
 ++  ldst_xor = (bufhelp_int_t *)(void *)dst_xor;
 ++  lsrc_xor = (const bufhelp_int_t *)(void *)src_xor;
 ++  lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy;
 ++  lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy;
 ++
 ++  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
 ++    {
 ++      ltemp = (lsrc_cpy++)->a;
 ++      (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a;
 ++      (lsrcdst_cpy++)->a = ltemp;
 ++    }
 ++
 ++  dst_xor = (byte *)ldst_xor;
 ++  src_xor = (const byte *)lsrc_xor;
 ++  srcdst_cpy = (byte *)lsrcdst_cpy;
 ++  src_cpy = (const byte *)lsrc_cpy;
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++do_bytes:
 ++#endif
 ++  /* Handle tail.  */
 ++  for (; len; len--)
 ++    {
 ++      temp = *src_cpy++;
 ++      *dst_xor++ = *srcdst_cpy ^ *src_xor++;
 ++      *srcdst_cpy++ = temp;
 ++    }
 ++}
 ++
 ++
 ++/* Optimized function for combined buffer xoring and copying.  Used by mainly
 ++   CFB mode decryption.  */
 ++static inline void
 ++buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
 ++{
 ++  buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len);
 ++}
 ++
 ++
 ++/* Constant-time compare of two buffers.  Returns 1 if buffers are equal,
 ++   and 0 if buffers differ.  */
 ++static inline int
 ++buf_eq_const(const void *_a, const void *_b, size_t len)
 ++{
 ++  const byte *a = _a;
 ++  const byte *b = _b;
 ++  size_t diff, i;
 ++
 ++  /* Constant-time compare. */
 ++  for (i = 0, diff = 0; i < len; i++)
 ++    diff -= !!(a[i] - b[i]);
 ++
 ++  return !diff;
 ++}
 ++
 ++
 ++#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
 ++
 ++/* Functions for loading and storing unaligned u32 values of different
 ++   endianness.  */
 ++static inline u32 buf_get_be32(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \
 ++         ((u32)in[2] << 8) | (u32)in[3];
 ++}
 ++
 ++static inline u32 buf_get_le32(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \
 ++         ((u32)in[1] << 8) | (u32)in[0];
 ++}
 ++
 ++static inline void buf_put_be32(void *_buf, u32 val)
 ++{
 ++  byte *out = _buf;
 ++  out[0] = val >> 24;
 ++  out[1] = val >> 16;
 ++  out[2] = val >> 8;
 ++  out[3] = val;
 ++}
 ++
 ++static inline void buf_put_le32(void *_buf, u32 val)
 ++{
 ++  byte *out = _buf;
 ++  out[3] = val >> 24;
 ++  out[2] = val >> 16;
 ++  out[1] = val >> 8;
 ++  out[0] = val;
 ++}
 ++
 ++
 ++/* Functions for loading and storing unaligned u64 values of different
 ++   endianness.  */
 ++static inline u64 buf_get_be64(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \
 ++         ((u64)in[2] << 40) | ((u64)in[3] << 32) | \
 ++         ((u64)in[4] << 24) | ((u64)in[5] << 16) | \
 ++         ((u64)in[6] << 8) | (u64)in[7];
 ++}
 ++
 ++static inline u64 buf_get_le64(const void *_buf)
 ++{
 ++  const byte *in = _buf;
 ++  return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \
 ++         ((u64)in[5] << 40) | ((u64)in[4] << 32) | \
 ++         ((u64)in[3] << 24) | ((u64)in[2] << 16) | \
 ++         ((u64)in[1] << 8) | (u64)in[0];
 ++}
 ++
 ++static inline void buf_put_be64(void *_buf, u64 val)
 ++{
 ++  byte *out = _buf;
 ++  out[0] = val >> 56;
 ++  out[1] = val >> 48;
 ++  out[2] = val >> 40;
 ++  out[3] = val >> 32;
 ++  out[4] = val >> 24;
 ++  out[5] = val >> 16;
 ++  out[6] = val >> 8;
 ++  out[7] = val;
 ++}
 ++
 ++static inline void buf_put_le64(void *_buf, u64 val)
 ++{
 ++  byte *out = _buf;
 ++  out[7] = val >> 56;
 ++  out[6] = val >> 48;
 ++  out[5] = val >> 40;
 ++  out[4] = val >> 32;
 ++  out[3] = val >> 24;
 ++  out[2] = val >> 16;
 ++  out[1] = val >> 8;
 ++  out[0] = val;
 ++}
 ++
 ++#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 ++
 ++typedef struct bufhelp_u32_s
 ++{
 ++  u32 a;
 ++} __attribute__((packed, aligned(1))) bufhelp_u32_t;
 ++
 ++/* Functions for loading and storing unaligned u32 values of different
 ++   endianness.  */
 ++static inline u32 buf_get_be32(const void *_buf)
 ++{
 ++  return be_bswap32(((const bufhelp_u32_t *)_buf)->a);
 ++}
 ++
 ++static inline u32 buf_get_le32(const void *_buf)
 ++{
 ++  return le_bswap32(((const bufhelp_u32_t *)_buf)->a);
 ++}
 ++
 ++static inline void buf_put_be32(void *_buf, u32 val)
 ++{
 ++  bufhelp_u32_t *out = _buf;
 ++  out->a = be_bswap32(val);
 ++}
 ++
 ++static inline void buf_put_le32(void *_buf, u32 val)
 ++{
 ++  bufhelp_u32_t *out = _buf;
 ++  out->a = le_bswap32(val);
 ++}
 ++
 ++
 ++typedef struct bufhelp_u64_s
 ++{
 ++  u64 a;
 ++} __attribute__((packed, aligned(1))) bufhelp_u64_t;
 ++
 ++/* Functions for loading and storing unaligned u64 values of different
 ++   endianness.  */
 ++static inline u64 buf_get_be64(const void *_buf)
 ++{
 ++  return be_bswap64(((const bufhelp_u64_t *)_buf)->a);
 ++}
 ++
 ++static inline u64 buf_get_le64(const void *_buf)
 ++{
 ++  return le_bswap64(((const bufhelp_u64_t *)_buf)->a);
 ++}
 ++
 ++static inline void buf_put_be64(void *_buf, u64 val)
 ++{
 ++  bufhelp_u64_t *out = _buf;
 ++  out->a = be_bswap64(val);
 ++}
 ++
 ++static inline void buf_put_le64(void *_buf, u64 val)
 ++{
 ++  bufhelp_u64_t *out = _buf;
 ++  out->a = le_bswap64(val);
 ++}
 ++
 ++
 ++#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 ++
 ++#endif /*GCRYPT_BUFHELP_H*/
 +diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c
 +new file mode 100644
 +index 000000000..28454f8ab
 +--- /dev/null
 ++++ b/grub-core/lib/libgcrypt/cipher/crc.c
 +@@ -0,0 +1,793 @@
 ++/* crc.c - Cyclic redundancy checks.
 ++ * Copyright (C) 2003 Free Software Foundation, Inc.
 ++ *
 ++ * This file is part of Libgcrypt.
 ++ *
 ++ * Libgcrypt is free software; you can redistribute it and/or modify
 ++ * it under the terms of the GNU Lesser General Public License as
 ++ * published by the Free Software Foundation; either version 2.1 of
 ++ * the License, or (at your option) any later version.
 ++ *
 ++ * Libgcrypt 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 Lesser General Public License for more details.
 ++ *
 ++ * You should have received a copy of the GNU Lesser General Public
 ++ * License along with this program; if not, write to the Free Software
 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 ++ *
 ++ */
 ++
 ++#include <config.h>
 ++#include <stdio.h>
 ++#include <stdlib.h>
 ++#include <string.h>
 ++
 ++#include "g10lib.h"
 ++#include "cipher.h"
 ++
 ++#include "bithelp.h"
 ++#include "bufhelp.h"
 ++
 ++
 ++typedef struct
 ++{
 ++  u32 CRC;
 ++  byte buf[4];
 ++}
 ++CRC_CONTEXT;
 ++
 ++
 ++/*
 ++ * Code generated by universal_crc by Danjel McGougan
 ++ *
 ++ * CRC parameters used:
 ++ *   bits:       32
 ++ *   poly:       0x04c11db7
 ++ *   init:       0xffffffff
 ++ *   xor:        0xffffffff
 ++ *   reverse:    true
 ++ *   non-direct: false
 ++ *
 ++ * CRC of the string "123456789" is 0xcbf43926
 ++ */
 ++
 ++static const u32 crc32_table[1024] = {
 ++  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
 ++  0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
 ++  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
 ++  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
 ++  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
 ++  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
 ++  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
 ++  0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
 ++  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
 ++  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
 ++  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
 ++  0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
 ++  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
 ++  0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
 ++  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
 ++  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
 ++  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
 ++  0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
 ++  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
 ++  0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
 ++  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
 ++  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
 ++  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
 ++  0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
 ++  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
 ++  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
 ++  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
 ++  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
 ++  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
 ++  0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 ++  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
 ++  0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
 ++  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
 ++  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
 ++  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
 ++  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
 ++  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
 ++  0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
 ++  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
 ++  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
 ++  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
 ++  0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
 ++  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
 ++  0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
 ++  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 ++  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
 ++  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
 ++  0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
 ++  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
 ++  0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
 ++  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
 ++  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
 ++  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
 ++  0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
 ++  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
 ++  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
 ++  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
 ++  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
 ++  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
 ++  0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 ++  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
 ++  0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
 ++  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
 ++  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
 ++  0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,
 ++  0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
 ++  0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,
 ++  0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
 ++  0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
 ++  0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
 ++  0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,
 ++  0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
 ++  0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,
 ++  0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
 ++  0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,
 ++  0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
 ++  0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,
 ++  0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
 ++  0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
 ++  0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
 ++  0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,
 ++  0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
 ++  0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,
 ++  0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
 ++  0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,
 ++  0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
 ++  0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,
 ++  0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
 ++  0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
 ++  0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
 ++  0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,
 ++  0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
 ++  0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,
 ++  0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
 ++  0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,
 ++  0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
 ++  0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,
 ++  0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
 ++  0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
 ++  0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
 ++  0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,
 ++  0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
 ++  0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,
 ++  0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
 ++  0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,
 ++  0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
 ++  0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,
 ++  0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
 ++  0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
 ++  0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
 ++  0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,
 ++  0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
 ++  0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,
 ++  0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
 ++  0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,
 ++  0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
 ++  0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,
 ++  0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
 ++  0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
 ++  0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
 ++  0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,
 ++  0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
 ++  0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,
 ++  0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
 ++  0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,
 ++  0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
 ++  0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,
 ++  0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,
 ++  0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,
 ++  0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
 ++  0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,
 ++  0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
 ++  0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
 ++  0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
 ++  0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,
 ++  0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
 ++  0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,
 ++  0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
 ++  0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,
 ++  0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
 ++  0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,
 ++  0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
 ++  0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
 ++  0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
 ++  0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,
 ++  0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
 ++  0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,
 ++  0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
 ++  0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,
 ++  0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
 ++  0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,
 ++  0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
 ++  0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
 ++  0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
 ++  0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,
 ++  0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
 ++  0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,
 ++  0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
 ++  0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,
 ++  0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
 ++  0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,
 ++  0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
 ++  0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
 ++  0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
 ++  0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,
 ++  0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
 ++  0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,
 ++  0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
 ++  0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,
 ++  0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
 ++  0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,
 ++  0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
 ++  0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
 ++  0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
 ++  0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,
 ++  0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
 ++  0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,
 ++  0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
 ++  0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,
 ++  0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
 ++  0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,
 ++  0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
 ++  0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
 ++  0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
 ++  0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,
 ++  0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
 ++  0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,
 ++  0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
 ++  0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,
 ++  0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
 ++  0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,
 ++  0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,
 ++  0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,
 ++  0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
 ++  0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,
 ++  0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
 ++  0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
 ++  0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
 ++  0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,
 ++  0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
 ++  0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,
 ++  0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
 ++  0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,
 ++  0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
 ++  0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,
 ++  0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
 ++  0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
 ++  0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
 ++  0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,
 ++  0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
 ++  0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,
 ++  0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
 ++  0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,
 ++  0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
 ++  0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,
 ++  0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
 ++  0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
 ++  0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
 ++  0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,
 ++  0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
 ++  0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,
 ++  0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
 ++  0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,
 ++  0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
 ++  0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,
 ++  0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
 ++  0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
 ++  0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
 ++  0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,
 ++  0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
 ++  0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,
 ++  0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
 ++  0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,
 ++  0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
 ++  0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,
 ++  0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
 ++  0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
 ++  0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
 ++  0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,
 ++  0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
 ++  0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,
 ++  0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
 ++  0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,
 ++  0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
 ++  0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,
 ++  0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
 ++  0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
 ++  0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
 ++  0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,
 ++  0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
 ++  0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,
 ++  0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
 ++  0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,
 ++  0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
 ++  0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,
 ++  0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
 ++};
 ++
 ++/* CRC32 */
 ++
 ++static inline u32
 ++crc32_next (u32 crc, byte data)
 ++{
 ++  return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data];
 ++}
 ++
 ++/*
 ++ * Process 4 bytes in one go
 ++ */
 ++static inline u32
 ++crc32_next4 (u32 crc, u32 data)
 ++{
 ++  crc ^= data;
 ++  crc = crc32_table[(crc & 0xff) + 0x300] ^
 ++        crc32_table[((crc >> 8) & 0xff) + 0x200] ^
 ++        crc32_table[((crc >> 16) & 0xff) + 0x100] ^
 ++        crc32_table[(crc >> 24) & 0xff];
 ++  return crc;
 ++}
 ++
 ++static void
 ++crc32_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = 0 ^ 0xffffffffL;
 ++}
 ++
 ++static void
 ++crc32_write (void *context, const void *inbuf_arg, size_t inlen)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  const byte *inbuf = inbuf_arg;
 ++  u32 crc;
 ++
 ++  if (!inbuf || !inlen)
 ++    return;
 ++
 ++  crc = ctx->CRC;
 ++
 ++  while (inlen >= 16)
 ++    {
 ++      inlen -= 16;
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[0]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[4]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[8]));
 ++      crc = crc32_next4(crc, buf_get_le32(&inbuf[12]));
 ++      inbuf += 16;
 ++    }
 ++
 ++  while (inlen >= 4)
 ++    {
 ++      inlen -= 4;
 ++      crc = crc32_next4(crc, buf_get_le32(inbuf));
 ++      inbuf += 4;
 ++    }
 ++
 ++  while (inlen--)
 ++    {
 ++      crc = crc32_next(crc, *inbuf++);
 ++    }
 ++
 ++  ctx->CRC = crc;
 ++}
 ++
 ++static byte *
 ++crc32_read (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  return ctx->buf;
 ++}
 ++
 ++static void
 ++crc32_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC ^= 0xffffffffL;
 ++  buf_put_be32 (ctx->buf, ctx->CRC);
 ++}
 ++
 ++/* CRC32 a'la RFC 1510 */
 ++/* CRC of the string "123456789" is 0x2dfd2d88 */
 ++
 ++static void
 ++crc32rfc1510_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = 0;
 ++}
 ++
 ++static void
 ++crc32rfc1510_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  buf_put_be32(ctx->buf, ctx->CRC);
 ++}
 ++
 ++/* CRC24 a'la RFC 2440 */
 ++/*
 ++ * Code generated by universal_crc by Danjel McGougan
 ++ *
 ++ * CRC parameters used:
 ++ *   bits:       24
 ++ *   poly:       0x864cfb
 ++ *   init:       0xb704ce
 ++ *   xor:        0x000000
 ++ *   reverse:    false
 ++ *   non-direct: false
 ++ *
 ++ * CRC of the string "123456789" is 0x21cf02
 ++ */
 ++
 ++static const u32 crc24_table[1024] =
 ++{
 ++  0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c,
 ++  0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f,
 ++  0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad,
 ++  0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e,
 ++  0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9,
 ++  0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a,
 ++  0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668,
 ++  0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb,
 ++  0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800,
 ++  0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93,
 ++  0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1,
 ++  0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32,
 ++  0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5,
 ++  0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056,
 ++  0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764,
 ++  0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7,
 ++  0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15,
 ++  0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86,
 ++  0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4,
 ++  0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27,
 ++  0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0,
 ++  0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243,
 ++  0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571,
 ++  0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2,
 ++  0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19,
 ++  0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a,
 ++  0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8,
 ++  0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b,
 ++  0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc,
 ++  0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f,
 ++  0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d,
 ++  0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee,
 ++  0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f,
 ++  0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac,
 ++  0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e,
 ++  0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d,
 ++  0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa,
 ++  0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669,
 ++  0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b,
 ++  0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8,
 ++  0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33,
 ++  0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0,
 ++  0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92,
 ++  0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801,
 ++  0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6,
 ++  0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765,
 ++  0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057,
 ++  0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4,
 ++  0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26,
 ++  0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5,
 ++  0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87,
 ++  0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14,
 ++  0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3,
 ++  0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570,
 ++  0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242,
 ++  0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1,
 ++  0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a,
 ++  0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9,
 ++  0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b,
 ++  0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18,
 ++  0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef,
 ++  0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c,
 ++  0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e,
 ++  0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd,
 ++  0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab,
 ++  0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7,
 ++  0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293,
 ++  0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f,
 ++  0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da,
 ++  0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6,
 ++  0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2,
 ++  0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe,
 ++  0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48,
 ++  0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54,
 ++  0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70,
 ++  0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c,
 ++  0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839,
 ++  0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925,
 ++  0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01,
 ++  0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d,
 ++  0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea,
 ++  0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6,
 ++  0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2,
 ++  0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce,
 ++  0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b,
 ++  0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687,
 ++  0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3,
 ++  0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf,
 ++  0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09,
 ++  0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15,
 ++  0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31,
 ++  0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d,
 ++  0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978,
 ++  0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864,
 ++  0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40,
 ++  0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c,
 ++  0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329,
 ++  0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235,
 ++  0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011,
 ++  0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d,
 ++  0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458,
 ++  0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544,
 ++  0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760,
 ++  0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c,
 ++  0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca,
 ++  0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6,
 ++  0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2,
 ++  0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee,
 ++  0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb,
 ++  0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7,
 ++  0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983,
 ++  0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f,
 ++  0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268,
 ++  0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374,
 ++  0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150,
 ++  0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c,
 ++  0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519,
 ++  0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405,
 ++  0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621,
 ++  0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d,
 ++  0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b,
 ++  0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97,
 ++  0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3,
 ++  0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf,
 ++  0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa,
 ++  0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6,
 ++  0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2,
 ++  0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de,
 ++  0x00000000, 0x00d70983, 0x00555f80, 0x00825603,
 ++  0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485,
 ++  0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88,
 ++  0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e,
 ++  0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92,
 ++  0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814,
 ++  0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219,
 ++  0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f,
 ++  0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7,
 ++  0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021,
 ++  0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c,
 ++  0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa,
 ++  0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36,
 ++  0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0,
 ++  0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd,
 ++  0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b,
 ++  0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd,
 ++  0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b,
 ++  0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46,
 ++  0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0,
 ++  0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c,
 ++  0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda,
 ++  0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7,
 ++  0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451,
 ++  0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669,
 ++  0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef,
 ++  0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2,
 ++  0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64,
 ++  0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8,
 ++  0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e,
 ++  0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273,
 ++  0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5,
 ++  0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218,
 ++  0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e,
 ++  0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93,
 ++  0x00a15e16, 0x00765795, 0x00f40196, 0x00230815,
 ++  0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89,
 ++  0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f,
 ++  0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602,
 ++  0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484,
 ++  0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc,
 ++  0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a,
 ++  0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37,
 ++  0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1,
 ++  0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d,
 ++  0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab,
 ++  0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6,
 ++  0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020,
 ++  0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6,
 ++  0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450,
 ++  0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d,
 ++  0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb,
 ++  0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47,
 ++  0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1,
 ++  0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc,
 ++  0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a,
 ++  0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272,
 ++  0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4,
 ++  0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9,
 ++  0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f,
 ++  0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3,
 ++  0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65,
 ++  0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668,
 ++  0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee,
 ++  0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a,
 ++  0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82,
 ++  0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c,
 ++  0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4,
 ++  0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736,
 ++  0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee,
 ++  0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100,
 ++  0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8,
 ++  0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282,
 ++  0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a,
 ++  0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4,
 ++  0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c,
 ++  0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee,
 ++  0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36,
 ++  0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8,
 ++  0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00,
 ++  0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c,
 ++  0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4,
 ++  0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a,
 ++  0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782,
 ++  0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800,
 ++  0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8,
 ++  0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36,
 ++  0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee,
 ++  0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4,
 ++  0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c,
 ++  0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82,
 ++  0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a,
 ++  0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8,
 ++  0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400,
 ++  0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee,
 ++  0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236,
 ++  0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436,
 ++  0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee,
 ++  0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200,
 ++  0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8,
 ++  0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a,
 ++  0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82,
 ++  0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c,
 ++  0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4,
 ++  0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee,
 ++  0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836,
 ++  0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8,
 ++  0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00,
 ++  0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182,
 ++  0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a,
 ++  0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4,
 ++  0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c,
 ++  0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00,
 ++  0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8,
 ++  0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36,
 ++  0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee,
 ++  0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c,
 ++  0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4,
 ++  0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a,
 ++  0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482,
 ++  0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8,
 ++  0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700,
 ++  0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee,
 ++  0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136,
 ++  0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4,
 ++  0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c,
 ++  0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882,
 ++  0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a
 ++};
 ++
 ++static inline
 ++u32 crc24_init (void)
 ++{
 ++  return 0xce04b7;
 ++}
 ++
 ++static inline
 ++u32 crc24_next (u32 crc, byte data)
 ++{
 ++  return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data];
 ++}
 ++
 ++/*
 ++ * Process 4 bytes in one go
 ++ */
 ++static inline
 ++u32 crc24_next4 (u32 crc, u32 data)
 ++{
 ++  crc ^= data;
 ++  crc = crc24_table[(crc & 0xff) + 0x300] ^
 ++        crc24_table[((crc >> 8) & 0xff) + 0x200] ^
 ++        crc24_table[((crc >> 16) & 0xff) + 0x100] ^
 ++        crc24_table[(crc >> 24) & 0xff];
 ++  return crc;
 ++}
 ++
 ++static inline
 ++u32 crc24_final (u32 crc)
 ++{
 ++  return crc & 0xffffff;
 ++}
 ++
 ++static void
 ++crc24rfc2440_init (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = crc24_init();
 ++}
 ++
 ++static void
 ++crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
 ++{
 ++  const unsigned char *inbuf = inbuf_arg;
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  u32 crc;
 ++
 ++  if (!inbuf || !inlen)
 ++    return;
 ++
 ++  crc = ctx->CRC;
 ++
 ++  while (inlen >= 16)
 ++    {
 ++      inlen -= 16;
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[0]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[4]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[8]));
 ++      crc = crc24_next4(crc, buf_get_le32(&inbuf[12]));
 ++      inbuf += 16;
 ++    }
 ++
 ++  while (inlen >= 4)
 ++    {
 ++      inlen -= 4;
 ++      crc = crc24_next4(crc, buf_get_le32(inbuf));
 ++      inbuf += 4;
 ++    }
 ++
 ++  while (inlen--)
 ++    {
 ++      crc = crc24_next(crc, *inbuf++);
 ++    }
 ++
 ++  ctx->CRC = crc;
 ++}
 ++
 ++static void
 ++crc24rfc2440_final (void *context)
 ++{
 ++  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 ++  ctx->CRC = crc24_final(ctx->CRC);
 ++  buf_put_le32 (ctx->buf, ctx->CRC);
 ++}
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc32 =
 ++  {
 ++    "CRC32", NULL, 0, NULL, 4,
 ++    crc32_init, crc32_write, crc32_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++  };
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
 ++  {
 ++    "CRC32RFC1510", NULL, 0, NULL, 4,
 ++    crc32rfc1510_init, crc32_write,
 ++    crc32rfc1510_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++  };
 ++
 ++gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
 ++  {
 ++    "CRC24RFC2440", NULL, 0, NULL, 3,
 ++    crc24rfc2440_init, crc24rfc2440_write,
 ++    crc24rfc2440_final, crc32_read,
 ++    sizeof (CRC_CONTEXT)
 ++  };
index d25e759a15d037954c721886adc550a114c0310c,0000000000000000000000000000000000000000..ccbf0841a3a7d0abefcc47bfe321476f05eb5061
mode 100644,000000..100644
--- /dev/null
@@@ -1,1320 -1,0 +1,1320 @@@
-  util/deviceiter.c              | 1021 ++++++++++++++++++++++++++++++++
 +From de91fba78b8d8bcc8dff5a5d15d763bd883bbda6 Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@debian.org>
 +Date: Mon, 13 Jan 2014 12:13:01 +0000
 +Subject: Restore grub-mkdevicemap
 +
 +This is kind of a mess, requiring lots of OS-specific code to iterate
 +over all possible devices.  However, we use it in a number of scripts to
 +discover devices and reimplementing those in terms of something else
 +would be very complicated.
 +
 +Author: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
 +Forwarded: no
 +Last-Update: 2018-03-16
 +
 +Patch-Name: restore_mkdevicemap.patch
 +---
 + Makefile.util.def              |   17 +
 + docs/man/grub-mkdevicemap.h2m  |    4 +
 + include/grub/util/deviceiter.h |   14 +
-  util/grub-mkdevicemap.c        |  181 ++++++
++ util/deviceiter.c              | 1021 ++++++++++++++++++++++++++++++++++++++++
 + util/devicemap.c               |   13 +
- @@ -314,6 +314,23 @@ program = {
-    condition = COND_GRUB_MKFONT;
++ util/grub-mkdevicemap.c        |  181 +++++++
 + 6 files changed, 1250 insertions(+)
 + create mode 100644 docs/man/grub-mkdevicemap.h2m
 + create mode 100644 include/grub/util/deviceiter.h
 + create mode 100644 util/deviceiter.c
 + create mode 100644 util/devicemap.c
 + create mode 100644 util/grub-mkdevicemap.c
 +
 +diff --git a/Makefile.util.def b/Makefile.util.def
 +index f9caccb97..c939deb92 100644
 +--- a/Makefile.util.def
 ++++ b/Makefile.util.def
- +program = {
++@@ -315,6 +315,23 @@ program = {
 + };
 + 
-  program = {
++ program = {
 ++  name = grub-mkdevicemap;
 ++  installdir = sbin;
 ++  mansection = 8;
 ++
 ++  common = util/grub-mkdevicemap.c;
 ++  common = util/deviceiter.c;
 ++  common = util/devicemap.c;
 ++  common = grub-core/osdep/init.c;
 ++
 ++  ldadd = libgrubmods.a;
 ++  ldadd = libgrubgcry.a;
 ++  ldadd = libgrubkern.a;
 ++  ldadd = grub-core/gnulib/libgnu.a;
 ++  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 ++};
 ++
+++program = {
 +   name = grub-probe;
 +   installdir = sbin;
++   mansection = 8;
 +diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m
 +new file mode 100644
 +index 000000000..96cd6ee72
 +--- /dev/null
 ++++ b/docs/man/grub-mkdevicemap.h2m
 +@@ -0,0 +1,4 @@
 ++[NAME]
 ++grub-mkdevicemap \- make a device map file automatically
 ++[SEE ALSO]
 ++.BR grub-probe (8)
 +diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h
 +new file mode 100644
 +index 000000000..85374978c
 +--- /dev/null
 ++++ b/include/grub/util/deviceiter.h
 +@@ -0,0 +1,14 @@
 ++#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER
 ++#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER  1
 ++
 ++#include <config.h>
 ++
 ++typedef int (*grub_util_iterate_devices_hook_t) (const char *name,
 ++                                              int is_floppy, void *data);
 ++
 ++void grub_util_iterate_devices (grub_util_iterate_devices_hook_t hook,
 ++                             void *hook_data, int floppy_disks);
 ++void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
 ++                                  int *num_fd, int *num_hd);
 ++
 ++#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */
 +diff --git a/util/deviceiter.c b/util/deviceiter.c
 +new file mode 100644
 +index 000000000..a4971ef42
 +--- /dev/null
 ++++ b/util/deviceiter.c
 +@@ -0,0 +1,1021 @@
 ++/* deviceiter.c - iterate over system devices */
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2011 Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#include <config.h>
 ++
 ++#include <stdio.h>
 ++#include <unistd.h>
 ++#include <string.h>
 ++#include <stdlib.h>
 ++#include <sys/types.h>
 ++#include <sys/stat.h>
 ++#include <errno.h>
 ++#include <fcntl.h>
 ++#include <limits.h>
 ++#include <dirent.h>
 ++
 ++#include <grub/util/misc.h>
 ++#include <grub/util/deviceiter.h>
 ++#include <grub/list.h>
 ++#include <grub/misc.h>
 ++#include <grub/emu/misc.h>
 ++
 ++#ifdef __linux__
 ++# if !defined(__GLIBC__) || \
 ++        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
 ++/* Maybe libc doesn't have large file support.  */
 ++#  include <linux/unistd.h>     /* _llseek */
 ++# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
 ++# include <sys/ioctl.h>              /* ioctl */
 ++# ifndef HDIO_GETGEO
 ++#  define HDIO_GETGEO        0x0301  /* get device geometry */
 ++/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
 ++   defined.  */
 ++struct hd_geometry
 ++{
 ++  unsigned char heads;
 ++  unsigned char sectors;
 ++  unsigned short cylinders;
 ++  unsigned long start;
 ++};
 ++# endif /* ! HDIO_GETGEO */
 ++# ifndef FLOPPY_MAJOR
 ++#  define FLOPPY_MAJOR       2       /* the major number for floppy */
 ++# endif /* ! FLOPPY_MAJOR */
 ++# ifndef MAJOR
 ++#  define MAJOR(dev) \
 ++  ({ \
 ++     unsigned long long __dev = (dev); \
 ++     (unsigned) ((__dev >> 8) & 0xfff) \
 ++                 | ((unsigned int) (__dev >> 32) & ~0xfff); \
 ++  })
 ++# endif /* ! MAJOR */
 ++# ifndef MINOR
 ++#  define MINOR(dev) \
 ++  ({ \
 ++     unsigned long long __dev = (dev); \
 ++     (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \
 ++  })
 ++# endif /* ! MINOR */
 ++# 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 */
 ++
 ++#ifdef HAVE_DEVICE_MAPPER
 ++# include <libdevmapper.h>
 ++# pragma GCC diagnostic ignored "-Wcast-align"
 ++#endif
 ++#endif /* __linux__ */
 ++
 ++/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
 ++   kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
 ++#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
 ++# define __FreeBSD_kernel__
 ++#endif
 ++#ifdef __FreeBSD_kernel__
 ++  /* Obtain version of kFreeBSD headers */
 ++# include <osreldate.h>
 ++# ifndef __FreeBSD_kernel_version
 ++#  define __FreeBSD_kernel_version __FreeBSD_version
 ++# endif
 ++
 ++  /* Runtime detection of kernel */
 ++# include <sys/utsname.h>
 ++static int
 ++get_kfreebsd_version (void)
 ++{
 ++  struct utsname uts;
 ++  int major;
 ++  int minor;
 ++  int v[2];
 ++
 ++  uname (&uts);
 ++  sscanf (uts.release, "%d.%d", &major, &minor);
 ++
 ++  if (major >= 9)
 ++    major = 9;
 ++  if (major >= 5)
 ++    {
 ++      v[0] = minor/10; v[1] = minor%10;
 ++    }
 ++  else
 ++    {
 ++      v[0] = minor%10; v[1] = minor/10;
 ++    }
 ++  return major*100000+v[0]*10000+v[1]*1000;
 ++}
 ++#endif /* __FreeBSD_kernel__ */
 ++
 ++#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
 ++# include <sys/ioctl.h>              /* ioctl */
 ++# include <sys/disklabel.h>
 ++# include <sys/cdio.h>               /* CDIOCCLRDEBUG */
 ++# if defined(__FreeBSD_kernel__)
 ++#  include <sys/param.h>
 ++#  if __FreeBSD_kernel_version >= 500040
 ++#   include <sys/disk.h>
 ++#  endif
 ++# endif /* __FreeBSD_kernel__ */
 ++#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
 ++
 ++#ifdef HAVE_OPENDISK
 ++# include <util.h>
 ++#endif /* HAVE_OPENDISK */
 ++
 ++#ifdef __linux__
 ++/* Check if we have devfs support.  */
 ++static int
 ++have_devfs (void)
 ++{
 ++  struct stat st;
 ++  return stat ("/dev/.devfsd", &st) == 0;
 ++}
 ++#endif /* __linux__ */
 ++
 ++/* These three functions are quite different among OSes.  */
 ++static void
 ++get_floppy_disk_name (char *name, int unit)
 ++{
 ++#if defined(__linux__)
 ++  /* GNU/Linux */
 ++  if (have_devfs ())
 ++    sprintf (name, "/dev/floppy/%d", unit);
 ++  else
 ++    sprintf (name, "/dev/fd%d", unit);
 ++#elif defined(__GNU__)
 ++  /* GNU/Hurd */
 ++  sprintf (name, "/dev/fd%d", unit);
 ++#elif defined(__FreeBSD_kernel__)
 ++  /* kFreeBSD */
 ++  if (get_kfreebsd_version () >= 400000)
 ++    sprintf (name, "/dev/fd%d", unit);
 ++  else
 ++    sprintf (name, "/dev/rfd%d", unit);
 ++#elif defined(__NetBSD__)
 ++  /* NetBSD */
 ++  /* opendisk() doesn't work for floppies.  */
 ++  sprintf (name, "/dev/rfd%da", unit);
 ++#elif defined(__OpenBSD__)
 ++  /* OpenBSD */
 ++  sprintf (name, "/dev/rfd%dc", unit);
 ++#elif defined(__QNXNTO__)
 ++  /* QNX RTP */
 ++  sprintf (name, "/dev/fd%d", unit);
 ++#elif defined(__CYGWIN__)
 ++  /* Cygwin */
 ++  sprintf (name, "/dev/fd%d", unit);
 ++#elif defined(__MINGW32__)
 ++  (void) unit;
 ++  *name = 0;
 ++#else
 ++# warning "BIOS floppy drives cannot be guessed in your operating system."
 ++  /* Set NAME to a bogus string.  */
 ++  *name = 0;
 ++#endif
 ++}
 ++
 ++static void
 ++get_ide_disk_name (char *name, int unit)
 ++{
 ++#if defined(__linux__)
 ++  /* GNU/Linux */
 ++  sprintf (name, "/dev/hd%c", unit + 'a');
 ++#elif defined(__GNU__)
 ++  /* GNU/Hurd */
 ++  sprintf (name, "/dev/hd%d", unit);
 ++#elif defined(__FreeBSD_kernel__)
 ++  /* kFreeBSD */
 ++  if (get_kfreebsd_version () >= 400000)
 ++    sprintf (name, "/dev/ad%d", unit);
 ++  else
 ++    sprintf (name, "/dev/rwd%d", unit);
 ++#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
 ++  /* NetBSD */
 ++  char shortname[16];
 ++  int fd;
 ++
 ++  sprintf (shortname, "wd%d", unit);
 ++  fd = opendisk (shortname, O_RDONLY, name,
 ++              16,    /* length of NAME */
 ++              0      /* char device */
 ++              );
 ++  close (fd);
 ++#elif defined(__OpenBSD__)
 ++  /* OpenBSD */
 ++  sprintf (name, "/dev/rwd%dc", unit);
 ++#elif defined(__QNXNTO__)
 ++  /* QNX RTP */
 ++  /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
 ++     contain SCSI disks.  */
 ++  sprintf (name, "/dev/hd%d", unit);
 ++#elif defined(__CYGWIN__)
 ++  /* Cygwin emulates all disks as /dev/sdX.  */
 ++  (void) unit;
 ++  *name = 0;
 ++#elif defined(__MINGW32__)
 ++  sprintf (name, "//./PHYSICALDRIVE%d", unit);
 ++#else
 ++# warning "BIOS IDE drives cannot be guessed in your operating system."
 ++  /* Set NAME to a bogus string.  */
 ++  *name = 0;
 ++#endif
 ++}
 ++
 ++static void
 ++get_scsi_disk_name (char *name, int unit)
 ++{
 ++#if defined(__linux__)
 ++  /* GNU/Linux */
 ++  sprintf (name, "/dev/sd%c", unit + 'a');
 ++#elif defined(__GNU__)
 ++  /* GNU/Hurd */
 ++  sprintf (name, "/dev/sd%d", unit);
 ++#elif defined(__FreeBSD_kernel__)
 ++  /* kFreeBSD */
 ++  if (get_kfreebsd_version () >= 400000)
 ++    sprintf (name, "/dev/da%d", unit);
 ++  else
 ++    sprintf (name, "/dev/rda%d", unit);
 ++#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
 ++  /* NetBSD */
 ++  char shortname[16];
 ++  int fd;
 ++
 ++  sprintf (shortname, "sd%d", unit);
 ++  fd = opendisk (shortname, O_RDONLY, name,
 ++              16,    /* length of NAME */
 ++              0      /* char device */
 ++              );
 ++  close (fd);
 ++#elif defined(__OpenBSD__)
 ++  /* OpenBSD */
 ++  sprintf (name, "/dev/rsd%dc", unit);
 ++#elif defined(__QNXNTO__)
 ++  /* QNX RTP */
 ++  /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
 ++     disable the detection of SCSI disks here.  */
 ++  *name = 0;
 ++#elif defined(__CYGWIN__)
 ++  /* Cygwin emulates all disks as /dev/sdX.  */
 ++  sprintf (name, "/dev/sd%c", unit + 'a');
 ++#elif defined(__MINGW32__)
 ++  (void) unit;
 ++  *name = 0;
 ++#else
 ++# warning "BIOS SCSI drives cannot be guessed in your operating system."
 ++  /* Set NAME to a bogus string.  */
 ++  *name = 0;
 ++#endif
 ++}
 ++
 ++#ifdef __FreeBSD_kernel__
 ++static void
 ++get_ada_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/ada%d", unit);
 ++}
 ++
 ++static void
 ++get_ataraid_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/ar%d", unit);
 ++}
 ++
 ++static void
 ++get_mfi_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/mfid%d", unit);
 ++}
 ++
 ++static void
 ++get_virtio_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/vtbd%d", unit);
 ++}
 ++
 ++static void
 ++get_xvd_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/xbd%d", unit);
 ++}
 ++#endif
 ++
 ++#ifdef __linux__
 ++static void
 ++get_virtio_disk_name (char *name, int unit)
 ++{
 ++#ifdef __sparc__
 ++  sprintf (name, "/dev/vdisk%c", unit + 'a');
 ++#else
 ++  sprintf (name, "/dev/vd%c", unit + 'a');
 ++#endif
 ++}
 ++
 ++static void
 ++get_dac960_disk_name (char *name, int controller, int drive)
 ++{
 ++  sprintf (name, "/dev/rd/c%dd%d", controller, drive);
 ++}
 ++
 ++static void
 ++get_acceleraid_disk_name (char *name, int controller, int drive)
 ++{
 ++  sprintf (name, "/dev/rs/c%dd%d", controller, drive);
 ++}
 ++
 ++static void
 ++get_ataraid_disk_name (char *name, int unit)
 ++{
 ++  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);
 ++}
 ++
 ++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_mmc_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/mmcblk%d", unit);
 ++}
 ++
 ++static void
 ++get_xvd_disk_name (char *name, int unit)
 ++{
 ++  sprintf (name, "/dev/xvd%c", unit + 'a');
 ++}
 ++
 ++static void
 ++get_nvme_disk_name (char *name, int controller, int namespace)
 ++{
 ++  sprintf (name, "/dev/nvme%dn%d", controller, namespace);
 ++}
 ++#endif
 ++
 ++static struct seen_device
 ++{
 ++  struct seen_device *next;
 ++  struct seen_device **prev;
 ++  const char *name;
 ++} *seen;
 ++
 ++/* Check if DEVICE can be read.  Skip any DEVICE that we have already seen.
 ++   If an error occurs, return zero, otherwise return non-zero.  */
 ++static int
 ++check_device_readable_unique (const char *device)
 ++{
 ++  char *real_device;
 ++  char buf[512];
 ++  FILE *fp;
 ++  struct seen_device *seen_elt;
 ++
 ++  /* If DEVICE is empty, just return error.  */
 ++  if (*device == 0)
 ++    return 0;
 ++
 ++  /* Have we seen this device already?  */
 ++  real_device = canonicalize_file_name (device);
 ++  if (! real_device)
 ++    return 0;
 ++  if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), real_device))
 ++    {
 ++      grub_dprintf ("deviceiter", "Already seen %s (%s)\n",
 ++                 device, real_device);
 ++      goto fail;
 ++    }
 ++
 ++  fp = fopen (device, "r");
 ++  if (! fp)
 ++    {
 ++      switch (errno)
 ++     {
 ++#ifdef ENOMEDIUM
 ++     case ENOMEDIUM:
 ++# if 0
 ++       /* At the moment, this finds only CDROMs, which can't be
 ++          read anyway, so leave it out. Code should be
 ++          reactivated if `removable disks' and CDROMs are
 ++          supported.  */
 ++       /* Accept it, it may be inserted.  */
 ++       return 1;
 ++# endif
 ++       break;
 ++#endif /* ENOMEDIUM */
 ++     default:
 ++       /* Break case and leave.  */
 ++       break;
 ++     }
 ++      /* Error opening the device.  */
 ++      goto fail;
 ++    }
 ++
 ++  /* Make sure CD-ROMs don't get assigned a BIOS disk number
 ++     before SCSI disks!  */
 ++#ifdef __linux__
 ++# ifdef CDROM_GET_CAPABILITY
 ++  if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
 ++    goto fail;
 ++# else /* ! CDROM_GET_CAPABILITY */
 ++  /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl.  */
 ++  {
 ++    struct hd_geometry hdg;
 ++    struct stat st;
 ++
 ++    if (fstat (fileno (fp), &st))
 ++      goto fail;
 ++
 ++    /* If it is a block device and isn't a floppy, check if HDIO_GETGEO
 ++       succeeds.  */
 ++    if (S_ISBLK (st.st_mode)
 ++     && MAJOR (st.st_rdev) != FLOPPY_MAJOR
 ++     && ioctl (fileno (fp), HDIO_GETGEO, &hdg))
 ++      goto fail;
 ++  }
 ++# endif /* ! CDROM_GET_CAPABILITY */
 ++#endif /* __linux__ */
 ++
 ++#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
 ++# ifdef CDIOCCLRDEBUG
 ++  if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
 ++    goto fail;
 ++# endif /* CDIOCCLRDEBUG */
 ++#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
 ++
 ++  /* Attempt to read the first sector.  */
 ++  if (fread (buf, 1, 512, fp) != 512)
 ++    {
 ++      fclose (fp);
 ++      goto fail;
 ++    }
 ++
 ++  /* Remember that we've seen this device.  */
 ++  seen_elt = xmalloc (sizeof (*seen_elt));
 ++  seen_elt->name = real_device; /* steal memory */
 ++  grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt));
 ++
 ++  fclose (fp);
 ++  return 1;
 ++
 ++fail:
 ++  free (real_device);
 ++  return 0;
 ++}
 ++
 ++static void
 ++clear_seen_devices (void)
 ++{
 ++  while (seen)
 ++    {
 ++      struct seen_device *seen_elt = seen;
 ++      seen = seen->next;
 ++      free (seen_elt);
 ++    }
 ++  seen = NULL;
 ++}
 ++
 ++#ifdef __linux__
 ++struct device
 ++{
 ++     char *stable;
 ++     char *kernel;
 ++};
 ++
 ++/* Sort by the kernel name for preference since that most closely matches
 ++   older device.map files, but sort by stable by-id names as a fallback.
 ++   This is because /dev/disk/by-id/ usually has a few alternative
 ++   identifications of devices (e.g. ATA vs. SATA).
 ++   check_device_readable_unique will ensure that we only get one for any
 ++   given disk, but sort the list so that the choice of which one we get is
 ++   stable.  */
 ++static int
 ++compare_devices (const void *a, const void *b)
 ++{
 ++  const struct device *left = (const struct device *) a;
 ++  const struct device *right = (const struct device *) b;
 ++
 ++  if (left->kernel && right->kernel)
 ++    {
 ++      int ret = strcmp (left->kernel, right->kernel);
 ++      if (ret)
 ++     return ret;
 ++    }
 ++
 ++  return strcmp (left->stable, right->stable);
 ++}
 ++#endif /* __linux__ */
 ++
 ++void
 ++grub_util_iterate_devices (int (*hook) (const char *, int, void *), void *hook_data,
 ++                        int floppy_disks)
 ++{
 ++  int i;
 ++
 ++  clear_seen_devices ();
 ++
 ++  /* Floppies.  */
 ++  for (i = 0; i < floppy_disks; i++)
 ++    {
 ++      char name[32];
 ++      struct stat st;
 ++
 ++      get_floppy_disk_name (name, i);
 ++      if (stat (name, &st) < 0)
 ++     break;
 ++      /* In floppies, write the map, whether check_device_readable_unique
 ++         succeeds or not, because the user just may not insert floppies.  */
 ++      if (hook (name, 1, hook_data))
 ++     goto out;
 ++    }
 ++
 ++#ifdef __linux__
 ++  {
 ++    DIR *dir = opendir ("/dev/disk/by-id");
 ++
 ++    if (dir)
 ++      {
 ++     struct dirent *entry;
 ++     struct device *devs;
 ++     size_t devs_len = 0, devs_max = 1024, dev;
 ++
 ++     devs = xmalloc (devs_max * sizeof (*devs));
 ++
 ++     /* Dump all the directory entries into names, resizing if
 ++        necessary.  */
 ++     for (entry = readdir (dir); entry; entry = readdir (dir))
 ++       {
 ++         /* Skip current and parent directory entries.  */
 ++         if (strcmp (entry->d_name, ".") == 0 ||
 ++             strcmp (entry->d_name, "..") == 0)
 ++           continue;
 ++         /* Skip partition entries.  */
 ++         if (strstr (entry->d_name, "-part"))
 ++           continue;
 ++         /* Skip device-mapper entries; we'll handle the ones we want
 ++            later.  */
 ++         if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0)
 ++           continue;
 ++         /* Skip RAID entries; they are handled by upper layers.  */
 ++         if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0)
 ++           continue;
 ++         if (devs_len >= devs_max)
 ++           {
 ++             devs_max *= 2;
 ++             devs = xrealloc (devs, devs_max * sizeof (*devs));
 ++           }
 ++         devs[devs_len].stable =
 ++           xasprintf ("/dev/disk/by-id/%s", entry->d_name);
 ++         devs[devs_len].kernel =
 ++           canonicalize_file_name (devs[devs_len].stable);
 ++         devs_len++;
 ++       }
 ++
 ++     qsort (devs, devs_len, sizeof (*devs), &compare_devices);
 ++
 ++     closedir (dir);
 ++
 ++     /* Now add all the devices in sorted order.  */
 ++     for (dev = 0; dev < devs_len; ++dev)
 ++       {
 ++         if (check_device_readable_unique (devs[dev].stable))
 ++           {
 ++             if (hook (devs[dev].stable, 0, hook_data))
 ++               goto out;
 ++           }
 ++         free (devs[dev].stable);
 ++         free (devs[dev].kernel);
 ++       }
 ++     free (devs);
 ++      }
 ++  }
 ++
 ++  if (have_devfs ())
 ++    {
 ++      i = 0;
 ++      while (1)
 ++     {
 ++       char discn[32];
 ++       char name[PATH_MAX];
 ++       struct stat st;
 ++
 ++       /* Linux creates symlinks "/dev/discs/discN" for convenience.
 ++          The way to number disks is the same as GRUB's.  */
 ++       sprintf (discn, "/dev/discs/disc%d", i++);
 ++       if (stat (discn, &st) < 0)
 ++         break;
 ++
 ++       if (realpath (discn, name))
 ++         {
 ++           strcat (name, "/disc");
 ++           if (hook (name, 0, hook_data))
 ++             goto out;
 ++         }
 ++     }
 ++      goto out;
 ++    }
 ++#endif /* __linux__ */
 ++
 ++  /* IDE disks.  */
 ++  for (i = 0; i < 96; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_ide_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++
 ++#ifdef __FreeBSD_kernel__
 ++  /* IDE disks using ATA Direct Access driver.  */
 ++  if (get_kfreebsd_version () >= 800000)
 ++    for (i = 0; i < 96; i++)
 ++      {
 ++     char name[16];
 ++
 ++     get_ada_disk_name (name, i);
 ++     if (check_device_readable_unique (name))
 ++       {
 ++         if (hook (name, 0, hook_data))
 ++           goto out;
 ++       }
 ++      }
 ++
 ++  /* ATARAID disks.  */
 ++  for (i = 0; i < 8; i++)
 ++    {
 ++      char name[20];
 ++
 ++      get_ataraid_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++        }
 ++    }
 ++
 ++  /* LSI MegaRAID SAS.  */
 ++  for (i = 0; i < 32; i++)
 ++    {
 ++      char name[20];
 ++
 ++      get_mfi_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++        }
 ++    }
 ++
 ++  /* Virtio disks.  */
 ++  for (i = 0; i < 96; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_virtio_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++
 ++  /* Xen virtual block devices.  */
 ++  for (i = 0; i < 96; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_xvd_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++#endif
 ++
 ++#ifdef __linux__
 ++  /* Virtio disks.  */
 ++  for (i = 0; i < 26; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_virtio_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++
 ++  /* ATARAID disks.  */
 ++  for (i = 0; i < 8; i++)
 ++    {
 ++      char name[20];
 ++
 ++      get_ataraid_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++        }
 ++    }
 ++
 ++  /* Xen virtual block devices.  */
 ++  for (i = 0; i < 26; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_xvd_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++#endif /* __linux__ */
 ++
 ++  /* The rest is SCSI disks.  */
 ++  for (i = 0; i < 48; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_scsi_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++
 ++#ifdef __linux__
 ++  /* This is for DAC960 - we have
 ++     /dev/rd/c<controller>d<logical drive>p<partition>.
 ++
 ++     DAC960 driver currently supports up to 8 controllers, 32 logical
 ++     drives, and 7 partitions.  */
 ++  {
 ++    int controller, drive;
 ++
 ++    for (controller = 0; controller < 8; controller++)
 ++      {
 ++     for (drive = 0; drive < 15; drive++)
 ++       {
 ++         char name[24];
 ++
 ++         get_dac960_disk_name (name, controller, drive);
 ++         if (check_device_readable_unique (name))
 ++           {
 ++             if (hook (name, 0, hook_data))
 ++               goto out;
 ++           }
 ++       }
 ++      }
 ++  }
 ++
 ++  /* This is for Mylex Acceleraid - we have
 ++     /dev/rd/c<controller>d<logical drive>p<partition>.  */
 ++  {
 ++    int controller, drive;
 ++
 ++    for (controller = 0; controller < 8; controller++)
 ++      {
 ++     for (drive = 0; drive < 15; drive++)
 ++       {
 ++         char name[24];
 ++
 ++         get_acceleraid_disk_name (name, controller, drive);
 ++         if (check_device_readable_unique (name))
 ++           {
 ++             if (hook (name, 0, hook_data))
 ++               goto out;
 ++           }
 ++       }
 ++      }
 ++  }
 ++
 ++  /* This is for CCISS - we have
 ++     /dev/cciss/c<controller>d<logical drive>p<partition>.  */
 ++  {
 ++    int controller, drive;
 ++
 ++    for (controller = 0; controller < 3; controller++)
 ++      {
 ++     for (drive = 0; drive < 16; drive++)
 ++       {
 ++         char name[24];
 ++
 ++         get_cciss_disk_name (name, controller, drive);
 ++         if (check_device_readable_unique (name))
 ++           {
 ++             if (hook (name, 0, hook_data))
 ++               goto out;
 ++           }
 ++       }
 ++      }
 ++  }
 ++
 ++  /* This is for Compaq Intelligent Drive Array - we have
 ++     /dev/ida/c<controller>d<logical drive>p<partition>.  */
 ++  {
 ++    int controller, drive;
 ++
 ++    for (controller = 0; controller < 3; controller++)
 ++      {
 ++     for (drive = 0; drive < 16; drive++)
 ++       {
 ++         char name[24];
 ++
 ++         get_ida_disk_name (name, controller, drive);
 ++         if (check_device_readable_unique (name))
 ++           {
 ++             if (hook (name, 0, hook_data))
 ++               goto out;
 ++           }
 ++       }
 ++      }
 ++  }
 ++
 ++  /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
 ++  {
 ++    char unit;
 ++
 ++    for (unit = 'a'; unit < 'f'; unit++)
 ++      {
 ++     char name[24];
 ++
 ++     get_i2o_disk_name (name, unit);
 ++     if (check_device_readable_unique (name))
 ++       {
 ++         if (hook (name, 0, hook_data))
 ++           goto out;
 ++       }
 ++      }
 ++  }
 ++
 ++  /* MultiMediaCard (MMC).  */
 ++  for (i = 0; i < 10; i++)
 ++    {
 ++      char name[16];
 ++
 ++      get_mmc_disk_name (name, i);
 ++      if (check_device_readable_unique (name))
 ++     {
 ++       if (hook (name, 0, hook_data))
 ++         goto out;
 ++     }
 ++    }
 ++
 ++  /* This is for standard NVMe controllers
 ++     /dev/nvme<controller>n<namespace>p<partition>. No idea about
 ++     actual limits of how many controllers a system can have and/or
 ++     how many namespace that would be, 10 for now. */
 ++  {
 ++    int controller, namespace;
 ++
 ++    for (controller = 0; controller < 10; controller++)
 ++      {
 ++     for (namespace = 0; namespace < 10; namespace++)
 ++       {
 ++         char name[16];
 ++
 ++         get_nvme_disk_name (name, controller, namespace);
 ++         if (check_device_readable_unique (name))
 ++           {
 ++             if (hook (name, 0, hook_data))
 ++               goto out;
 ++           }
 ++       }
 ++      }
 ++  }
 ++
 ++# ifdef HAVE_DEVICE_MAPPER
 ++#  define dmraid_check(cond, ...) \
 ++  if (! (cond)) \
 ++    { \
 ++      grub_dprintf ("deviceiter", __VA_ARGS__); \
 ++      goto dmraid_end; \
 ++    }
 ++
 ++  /* DM-RAID.  */
 ++  if (grub_device_mapper_supported ())
 ++    {
 ++      struct dm_tree *tree = NULL;
 ++      struct dm_task *task = NULL;
 ++      struct dm_names *names = NULL;
 ++      unsigned int next = 0;
 ++      void *top_handle, *second_handle;
 ++      struct dm_tree_node *root, *top, *second;
 ++
 ++      /* Build DM tree for all devices.  */
 ++      tree = dm_tree_create ();
 ++      dmraid_check (tree, "dm_tree_create failed\n");
 ++      task = dm_task_create (DM_DEVICE_LIST);
 ++      dmraid_check (task, "dm_task_create failed\n");
 ++      dmraid_check (dm_task_run (task), "dm_task_run failed\n");
 ++      names = dm_task_get_names (task);
 ++      dmraid_check (names, "dm_task_get_names failed\n");
 ++      dmraid_check (names->dev, "No DM devices found\n");
 ++      do
 ++     {
 ++       names = (struct dm_names *) ((char *) names + next);
 ++       dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev),
 ++                                      MINOR (names->dev)),
 ++                        "dm_tree_add_dev (%s) failed\n", names->name);
 ++       next = names->next;
 ++     }
 ++      while (next);
 ++
 ++      /* Walk the second-level children of the inverted tree; that is, devices
 ++      which are directly composed of non-DM devices such as hard disks.
 ++      This class includes all DM-RAID disks and excludes all DM-RAID
 ++      partitions.  */
 ++      root = dm_tree_find_node (tree, 0, 0);
 ++      top_handle = NULL;
 ++      top = dm_tree_next_child (&top_handle, root, 1);
 ++      while (top)
 ++     {
 ++       second_handle = NULL;
 ++       second = dm_tree_next_child (&second_handle, top, 1);
 ++       while (second)
 ++         {
 ++           const char *node_name, *node_uuid;
 ++           char *name;
 ++
 ++           node_name = dm_tree_node_get_name (second);
 ++           dmraid_check (node_name, "dm_tree_node_get_name failed\n");
 ++           node_uuid = dm_tree_node_get_uuid (second);
 ++           dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n");
 ++           if (strstr (node_uuid, "DMRAID-") == 0)
 ++             {
 ++               grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name);
 ++               goto dmraid_next_child;
 ++             }
 ++
 ++           name = xasprintf ("/dev/mapper/%s", node_name);
 ++           if (check_device_readable_unique (name))
 ++             {
 ++               if (hook (name, 0, hook_data))
 ++                 {
 ++                   free (name);
 ++                   if (task)
 ++                     dm_task_destroy (task);
 ++                   if (tree)
 ++                     dm_tree_free (tree);
 ++                   goto out;
 ++                 }
 ++             }
 ++           free (name);
 ++
 ++dmraid_next_child:
 ++           second = dm_tree_next_child (&second_handle, top, 1);
 ++         }
 ++       top = dm_tree_next_child (&top_handle, root, 1);
 ++     }
 ++
 ++dmraid_end:
 ++      if (task)
 ++     dm_task_destroy (task);
 ++      if (tree)
 ++     dm_tree_free (tree);
 ++    }
 ++# endif /* HAVE_DEVICE_MAPPER */
 ++#endif /* __linux__ */
 ++
 ++out:
 ++  clear_seen_devices ();
 ++}
 +diff --git a/util/devicemap.c b/util/devicemap.c
 +new file mode 100644
 +index 000000000..c61864420
 +--- /dev/null
 ++++ b/util/devicemap.c
 +@@ -0,0 +1,13 @@
 ++#include <stdio.h>
 ++
 ++#include <grub/util/deviceiter.h>
 ++
 ++void
 ++grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
 ++                             int *num_fd, int *num_hd)
 ++{
 ++    if (is_floppy)
 ++      fprintf (fp, "(fd%d)\t%s\n", (*num_fd)++, name);
 ++    else
 ++      fprintf (fp, "(hd%d)\t%s\n", (*num_hd)++, name);
 ++}
 +diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c
 +new file mode 100644
 +index 000000000..c4bbdbf69
 +--- /dev/null
 ++++ b/util/grub-mkdevicemap.c
 +@@ -0,0 +1,181 @@
 ++/* grub-mkdevicemap.c - make a device map file automatically */
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#include <config.h>
 ++
 ++#include <stdio.h>
 ++#include <unistd.h>
 ++#include <string.h>
 ++#include <stdlib.h>
 ++#include <sys/types.h>
 ++#include <sys/stat.h>
 ++#include <errno.h>
 ++#include <fcntl.h>
 ++#include <limits.h>
 ++
 ++#include <grub/emu/misc.h>
 ++#include <grub/emu/hostdisk.h>
 ++#include <grub/util/misc.h>
 ++#include <grub/util/deviceiter.h>
 ++#include <grub/env.h>
 ++#include <grub/i18n.h>
 ++
 ++#define _GNU_SOURCE  1
 ++#include <getopt.h>
 ++
 ++#include "progname.h"
 ++
 ++/* Context for make_device_map.  */
 ++struct make_device_map_ctx
 ++{
 ++  FILE *fp;
 ++  int num_fd;
 ++  int num_hd;
 ++};
 ++
 ++/* Helper for make_device_map.  */
 ++static int
 ++process_device (const char *name, int is_floppy, void *data)
 ++{
 ++  struct make_device_map_ctx *ctx = data;
 ++
 ++  grub_util_emit_devicemap_entry (ctx->fp, (char *) name,
 ++                               is_floppy, &ctx->num_fd, &ctx->num_hd);
 ++  return 0;
 ++}
 ++
 ++static void
 ++make_device_map (const char *device_map, int floppy_disks)
 ++{
 ++  struct make_device_map_ctx ctx = {
 ++    .num_fd = 0,
 ++    .num_hd = 0
 ++  };
 ++
 ++  if (strcmp (device_map, "-") == 0)
 ++    ctx.fp = stdout;
 ++  else
 ++    ctx.fp = fopen (device_map, "w");
 ++
 ++  if (! ctx.fp)
 ++    grub_util_error (_("cannot open %s"), device_map);
 ++
 ++  grub_util_iterate_devices (process_device, &ctx, floppy_disks);
 ++
 ++  if (ctx.fp != stdout)
 ++    fclose (ctx.fp);
 ++}
 ++
 ++static struct option options[] =
 ++  {
 ++    {"device-map", required_argument, 0, 'm'},
 ++    {"probe-second-floppy", no_argument, 0, 's'},
 ++    {"no-floppy", no_argument, 0, 'n'},
 ++    {"help", no_argument, 0, 'h'},
 ++    {"version", no_argument, 0, 'V'},
 ++    {"verbose", no_argument, 0, 'v'},
 ++    {0, 0, 0, 0}
 ++  };
 ++
 ++static void
 ++usage (int status)
 ++{
 ++  if (status)
 ++    fprintf (stderr,
 ++          _("Try `%s --help' for more information.\n"), program_name);
 ++  else
 ++    printf (_("\
 ++Usage: %s [OPTION]...\n\
 ++\n\
 ++Generate a device map file automatically.\n\
 ++\n\
 ++  -n, --no-floppy           do not probe any floppy drive\n\
 ++  -s, --probe-second-floppy probe the second floppy drive\n\
 ++  -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
 ++  -h, --help                display this message and exit\n\
 ++  -V, --version             print version information and exit\n\
 ++  -v, --verbose             print verbose messages\n\
 ++\n\
 ++Report bugs to <%s>.\n\
 ++"), program_name,
 ++         DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
 ++
 ++  exit (status);
 ++}
 ++
 ++int
 ++main (int argc, char *argv[])
 ++{
 ++  char *dev_map = 0;
 ++  int floppy_disks = 1;
 ++
 ++  grub_util_host_init (&argc, &argv);
 ++
 ++  /* Check for options.  */
 ++  while (1)
 ++    {
 ++      int c = getopt_long (argc, argv, "snm:r:hVv", options, 0);
 ++
 ++      if (c == -1)
 ++     break;
 ++      else
 ++     switch (c)
 ++       {
 ++       case 'm':
 ++         if (dev_map)
 ++           free (dev_map);
 ++
 ++         dev_map = xstrdup (optarg);
 ++         break;
 ++
 ++       case 'n':
 ++         floppy_disks = 0;
 ++         break;
 ++
 ++       case 's':
 ++         floppy_disks = 2;
 ++         break;
 ++
 ++       case 'h':
 ++         usage (0);
 ++         break;
 ++
 ++       case 'V':
 ++         printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
 ++         return 0;
 ++
 ++       case 'v':
 ++         verbosity++;
 ++         break;
 ++
 ++       default:
 ++         usage (1);
 ++         break;
 ++       }
 ++    }
 ++
 ++  if (verbosity > 1)
 ++    grub_env_set ("debug", "all");
 ++
 ++  make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks);
 ++
 ++  free (dev_map);
 ++
 ++  return 0;
 ++}
index a053205b97fe9b91076e7a383bdc1d54191d868a,0000000000000000000000000000000000000000..df24fe60d5beff1e826ff01f9c21d2c6cb605f3d
mode 100644,000000..100644
--- /dev/null
@@@ -1,65 -1,0 +1,67 @@@
 +replace-libgcrypt-crc.patch
 +olpc_prefix_hack.patch
 +core_in_fs.patch
 +dpkg_version_comparison.patch
 +grub_legacy_0_based_partitions.patch
 +disable_floppies.patch
 +grub.cfg_400.patch
 +gfxpayload_keep_default.patch
 +install_stage2_confusion.patch
 +mkrescue_efi_modules.patch
 +mkconfig_loopback.patch
 +restore_mkdevicemap.patch
 +gettext_quiet.patch
 +mkconfig_mid_upgrade.patch
 +install_efi_fallback.patch
 +mkconfig_ubuntu_recovery.patch
 +install_locale_langpack.patch
 +mkconfig_nonexistent_loopback.patch
 +no_insmod_on_sb.patch
 +default_grub_d.patch
 +blacklist_1440x900x32.patch
 +uefi_firmware_setup.patch
 +mkconfig_ubuntu_distributor.patch
 +linuxefi.patch
 +linuxefi_debug.patch
 +linuxefi_require_shim.patch
 +linuxefi_non_sb_fallback.patch
 +mkconfig_signed_kernel.patch
 +install_signed.patch
 +sleep_shift.patch
 +wubi_no_windows.patch
 +maybe_quiet.patch
 +install_efi_ubuntu_flavours.patch
 +quick_boot.patch
 +gfxpayload_dynamic.patch
 +vt_handoff.patch
 +probe_fusionio.patch
 +ignore_grub_func_test_failures.patch
 +mkconfig_recovery_title.patch
 +skip_gettext_strings_test.patch
 +install_powerpc_machtypes.patch
 +ieee1275-clear-reset.patch
 +ppc64el-disable-vsx.patch
 +grub-install-pvxen-paths.patch
 +insmod-xzio-and-lzopio-on-xen.patch
 +grub-install-extra-removable.patch
 +mkconfig_other_inits.patch
 +syslinux-test-out-of-tree.patch
 +zpool_full_device_name.patch
 +misc-fix-invalid-char-strtol.patch
 +net_read_bracketed_ipv6_addr.patch
 +bootp_new_net_bootp6_command.patch
 +efinet_uefi_ipv6_pxe_support.patch
 +bootp_process_dhcpack_http_boot.patch
 +efinet_set_network_from_uefi_devpath.patch
 +efinet_set_dns_from_uefi_proto.patch
 +grub-install-efibootmgr-check.patch
 +ext4_feature_encrypt.patch
 +tsc_efi_default_to_pmtimer.patch
 +freetype-capitalise-variables.patch
 +freetype-pkg-config.patch
 +fix-yylex-build.patch
 +sparc64-support.patch
 +printf-unit-test-gcc7.patch
 +xen-multiboot2.patch
++linuxefi_disable_sb_fallback.patch
++fix_lockdown.patch
index c7ead3e646bfa939929d1ce64c336f57dee14ee6,0000000000000000000000000000000000000000..dceeb88e487c8bf70fb95369220237459aedfe81
mode 100644,000000..100644
--- /dev/null
@@@ -1,2343 -1,0 +1,2343 @@@
-  grub-core/disk/ieee1275/obdisk.c           | 1079 ++++++++++++++++++++
 +From 8bb113820827608a4d12fbafe12bfb3adcf3babf Mon Sep 17 00:00:00 2001
 +From: Eric Snowberg <eric.snowberg@oracle.com>
 +Date: Thu, 22 Feb 2018 10:03:46 +0000
 +Subject: Add support for modern sparc64 hardware
 +
 +Origin: other, https://github.com/esnowberg/grub2-sparc/tree/sparc-next-v4
 +Bug-Debian: https://bugs.debian.org/854568
 +Last-Update: 2018-03-02
 +
 +Patch-Name: sparc64-support.patch
 +---
 + grub-core/Makefile.core.def                |    1 +
 + grub-core/boot/sparc64/ieee1275/boot.S     |   10 +
 + grub-core/commands/ls.c                    |    2 +
 + grub-core/commands/nativedisk.c            |    1 +
-  grub-core/kern/ieee1275/ieee1275.c         |  199 ++++
++ grub-core/disk/ieee1275/obdisk.c           | 1079 ++++++++++++++++++++++++++++
 + grub-core/disk/ieee1275/ofdisk.c           |   30 +-
 + grub-core/kern/ieee1275/cmain.c            |    3 +
-  grub-core/kern/sparc64/ieee1275/ieee1275.c |   53 +
++ grub-core/kern/ieee1275/ieee1275.c         |  199 +++++
 + grub-core/kern/ieee1275/init.c             |   36 +-
 + grub-core/kern/ieee1275/openfw.c           |   27 +
 + grub-core/kern/parser.c                    |    1 -
-  grub-core/osdep/linux/ofpath.c             |  204 +++-
++ grub-core/kern/sparc64/ieee1275/ieee1275.c |   53 ++
 + grub-core/osdep/linux/blocklist.c          |    5 +
-  util/setup.c                               |   87 +-
++ grub-core/osdep/linux/ofpath.c             |  204 +++++-
 + include/grub/disk.h                        |    1 +
 + include/grub/ieee1275/ieee1275.h           |   27 +
 + include/grub/ieee1275/obdisk.h             |   25 +
 + include/grub/sparc64/ieee1275/ieee1275.h   |    2 +
 + util/grub-install.c                        |    1 +
 + util/ieee1275/grub-ofpathname.c            |    4 +-
- @@ -482,6 +483,93 @@ grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
-    return 0;
++ util/setup.c                               |   87 ++-
 + 21 files changed, 1743 insertions(+), 55 deletions(-)
 + create mode 100644 grub-core/disk/ieee1275/obdisk.c
 + create mode 100644 include/grub/ieee1275/obdisk.h
 +
 +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
 +index 3b389277c..e751e334c 100644
 +--- a/grub-core/Makefile.core.def
 ++++ b/grub-core/Makefile.core.def
 +@@ -270,6 +270,7 @@ kernel = {
 +   sparc64_ieee1275 = kern/sparc64/cache.S;
 +   sparc64_ieee1275 = kern/sparc64/dl.c;
 +   sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c;
 ++  sparc64_ieee1275 = disk/ieee1275/obdisk.c;
 + 
 +   arm = kern/arm/dl.c;
 +   arm = kern/arm/dl_helper.c;
 +diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S
 +index 586efb401..9ea9b4e06 100644
 +--- a/grub-core/boot/sparc64/ieee1275/boot.S
 ++++ b/grub-core/boot/sparc64/ieee1275/boot.S
 +@@ -69,6 +69,10 @@ prom_seek_name:            .asciz "seek"
 + prom_read_name:              .asciz "read"
 + prom_exit_name:              .asciz "exit"
 + grub_name:           .asciz "GRUB "
 ++#ifdef CDBOOT
 ++prom_close_name:     .asciz "close"
 ++#endif
 ++
 + #define GRUB_NAME_LEN        5
 + 
 +      .align  4
 +@@ -213,6 +217,12 @@ bootpath_known:
 +      call    prom_call_3_1_o1
 + #ifdef CDBOOT
 +       LDUW_ABS(kernel_size, 0x00, %o3)
 ++
 ++     GET_ABS(prom_close_name, %o0)
 ++     mov     1, %g1
 ++     mov     0, %o5
 ++     call    prom_call
 ++      mov    BOOTDEV_REG, %o1
 + #else
 +       mov    512, %o3
 + #endif
 +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
 +index 0eaf83652..a7318ab84 100644
 +--- a/grub-core/commands/ls.c
 ++++ b/grub-core/commands/ls.c
 +@@ -201,6 +201,8 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
 +       if (grub_errno == GRUB_ERR_UNKNOWN_FS)
 +      grub_errno = GRUB_ERR_NONE;
 + 
 ++      grub_device_close (dev);
 ++      dev = NULL;
 +       grub_normal_print_device_info (device_name);
 +     }
 +   else if (fs)
 +diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
 +index 2f56a870e..2f2315d77 100644
 +--- a/grub-core/commands/nativedisk.c
 ++++ b/grub-core/commands/nativedisk.c
 +@@ -66,6 +66,7 @@ get_uuid (const char *name, char **uuid, int getnative)
 +       /* Firmware disks.  */
 +     case GRUB_DISK_DEVICE_BIOSDISK_ID:
 +     case GRUB_DISK_DEVICE_OFDISK_ID:
 ++    case GRUB_DISK_DEVICE_OBDISK_ID:
 +     case GRUB_DISK_DEVICE_EFIDISK_ID:
 +     case GRUB_DISK_DEVICE_NAND_ID:
 +     case GRUB_DISK_DEVICE_ARCDISK_ID:
 +diff --git a/grub-core/disk/ieee1275/obdisk.c b/grub-core/disk/ieee1275/obdisk.c
 +new file mode 100644
 +index 000000000..006bb6f91
 +--- /dev/null
 ++++ b/grub-core/disk/ieee1275/obdisk.c
 +@@ -0,0 +1,1079 @@
 ++/* obdisk.c - Open Boot disk access.  */
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 2017 Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#include <grub/disk.h>
 ++#include <grub/env.h>
 ++#include <grub/i18n.h>
 ++#include <grub/kernel.h>
 ++#include <grub/list.h>
 ++#include <grub/misc.h>
 ++#include <grub/mm.h>
 ++#include <grub/scsicmd.h>
 ++#include <grub/time.h>
 ++#include <grub/ieee1275/ieee1275.h>
 ++#include <grub/ieee1275/obdisk.h>
 ++
 ++struct disk_dev
 ++{
 ++  struct disk_dev *next;
 ++  struct disk_dev **prev;
 ++  /* open boot canonical name */
 ++  char *name;
 ++  /* open boot raw disk name to access entire disk */
 ++  char *raw_name;
 ++  /* grub encoded device name */
 ++  char *grub_devpath;
 ++  /* grub encoded alias name  */
 ++  char *grub_alias_devpath;
 ++  /* grub unescaped name */
 ++  char *grub_decoded_devpath;
 ++  grub_ieee1275_ihandle_t ihandle;
 ++  grub_uint32_t block_size;
 ++  grub_uint64_t num_blocks;
 ++  unsigned int log_sector_size;
 ++  grub_uint32_t opened;
 ++  grub_uint32_t valid;
 ++  grub_uint32_t boot_dev;
 ++};
 ++
 ++struct parent_dev
 ++{
 ++  struct parent_dev *next;
 ++  struct parent_dev **prev;
 ++  /* canonical parent name */
 ++  char *name;
 ++  char *type;
 ++  grub_ieee1275_ihandle_t ihandle;
 ++  grub_uint32_t address_cells;
 ++};
 ++
 ++static struct grub_scsi_test_unit_ready tur =
 ++{
 ++  .opcode = grub_scsi_cmd_test_unit_ready,
 ++  .lun = 0,
 ++  .reserved1 = 0,
 ++  .reserved2 = 0,
 ++  .reserved3 = 0,
 ++  .control = 0,
 ++};
 ++
 ++static int disks_enumerated = 0;
 ++static struct disk_dev *disk_devs = NULL;
 ++static struct parent_dev *parent_devs = NULL;
 ++
 ++static const char *block_blacklist[] = {
 ++  /* Requires addition work in grub before being able to be used */
 ++  "/iscsi-hba",
 ++  /* This block device should never be used by grub */
 ++  "/reboot-memory@0",
 ++  0
 ++};
 ++
 ++#define STRCMP(a, b) ((a) && (b) && (grub_strcmp (a, b) == 0))
 ++
 ++static char *
 ++strip_ob_partition (char *path)
 ++{
 ++  char *sptr;
 ++
 ++  sptr = grub_strstr (path, ":");
 ++
 ++  if (sptr)
 ++    *sptr = '\0';
 ++
 ++  return path;
 ++}
 ++
 ++static char *
 ++remove_escaped_commas (char *src)
 ++{
 ++  char *iptr;
 ++
 ++  for (iptr = src; *iptr; )
 ++    {
 ++      if ((*iptr == '\\') && (*(iptr + 1) == ','))
 ++        {
 ++          *iptr++ = '_';
 ++          *iptr++ = '_';
 ++        }
 ++      iptr++;
 ++    }
 ++
 ++  return src;
 ++}
 ++
 ++static int
 ++count_commas (const char *src)
 ++{
 ++  int count = 0;
 ++
 ++  for ( ; *src; src++)
 ++    if (*src == ',')
 ++      count++;
 ++
 ++  return count;
 ++}
 ++
 ++static void
 ++escape_commas (const char *src, char *dest)
 ++{
 ++  const char *iptr;
 ++
 ++  for (iptr = src; *iptr; )
 ++    {
 ++      if (*iptr == ',')
 ++     *dest++ ='\\';
 ++
 ++      *dest++ = *iptr++;
 ++    }
 ++
 ++  *dest = '\0';
 ++}
 ++
 ++static char *
 ++decode_grub_devname (const char *name)
 ++{
 ++  char *devpath = grub_malloc (grub_strlen (name) + 1);
 ++  char *p, c;
 ++
 ++  if (!devpath)
 ++    return NULL;
 ++
 ++  /* Un-escape commas. */
 ++  p = devpath;
 ++  while ((c = *name++) != '\0')
 ++    {
 ++      if (c == '\\' && *name == ',')
 ++     {
 ++       *p++ = ',';
 ++       name++;
 ++     }
 ++      else
 ++     *p++ = c;
 ++    }
 ++
 ++  *p++ = '\0';
 ++
 ++  return devpath;
 ++}
 ++
 ++static char *
 ++encode_grub_devname (const char *path)
 ++{
 ++  char *encoding, *optr;
 ++
 ++  if (path == NULL)
 ++    return NULL;
 ++
 ++  encoding = grub_malloc (sizeof ("ieee1275/") + count_commas (path) +
 ++                          grub_strlen (path) + 1);
 ++
 ++  if (encoding == NULL)
 ++    {
 ++      grub_print_error ();
 ++      return NULL;
 ++    }
 ++
 ++  optr = grub_stpcpy (encoding, "ieee1275/");
 ++  escape_commas (path, optr);
 ++  return encoding;
 ++}
 ++
 ++static char *
 ++get_parent_devname (const char *devname)
 ++{
 ++  char *parent, *pptr;
 ++
 ++  parent = grub_strdup (devname);
 ++
 ++  if (parent == NULL)
 ++    {
 ++      grub_print_error ();
 ++      return NULL;
 ++    }
 ++
 ++  pptr = grub_strstr (parent, "/disk@");
 ++
 ++  if (pptr)
 ++    *pptr = '\0';
 ++
 ++  return parent;
 ++}
 ++
 ++static void
 ++free_parent_dev (struct parent_dev *parent)
 ++{
 ++  if (parent)
 ++    {
 ++      grub_free (parent->name);
 ++      grub_free (parent->type);
 ++      grub_free (parent);
 ++    }
 ++}
 ++
 ++static struct parent_dev *
 ++init_parent (const char *parent)
 ++{
 ++  struct parent_dev *op;
 ++
 ++  op = grub_zalloc (sizeof (struct parent_dev));
 ++
 ++  if (op == NULL)
 ++    {
 ++      grub_print_error ();
 ++      return NULL;
 ++    }
 ++
 ++  op->name = grub_strdup (parent);
 ++  op->type = grub_malloc (IEEE1275_MAX_PROP_LEN);
 ++
 ++  if ((op->name == NULL) || (op->type == NULL))
 ++    {
 ++      grub_print_error ();
 ++      free_parent_dev (op);
 ++      return NULL;
 ++    }
 ++
 ++  return op;
 ++}
 ++
 ++static struct parent_dev *
 ++open_new_parent (const char *parent)
 ++{
 ++  struct parent_dev *op = init_parent(parent);
 ++  grub_ieee1275_ihandle_t ihandle;
 ++  grub_ieee1275_phandle_t phandle;
 ++  grub_uint32_t address_cells = 2;
 ++  grub_ssize_t actual = 0;
 ++
 ++  if (op == NULL)
 ++    return NULL;
 ++
 ++  grub_ieee1275_open (parent, &ihandle);
 ++
 ++  if (ihandle == 0)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent);
 ++      grub_print_error ();
 ++      free_parent_dev (op);
 ++      return NULL;
 ++    }
 ++
 ++  if (grub_ieee1275_instance_to_package (ihandle, &phandle))
 ++    {
 ++      grub_error (GRUB_ERR_BAD_DEVICE, "unable to get parent %s", parent);
 ++      grub_print_error ();
 ++      free_parent_dev (op);
 ++      return NULL;
 ++    }
 ++
 ++  /* IEEE Std 1275-1994 page 110: A missing “#address-cells” property
 ++     signifies that the number of address cells is two. So ignore on error. */
 ++  grub_ieee1275_get_integer_property (phandle, "#address-cells", &address_cells,
 ++                                      sizeof (address_cells), 0);
 ++
 ++  grub_ieee1275_get_property (phandle, "device_type", op->type,
 ++                              IEEE1275_MAX_PROP_LEN, &actual);
 ++  op->ihandle = ihandle;
 ++  op->address_cells = address_cells;
 ++  return op;
 ++}
 ++
 ++static struct parent_dev *
 ++open_parent (const char *parent)
 ++{
 ++  struct parent_dev *op;
 ++
 ++  if ((op =
 ++       grub_named_list_find (GRUB_AS_NAMED_LIST (parent_devs), parent)) == NULL)
 ++  {
 ++     op = open_new_parent (parent);
 ++
 ++    if (op)
 ++      grub_list_push (GRUB_AS_LIST_P (&parent_devs), GRUB_AS_LIST (op));
 ++  }
 ++
 ++  return op;
 ++}
 ++
 ++static void
 ++display_parents (void)
 ++{
 ++  struct parent_dev *parent;
 ++
 ++  grub_printf ("-------------------- PARENTS --------------------\n");
 ++
 ++  FOR_LIST_ELEMENTS (parent, parent_devs)
 ++    {
 ++      grub_printf ("name: %s\n", parent->name);
 ++      grub_printf ("type: %s\n", parent->type);
 ++      grub_printf ("address_cells %x\n", parent->address_cells);
 ++    }
 ++
 ++  grub_printf ("-------------------------------------------------\n");
 ++}
 ++
 ++static char *
 ++canonicalise_4cell_ua (grub_ieee1275_ihandle_t ihandle, char *unit_address)
 ++{
 ++  grub_uint32_t phy_lo, phy_hi, lun_lo, lun_hi;
 ++  int valid_phy = 0;
 ++  grub_size_t size;
 ++  char *canon = NULL;
 ++
 ++  valid_phy = grub_ieee1275_decode_unit4 (ihandle, unit_address,
 ++                                          grub_strlen (unit_address), &phy_lo,
 ++                                          &phy_hi, &lun_lo, &lun_hi);
 ++
 ++  if ((!valid_phy) && (phy_hi != 0xffffffff))
 ++    canon = grub_ieee1275_encode_uint4 (ihandle, phy_lo, phy_hi,
 ++                                        lun_lo, lun_hi, &size);
 ++
 ++  return canon;
 ++}
 ++
 ++static char *
 ++canonicalise_disk (const char *devname)
 ++{
 ++  char *canon, *parent;
 ++  struct parent_dev *op;
 ++
 ++  canon = grub_ieee1275_canonicalise_devname (devname);
 ++
 ++  if (canon == NULL)
 ++    {
 ++      /* This should not happen */
 ++      grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed");
 ++      grub_print_error ();
 ++      return NULL;
 ++    }
 ++
 ++  /* Don't try to open the parent of a virtual device */
 ++  if (grub_strstr (canon, "virtual-devices"))
 ++    return canon;
 ++
 ++  parent = get_parent_devname (canon);
 ++
 ++  if (parent == NULL)
 ++    return NULL;
 ++
 ++  op = open_parent (parent);
 ++
 ++  /* Devices with 4 address cells can have many different types of addressing
 ++     (phy, wwn, and target lun). Use the parents encode-unit / decode-unit
 ++     to find the true canonical name. */
 ++  if ((op) && (op->address_cells == 4))
 ++    {
 ++      char *unit_address, *real_unit_address, *real_canon;
 ++
 ++      unit_address = grub_strstr (canon, "/disk@");
 ++      unit_address += grub_strlen ("/disk@");
 ++
 ++      if (unit_address == NULL)
 ++        {
 ++          /* This should not be possible, but return the canonical name for
 ++             the non-disk block device */
 ++          grub_free (parent);
 ++          return (canon);
 ++        }
 ++
 ++      real_unit_address = canonicalise_4cell_ua (op->ihandle, unit_address);
 ++
 ++      if (real_unit_address == NULL)
 ++        {
 ++          /* This is not an error, since this function could be called with a devalias
 ++             containing a drive that isn't installed in the system. */
 ++          grub_free (parent);
 ++          return NULL;
 ++        }
 ++
 ++      real_canon = grub_malloc (grub_strlen (op->name) + sizeof ("/disk@") +
 ++                                grub_strlen (real_unit_address));
 ++
 ++      grub_snprintf (real_canon, grub_strlen (op->name) + sizeof ("/disk@") +
 ++                     grub_strlen (real_unit_address), "%s/disk@%s",
 ++                     op->name, real_unit_address);
 ++
 ++      grub_free (canon);
 ++      canon = real_canon;
 ++    }
 ++
 ++  grub_free (parent);
 ++  return (canon);
 ++}
 ++
 ++static struct disk_dev *
 ++add_canon_disk (const char *cname)
 ++{
 ++  struct disk_dev *dev;
 ++
 ++  dev = grub_zalloc (sizeof (struct disk_dev));
 ++
 ++  if (!dev)
 ++    goto failed;
 ++
 ++  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES))
 ++    {
 ++    /* Append :nolabel to the end of all SPARC disks.
 ++
 ++       nolabel is mutually exclusive with all other
 ++       arguments and allows a client program to open
 ++       the entire (raw) disk. Any disk label is ignored. */
 ++      dev->raw_name = grub_malloc (grub_strlen (cname) + sizeof (":nolabel"));
 ++
 ++      if (dev->raw_name == NULL)
 ++        goto failed;
 ++
 ++      grub_snprintf (dev->raw_name, grub_strlen (cname) + sizeof (":nolabel"),
 ++                     "%s:nolabel", cname);
 ++    }
 ++
 ++  /* Don't use grub_ieee1275_encode_devname here, the devpath in grub.cfg doesn't
 ++     understand device aliases, which the layer above sometimes sends us. */
 ++  dev->grub_devpath = encode_grub_devname(cname);
 ++
 ++  if (dev->grub_devpath == NULL)
 ++    goto failed;
 ++
 ++  dev->name = grub_strdup (cname);
 ++
 ++  if (dev->name == NULL)
 ++    goto failed;
 ++
 ++  dev->valid = 1;
 ++  grub_list_push (GRUB_AS_LIST_P (&disk_devs), GRUB_AS_LIST (dev));
 ++  return dev;
 ++
 ++failed:
 ++  grub_print_error ();
 ++
 ++  if (dev)
 ++    {
 ++      grub_free (dev->name);
 ++      grub_free (dev->grub_devpath);
 ++      grub_free (dev->raw_name);
 ++    }
 ++
 ++  grub_free (dev);
 ++  return NULL;
 ++}
 ++
 ++static grub_err_t
 ++add_disk (const char *path)
 ++{
 ++  grub_err_t rval = GRUB_ERR_NONE;
 ++  struct disk_dev *dev;
 ++  char *canon;
 ++
 ++  canon = canonicalise_disk (path);
 ++  dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon);
 ++
 ++  if ((canon != NULL) && (dev == NULL))
 ++    {
 ++      struct disk_dev *ob_device;
 ++
 ++      ob_device = add_canon_disk (canon);
 ++
 ++      if (ob_device == NULL)
 ++        rval = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure to add disk");
 ++    }
 ++  else if (dev)
 ++    dev->valid = 1;
 ++
 ++  grub_free (canon);
 ++  return (rval);
 ++}
 ++
 ++static grub_err_t
 ++grub_obdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
 ++               grub_size_t size, char *dest)
 ++{
 ++  grub_err_t rval = GRUB_ERR_NONE;
 ++  struct disk_dev *dev;
 ++  unsigned long long pos;
 ++  grub_ssize_t result = 0;
 ++
 ++  if (disk->data == NULL)
 ++    return grub_error (GRUB_ERR_BAD_DEVICE, "invalid disk data");
 ++
 ++  dev = (struct disk_dev *)disk->data;
 ++  pos = sector << disk->log_sector_size;
 ++  grub_ieee1275_seek (dev->ihandle, pos, &result);
 ++
 ++  if (result < 0)
 ++    {
 ++      dev->opened = 0;
 ++      return grub_error (GRUB_ERR_READ_ERROR, "seek error, can't seek block %llu",
 ++                         (long long) sector);
 ++    }
 ++
 ++  grub_ieee1275_read (dev->ihandle, dest, size << disk->log_sector_size,
 ++                      &result);
 ++
 ++  if (result != (grub_ssize_t) (size  << disk->log_sector_size))
 ++    {
 ++      dev->opened = 0;
 ++      return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx "
 ++                                                 "from `%s'"),
 ++                         (unsigned long long) sector,
 ++                         disk->name);
 ++    }
 ++  return rval;
 ++}
 ++
 ++static void
 ++grub_obdisk_close (grub_disk_t disk)
 ++{
 ++  disk->data = NULL;
 ++  disk->id = 0;
 ++  disk->total_sectors = 0;
 ++  disk->log_sector_size = 0;
 ++}
 ++
 ++static void
 ++scan_usb_disk (const char *parent)
 ++{
 ++  struct parent_dev *op;
 ++  grub_ssize_t result;
 ++
 ++  op = open_parent (parent);
 ++
 ++  if (op == NULL)
 ++    {
 ++      grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent);
 ++      grub_print_error ();
 ++      return;
 ++    }
 ++
 ++  if ((grub_ieee1275_set_address (op->ihandle, 0, 0) == 0) &&
 ++      (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) &&
 ++      (result == 0))
 ++    {
 ++      char *buf;
 ++
 ++      buf = grub_malloc (IEEE1275_MAX_PATH_LEN);
 ++
 ++      if (buf == NULL)
 ++        {
 ++          grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure");
 ++          grub_print_error ();
 ++          return;
 ++        }
 ++
 ++      grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@0", parent);
 ++      add_disk (buf);
 ++      grub_free (buf);
 ++    }
 ++}
 ++
 ++static void
 ++scan_nvme_disk (const char *path)
 ++{
 ++  char *buf;
 ++
 ++  buf = grub_malloc (IEEE1275_MAX_PATH_LEN);
 ++
 ++  if (buf == NULL)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure");
 ++      grub_print_error ();
 ++      return;
 ++    }
 ++
 ++  grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@1", path);
 ++  add_disk (buf);
 ++  grub_free (buf);
 ++}
 ++
 ++static void
 ++scan_sparc_sas_2cell (struct parent_dev *op)
 ++{
 ++  grub_ssize_t result;
 ++  grub_uint8_t tgt;
 ++  char *buf;
 ++
 ++  buf = grub_malloc (IEEE1275_MAX_PATH_LEN);
 ++
 ++  if (buf == NULL)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure");
 ++      grub_print_error ();
 ++      return;
 ++    }
 ++
 ++  for (tgt = 0; tgt < 0xf; tgt++)
 ++    {
 ++
 ++      if ((grub_ieee1275_set_address(op->ihandle, tgt, 0) == 0) &&
 ++          (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) &&
 ++          (result == 0))
 ++        {
 ++
 ++          grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%"
 ++                         PRIxGRUB_UINT32_T, op->name, tgt);
 ++
 ++          add_disk (buf);
 ++        }
 ++    }
 ++}
 ++
 ++static void
 ++scan_sparc_sas_4cell (struct parent_dev *op)
 ++{
 ++  grub_uint16_t exp;
 ++  grub_uint8_t phy;
 ++  char *buf;
 ++
 ++  buf = grub_malloc (IEEE1275_MAX_PATH_LEN);
 ++
 ++  if (buf == NULL)
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure");
 ++      grub_print_error ();
 ++      return;
 ++    }
 ++
 ++  for (exp = 0; exp <= 0x100; exp+=0x100)
 ++
 ++    for (phy = 0; phy < 0x20; phy++)
 ++      {
 ++        char *canon = NULL;
 ++
 ++        grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "p%" PRIxGRUB_UINT32_T ",0",
 ++                       exp | phy);
 ++
 ++        canon = canonicalise_4cell_ua (op->ihandle, buf);
 ++
 ++        if (canon)
 ++          {
 ++            grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%s",
 ++                           op->name, canon);
 ++
 ++            add_disk (buf);
 ++            grub_free (canon);
 ++          }
 ++      }
 ++
 ++  grub_free (buf);
 ++}
 ++
 ++static void
 ++scan_sparc_sas_disk (const char *parent)
 ++{
 ++  struct parent_dev *op;
 ++
 ++  op = open_parent (parent);
 ++
 ++  if ((op) && (op->address_cells == 4))
 ++    scan_sparc_sas_4cell (op);
 ++  else if ((op) && (op->address_cells == 2))
 ++    scan_sparc_sas_2cell (op);
 ++}
 ++
 ++static void
 ++iterate_devtree (const struct grub_ieee1275_devalias *alias)
 ++{
 ++  struct grub_ieee1275_devalias child;
 ++
 ++  if ((grub_strcmp (alias->type, "scsi-2") == 0) ||
 ++      (grub_strcmp (alias->type, "scsi-sas") == 0))
 ++    return scan_sparc_sas_disk (alias->path);
 ++
 ++  else if (grub_strcmp (alias->type, "nvme") == 0)
 ++    return scan_nvme_disk (alias->path);
 ++
 ++  else if (grub_strcmp (alias->type, "scsi-usb") == 0)
 ++    return scan_usb_disk (alias->path);
 ++
 ++  else if (grub_strcmp (alias->type, "block") == 0)
 ++    {
 ++      const char **bl = block_blacklist;
 ++
 ++      while (*bl != NULL)
 ++        {
 ++          if (grub_strstr (alias->path, *bl))
 ++            return;
 ++          bl++;
 ++        }
 ++
 ++      add_disk (alias->path);
 ++      return;
 ++    }
 ++
 ++  FOR_IEEE1275_DEVCHILDREN (alias->path, child)
 ++    iterate_devtree (&child);
 ++}
 ++
 ++static void
 ++unescape_devices (void)
 ++{
 ++  struct disk_dev *dev;
 ++
 ++  FOR_LIST_ELEMENTS (dev, disk_devs)
 ++    {
 ++      grub_free (dev->grub_decoded_devpath);
 ++
 ++      if ((dev->grub_alias_devpath) &&
 ++        (grub_strcmp (dev->grub_alias_devpath, dev->grub_devpath) != 0))
 ++        dev->grub_decoded_devpath =
 ++          remove_escaped_commas (grub_strdup (dev->grub_alias_devpath));
 ++      else
 ++        dev->grub_decoded_devpath =
 ++          remove_escaped_commas (grub_strdup (dev->grub_devpath));
 ++    }
 ++}
 ++
 ++static void
 ++enumerate_disks (void)
 ++{
 ++  struct grub_ieee1275_devalias alias;
 ++
 ++  FOR_IEEE1275_DEVCHILDREN("/", alias)
 ++    iterate_devtree (&alias);
 ++}
 ++
 ++static grub_err_t
 ++add_bootpath (void)
 ++{
 ++  struct disk_dev *ob_device;
 ++  grub_err_t rval = GRUB_ERR_NONE;
 ++  char *dev, *alias = NULL;
 ++  char *type;
 ++
 ++  grub_ieee1275_get_boot_dev (&dev);
 ++  type = grub_ieee1275_get_device_type (dev);
 ++
 ++  if (!(type && grub_strcmp (type, "network") == 0))
 ++    {
 ++      dev = strip_ob_partition (dev);
 ++      ob_device = add_canon_disk (dev);
 ++
 ++      if (ob_device == NULL)
 ++        rval =  grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device");
 ++
 ++      ob_device->valid = 1;
 ++
 ++      alias = grub_ieee1275_get_devname (dev);
 ++
 ++      if (grub_strcmp (alias, dev) != 0)
 ++        ob_device->grub_alias_devpath = grub_ieee1275_encode_devname (dev);
 ++
 ++      ob_device->boot_dev = 1;
 ++    }
 ++
 ++  grub_free (type);
 ++  grub_free (dev);
 ++  grub_free (alias);
 ++  return rval;
 ++}
 ++
 ++static void
 ++enumerate_aliases (void)
 ++{
 ++  struct grub_ieee1275_devalias alias;
 ++
 ++  /* Some block device aliases are not in canonical form
 ++
 ++     For example:
 ++
 ++     disk3                    /pci@301/pci@1/scsi@0/disk@p3
 ++     disk2                    /pci@301/pci@1/scsi@0/disk@p2
 ++     disk1                    /pci@301/pci@1/scsi@0/disk@p1
 ++     disk                     /pci@301/pci@1/scsi@0/disk@p0
 ++     disk0                    /pci@301/pci@1/scsi@0/disk@p0
 ++
 ++     None of these devices are in canonical form.
 ++
 ++     Also, just because there is a devalias, doesn't mean there is a disk
 ++     at that location.  And a valid boot block device doesn't have to have
 ++     a devalias at all.
 ++
 ++     At this point, all valid disks have been found in the system
 ++     and devaliases that point to canonical names are stored in the
 ++     disk_devs list already.  */
 ++  FOR_IEEE1275_DEVALIASES (alias)
 ++    {
 ++      struct disk_dev *dev;
 ++      char *canon;
 ++
 ++      if (grub_strcmp (alias.type, "block") != 0)
 ++        continue;
 ++
 ++      canon = canonicalise_disk (alias.name);
 ++
 ++      if (canon == NULL)
 ++        /* This is not an error, a devalias could point to a
 ++           nonexistent disk */
 ++        continue;
 ++
 ++      dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon);
 ++
 ++      if (dev)
 ++        {
 ++          /* If more than one alias points to the same device,
 ++             remove the previous one unless it is the boot dev,
 ++             since the upper level will use the first one. The reason
 ++             all the others are redone is in the case of hot-plugging
 ++             a disk.  If the boot disk gets hot-plugged, it will come
 ++             thru here with a different name without the boot_dev flag
 ++             set. */
 ++          if ((dev->boot_dev) && (dev->grub_alias_devpath))
 ++            continue;
 ++
 ++          grub_free (dev->grub_alias_devpath);
 ++          dev->grub_alias_devpath = grub_ieee1275_encode_devname (alias.path);
 ++        }
 ++      grub_free (canon);
 ++    }
 ++}
 ++
 ++static void
 ++display_disks (void)
 ++{
 ++  struct disk_dev *dev;
 ++
 ++  grub_printf ("--------------------- DISKS ---------------------\n");
 ++
 ++  FOR_LIST_ELEMENTS (dev, disk_devs)
 ++    {
 ++      grub_printf ("name: %s\n", dev->name);
 ++      grub_printf ("grub_devpath: %s\n", dev->grub_devpath);
 ++      grub_printf ("grub_alias_devpath: %s\n", dev->grub_alias_devpath);
 ++      grub_printf ("grub_decoded_devpath: %s\n", dev->grub_decoded_devpath);
 ++      grub_printf ("valid: %s\n", (dev->valid) ? "yes" : "no");
 ++      grub_printf ("boot_dev: %s\n", (dev->boot_dev) ? "yes" : "no");
 ++      grub_printf ("opened: %s\n", (dev->ihandle) ? "yes" : "no");
 ++      grub_printf ("block size: %" PRIuGRUB_UINT32_T "\n", dev->block_size);
 ++      grub_printf ("num blocks: %" PRIuGRUB_UINT64_T "\n", dev->num_blocks);
 ++      grub_printf ("log sector size: %" PRIuGRUB_UINT32_T "\n",
 ++                   dev->log_sector_size);
 ++      grub_printf ("\n");
 ++    }
 ++
 ++  grub_printf ("-------------------------------------------------\n");
 ++}
 ++
 ++static void
 ++display_stats (void)
 ++{
 ++  const char *debug = grub_env_get ("debug");
 ++
 ++  if (! debug)
 ++    return;
 ++
 ++  if (grub_strword (debug, "all") || grub_strword (debug, "obdisk"))
 ++    {
 ++      display_parents ();
 ++      display_disks ();
 ++    }
 ++}
 ++
 ++static void
 ++invalidate_all_disks (void)
 ++{
 ++  struct disk_dev *dev = NULL;
 ++
 ++  if (disks_enumerated)
 ++    FOR_LIST_ELEMENTS (dev, disk_devs)
 ++      dev->valid = 0;
 ++}
 ++
 ++/* This is for backwards compatibility, since the path should be generated
 ++   correctly now. */
 ++static struct disk_dev *
 ++find_legacy_grub_devpath (const char *name)
 ++{
 ++  struct disk_dev *dev = NULL;
 ++  char *canon, *devpath = NULL;
 ++
 ++  devpath = decode_grub_devname (name + sizeof ("ieee1275"));
 ++  canon = canonicalise_disk (devpath);
 ++
 ++  if (canon != NULL)
 ++    dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon);
 ++
 ++  grub_free (devpath);
 ++  grub_free (canon);
 ++  return dev;
 ++}
 ++
 ++static void
 ++enumerate_devices (void)
 ++{
 ++  invalidate_all_disks ();
 ++  enumerate_disks ();
 ++  enumerate_aliases ();
 ++  unescape_devices ();
 ++  disks_enumerated = 1;
 ++  display_stats ();
 ++}
 ++
 ++static struct disk_dev *
 ++find_grub_devpath_real (const char *name)
 ++{
 ++  struct disk_dev *dev = NULL;
 ++
 ++  FOR_LIST_ELEMENTS (dev, disk_devs)
 ++    {
 ++      if ((STRCMP (dev->grub_devpath, name))
 ++        || (STRCMP (dev->grub_alias_devpath, name))
 ++        || (STRCMP (dev->grub_decoded_devpath, name)))
 ++        break;
 ++    }
 ++
 ++  return dev;
 ++}
 ++
 ++static struct disk_dev *
 ++find_grub_devpath (const char *name)
 ++{
 ++  struct disk_dev *dev = NULL;
 ++  int enumerated;
 ++
 ++  do {
 ++    enumerated = disks_enumerated;
 ++    dev = find_grub_devpath_real (name);
 ++
 ++    if (dev)
 ++      break;
 ++
 ++    dev = find_legacy_grub_devpath (name);
 ++
 ++    if (dev)
 ++      break;
 ++
 ++    enumerate_devices ();
 ++  } while (enumerated == 0);
 ++
 ++  return dev;
 ++}
 ++
 ++static int
 ++grub_obdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
 ++                  grub_disk_pull_t pull)
 ++{
 ++  struct disk_dev *dev;
 ++
 ++  if (pull != GRUB_DISK_PULL_NONE)
 ++    return 0;
 ++
 ++  enumerate_devices ();
 ++
 ++  FOR_LIST_ELEMENTS (dev, disk_devs)
 ++    {
 ++      if (dev->valid == 1)
 ++        if (hook (dev->grub_decoded_devpath, hook_data))
 ++          return 1;
 ++    }
 ++
 ++  return 0;
 ++}
 ++
 ++static grub_err_t
 ++grub_obdisk_open (const char *name, grub_disk_t disk)
 ++{
 ++  grub_ieee1275_ihandle_t ihandle = 0;
 ++  struct disk_dev *dev = NULL;
 ++
 ++  if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
 ++    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not IEEE1275 device");
 ++
 ++  dev = find_grub_devpath (name);
 ++
 ++  if (dev == NULL)
 ++    {
 ++      grub_printf ("UNKNOWN DEVICE: %s\n", name);
 ++      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "%s", name);
 ++    }
 ++
 ++  if (dev->opened == 0)
 ++    {
 ++      if (dev->raw_name)
 ++        grub_ieee1275_open (dev->raw_name, &ihandle);
 ++      else
 ++        grub_ieee1275_open (dev->name, &ihandle);
 ++
 ++      if (ihandle == 0)
 ++        {
 ++          grub_printf ("Can't open device %s\n", name);
 ++          return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device %s", name);
 ++        }
 ++
 ++      dev->block_size = grub_ieee1275_get_block_size (ihandle);
 ++      dev->num_blocks = grub_ieee1275_num_blocks (ihandle);
 ++
 ++      if (dev->num_blocks == 0)
 ++        dev->num_blocks = grub_ieee1275_num_blocks64 (ihandle);
 ++
 ++      if (dev->num_blocks == 0)
 ++        dev->num_blocks = GRUB_DISK_SIZE_UNKNOWN;
 ++
 ++      if (dev->block_size != 0)
 ++        {
 ++          for (dev->log_sector_size = 0;
 ++               (1U << dev->log_sector_size) < dev->block_size;
 ++               dev->log_sector_size++);
 ++        }
 ++      else
 ++        dev->log_sector_size = 9;
 ++
 ++      dev->ihandle = ihandle;
 ++      dev->opened = 1;
 ++    }
 ++
 ++  disk->total_sectors = dev->num_blocks;
 ++  disk->id = dev->ihandle;
 ++  disk->data = dev;
 ++  disk->log_sector_size = dev->log_sector_size;
 ++  return GRUB_ERR_NONE;
 ++}
 ++
 ++
 ++static struct grub_disk_dev grub_obdisk_dev =
 ++  {
 ++    .name = "obdisk",
 ++    .id = GRUB_DISK_DEVICE_OBDISK_ID,
 ++    .iterate = grub_obdisk_iterate,
 ++    .open = grub_obdisk_open,
 ++    .close = grub_obdisk_close,
 ++    .read = grub_obdisk_read,
 ++    .next = 0
 ++  };
 ++
 ++void
 ++grub_obdisk_init (void)
 ++{
 ++  grub_disk_firmware_fini = grub_obdisk_fini;
 ++  add_bootpath ();
 ++  grub_disk_dev_register (&grub_obdisk_dev);
 ++}
 ++
 ++void
 ++grub_obdisk_fini (void)
 ++{
 ++  struct disk_dev *dev;
 ++
 ++  FOR_LIST_ELEMENTS (dev, disk_devs)
 ++    {
 ++      if (dev->opened)
 ++          grub_ieee1275_close (dev->ihandle);
 ++    }
 ++
 ++  grub_disk_dev_unregister (&grub_obdisk_dev);
 ++}
 +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
 +index 235c0fe2c..18d2e9512 100644
 +--- a/grub-core/disk/ieee1275/ofdisk.c
 ++++ b/grub-core/disk/ieee1275/ofdisk.c
 +@@ -74,7 +74,7 @@ ofdisk_hash_find (const char *devpath)
 + }
 + 
 + static struct ofdisk_hash_ent *
 +-ofdisk_hash_add_real (char *devpath)
 ++ofdisk_hash_add_real (const char *devpath)
 + {
 +   struct ofdisk_hash_ent *p;
 +   struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
 +@@ -85,13 +85,20 @@ ofdisk_hash_add_real (char *devpath)
 +   if (!p)
 +     return NULL;
 + 
 +-  p->devpath = devpath;
 ++  p->devpath = grub_strdup (devpath);
 ++
 ++  if (!p->devpath)
 ++    {
 ++      grub_free (p);
 ++      return NULL;
 ++    }
 + 
 +   p->grub_devpath = grub_malloc (sizeof ("ieee1275/")
 +                               + 2 * grub_strlen (p->devpath));
 + 
 +   if (!p->grub_devpath)
 +     {
 ++      grub_free (p->devpath);
 +       grub_free (p);
 +       return NULL;
 +     }
 +@@ -101,6 +108,7 @@ ofdisk_hash_add_real (char *devpath)
 +       p->open_path = grub_malloc (grub_strlen (p->devpath) + 3);
 +       if (!p->open_path)
 +      {
 ++          grub_free (p->devpath);
 +        grub_free (p->grub_devpath);
 +        grub_free (p);
 +        return NULL;
 +@@ -140,7 +148,7 @@ check_string_removable (const char *str)
 + }
 + 
 + static struct ofdisk_hash_ent *
 +-ofdisk_hash_add (char *devpath, char *curcan)
 ++ofdisk_hash_add (const char *devpath, const char *curcan)
 + {
 +   struct ofdisk_hash_ent *p, *pcan;
 + 
 +@@ -160,8 +168,6 @@ ofdisk_hash_add (char *devpath, char *curcan)
 +   pcan = ofdisk_hash_find (curcan);
 +   if (!pcan)
 +     pcan = ofdisk_hash_add_real (curcan);
 +-  else
 +-    grub_free (curcan);
 + 
 +   if (check_string_removable (devpath) || check_string_removable (curcan))
 +     pcan->is_removable = 1;
 +@@ -191,18 +197,7 @@ dev_iterate_real (const char *name, const char *path)
 + 
 +   op = ofdisk_hash_find (path);
 +   if (!op)
 +-    {
 +-      char *name_dup = grub_strdup (name);
 +-      char *can = grub_strdup (path);
 +-      if (!name_dup || !can)
 +-     {
 +-       grub_errno = GRUB_ERR_NONE;
 +-       grub_free (name_dup);
 +-       grub_free (can);
 +-       return;
 +-     }
 +-      op = ofdisk_hash_add (name_dup, can);
 +-    }
 ++    op = ofdisk_hash_add (name, path);
 +   return;
 + }
 + 
 +@@ -658,6 +653,7 @@ insert_bootpath (void)
 +       char *device = grub_ieee1275_get_devname (bootpath);
 +       op = ofdisk_hash_add (device, NULL);
 +       op->is_boot = 1;
 ++      grub_free (device);
 +     }
 +   grub_free (type);
 +   grub_free (bootpath);
 +diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c
 +index 3e12e6b24..20cbbd761 100644
 +--- a/grub-core/kern/ieee1275/cmain.c
 ++++ b/grub-core/kern/ieee1275/cmain.c
 +@@ -108,6 +108,9 @@ grub_ieee1275_find_options (void)
 +   if (rc >= 0)
 +     {
 +       char *ptr;
 ++
 ++      if (grub_strncmp (tmp, "sun4v", 5) == 0)
 ++        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES);
 +       for (ptr = tmp; ptr - tmp < actual; ptr += grub_strlen (ptr) + 1)
 +      {
 +        if (grub_memcmp (ptr, "MacRISC", sizeof ("MacRISC") - 1) == 0
 +diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c
 +index 98217029f..e14170821 100644
 +--- a/grub-core/kern/ieee1275/ieee1275.c
 ++++ b/grub-core/kern/ieee1275/ieee1275.c
 +@@ -19,6 +19,7 @@
 + 
 + #include <grub/ieee1275/ieee1275.h>
 + #include <grub/types.h>
 ++#include <grub/misc.h>
 + 
 + #define IEEE1275_PHANDLE_INVALID  ((grub_ieee1275_cell_t) -1)
 + #define IEEE1275_IHANDLE_INVALID  ((grub_ieee1275_cell_t) 0)
- +int
++@@ -483,6 +484,93 @@ grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
 + }
 + 
-  int
++ int
 ++grub_ieee1275_decode_unit4 (grub_ieee1275_ihandle_t ihandle,
 ++                            void *addr, grub_size_t size,
 ++                            grub_uint32_t *phy_lo, grub_uint32_t *phy_hi,
 ++                            grub_uint32_t *lun_lo, grub_uint32_t *lun_hi)
 ++{
 ++  struct decode_args
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t size;
 ++    grub_ieee1275_cell_t addr;
 ++    grub_ieee1275_cell_t catch_result;
 ++    grub_ieee1275_cell_t tgt_h;
 ++    grub_ieee1275_cell_t tgt_l;
 ++    grub_ieee1275_cell_t lun_h;
 ++    grub_ieee1275_cell_t lun_l;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 5);
 ++  args.method = (grub_ieee1275_cell_t) "decode-unit";
 ++  args.ihandle = ihandle;
 ++  args.size = size;
 ++  args.addr = (grub_ieee1275_cell_t) addr;
 ++  args.catch_result = 1;
 ++
 ++  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_RANGE, "decode-unit failed\n");
 ++      return -1;
 ++    }
 ++
 ++  *phy_lo = args.tgt_l;
 ++  *phy_hi = args.tgt_h;
 ++  *lun_lo = args.lun_l;
 ++  *lun_hi = args.lun_h;
 ++  return 0;
 ++}
 ++
 ++char *
 ++grub_ieee1275_encode_uint4 (grub_ieee1275_ihandle_t ihandle,
 ++                            grub_uint32_t phy_lo, grub_uint32_t phy_hi,
 ++                            grub_uint32_t lun_lo, grub_uint32_t lun_hi,
 ++                            grub_size_t *size)
 ++{
 ++  char *addr;
 ++  struct encode_args
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t tgt_h;
 ++    grub_ieee1275_cell_t tgt_l;
 ++    grub_ieee1275_cell_t lun_h;
 ++    grub_ieee1275_cell_t lun_l;
 ++    grub_ieee1275_cell_t catch_result;
 ++    grub_ieee1275_cell_t size;
 ++    grub_ieee1275_cell_t addr;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 3);
 ++  args.method = (grub_ieee1275_cell_t) "encode-unit";
 ++  args.ihandle = ihandle;
 ++
 ++  args.tgt_l = phy_lo;
 ++  args.tgt_h = phy_hi;
 ++  args.lun_l = lun_lo;
 ++  args.lun_h = lun_hi;
 ++  args.catch_result = 1;
 ++
 ++  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
 ++    {
 ++      grub_error (GRUB_ERR_OUT_OF_RANGE, "encode-unit failed\n");
 ++      return 0;
 ++    }
 ++
 ++  addr = (void *)args.addr;
 ++  *size = args.size;
 ++  addr = grub_strdup ((char *)args.addr);
 ++  return addr;
 ++}
 ++
 ++
 ++
+++int
 + grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
 +                   grub_addr_t *result)
++ {
 +@@ -607,3 +695,114 @@ grub_ieee1275_milliseconds (grub_uint32_t *msecs)
 +   *msecs = args.msecs;
 +   return 0;
 + }
 ++
 ++int
 ++grub_ieee1275_set_address (grub_ieee1275_ihandle_t ihandle,
 ++                           grub_uint32_t target, grub_uint32_t lun)
 ++{
 ++  struct set_address
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t tgt;
 ++    grub_ieee1275_cell_t lun;
 ++    grub_ieee1275_cell_t catch_result;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 1);
 ++
 ++  /* IEEE Standard for Boot (Initialization Configuration)
 ++     Firmware: Core Requirements and Practices
 ++     E.3.2.2 Bus-specific methods for bus nodes
 ++
 ++     A package implementing the scsi-2 device type shall implement the
 ++     following bus-specific method:
 ++
 ++     set-address ( unit# target# -- )
 ++     Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which
 ++     subsequent commands apply.
 ++  */
 ++  args.method = (grub_ieee1275_cell_t) "set-address";
 ++  args.ihandle = ihandle;
 ++  args.tgt = target;
 ++  args.lun = lun;
 ++
 ++  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
 ++    return -1;
 ++
 ++  return args.catch_result;
 ++}
 ++
 ++int
 ++grub_ieee1275_no_data_command (grub_ieee1275_ihandle_t ihandle,
 ++                               const void *cmd_addr, grub_ssize_t *result)
 ++{
 ++  struct set_address
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t cmd_addr;
 ++    grub_ieee1275_cell_t error;
 ++    grub_ieee1275_cell_t catch_result;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
 ++  /* IEEE 1275-1994 Standard for Boot (Initialization Configuration)
 ++     Firmware: Core Requirements and Practices
 ++
 ++     E.3.2.2 Bus-specific methods for bus nodes
 ++
 ++     A package implementing the scsi-2 device type shall implement the
 ++     following bus-specific method:
 ++
 ++     no-data-command ( cmd-addr -- error? )
 ++     Executes a simple SCSI command, automatically retrying under
 ++     certain conditions.  cmd-addr is the address of a 6-byte command buffer
 ++     containing an SCSI command that does not have a data transfer phase.
 ++     Executes the command, retrying indefinitely with the same retry criteria
 ++     as retry-command.
 ++
 ++     error? is nonzero if an error occurred, zero otherwise.
 ++     NOTE no-data-command is a convenience function. It provides
 ++     no capabilities that are not present in retry-command, but for
 ++     those commands that meet its restrictions, it is easier to use.
 ++   */
 ++  args.method = (grub_ieee1275_cell_t) "no-data-command";
 ++  args.ihandle = ihandle;
 ++  args.cmd_addr = (grub_ieee1275_cell_t) cmd_addr;
 ++
 ++  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
 ++    return -1;
 ++
 ++  if (result)
 ++    *result = args.error;
 ++
 ++  return args.catch_result;
 ++}
 ++
 ++int
 ++grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle)
 ++{
 ++  struct size_args_ieee1275
 ++    {
 ++      struct grub_ieee1275_common_hdr common;
 ++      grub_ieee1275_cell_t method;
 ++      grub_ieee1275_cell_t ihandle;
 ++      grub_ieee1275_cell_t result;
 ++      grub_ieee1275_cell_t size;
 ++    } args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
 ++  args.method = (grub_ieee1275_cell_t) "block-size";
 ++  args.ihandle = ihandle;
 ++  args.result = 1;
 ++
 ++  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
 ++    return 0;
 ++
 ++  return args.size;
 ++}
 +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
 +index 9d163abcd..6e87cada6 100644
 +--- a/grub-core/kern/ieee1275/init.c
 ++++ b/grub-core/kern/ieee1275/init.c
 +@@ -30,6 +30,9 @@
 + #include <grub/time.h>
 + #include <grub/ieee1275/console.h>
 + #include <grub/ieee1275/ofdisk.h>
 ++#ifdef __sparc__
 ++#include <grub/ieee1275/obdisk.h>
 ++#endif
 + #include <grub/ieee1275/ieee1275.h>
 + #include <grub/net.h>
 + #include <grub/offsets.h>
 +@@ -103,29 +106,13 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
 + void
 + grub_machine_get_bootlocation (char **device, char **path)
 + {
 +-  char *bootpath;
 +-  grub_ssize_t bootpath_size;
 ++  char *bootpath = NULL;
 +   char *filename;
 +   char *type;
 + 
 +-  if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
 +-                                      &bootpath_size)
 +-      || bootpath_size <= 0)
 +-    {
 +-      /* Should never happen.  */
 +-      grub_printf ("/chosen/bootpath property missing!\n");
 +-      return;
 +-    }
 +-
 +-  bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
 +-  if (! bootpath)
 +-    {
 +-      grub_print_error ();
 +-      return;
 +-    }
 +-  grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath,
 +-                              (grub_size_t) bootpath_size + 1, 0);
 +-  bootpath[bootpath_size] = '\0';
 ++  grub_ieee1275_get_boot_dev (&bootpath);
 ++  if (bootpath == NULL)
 ++    return;
 + 
 +   /* Transform an OF device path to a GRUB path.  */
 + 
 +@@ -305,8 +292,11 @@ grub_machine_init (void)
 +   grub_console_init_early ();
 +   grub_claim_heap ();
 +   grub_console_init_lately ();
 ++#ifdef __sparc__
 ++  grub_obdisk_init ();
 ++#else
 +   grub_ofdisk_init ();
 +-
 ++#endif
 +   grub_parse_cmdline ();
 + 
 + #ifdef __i386__
 +@@ -321,7 +311,11 @@ grub_machine_fini (int flags)
 + {
 +   if (flags & GRUB_LOADER_FLAG_NORETURN)
 +     {
 ++#ifdef __sparc__
 ++      grub_obdisk_fini ();
 ++#else
 +       grub_ofdisk_fini ();
 ++#endif
 +       grub_console_fini ();
 +     }
 + }
 +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
 +index ddb778340..81c03cf03 100644
 +--- a/grub-core/kern/ieee1275/openfw.c
 ++++ b/grub-core/kern/ieee1275/openfw.c
 +@@ -561,3 +561,30 @@ grub_ieee1275_canonicalise_devname (const char *path)
 +   return NULL;
 + }
 + 
 ++void
 ++grub_ieee1275_get_boot_dev (char **boot_dev)
 ++{
 ++  char *bootpath;
 ++  grub_ssize_t bootpath_size;
 ++
 ++  if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
 ++                                      &bootpath_size)
 ++      || bootpath_size <= 0)
 ++    {
 ++      /* Should never happen.  */
 ++      grub_printf ("/chosen/bootpath property missing!\n");
 ++      return;
 ++    }
 ++
 ++  bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
 ++  if (! bootpath)
 ++    {
 ++      grub_print_error ();
 ++      return;
 ++    }
 ++  grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath,
 ++                              (grub_size_t) bootpath_size + 1, 0);
 ++  bootpath[bootpath_size] = '\0';
 ++
 ++  *boot_dev = bootpath;
 ++}
 +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
 +index 78175aac2..be88baa60 100644
 +--- a/grub-core/kern/parser.c
 ++++ b/grub-core/kern/parser.c
 +@@ -30,7 +30,6 @@ static struct grub_parser_state_transition state_transitions[] = {
 +   {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
 +   {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
 +   {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
 +-  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
 + 
 +   {GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
 + 
 +diff --git a/grub-core/kern/sparc64/ieee1275/ieee1275.c b/grub-core/kern/sparc64/ieee1275/ieee1275.c
 +index 53be692c3..6e5b90a4f 100644
 +--- a/grub-core/kern/sparc64/ieee1275/ieee1275.c
 ++++ b/grub-core/kern/sparc64/ieee1275/ieee1275.c
 +@@ -89,3 +89,56 @@ grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size,
 + 
 +   return args.catch_result;
 + }
 ++
 ++grub_uint64_t
 ++grub_ieee1275_num_blocks (grub_ieee1275_ihandle_t ihandle)
 ++{
 ++  struct nblocks_args_ieee1275
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t catch_result;
 ++    grub_ieee1275_cell_t blocks;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
 ++  args.method = (grub_ieee1275_cell_t) "#blocks";
 ++  args.ihandle = ihandle;
 ++  args.catch_result = 1;
 ++
 ++  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0))
 ++    return -1;
 ++
 ++  /* If the number of blocks exceeds the range of an unsigned number,
 ++     return 0 to alert the caller to try the #blocks64 command. */
 ++  if (args.blocks >= 0xffffffffULL)
 ++    return 0;
 ++
 ++  return args.blocks;
 ++}
 ++grub_uint64_t
 ++grub_ieee1275_num_blocks64 (grub_ieee1275_ihandle_t ihandle)
 ++{
 ++  struct nblocks_args_ieee1275
 ++  {
 ++    struct grub_ieee1275_common_hdr common;
 ++    grub_ieee1275_cell_t method;
 ++    grub_ieee1275_cell_t ihandle;
 ++    grub_ieee1275_cell_t catch_result;
 ++    grub_ieee1275_cell_t hi_blocks;
 ++    grub_ieee1275_cell_t lo_blocks;
 ++  }
 ++  args;
 ++
 ++  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
 ++  args.method = (grub_ieee1275_cell_t) "#blocks64";
 ++  args.ihandle = ihandle;
 ++  args.catch_result = 1;
 ++
 ++  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0))
 ++    return -1;
 ++
 ++  return ((args.hi_blocks << 32) | (args.lo_blocks));
 ++}
 +diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c
 +index c77d6085c..caf8d4ee5 100644
 +--- a/grub-core/osdep/linux/blocklist.c
 ++++ b/grub-core/osdep/linux/blocklist.c
 +@@ -58,6 +58,11 @@ grub_install_get_blocklist (grub_device_t root_dev,
 +   struct fiemap fie1;
 +   int fd;
 + 
 ++#ifdef __sparc__
 ++  if (grub_strstr (container->partmap->name, "gpt"))
 ++    container_start = 0;
 ++#endif
 ++
 +   /* Write the first two sectors of the core image onto the disk.  */
 +   grub_util_info ("opening the core image `%s'", core_path);
 +   fd = open (core_path, O_RDONLY);
 +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
 +index a79682a5e..5155b0620 100644
 +--- a/grub-core/osdep/linux/ofpath.c
 ++++ b/grub-core/osdep/linux/ofpath.c
 +@@ -38,6 +38,44 @@
 + #include <errno.h>
 + #include <ctype.h>
 + 
 ++#ifdef __sparc__
 ++typedef enum
 ++  {
 ++    GRUB_OFPATH_SPARC_WWN_ADDR = 1,
 ++    GRUB_OFPATH_SPARC_TGT_LUN,
 ++  } ofpath_sparc_addressing;
 ++
 ++struct ofpath_sparc_hba
 ++{
 ++  grub_uint32_t device_id;
 ++  ofpath_sparc_addressing addressing;
 ++};
 ++
 ++static struct ofpath_sparc_hba sparc_lsi_hba[] = {
 ++  /* Rhea, Jasper 320, LSI53C1020/1030.  */
 ++  {0x30, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* SAS-1068E.  */
 ++  {0x50, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* SAS-1064E.  */
 ++  {0x56, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* Pandora SAS-1068E.  */
 ++  {0x58, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* Aspen, Invader, LSI SAS-3108.  */
 ++  {0x5d, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* Niwot, SAS 2108.  */
 ++  {0x79, GRUB_OFPATH_SPARC_TGT_LUN},
 ++  /* Erie, Falcon, LSI SAS 2008.  */
 ++  {0x72, GRUB_OFPATH_SPARC_WWN_ADDR},
 ++  /* LSI WarpDrive 6203.  */
 ++  {0x7e, GRUB_OFPATH_SPARC_WWN_ADDR},
 ++  /* LSI SAS 2308.  */
 ++  {0x87, GRUB_OFPATH_SPARC_WWN_ADDR},
 ++  /* LSI SAS 3008.  */
 ++  {0x97, GRUB_OFPATH_SPARC_WWN_ADDR},
 ++  {0, 0}
 ++};
 ++#endif
 ++
 + #ifdef OFPATH_STANDALONE
 + #define xmalloc malloc
 + void
 +@@ -120,6 +158,8 @@ find_obppath (const char *sysfs_path_orig)
 + #endif
 + 
 +       fd = open(path, O_RDONLY);
 ++
 ++#ifndef __sparc__
 +       if (fd < 0 || fstat (fd, &st) < 0)
 +      {
 +        if (fd >= 0)
 +@@ -127,6 +167,7 @@ find_obppath (const char *sysfs_path_orig)
 +        snprintf(path, path_size, "%s/devspec", sysfs_path);
 +        fd = open(path, O_RDONLY);
 +      }
 ++#endif
 + 
 +       if (fd < 0 || fstat (fd, &st) < 0)
 +      {
 +@@ -307,6 +348,55 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
 +   return ret;
 + }
 + 
 ++#ifdef __sparc__
 ++static char *
 ++of_path_of_nvme(const char *sys_devname __attribute__((unused)),
 ++             const char *device,
 ++             const char *devnode __attribute__((unused)),
 ++             const char *devicenode)
 ++{
 ++  char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
 ++  const char *digit_string, *part_end;
 ++
 ++  digit_string = trailing_digits (device);
 ++  part_end = devicenode + strlen (devicenode) - 1;
 ++
 ++  if ((*digit_string != '\0') && (*part_end == 'p'))
 ++    {
 ++      /* We have a partition number, strip it off.  */
 ++      int part;
 ++      char *nvmedev, *end;
 ++
 ++      nvmedev = strdup (devicenode);
 ++
 ++      if (nvmedev == NULL)
 ++        return NULL;
 ++
 ++      end = nvmedev + strlen (nvmedev) - 1;
 ++      /* Remove the p.  */
 ++      *end = '\0';
 ++      sscanf (digit_string, "%d", &part);
 ++      snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
 ++      sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
 ++      free (nvmedev);
 ++    }
 ++  else
 ++    {
 ++      /* We do not have the parition.  */
 ++      snprintf (disk, sizeof (disk), "/disk@1");
 ++      sysfs_path = block_device_get_sysfs_path_and_link (device);
 ++    }
 ++
 ++  of_path = find_obppath (sysfs_path);
 ++
 ++  if (of_path)
 ++    strcat (of_path, disk);
 ++
 ++  free (sysfs_path);
 ++  return of_path;
 ++}
 ++#endif
 ++
 + static int
 + vendor_is_ATA(const char *path)
 + {
 +@@ -335,6 +425,66 @@ vendor_is_ATA(const char *path)
 +   return (memcmp(bufcont, "ATA", 3) == 0);
 + }
 + 
 ++#ifdef __sparc__
 ++static void
 ++check_hba_identifiers (const char *sysfs_path, int *vendor, int *device_id)
 ++{
 ++  char *ed = strstr (sysfs_path, "host");
 ++  size_t path_size;
 ++  char *p = NULL, *path = NULL;
 ++  char buf[8];
 ++  int fd;
 ++
 ++  if (!ed)
 ++    return;
 ++
 ++  p = xstrdup (sysfs_path);
 ++  ed = strstr (p, "host");
 ++
 ++  if (!ed)
 ++    goto out;
 ++
 ++  *ed = '\0';
 ++
 ++  path_size = (strlen (p) + sizeof ("vendor"));
 ++  path = xmalloc (path_size);
 ++
 ++  if (!path)
 ++    goto out;
 ++
 ++  snprintf (path, path_size, "%svendor", p);
 ++  fd = open (path, O_RDONLY);
 ++
 ++  if (fd < 0)
 ++    goto out;
 ++
 ++  memset (buf, 0, sizeof (buf));
 ++
 ++  if (read (fd, buf, sizeof (buf) - 1) < 0)
 ++    goto out;
 ++
 ++  close (fd);
 ++  sscanf (buf, "%x", vendor);
 ++  snprintf (path, path_size, "%sdevice", p);
 ++  fd = open (path, O_RDONLY);
 ++
 ++  if (fd < 0)
 ++    goto out;
 ++
 ++  memset (buf, 0, sizeof (buf));
 ++
 ++  if (read (fd, buf, sizeof (buf) - 1) < 0)
 ++    goto out;
 ++
 ++  close (fd);
 ++  sscanf (buf, "%x", device_id);
 ++
 ++out:
 ++  free (path);
 ++  free (p);
 ++}
 ++#endif
 ++
 + static void
 + check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address)
 + {
 +@@ -396,7 +546,7 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
 + {
 +   const char *p, *digit_string, *disk_name;
 +   int host, bus, tgt, lun;
 +-  unsigned long int sas_address;
 ++  unsigned long int sas_address = 0;
 +   char *sysfs_path, disk[MAX_DISK_CAT - sizeof ("/fp@0,0")];
 +   char *of_path;
 + 
 +@@ -413,9 +563,11 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
 +     }
 + 
 +   of_path = find_obppath(sysfs_path);
 +-  free (sysfs_path);
 +   if (!of_path)
 +-    return NULL;
 ++    {
 ++      free (sysfs_path);
 ++      return NULL;
 ++    }
 + 
 +   if (strstr (of_path, "qlc"))
 +     strcat (of_path, "/fp@0,0");
 +@@ -444,6 +596,45 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
 +     }
 +   else
 +     {
 ++#ifdef __sparc__
 ++      ofpath_sparc_addressing addressing = GRUB_OFPATH_SPARC_TGT_LUN;
 ++      int vendor = 0, device_id = 0;
 ++      char *optr = disk;
 ++
 ++      check_hba_identifiers (sysfs_path, &vendor, &device_id);
 ++
 ++      /* LSI Logic Vendor ID */
 ++      if (vendor == 0x1000)
 ++        {
 ++          struct ofpath_sparc_hba *lsi_hba;
 ++
 ++          /* Over time different OF addressing schemes have been supported.
 ++             There is no generic addressing scheme that works across
 ++             every HBA. */
 ++          for (lsi_hba = sparc_lsi_hba; lsi_hba->device_id; lsi_hba++)
 ++            if (lsi_hba->device_id == device_id)
 ++              {
 ++                addressing = lsi_hba->addressing;
 ++                break;
 ++              }
 ++        }
 ++
 ++      if (addressing == GRUB_OFPATH_SPARC_WWN_ADDR)
 ++        optr += snprintf (disk, sizeof (disk), "/%s@w%lx,%x", disk_name,
 ++                          sas_address, lun);
 ++      else
 ++        optr += snprintf (disk, sizeof (disk), "/%s@%x,%x", disk_name, tgt,
 ++                          lun);
 ++
 ++      if (*digit_string != '\0')
 ++        {
 ++          int part;
 ++
 ++          sscanf (digit_string, "%d", &part);
 ++          snprintf (optr, sizeof (disk) - (optr - disk - 1), ":%c", 'a'
 ++                    + (part - 1));
 ++        }
 ++#else
 +       if (lun == 0)
 +         {
 +           int sas_id = 0;
 +@@ -491,7 +682,9 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
 +             }
 +        free (lunstr);
 +         }
 ++#endif
 +     }
 ++  free (sysfs_path);
 +   strcat(of_path, disk);
 +   return of_path;
 + }
 +@@ -537,6 +730,11 @@ grub_util_devname_to_ofpath (const char *sys_devname)
 +     /* All the models I've seen have a devalias "floppy".
 +        New models have no floppy at all. */
 +     ofpath = xstrdup ("floppy");
 ++#ifdef __sparc__
 ++  else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm'
 ++           && device[3] == 'e')
 ++    ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode);
 ++#endif
 +   else
 +     {
 +       grub_util_warn (_("unknown device type %s"), device);
 +diff --git a/include/grub/disk.h b/include/grub/disk.h
 +index b385af826..bd58b11d5 100644
 +--- a/include/grub/disk.h
 ++++ b/include/grub/disk.h
 +@@ -49,6 +49,7 @@ enum grub_disk_dev_id
 +     GRUB_DISK_DEVICE_CBFSDISK_ID,
 +     GRUB_DISK_DEVICE_UBOOTDISK_ID,
 +     GRUB_DISK_DEVICE_XEN,
 ++    GRUB_DISK_DEVICE_OBDISK_ID,
 +   };
 + 
 + struct grub_disk;
 +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
 +index 8e4251303..27b173678 100644
 +--- a/include/grub/ieee1275/ieee1275.h
 ++++ b/include/grub/ieee1275/ieee1275.h
 +@@ -146,6 +146,8 @@ enum grub_ieee1275_flag
 +   GRUB_IEEE1275_FLAG_BROKEN_REPEAT,
 + 
 +   GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN,
 ++
 ++  GRUB_IEEE1275_FLAG_RAW_DEVNAMES,
 + };
 + 
 + extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
 +@@ -211,6 +213,30 @@ int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle,
 +                                        int index, int r, int g, int b);
 + int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs);
 + 
 ++int EXPORT_FUNC(grub_ieee1275_set_address) (grub_ieee1275_ihandle_t ihandle,
 ++                                            grub_uint32_t target,
 ++                                            grub_uint32_t lun);
 ++
 ++int EXPORT_FUNC(grub_ieee1275_no_data_command) (grub_ieee1275_ihandle_t ihandle,
 ++                                                const void *cmd_addr,
 ++                                                grub_ssize_t *result);
 ++
 ++int EXPORT_FUNC(grub_ieee1275_decode_unit4) (grub_ieee1275_ihandle_t ihandle,
 ++                                             void *addr, grub_size_t size,
 ++                                             grub_uint32_t *phy_lo,
 ++                                             grub_uint32_t *phy_hi,
 ++                                             grub_uint32_t *lun_lo,
 ++                                             grub_uint32_t *lun_hi);
 ++
 ++char *EXPORT_FUNC(grub_ieee1275_encode_uint4) (grub_ieee1275_ihandle_t ihandle,
 ++                                             grub_uint32_t phy_lo,
 ++                                             grub_uint32_t phy_hi,
 ++                                             grub_uint32_t lun_lo,
 ++                                             grub_uint32_t lun_hi,
 ++                                             grub_size_t *size);
 ++
 ++int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle);
 ++
 + 
 + grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
 + 
 +@@ -235,6 +261,7 @@ void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *al
 + void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath,
 +                                              struct grub_ieee1275_devalias *alias);
 + 
 ++void EXPORT_FUNC(grub_ieee1275_get_boot_dev) (char **boot_dev);
 + #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));)
 + 
 + #define FOR_IEEE1275_DEVCHILDREN(devpath, alias) for (grub_ieee1275_children_first ((devpath), &(alias)); \
 +diff --git a/include/grub/ieee1275/obdisk.h b/include/grub/ieee1275/obdisk.h
 +new file mode 100644
 +index 000000000..3d6fa0e62
 +--- /dev/null
 ++++ b/include/grub/ieee1275/obdisk.h
 +@@ -0,0 +1,25 @@
 ++/*
 ++ *  GRUB  --  GRand Unified Bootloader
 ++ *  Copyright (C) 2017  Free Software Foundation, Inc.
 ++ *
 ++ *  GRUB 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 3 of the License, or
 ++ *  (at your option) any later version.
 ++ *
 ++ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++ */
 ++
 ++#ifndef GRUB_OBDISK_HEADER
 ++#define GRUB_OBDISK_HEADER   1
 ++
 ++extern void grub_obdisk_init (void);
 ++extern void grub_obdisk_fini (void);
 ++
 ++#endif
 +diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h
 +index 32c77f80f..4b18468d8 100644
 +--- a/include/grub/sparc64/ieee1275/ieee1275.h
 ++++ b/include/grub/sparc64/ieee1275/ieee1275.h
 +@@ -42,6 +42,8 @@ extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr,
 + extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr,
 +                                                   grub_size_t size,
 +                                                   grub_uint32_t align);
 ++extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks) (grub_uint32_t ihandle);
 ++extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks64) (grub_uint32_t ihandle);
 + 
 + extern grub_addr_t EXPORT_VAR (grub_ieee1275_original_stack);
 + 
 +diff --git a/util/grub-install.c b/util/grub-install.c
 +index 04a520481..0b97c1ac0 100644
 +--- a/util/grub-install.c
 ++++ b/util/grub-install.c
 +@@ -1616,6 +1616,7 @@ main (int argc, char *argv[])
 +              {
 +                grub_util_fprint_full_disk_name (load_cfg_f, g, dev);
 +                fprintf (load_cfg_f, " ");
 ++               free (g);
 +              }
 +            if (dev != grub_dev)
 +              grub_device_close (dev);
 +diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c
 +index 8e5d766cb..300fbddad 100644
 +--- a/util/ieee1275/grub-ofpathname.c
 ++++ b/util/ieee1275/grub-ofpathname.c
 +@@ -46,7 +46,9 @@ int main(int argc, char **argv)
 +     }
 + 
 +   of_path = grub_util_devname_to_ofpath (argv[1]);
 +-  printf("%s\n", of_path);
 ++
 ++  if (of_path)
 ++    printf ("%s\n", of_path);
 + 
 +   free (of_path);
 + 
 +diff --git a/util/setup.c b/util/setup.c
 +index 3b5c46fde..15e7de0a7 100644
 +--- a/util/setup.c
 ++++ b/util/setup.c
 +@@ -200,7 +200,6 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length,
 + #endif
 + }
 + 
 +-#ifdef GRUB_SETUP_BIOS
 + /* Context for setup/identify_partmap.  */
 + struct identify_partmap_ctx
 + {
 +@@ -236,7 +235,6 @@ identify_partmap (grub_disk_t disk __attribute__ ((unused)),
 +   ctx->multiple_partmaps = 1;
 +   return 1;
 + }
 +-#endif
 + 
 + #ifdef GRUB_SETUP_BIOS
 + #define SETUP grub_util_bios_setup
 +@@ -257,9 +255,7 @@ SETUP (const char *dir,
 +   char *boot_img, *core_img, *boot_path;
 +   char *root = 0;
 +   size_t boot_size, core_size;
 +-#ifdef GRUB_SETUP_BIOS
 +   grub_uint16_t core_sectors;
 +-#endif
 +   grub_device_t root_dev = 0, dest_dev, core_dev;
 +   grub_util_fd_t fp;
 +   struct blocklists bl;
 +@@ -283,10 +279,8 @@ SETUP (const char *dir,
 + 
 +   core_path = grub_util_get_path (dir, core_file);
 +   core_size = grub_util_get_image_size (core_path);
 +-#ifdef GRUB_SETUP_BIOS
 +   core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
 +                >> GRUB_DISK_SECTOR_BITS);
 +-#endif
 +   if (core_size < GRUB_DISK_SECTOR_SIZE)
 +     grub_util_error (_("the size of `%s' is too small"), core_path);
 + #ifdef GRUB_SETUP_BIOS
 +@@ -368,8 +362,8 @@ SETUP (const char *dir,
 +   if (grub_env_set ("root", root) != GRUB_ERR_NONE)
 +     grub_util_error ("%s", grub_errmsg);
 + 
 +-#ifdef GRUB_SETUP_BIOS
 +   {
 ++#ifdef GRUB_SETUP_BIOS
 +     char *tmp_img;
 +     grub_uint8_t *boot_drive_check;
 + 
 +@@ -394,6 +388,7 @@ SETUP (const char *dir,
 +      boot_drive_check[0] = 0x90;
 +      boot_drive_check[1] = 0x90;
 +       }
 ++#endif
 + 
 +     struct identify_partmap_ctx ctx = {
 +       .dest_partmap = NULL,
 +@@ -409,6 +404,7 @@ SETUP (const char *dir,
 + 
 +     grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx);
 + 
 ++#ifdef GRUB_SETUP_BIOS
 +     /* Copy the partition table.  */
 +     if (ctx.dest_partmap ||
 +         (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)))
 +@@ -417,6 +413,7 @@ SETUP (const char *dir,
 +            GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);
 + 
 +     free (tmp_img);
 ++#endif
 + 
 +     if (ctx.container
 +      && grub_strcmp (ctx.container->partmap->name, "msdos") == 0
 +@@ -504,10 +501,21 @@ SETUP (const char *dir,
 +     else
 +       maxsec = core_sectors;
 + 
 ++#ifdef GRUB_SETUP_BIOS
 +     if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 +              >> GRUB_DISK_SECTOR_BITS))
 +       maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 +              >> GRUB_DISK_SECTOR_BITS);
 ++#endif
 ++
 ++#ifdef GRUB_SETUP_SPARC64
 ++    /* On SPARC we need two extra.  One is because we are combining the
 ++     * core.img with the boot.img. The other is because the boot sector
 ++     * starts at 1.
 ++     */
 ++    nsec += 2;
 ++    maxsec += 2;
 ++#endif
 + 
 +     if (is_ldm)
 +       err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
 +@@ -556,9 +564,35 @@ SETUP (const char *dir,
 +       bl.block--;
 +     bl.block->start = 0;
 +     bl.block->len = 0;
 ++#ifdef GRUB_SETUP_BIOS
 +     bl.block->segment = 0;
 ++#endif
 + 
 ++#ifdef GRUB_SETUP_SPARC64
 ++    {
 ++      /* On SPARC, the block-list entries need to be based off the beginning
 ++         of the parition, not the beginning of the disk. */
 ++      struct grub_boot_blocklist *block;
 ++      block = bl.first_block;
 ++
 ++      while (block->len)
 ++        {
 ++          block->start -= bl.first_sector;
 ++          block--;
 ++        }
 ++    }
 ++
 ++    /* Reserve space for the boot block since it can not be in the
 ++       Parition table on SPARC */
 ++    assert (bl.first_block->len > 2);
 ++    bl.first_block->start += 2;
 ++    bl.first_block->len -= 2;
 ++    write_rootdev (root_dev, boot_img, sectors[BOOT_SECTOR + 1] - bl.first_sector);
 ++#endif
 ++
 ++#ifdef GRUB_SETUP_BIOS
 +     write_rootdev (root_dev, boot_img, bl.first_sector);
 ++#endif
 + 
 +     /* Round up to the nearest sector boundary, and zero the extra memory */
 +     core_img = xrealloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
 +@@ -568,7 +602,7 @@ SETUP (const char *dir,
 +     bl.first_block = (struct grub_boot_blocklist *) (core_img
 +                                                   + GRUB_DISK_SECTOR_SIZE
 +                                                   - sizeof (*bl.block));
 +-
 ++#if GRUB_SETUP_BIOS
 +     grub_size_t no_rs_length;
 +     no_rs_length = grub_target_to_host16 
 +       (grub_get_unaligned16 (core_img
 +@@ -599,6 +633,26 @@ SETUP (const char *dir,
 +       grub_disk_write (dest_dev->disk, sectors[i], 0,
 +                     GRUB_DISK_SECTOR_SIZE,
 +                     core_img + i * GRUB_DISK_SECTOR_SIZE);
 ++#endif
 ++#ifdef GRUB_SETUP_SPARC64
 ++    {
 ++      int isec = BOOT_SECTOR;
 ++
 ++      /* Write the boot image onto the disk. */
 ++      if (grub_disk_write (dest_dev->disk, sectors[isec++], 0,
 ++                           GRUB_DISK_SECTOR_SIZE, boot_img))
 ++        grub_util_error ("%s", grub_errmsg);
 ++
 ++      /* Write the core image onto the disk. */
 ++      for (i = 0 ; isec < nsec; i++, isec++)
 ++        {
 ++          if (grub_disk_write (dest_dev->disk, sectors[isec], 0,
 ++                               GRUB_DISK_SECTOR_SIZE,
 ++                               core_img  + i * GRUB_DISK_SECTOR_SIZE))
 ++            grub_util_error ("%s", grub_errmsg);
 ++        }
 ++    }
 ++#endif
 + 
 +     grub_free (sectors);
 + 
 +@@ -608,7 +662,6 @@ SETUP (const char *dir,
 +   }
 + 
 + unable_to_embed:
 +-#endif
 + 
 +   if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
 +     grub_util_error ("%s", _("embedding is not possible, but this is required for "
 +@@ -729,15 +782,21 @@ unable_to_embed:
 +   {
 +     char *buf, *ptr = core_img;
 +     size_t len = core_size;
 +-    grub_uint64_t blk;
 ++    grub_uint64_t blk, offset = 0;
 +     grub_partition_t container = core_dev->disk->partition;
 +     grub_err_t err;
 + 
 +     core_dev->disk->partition = 0;
 ++#ifdef GRUB_SETUP_SPARC64
 ++    {
 ++      if (grub_strstr (container->partmap->name, "gpt"))
 ++        offset = grub_partition_get_start (container);
 ++    }
 ++#endif
 + 
 +     buf = xmalloc (core_size);
 +     blk = bl.first_sector;
 +-    err = grub_disk_read (core_dev->disk, blk, 0, GRUB_DISK_SECTOR_SIZE, buf);
 ++    err = grub_disk_read (core_dev->disk, blk + offset, 0, GRUB_DISK_SECTOR_SIZE, buf);
 +     if (err)
 +       grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name,
 +                     grub_errmsg);
 +@@ -756,7 +815,7 @@ unable_to_embed:
 +      if (cur > len)
 +        cur = len;
 + 
 +-     err = grub_disk_read (core_dev->disk, blk, 0, cur, buf);
 ++     err = grub_disk_read (core_dev->disk, blk + offset, 0, cur, buf);
 +      if (err)
 +        grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name,
 +                         grub_errmsg);
 +@@ -786,6 +845,10 @@ unable_to_embed:
 +                     0, GRUB_DISK_SECTOR_SIZE, boot_img))
 +     grub_util_error ("%s", grub_errmsg);
 + 
 ++#ifdef GRUB_SETUP_SPARC64
 ++ finish:
 ++#endif
 ++
 +   grub_util_biosdisk_flush (root_dev->disk);
 +   grub_util_biosdisk_flush (dest_dev->disk);
 + 
index bb958eba4bc793847326ba53d2ae940714faff35,0000000000000000000000000000000000000000..987fb572ed0d8e010179dc019084b0e318c7f8a7
mode 100644,000000..100644
--- /dev/null
@@@ -1,173 -1,0 +1,173 @@@
-  tests/syslinux/ubuntu10.04_grub.cfg.in | 30 +++++++++++++-------------
-  tests/syslinux_test.in                 | 14 ++++++++----
 +From 3773848cf605c69e54ad802ebf05e3de596eb5aa Mon Sep 17 00:00:00 2001
 +From: Colin Watson <cjwatson@ubuntu.com>
 +Date: Sun, 18 Sep 2016 17:26:00 +0100
 +Subject: syslinux_test: Fix out-of-tree build handling
 +
 +When doing out-of-tree builds, abs_top_srcdir may well contain ".."
 +segments, and grub-syslinux2cfg canonicalises its --root argument.  As a
 +result, the expansion of @abs_top_srcdir@ may not match what
 +grub-syslinux2cfg produces.
 +
 +It's somewhat difficult to portably canonicalize a path in shell, and
 +autoconf/automake don't offer any support for this.  But there's a much
 +simpler option: copy the test data to a temporary directory and make
 +substitutions in the expected output file based on that.
 +
 +Forwarded: http://lists.gnu.org/archive/html/grub-devel/2016-09/msg00013.html
 +Last-Update: 2016-09-19
 +
 +Patch-Name: syslinux-test-out-of-tree.patch
 +---
 + Makefile.am                            |  6 ------
++ tests/syslinux/ubuntu10.04_grub.cfg.in | 30 +++++++++++++++---------------
++ tests/syslinux_test.in                 | 14 ++++++++++----
 + 3 files changed, 25 insertions(+), 25 deletions(-)
 +
 +diff --git a/Makefile.am b/Makefile.am
 +index 7795baeb6..f0ab1adc3 100644
 +--- a/Makefile.am
 ++++ b/Makefile.am
 +@@ -473,9 +473,3 @@ ChangeLog: FORCE
 +      fi
 + 
 + EXTRA_DIST += ChangeLog ChangeLog-2015
 +-
 +-syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg
 +-
 +-tests/syslinux/ubuntu10.04_grub.cfg: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg.in
 +-     (for x in tests/syslinux/ubuntu10.04_grub.cfg.in ; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
 +-CLEANFILES += tests/syslinux/ubuntu10.04_grub.cfg
 +diff --git a/tests/syslinux/ubuntu10.04_grub.cfg.in b/tests/syslinux/ubuntu10.04_grub.cfg.in
 +index 846e4acf0..f285afb1e 100644
 +--- a/tests/syslinux/ubuntu10.04_grub.cfg.in
 ++++ b/tests/syslinux/ubuntu10.04_grub.cfg.in
 +@@ -1,4 +1,4 @@
 +-  background_image '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux'/'splash.png'
 ++  background_image '@dir@/ubuntu10.04/isolinux'/'splash.png'
 + # D-I config version 2.0
 +   # UNSUPPORTED command 'menu hshift 13'
 +   # UNSUPPORTED command 'menu width 49'
 +@@ -41,7 +41,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' {
 +   linux$linux_suffix '/'/'/install/mt86plus' 
 + }
 + menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/gtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux/gtk.cfg not found
 +   # UNSUPPORTED command 'menu begin advanced'
 +   # UNSUPPORTED command 'menu title Advanced options'
 +   # UNSUPPORTED command 'menu color title    * #FFFFFFFF *'
 +@@ -63,15 +63,15 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 + }
 + menuentry 'Back..' --hotkey 'b' --id 'mainmenu' {
 +   # UNSUPPORTED command 'menu exit'
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/adgtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux/adgtk.cfg not found
 +   # UNSUPPORTED command 'menu end'
 +   # UNSUPPORTED entry type 0
 + true;
 + }
 + menuentry 'Help' --hotkey 'h' --id 'help' {
 +   # UNSUPPORTED command 'ui gfxboot bootlogo'
 +-#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg:
 +-  background_image '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'splash.png'
 ++#'@dir@/ubuntu10.04/isolinux'/'prompt.cfg' (host)@dir@/ubuntu10.04/isolinux/prompt.cfg:
 ++  background_image '@dir@/ubuntu10.04/isolinux/'/'splash.png'
 +   # UNSUPPORTED command 'display f1.txt'
 +   # UNSUPPORTED command 'menu hshift 13'
 +   # UNSUPPORTED command 'menu width 49'
 +@@ -114,7 +114,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' {
 +   linux$linux_suffix '/'/'/install/mt86plus' 
 + }
 + menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//gtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux//gtk.cfg not found
 +   # UNSUPPORTED command 'menu begin advanced'
 +   # UNSUPPORTED command 'menu title Advanced options'
 +   # UNSUPPORTED command 'menu color title    * #FFFFFFFF *'
 +@@ -136,14 +136,14 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 + }
 + menuentry 'Back..' --hotkey 'b' --id 'mainmenu' {
 +   # UNSUPPORTED command 'menu exit'
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//adgtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux//adgtk.cfg not found
 +   # UNSUPPORTED command 'menu end'
 +   # UNSUPPORTED entry type 0
 + true;
 + }
 + menuentry 'Help' --hotkey 'h' --id 'help' {
 +-#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg:
 +-  syslinux_configfile -r '/'/'/' -c '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'' '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'prompt.cfg'
 ++#'@dir@/ubuntu10.04/isolinux/'/'prompt.cfg' (host)@dir@/ubuntu10.04/isolinux/prompt.cfg:
 ++  syslinux_configfile -r '/'/'/' -c '@dir@/ubuntu10.04/isolinux/'/'' '@dir@/ubuntu10.04/isolinux/'/'prompt.cfg'
 + }
 + menuentry 'menu' --id 'menu' {
 +   # UNSUPPORTED command 'f1 f1.txt'
 +@@ -156,8 +156,8 @@ menuentry 'menu' --id 'menu' {
 +   # UNSUPPORTED command 'f8 f8.txt'
 +   # UNSUPPORTED command 'f9 f9.txt'
 +   # UNSUPPORTED command 'f0 f10.txt'
 +-#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'isolinux.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg:
 +-  background_image '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'splash.png'
 ++#'@dir@/ubuntu10.04/isolinux/'/'isolinux.cfg' (host)@dir@/ubuntu10.04/isolinux/isolinux.cfg:
 ++  background_image '@dir@/ubuntu10.04/isolinux//'/'splash.png'
 + # D-I config version 2.0
 +   # UNSUPPORTED command 'menu hshift 13'
 +   # UNSUPPORTED command 'menu width 49'
 +@@ -200,7 +200,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' {
 +   linux$linux_suffix '/'/'/install/mt86plus' 
 + }
 + menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///gtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux///gtk.cfg not found
 +   # UNSUPPORTED command 'menu begin advanced'
 +   # UNSUPPORTED command 'menu title Advanced options'
 +   # UNSUPPORTED command 'menu color title    * #FFFFFFFF *'
 +@@ -222,15 +222,15 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' {
 + }
 + menuentry 'Back..' --hotkey 'b' --id 'mainmenu' {
 +   # UNSUPPORTED command 'menu exit'
 +-# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///adgtk.cfg not found
 ++# File (host)/@dir@/ubuntu10.04/isolinux///adgtk.cfg not found
 +   # UNSUPPORTED command 'menu end'
 +   # UNSUPPORTED entry type 0
 + true;
 + }
 + menuentry 'Help' --hotkey 'h' --id 'help' {
 +   # UNSUPPORTED command 'ui gfxboot bootlogo'
 +-#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg:
 +-  syslinux_configfile -r '/'/'/' -c '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'' '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'prompt.cfg'
 ++#'@dir@/ubuntu10.04/isolinux//'/'prompt.cfg' (host)@dir@/ubuntu10.04/isolinux/prompt.cfg:
 ++  syslinux_configfile -r '/'/'/' -c '@dir@/ubuntu10.04/isolinux//'/'' '@dir@/ubuntu10.04/isolinux//'/'prompt.cfg'
 + }
 + }
 + }
 +diff --git a/tests/syslinux_test.in b/tests/syslinux_test.in
 +index fc4edd8ef..4ba94c576 100644
 +--- a/tests/syslinux_test.in
 ++++ b/tests/syslinux_test.in
 +@@ -2,15 +2,21 @@
 + 
 + set -e
 + 
 ++tdir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
 + outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
 + 
 +-"@builddir@/grub-syslinux2cfg" -r "@abs_top_srcdir@/tests/syslinux/ubuntu10.04" "@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg" -o "$outfile"
 ++cp -a "@top_srcdir@/tests/syslinux/ubuntu10.04" "$tdir/ubuntu10.04"
 + 
 +-echo "$outfile"
 ++"@builddir@/grub-syslinux2cfg" -r "$tdir/ubuntu10.04" "$tdir/ubuntu10.04/isolinux/isolinux.cfg" -o "$tdir/observed.cfg"
 + 
 +-if ! diff -u "$outfile" "@builddir@/tests/syslinux/ubuntu10.04_grub.cfg"; then
 ++echo "$tdir/observed.cfg"
 ++
 ++sed -e "s,@dir@,$tdir,g" "@top_srcdir@/tests/syslinux/ubuntu10.04_grub.cfg.in" >"$tdir/expected.cfg"
 ++if ! diff -u "$tdir/observed.cfg" "$tdir/expected.cfg"; then
 +   echo "Mismatch in ubuntu10.04"
 +-  exit 1;
 ++  rm -rf "$tdir"
 ++  exit 1
 + fi
 + 
 ++rm -rf "$tdir"
 + exit 0
index b420c138b0d9cab527da7dfc539d1e370b75e12d,0000000000000000000000000000000000000000..a8d0846612192d9ab545499385fa06cf8a958895
mode 100644,000000..100644
--- /dev/null
@@@ -1,84 -1,0 +1,84 @@@
-  Makefile.util.def               |  6 +++++
-  util/grub.d/30_uefi-firmware.in | 46 +++++++++++++++++++++++++++++++++
 +From 78b220997f3f16b5d3bd351e5573fc2779cc2cfd Mon Sep 17 00:00:00 2001
 +From: Steve Langasek <steve.langasek@ubuntu.com>
 +Date: Mon, 13 Jan 2014 12:13:12 +0000
 +Subject: Output a menu entry for firmware setup on UEFI FastBoot systems
 +
 +Forwarded: no
 +Last-Update: 2015-09-04
 +
 +Patch-Name: uefi_firmware_setup.patch
 +---
- @@ -509,6 +509,12 @@ script = {
-    installdir = grubconf;
++ Makefile.util.def               |  6 ++++++
++ util/grub.d/30_uefi-firmware.in | 46 +++++++++++++++++++++++++++++++++++++++++
 + 2 files changed, 52 insertions(+)
 + create mode 100644 util/grub.d/30_uefi-firmware.in
 +
 +diff --git a/Makefile.util.def b/Makefile.util.def
 +index c939deb92..168acbe59 100644
 +--- a/Makefile.util.def
 ++++ b/Makefile.util.def
- +script = {
++@@ -510,6 +510,12 @@ script = {
 + };
 + 
-  script = {
++ script = {
 ++  name = '30_uefi-firmware';
 ++  common = util/grub.d/30_uefi-firmware.in;
 ++  installdir = grubconf;
 ++};
 ++
+++script = {
 +   name = '40_custom';
 +   common = util/grub.d/40_custom.in;
++   installdir = grubconf;
 +diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in
 +new file mode 100644
 +index 000000000..3c9f533d8
 +--- /dev/null
 ++++ b/util/grub.d/30_uefi-firmware.in
 +@@ -0,0 +1,46 @@
 ++#! /bin/sh
 ++set -e
 ++
 ++# grub-mkconfig helper script.
 ++# Copyright (C) 2012  Free Software Foundation, Inc.
 ++#
 ++# GRUB 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 3 of the License, or
 ++# (at your option) any later version.
 ++#
 ++# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 ++
 ++prefix="@prefix@"
 ++exec_prefix="@exec_prefix@"
 ++datarootdir="@datarootdir@"
 ++
 ++export TEXTDOMAIN=@PACKAGE@
 ++export TEXTDOMAINDIR="@localedir@"
 ++
 ++. "@datadir@/@PACKAGE@/grub-mkconfig_lib"
 ++
 ++efi_vars_dir=/sys/firmware/efi/vars
 ++EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c
 ++OsIndications="$efi_vars_dir/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE/data"
 ++
 ++if [ -e "$OsIndications" ] && \
 ++   [ "$(( $(printf 0x%x \'"$(cat $OsIndications | cut -b1)") & 1 ))" = 1 ]; then
 ++  LABEL="System setup"
 ++
 ++  gettext_printf "Adding boot menu entry for EFI firmware configuration\n" >&2
 ++
 ++  onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
 ++
 ++  cat << EOF
 ++menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' {
 ++     fwsetup
 ++}
 ++EOF
 ++fi