Compare commits

...

471 Commits

Author SHA1 Message Date
Daniel Kiper f678575ad9 Release 2.04
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Thomas Schmitt 56157556b6 docs: Document workaround for grub-mkrescue with older MacBooks
Add a description of the workaround for firmware of older MacBooks
which stalls with a grub-mkrescue ISO image for x86_64-efi target
on an USB stick.

Signed-off-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Eric Snowberg 16b648d95c docs: Bootstrap changes required for older distros
Some older distros do not contain gettext 0.18. Document the workaround
to use the bootstrap utility on these systems.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Leif Lindholm 21030a65de ia64: build fix in cache.h
Add IA64 to the architectures excluding a declaration for
grub_arch_sync_dma_caches().

IA64 does not include any of the source files that require the function,
but was overlooked for d8901e3ba1 ("cache: Fix compilation for ppc,
sparc and arm64").

Add it to the list of excluding architectures in order to not get
missing symbol errors when running grub-mkimage.

Reported-by: Alexander Graf <agraf@csgraf.de>
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Vladimir 'phcoder' Serbinenko 40d8754bd7 hostfs: #undef open and close.
Unlike in case of disks in this case it's just a single place, so it's easier
to just #undef

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
John Paul Adrian Glaubitz da3eb55d69 f2fs: Disable gcc9 -Waddress-of-packed-member
Disable the -Wadress-of-packaed-member diagnostic for the grub_f2fs_label
function since the result is found to be false postive.

A pointer to the 'volume_name' member of 'struct grub_f2fs_superblock' is
guaranteed to be aligned as the offset of 'volume_name' within the struct
is dividable by the natural alignment on both 32- and 64-bit targets.

grub-core/fs/f2fs.c: In function ‘grub_f2fs_label’:
grub-core/fs/f2fs.c:1253:60: error: taking address of packed member of ‘struct grub_f2fs_superblock’ may result in an unaligned pointer value [-Werror=address-of-packed-member]
 1253 |     *label = (char *) grub_f2fs_utf16_to_utf8 (data->sblock.volume_name);
      |                                                ~~~~~~~~~~~~^~~~~~~~~~~~
cc1: all warnings being treated as errors

Reported-by: Neil MacLeod <neil@nmacleod.com>
Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Tested-by: Neil MacLeod <neil@nmacleod.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Vincent Legoll f2bb98e1ef grub-mkrescue: Fix error message about the wrong command having failed: mformat instead of mcopy
Signed-off-by: Vincent Legoll <vincent.legoll@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Mathieu Trudel-Lapierre 407f685d5d video: skip 'text' gfxpayload if not supported, to fallback to default
On UEFI, 'text' gfxpayload is not supported, but we still reach parse_modespec()
with it, which will obviously fail. Fortunately, whatever gfxpayload is set,
we still still have the 'auto' default to fall back to. Allow getting to this
fallback by not trying to parse 'text' as a modespec.

This is because 'text' correctly doesn't parse as a modespec, and ought to have
been ignored before we got to that point, just like it is immediately picked if
we're running on a system where 'text' is a supported video mode.

Bug: https://savannah.gnu.org/bugs/index.php?56217

Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Ovidiu Panait 1c4e3f0347 grub-mkconfig: Use -c instead of --printf for stat
"--printf" only works with the stat variant provided by coreutils.

With busybox, stat will fail with the following error:
stat: unrecognized option '--printf=%T'

Usage: stat [OPTIONS] FILE...

Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 16607eba81 f2fs: Fix gcc9 error -Werror=maybe-uninitialized
The function grub_get_node_path() could return uninitialized offset with
level == 0 if the block is greater than direct_index + 2 * direct_blks +
2 * indirect_blks + dindirect_blks. The uninitialized offset is then used
by function grub_f2fs_get_block() because level == 0 is valid and
meaningful return to be processed.

The fix is to set level = -1 as return value by grub_get_node_path() to
signify an error that the input block cannot be handled. Any caller
should therefore check level is negative or not before processing the
output.

Reported-by: Neil MacLeod <neil@nmacleod.com>
Signed-off-by: Michael Chang <mchang@suse.com>
Tested-by: Neil MacLeod <neil@nmacleod.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Alexander Graf acb3cd33f1 arm: Align section alignment with manual relocation offset code
The arm relocation code has a manual special case for EFI binaries to
add the natural alignment to its own relocation awareness.

Since commit a51f953f4e ("mkimage: Align efi sections on 4k
boundary") we changed that alignment from 0x400 to 0x1000 bytes. Reflect
the change in that branch that we forgot as well.

This fixes running 32bit arm grub efi binaries for me again.

Fixes: a51f953f4e ("mkimage: Align efi sections on 4k boundary")
Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reported-by: Steve McIntyre <steve@einval.com>
Signed-off-by: Alexander Graf <agraf@csgraf.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Julien ROBIN <julien.robin28@free.fr>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Alexander Graf 497438f0f5 arm: Move trampolines into code section
When creating T32->A32 transition jumps, the relocation code in grub
will generate trampolines. These trampolines live in the .data section
of our PE binary which means they are not marked as executable.

This misbehavior was unmasked by commit a51f953f4e ("mkimage: Align
efi sections on 4k boundary") which made the X/NX boundary more obvious
because everything became page aligned.

To put things into proper order, let's move the arm trampolines into the
.text section instead. That way everyone knows they are executable.

Fixes: a51f953f4e ("mkimage: Align efi sections on 4k boundary")
Reported-by: Julien ROBIN <julien.robin28@free.fr>
Reported-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Alexander Graf <agraf@csgraf.de>
Tested-by: Julien ROBIN <julien.robin28@free.fr>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 35e918e7c9 efi: Fix gcc9 error -Waddress-of-packed-member
The address of fp->path_name could be unaligned since seeking into the
device path buffer for a given node could end in byte boundary.

The fix is allocating aligned buffer by grub_malloc for holding the
UTF16 string copied from fp->path_name, and after using that buffer as
argument for grub_utf16_to_utf8 to convert it to UTF8 string.

[  255s] ../../grub-core/kern/efi/efi.c: In function 'grub_efi_get_filename':
[  255s] ../../grub-core/kern/efi/efi.c:410:60: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  255s]   410 |    p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
[  255s]       |                                                          ~~^~~~~~~~~~~
[  255s] ../../grub-core/kern/efi/efi.c: In function 'grub_efi_print_device_path':
[  255s] ../../grub-core/kern/efi/efi.c:900:33: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  255s]   900 |     *grub_utf16_to_utf8 (buf, fp->path_name,
[  255s]       |                               ~~^~~~~~~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 9093277187 chainloader: Fix gcc9 error -Waddress-of-packed-member
The address of fp->path_name could be unaligned since seeking into the
device path buffer for a given node could end in byte boundary.

The fix is using aligned buffer allocated by grub_malloc for receiving
the converted UTF16 string by grub_utf8_to_utf16 and also the processing
after. The resulting string then gets copied to fp->path_name.

[  243s] ../../grub-core/loader/efi/chainloader.c: In function 'copy_file_path':
[  243s] ../../grub-core/loader/efi/chainloader.c:136:32: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  243s]   136 |   size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8,
[  243s]       |                              ~~^~~~~~~~~~~
[  243s] ../../grub-core/loader/efi/chainloader.c:138:12: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  243s]   138 |   for (p = fp->path_name; p < fp->path_name + size; p++)
[  243s]       |            ^~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 01ef6d09db usbtest: Disable gcc9 -Waddress-of-packed-member
Disable the -Wadress-of-packaed-member diagnostic for the
grub_usb_get_string function since the result is false postive. The
descstrp->str is found to be aligned in the buffer allocated for 'struct
grub_usb_desc_str'.

[  229s] ../../grub-core/commands/usbtest.c: In function 'grub_usb_get_string':
[  229s] ../../grub-core/commands/usbtest.c:104:58: error: taking address of packed member of 'struct grub_usb_desc_str' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  229s]   104 |   *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
[  229s]       |                                                  ~~~~~~~~^~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 7503171eea acpi: Fix gcc9 error -Waddress-of-packed-member
Simply adds the missing packed attribute to 'struct grub_acpi_madt'.

[  233s] ../../grub-core/commands/lsacpi.c: In function 'disp_acpi_xsdt_table':
[  233s] ../../grub-core/commands/lsacpi.c:201:27: error: converting a packed 'struct grub_acpi_table_header' pointer (alignment 1) to a 'struct grub_acpi_madt' pointer (alignment 4) may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  233s]   201 |  disp_madt_table ((struct grub_acpi_madt *) t);
[  233s]       |                           ^~~~~~~~~~~~~~
[  233s] In file included from ../../grub-core/commands/lsacpi.c:23:
[  233s] ../../include/grub/acpi.h:50:8: note: defined here
[  233s]    50 | struct grub_acpi_table_header
[  233s]       |        ^~~~~~~~~~~~~~~~~~~~~~
[  233s] ../../include/grub/acpi.h:90:8: note: defined here
[  233s]    90 | struct grub_acpi_madt
[  233s]       |        ^~~~~~~~~~~~~~
[  233s] ../../grub-core/commands/lsacpi.c: In function 'disp_acpi_rsdt_table':
[  233s] ../../grub-core/commands/lsacpi.c:225:27: error: converting a packed 'struct grub_acpi_table_header' pointer (alignment 1) to a 'struct grub_acpi_madt' pointer (alignment 4) may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  233s]   225 |  disp_madt_table ((struct grub_acpi_madt *) t);
[  233s]       |                           ^~~~~~~~~~~~~~
[  233s] In file included from ../../grub-core/commands/lsacpi.c:23:
[  233s] ../../include/grub/acpi.h:50:8: note: defined here
[  233s]    50 | struct grub_acpi_table_header
[  233s]       |        ^~~~~~~~~~~~~~~~~~~~~~
[  233s] ../../include/grub/acpi.h:90:8: note: defined here
[  233s]    90 | struct grub_acpi_madt
[  233s]       |        ^~~~~~~~~~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang b0f3e50964 hfsplus: Fix gcc9 error with -Waddress-of-packed-member
The catkey->name could be unaligned since the address of 'void* record'
is calculated as offset in bytes to a malloc buffer.

The fix is using aligned buffer allocated by grub_malloc for holding
the UTF16 string copied from catkey->name. And use that buffer as
argument for grub_utf16_to_utf8 to convert to UTF8 strings.

In addition, using a new copy of buffer rather than catkey->name itself
for processing the endianess conversion, we can also get rid of the hunk
restoring byte order of catkey->name to what it was previously.

[   59s] ../grub-core/fs/hfsplus.c: In function 'list_nodes':
[   59s] ../grub-core/fs/hfsplus.c:738:57: error: taking address of packed member of 'struct grub_hfsplus_catkey' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]   738 |   *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
[   59s]       |                                                   ~~~~~~^~~~~~
[   59s] ../grub-core/fs/hfsplus.c: In function 'grub_hfsplus_label':
[   59s] ../grub-core/fs/hfsplus.c:1019:57: error: taking address of packed member of 'struct grub_hfsplus_catkey' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]  1019 |   *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name,
[   59s]       |                                                   ~~~~~~^~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang c69d36c9d7 hfs: Fix gcc9 error -Waddress-of-packed-member
Simply adds the missing packed attribute to 'struct grub_hfs_extent'.

[   83s] ../grub-core/fs/hfs.c: In function 'grub_hfs_iterate_records':
[   83s] ../grub-core/fs/hfs.c:699:9: error: taking address of packed member of 'struct grub_hfs_sblock' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   83s]   699 |      ? (&data->sblock.catalog_recs)
[   83s]       |        ~^~~~~~~~~~~~~~~~~~~~~~~~~~~
[   83s] ../grub-core/fs/hfs.c:700:9: error: taking address of packed member of 'struct grub_hfs_sblock' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   83s]   700 |      : (&data->sblock.extent_recs));
[   83s]       |        ~^~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang 3b68544cc7 jfs: Disable gcc9 -Waddress-of-packed-member
Disable the -Wadress-of-packaed-member diagnostic for the
grub_jfs_getent function since the result is found to be false postive.

The leaf is read into memory as continous chunks in size of 32 bytes and
the pointer to its base is aligned, which also guarentee its member
leaf->namepart is aligned.

[   60s] ../grub-core/fs/jfs.c: In function 'grub_jfs_getent':
[   60s] ../grub-core/fs/jfs.c:557:44: error: taking address of packed member of 'struct grub_jfs_leaf_dirent' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   60s]   557 |   le_to_cpu16_copy (filename + strpos, leaf->namepart, len < diro->data->namecomponentlen ? len
[   60s]       |                                        ~~~~^~~~~~~~~~
[   60s] ../grub-core/fs/jfs.c:570:48: error: taking address of packed member of 'struct grub_jfs_leaf_next_dirent' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   60s]   570 |  le_to_cpu16_copy (filename + strpos, next_leaf->namepart, len < 15 ? len : 15);
[   60s]       |                                       ~~~~~~~~~^~~~~~~~~~
[   60s] cc1: all warnings being treated as errors

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Michael Chang a8b71f2d90 cpio: Disable gcc9 -Waddress-of-packed-member
Disable the -Wadress-of-packaed-member diagnostic for the
grub_cpio_find_file function since the result is found to be false
postive. Any pointers to member of the 'struct head hd' is aligned even
if the structure is packed without paddings.

[   59s] In file included from ../grub-core/fs/cpio.c:51:
[   59s] ../grub-core/fs/cpio_common.c: In function 'grub_cpio_find_file':
[   59s] ../grub-core/fs/cpio_common.c:58:31: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    58 |   data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
[   59s]       |                             ~~^~~~~~~~~
[   59s] ../grub-core/fs/cpio_common.c:60:29: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    60 |     *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
[   59s]       |                           ~~^~~~~~
[   59s] ../grub-core/fs/cpio_common.c:61:28: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    61 |   modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
[   59s]       |                          ~~^~~~~
[   59s] ../grub-core/fs/cpio_common.c:62:29: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    62 |   namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
[   59s]       |                           ~~^~~~~~~~~
[   59s] In file included from ../grub-core/fs/cpio_be.c:51:
[   59s] ../grub-core/fs/cpio_common.c: In function 'grub_cpio_find_file':
[   59s] ../grub-core/fs/cpio_common.c:58:31: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    58 |   data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
[   59s]       |                             ~~^~~~~~~~~
[   59s] ../grub-core/fs/cpio_common.c:60:29: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    60 |     *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
[   59s]       |                           ~~^~~~~~
[   59s] ../grub-core/fs/cpio_common.c:61:28: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    61 |   modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
[   59s]       |                          ~~^~~~~
[   59s] ../grub-core/fs/cpio_common.c:62:29: error: taking address of packed member of 'struct head' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[   59s]    62 |   namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
[   59s]       |                           ~~^~~~~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Heinrich Schuchardt 7195688f47 efi: Avoid NULL dereference if FilePath is NULL
The UEFI specification allows LoadImage() to be called with a memory
location only and without a device path. In this case FilePath will not be
set in the EFI_LOADED_IMAGE_PROTOCOL.

So in function grub_efi_get_filename() the device path argument may be
NULL. As we cannot determine the device path in this case just return NULL
from the function.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Daniel Kiper bf8e8cc6f0 x86/msr: Fix build with older GCC versions
Some older GCC versions produce following error when x86 MSR modules are build:

  In file included from commands/i386/rdmsr.c:29:0:
  ../include/grub/i386/rdmsr.h:27:29: error: no previous prototype for ‘grub_msr_read’ [-Werror=missing-prototypes]
   extern inline grub_uint64_t grub_msr_read (grub_uint32_t msr_id)
                               ^
  cc1: all warnings being treated as errors

This happens due to lack of support for a such usage of extern keyword
in older GCCs. Additionally, this usage is not consistent with the rest
of codebase. So, replace it with static keyword.

Additionally, fix incorrect coding style.

Reported-by: Eric Snowberg <eric.snowberg@oracle.com>
Reported-by: adrian15 <adrian15sgd@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Reviewed-by: Eric Snowberg <eric.snowberg@oracle.com>
Tested-by: adrian15 <adrian15sgd@gmail.com>
2020-09-21 20:05:48 -04:00
Vladimir Serbinenko ca187ab825 Release 2.04~rc1 2020-09-21 20:05:48 -04:00
Vladimir Serbinenko afeb7b4bd9 Change fs functions to add fs_ prefix
This avoid conflict with gnulib

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:05:48 -04:00
Vladimir Serbinenko 08452decc8 A workaround for clang problem assembling startup_raw.S
Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:00:17 -04:00
Eric Snowberg d51d7d538e ieee1275: NULL pointer dereference in grub_ieee1275_encode_devname()
Function grub_strndup() may return NULL, this is called from
function grub_ieee1275_get_devname() which is then called from
function grub_ieee1275_encode_devname() to set device. The device
variable could then be used with a NULL pointer.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 20:00:17 -04:00
Daniel Kiper 1d1da9e31b docs/grub-dev: Change comments rules
Current comments forms are annoying, so, some of them are disallowed
starting from now. New rules are more flexible and mostly aligned
with, e.g., Linux kernel comments rules.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 20:00:17 -04:00
Andrew Jeddeloh f9b054242e loader/i386/linux: Calculate the setup_header length
Previously the setup_header length was just assumed to be the size of the
linux_kernel_params struct. The linux x86 32-bit boot protocol says that the
end of the linux_i386_kernel_header is at 0x202 + the byte value at 0x201 in
the linux_i386_kernel_header. So, calculate the size of the header using the
end of the linux_i386_kernel_header, rather than assume it is the size of the
linux_kernel_params struct.

Additionally, add some required members to the linux_kernel_params
struct and align the content of linux_i386_kernel_header struct with
it. New members naming was taken directly from Linux kernel source.

linux_kernel_params and linux_i386_kernel_header structs require more
cleanup. However, this is not urgent, so, let's do this after release.
Just in case...

Signed-off-by: Andrew Jeddeloh <andrew.jeddeloh@coreos.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 20:00:17 -04:00
Eric Snowberg 28031a0791 efidisk: NULL pointer dereference in grub_efidisk_get_device_name()
Function grub_efi_find_last_device_path() may return NULL when called
from grub_efidisk_get_device_name().

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Eric Snowberg 3ed79c36da efidisk: NULL pointer dereference in is_child()
Function grub_efi_find_last_device() path may return NULL when called
from is_child().

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Eric Snowberg 3d8f6ea345 efidisk: Write to NULL pointer ldp
Function grub_efi_find_last_device_path() may return constant NULL when
called from find_parent_device().

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 77ba219376 clang: Pair -Qn with -Qunused-arguments.
When assembling module wirh clang -Qn ends up on command line but later ignored
To avoid it breaking the compile, add -Qunused-arguments.

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
John Paul Adrian Glaubitz ffa8d2c75b ieee1275: Fix path reference in comment of sparc64 boot loader code
Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
John Paul Adrian Glaubitz 8146f22eba ieee1275: Include a.out header in assembly of sparc64 boot loader
Recent versions of binutils dropped support for the a.out and COFF
formats on sparc64 targets. Since the boot loader on sparc64 is
supposed to be an a.out binary and the a.out header entries are
rather simple to calculate in our case, we just write the header
ourselves instead of relying on external tools to do that.

Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 997ca85f0a Propagate GNU_PRINTF from gnulib vfprintf
gnulib now replaces vfprintf and hence its format becomes GNU_PRINTF format

This also fixes matching definitions to always use GNU format

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko a2867b7cc3 efi/tpm.c: Add missing casts
Without those casts we get a warning about implicit conversion of pointer
to integer.

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 335f57a915 POTFILES: Don't include gnulib in grub.pot
They're translated as a separate project, so we
don't want to submit them again.

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 9763a619a9 configure.ac: Use nostdlib when checking for nostdinc
With clang nostdinc behaviour is influenced by nostdlib. Since we
always add nostdlib, add it in test as well

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 42786d0f4d efi/tpm.h: Fix hash_log_extend_event definition.
I didn't check the spec but pointer to address doesn't make much sense
and doesn't match the code.

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko f762850a1c Rename grub_disk members
Otherwise it horribly clashes with gnulib when it's
replacing open/write/read/close

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 4745ee216c grub-mkimagexx: Fix RISCV error message
Outputting a raw pointer doesn't match the format and is
also useless. Output offset instead.

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 59e9844792 kern/emu/misc.c: Don't include config-util.h when running as GRUB_BUILD
Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Vladimir Serbinenko 28e02c29eb Support R_PPC_PLTREL24
It's emitted by clang 7. It's the same as R_PPC_REL24.

Signed-off-by: Vladimir Serbinenko <phcoder@google.com>
2020-09-21 19:37:19 -04:00
Daniel Kiper d422df6711 sparc: Enable __clzsi2() and __clzdi2()
This patch is similiar to commit e795b9011 (RISC-V: Add libgcc helpers
for clz) but for SPARC target.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 19:37:19 -04:00
Daniel Kiper 9c4c933f05 mips: Enable __clzsi2()
This patch is similiar to commit e795b9011 (RISC-V: Add libgcc helpers
for clz) but for MIPS target.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 19:37:19 -04:00
Daniel Kiper bd0f543cc3 verifiers: MIPS fallout cleanup
MIPS fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines).

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 19:37:19 -04:00
Daniel Kiper 12fafad345 verifiers: PowerPC fallout cleanup
PowerPC fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines) and ca0a4f689 (verifiers: File
type for fine-grained signature-verification controlling).

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 19:37:19 -04:00
Daniel Kiper 9681197098 verifiers: IA-64 fallout cleanup
IA-64 fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines).

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 19:37:19 -04:00
Colin Watson ab9b6c43ab posix_wrap: Flesh out posix_wrap/limits.h a little more
In addition to what was already there, Gnulib's <intprops.h> needs SCHAR_MIN,
SCHAR_MAX, SHRT_MIN, INT_MIN, LONG_MIN, and LONG_MAX. Fixes build on CentOS 7.

Reported-by: "Chen, Farrah" <farrah.chen@intel.com>
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Marek Marczykowski-Górecki ebc4b92fc0 xen: Look for Xen notes in section headers too
Mirror behaviour of ELF loader in libxc: first look for Xen notes in
PT_NOTE segment, then in SHT_NOTE section and only then fallback to
a section with __xen_guest name. This fixes loading PV kernels that
Xen note have outside of PT_NOTE. While this may be result of a buggy
linker script, loading such kernel directly works fine, so make it work
with GRUB too. Specifically, this applies to binaries built from Unikraft.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Colin Watson a2665bd0a4 getroot: Save/restore CWD more reliably on Unix
Various GRUB utilities fail if the current directory doesn't exist,
because grub_find_device() chdirs to a different directory and then
fails when trying to chdir back.  Gnulib's save-cwd module uses fchdir()
instead when it can, avoiding this category of problem.

Fixes Debian bug #918700.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Andrei Borzenkov 07b96482c4 net/dhcp: Add explicit net_dhcp command
Mostly for cosmetic reasons, we add a "net_dhcp" command, which is (at the
moment) identical to the existing "net_bootp" command. Both actually trigger
a DHCP handshake now, and both should be able to deal with pure BOOTP servers.
We could think about dropping the DHCP options from the initial DISCOVER packet
when the user issues the net_bootp command, but it's unclear whether this is
really useful, as both protocols should be able to coexist.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:19 -04:00
Andrei Borzenkov 723c3174e4 net/dhcp: Actually send out DHCPv4 DISCOVER and REQUEST messages
Even though we were parsing some DHCP options sent by the server, so far
we are only using the BOOTP 2-way handshake, even when talking to a DHCP
server.

Change this by actually sending out DHCP DISCOVER packets instead of the
generic (mostly empty) BOOTP BOOTREQUEST packets.

A pure BOOTP server would ignore the extra DHCP options in the DISCOVER
packet and would just reply with a BOOTREPLY packet, which we also
handle in the code.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:37:18 -04:00
Andrei Borzenkov ada2f6d40c net/dhcp: Allow receiving DHCP OFFER and ACK packets
In respone to a BOOTREQUEST packet a BOOTP server would answer with a BOOTREPLY
packet, which ends the conversation for good. DHCP uses a 4-way handshake,
where the initial server respone is an OFFER, which has to be answered with
REQUEST by the client again, only to be completed by an ACKNOWLEDGE packet
from the server.

Teach the grub_net_process_dhcp() function to deal with OFFER packets,
and treat ACK packets the same es BOOTREPLY packets.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:19:36 -04:00
Andrei Borzenkov 1157a45292 net/dhcp: Use DHCP options for name and bootfile
The BOOTP RFC describes the boot file name and the server name as being part
of the integral BOOTP data structure, with some limits on the size of them.
DHCP extends this by allowing them to be separate DHCP options, which is more
flexible.

Teach the code dealing with those fields to check for those DHCP options first
and use this information, if provided. We fall back to using the BOOTP
information if those options are not used.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:19:36 -04:00
Andrei Borzenkov 6767cde642 net/dhcp: Introduce per-interface timeout
Currently we have a global timeout for all network cards in the BOOTP/DHCP
discovery process.

Make this timeout a per-interface one, so better accommodate the upcoming
4-way DHCP handshake and to also cover the lease time limit a DHCP offer
will come with.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:19:36 -04:00
Andrei Borzenkov 4013ed17a3 net/dhcp: Make grub_net_process_dhcp() take an interface
Change the interface of the function dealing with incoming BOOTP packets
to take an interface instead of a card, to allow more fine per-interface
state (timeout, handshake state) later on.

Use the opportunity to clean up the code a bit.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:19:36 -04:00
Andrei Borzenkov f8da4f6154 net/dhcp: Refactor DHCP packet transmission into separate function
In contrast to BOOTP, DHCP uses a 4-way handshake, so requires to send
packets more often.

Refactor the generation and sending of the BOOTREQUEST packet into
a separate function, so that future code can more easily reuse this.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 19:19:36 -04:00
Andrei Borzenkov 6c0969eed5 net/dhcp: Allow overloading legacy bootfile and name field
DHCP specifies a special dummy option OVERLOAD, to allow DHCP options to
spill over into the (legacy) BOOTFILE and SNAME fields.

Parse and handle this option properly.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:58:21 -04:00
Andrei Borzenkov 6c38b920c8 net/dhcp: Replace parse_dhcp_vendor() with find_dhcp_option()
For proper DHCP support we will need to parse DHCP options from a packet
more often and at various places.

Refactor the option parsing into a new function, which will scan a packet to
find *a particular* option field. Use that new function in places where we
were dealing with DHCP options before.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:56:11 -04:00
Andrei Borzenkov 526fa11df7 net/dhcp: Remove dead code
The comment is right, the "giaddr" fields holds the IP address of the BOOTP
relay, not a general purpose router address. Just remove the commented code,
archeologists can find it in the git history.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:52:54 -04:00
Jesús Diéguez Fernández a728cd4d1d msr: Add new MSR modules (rdmsr/wrmsr)
In order to be able to read from and write to model-specific registers,
two new modules are added. They are i386 specific, as the cpuid module.

rdmsr module registers the command rdmsr that allows reading from a MSR.
wrmsr module registers the command wrmsr that allows writing to a MSR.

wrmsr module is disabled if UEFI secure boot is enabled.

Please note that on SMP systems, interacting with a MSR that has a scope
per hardware thread, implies that the value only applies to the
particular cpu/core/thread that ran the command.

Also, if you specify a reserved or unimplemented MSR address, it will
cause a general protection exception (which is not currently being
handled) and the system will reboot.

Signed-off-by: Jesús Diéguez Fernández <jesusdf@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:52:54 -04:00
Jesús Diéguez Fernández 8d417db48d asm: Replace "__asm__ __volatile__" with "asm volatile"
In order to maintain the coding style consistency, it was requested to
replace the methods that use "__asm__ __volatile__" with "asm volatile".

Signed-off-by: Jesús Diéguez Fernández <jesusdf@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:44:29 -04:00
Eric Snowberg 927267be58 sparc64: Add bios boot partition support
Add BIOS Boot Partition support for sparc64 platforms.  This will work a
little different than x86.  With GPT, both the OBP "load" and "boot" commands
are partition aware and neither command can see the partition table.  Therefore
the entire boot-loader is stored within the BIOS Boot Partition and nothing
is stored within the bootstrap code area of MBR.

To use it, the end user will issue the boot command with the path pointing to
the BIOS Boot Partition.

For example with the disk below:

Model: Unknown (unknown)
Disk /dev/nvme1n1: 1600GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
1      1049kB  1075MB  1074MB   ext3
2      1075MB  1076MB  1049kB                     bios_grub
3      1076MB  1600GB  1599GB                     lvm

To boot grub2 from OBP, you would use:

boot /pci@302/pci@1/pci@0/pci@13/nvme@0/disk@1:b

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:44:29 -04:00
Eric Snowberg a492f4ebdb ieee1275: obdisk driver
Add a new disk driver called obdisk for IEEE1275 platforms.  Currently
the only platform using this disk driver is SPARC, however other IEEE1275
platforms could start using it if they so choose.  While the functionality
within the current IEEE1275 ofdisk driver may be suitable for PPC and x86, it
presented too many problems on SPARC hardware.

Within the old ofdisk, there is not a way to determine the true canonical
name for the disk.  Within Open Boot, the same disk can have multiple names
but all reference the same disk.  For example the same disk can be referenced
by its SAS WWN, using this form:

/pci@302/pci@2/pci@0/pci@17/LSI,sas@0/disk@w5000cca02f037d6d,0

It can also be referenced by its PHY identifier using this form:

/pci@302/pci@2/pci@0/pci@17/LSI,sas@0/disk@p0

It can also be referenced by its Target identifier using this form:

/pci@302/pci@2/pci@0/pci@17/LSI,sas@0/disk@0

Also, when the LUN=0, it is legal to omit the ,0 from the device name.  So with
the disk above, before taking into account the device aliases, there are 6 ways
to reference the same disk.

Then it is possible to have 0 .. n device aliases all representing the same disk.
Within this new driver the true canonical name is determined using the the
IEEE1275 encode-unit and decode-unit commands when address_cells == 4.  This
will determine the true single canonical name for the device so multiple ihandles
are not opened for the same device.  This is what frequently happens with the old
ofdisk driver.  With some devices when they are opened multiple times it causes
the entire system to hang.

Another problem solved with this driver is devices that do not have a device
alias can be booted and used within GRUB. Within the old ofdisk, this was not
possible, unless it was the original boot device.  All devices behind a SAS
or SCSI parent can be found.   Within the old ofdisk, finding these disks
relied on there being an alias defined.  The alias requirement is not
necessary with this new driver.  It can also find devices behind a parent
after they have been hot-plugged.  This is something that is not possible
with the old ofdisk driver.

The old ofdisk driver also incorrectly assumes that the device pointing to by a
device alias is in its true canonical form. This assumption is never made with
this new driver.

Another issue solved with this driver is that it properly caches the ihandle
for all open devices.  The old ofdisk tries to do this by caching the last
opened ihandle.  However this does not work properly because the layer above
does not use a consistent device name for the same disk when calling into the
driver.  This is because the upper layer uses the bootpath value returned within
/chosen, other times it uses the device alias, and other times it uses the
value within grub.cfg.  It does not have a way to figure out that these devices
are the same disk.  This is not a problem with this new driver.

Due to the way GRUB repeatedly opens and closes the same disk. Caching the
ihandle is important on SPARC.  Without caching, some SAS devices can take
15 - 20 minutes to get to the GRUB menu. This ihandle caching is not possible
without correctly having the canonical disk name.

When available, this driver also tries to use the deblocker #blocks and
a way of determining the disk size.

Finally and probably most importantly, this new driver is also capable of
seeing all partitions on a GPT disk.  With the old driver, the GPT
partition table can not be read and only the first partition on the disk
can be seen.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:44:29 -04:00
Paul Menzel 1a2494b7c7 Makefile: Allow to set file systems modules for default_payload.elf
By default all file system modules are added to the GRUB coreboot
payload `default_payload.elf`. This makes the image quite big,
especially as often not all modules are needed.

Introduce the variable `FS_PAYLOAD_MODULES`, which can be used to
explicitly set file systems modules to be added.

    $ make default_payload.elf
    test -f default_payload.elf && rm default_payload.elf || true
    pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o default_payload.elf --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu affs afs bfs btrfs cbfs cpio cpio_be exfat ext2 f2fs fat hfs hfsplus iso9660 jfs minix minix2 minix2_be minix3 minix3_be minix_be newc nilfs2 ntfs odc procfs reiserfs romfs sfs squash4 tar udf ufs1 ufs1_be ufs2 xfs zfs password_pbkdf2 ' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=./coreboot.cfg
    $ ls -l default_payload.elf
    -rw-rw---- 1 joey joey 1199568 Mar  6 13:58 default_payload.elf

    $ make default_payload.elf FS_PAYLOAD_MODULES="" # ext2 already in `--modules`
    test -f default_payload.elf && rm default_payload.elf || true
    pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o default_payload.elf --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu  password_pbkdf2 ' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=./coreboot.cfg
    $ ls -l default_payload.elf
    -rw-rw---- 1 joey joey 832976 Mar  7 12:13 default_payload.elf

So, the resulting payload size is around 370 kB smaller. (Adding it to
the CBFS, it will be compressed, so the effective size difference will
be smaller.)

Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:44:29 -04:00
Vladimir Serbinenko 96dc8a6e2a windows/platform.c: Fix compilation errors 2020-09-21 16:44:29 -04:00
Colin Watson 4517db3592 gnulib: Upgrade Gnulib and switch to bootstrap tool
Upgrade Gnulib files to 20190105.

It's much easier to maintain GRUB's use of portability support files
from Gnulib when the process is automatic and driven by a single
configuration file, rather than by maintainers occasionally running
gnulib-tool and committing the result.  Removing these
automatically-copied files from revision control also removes the
temptation to hack the output in ways that are difficult for future
maintainers to follow.  Gnulib includes a "bootstrap" program which is
designed for this.

The canonical way to bootstrap GRUB from revision control is now
"./bootstrap", but "./autogen.sh" is still useful if you just want to
generate the GRUB-specific parts of the build system.

GRUB now requires Autoconf >= 2.63 and Automake >= 1.11, in line with
Gnulib.

Gnulib source code is now placed in grub-core/lib/gnulib/ (which should
not be edited directly), and GRUB's patches are in
grub-core/lib/gnulib-patches/.  I've added a few notes to the developer
manual on how to maintain this.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:44:29 -04:00
Colin Watson 4b36a84bb1 syslinux: Fix syslinux_test in out-of-tree builds
syslinux_parse simplifies some filenames by removing things like ".."
segments, but the tests assumed that @abs_top_srcdir@ would be
untouched, which is not true in the case of out-of-tree builds where
@abs_top_srcdir@ may contain ".." segments.

Performing the substitution requires some awkwardness in Makefile.am due
to details of how config.status works.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Colin Watson 440ba4b011 util: Detect more I/O errors
Many of GRUB's utilities don't check anywhere near all the possible
write errors.  For example, if grub-install runs out of space when
copying a file, it won't notice.  There were missing checks for the
return values of write, fflush, fsync, and close (or the equivalents on
other OSes), all of which must be checked.

I tried to be consistent with the existing logging practices of the
various hostdisk implementations, but they weren't entirely consistent
to start with so I used my judgement.  The result at least looks
reasonable on GNU/Linux when I provoke a write error:

  Installing for x86_64-efi platform.
  grub-install: error: cannot copy `/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed' to `/boot/efi/EFI/debian/grubx64.efi': No space left on device.

There are more missing checks in other utilities, but this should fix
the most critical ones.

Fixes Debian bug #922741.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
James Clarke 0726ab2d54 osdep/freebsd: Fix partition calculation for EBR entries
For EBR partitions, "start" is the relative starting sector of the EBR
header itself, whereas "offset" is the relative starting byte of the
partition's contents, excluding the EBR header and any padding. Thus we
must use "offset", and divide by the sector size to convert to sectors.

Fixes Debian bug #923253.

Signed-off-by: James Clarke <jrtc27@jrtc27.com>
Reviewed-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Steve McIntyre c28c107e24 grub-install: Check for arm-efi as a default target
Much like on x86, we can work out if the system is running on top of EFI
firmware. If so, return "arm-efi". If not, fall back to "arm-uboot" as
previously.

Split out the code to (maybe) load the efivar module and check for
/sys/firmware/efi into a common helper routine is_efi_system().

Signed-off-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Daniel Kiper efdfac9e2f Revert "grub-install: Check for arm-efi as a default target"
This reverts commit 082fd84d52.

Incorrect version of the patch was pushed into the git repo.

Reported-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Alexander Graf 18f824dd18 travis: Add Travis CI config file
There is a really convenient service for open source project from Travis
CI: They allow for free CI testing using their infrastructure.

GRUB has had issues with broken builds for various targets for a long time
already. The main reason is a lack of CI to just do smoke tests on whether
all targets still at least compile.

This patch adds a Travis config file which builds (almost) all currently
available targets.

On top of that, this Travis config also runs a small execution test on the
x86_64-efi target.

All of this config file can easily be extended further on. It probably
makes sense to do something similar to the u-boot test infrastructure
that communicates with the payload properly. Going forward, we also will
want to do more QEMU runtime checks for other targets.

Currently, with this config alone, I already see about half of the available
targets as broken. So it's definitely desperately needed :).

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Steve McIntyre 65a251af6f grub-install: Check for arm-efi as a default target
Much like on x86, we can work out if the system is running on top
of EFI firmware. If so, return "arm-efi". If not, fall back to
"arm-uboot" as previously.

Heavily inspired by the existing code for x86.

Signed-off-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:55 -04:00
Leif Lindholm 38854336c2 arm64/efi: Fix grub_efi_get_ram_base()
grub_efi_get_ram_base() looks for the lowest available RAM address by
traversing the memory map, comparing lowest address found so far.
Due to a brain glitch, that "so far" was initialized to GRUB_UINT_MAX -
completely preventing boot on systems without RAM below 4GB.

Change the initial value to GRUB_EFI_MAX_USABLE_ADDRESS, as originally
intended.

Reported-by: Steve McIntyre <93sam@debian.org>
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Paul Menzel 3be9268318 normal/menu: Do not treat error values as key presses
Some terminals, like `grub-core/term/at_keyboard.c`, return `-1` in case
they are not ready yet.

      if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
        return -1;

Currently, that is treated as a key press, and the menu time-out is
cancelled/cleared. This is unwanted, as the boot is stopped and the user
manually has to select a menu entry. Therefore, adapt the condition to
require the key value also to be greater than 0.

`GRUB_TERM_NO_KEY` is defined as 0, so the condition could be collapsed
to greater or equal than (≥) 0, but the compiler will probably do that
for us anyway, so keep the cases separate for clarity.

This is tested with coreboot, the GRUB default payload, and the
configuration file `grub.cfg` below.

For GRUB:

    $ ./autogen.sh
    $ ./configure --with-platform=coreboot
    $ make -j`nproc`
    $ make default_payload.elf

For coreboot:

    $ more grub.cfg
    serial --unit 0 --speed 115200
    set timeout=5

    menuentry 'halt' {
        halt
    }
    $ build/cbfstool build/coreboot.rom add-payload \
        -f /dev/shm/grub/default_payload.elf -n fallback/payload -c lzma
    $ build/cbfstool build/coreboot.rom add -f grub.cfg -n etc/grub.cfg -t raw
    $ qemu-system-x86_64 --version
    QEMU emulator version 3.1.0 (Debian 1:3.1+dfsg-2+b1)
    Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers
    $ qemu-system-x86_64 -M pc -bios build/coreboot.rom -serial stdio -nic none

Currently, the time-out is cancelled/cleared. With the commit, it is not.
With a small GRUB payload, this the problem is also reproducible on the
ASRock E350M1.

Link: http://lists.gnu.org/archive/html/grub-devel/2019-01/msg00037.html

Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 3591313ca9 fdt: Treat device tree file type like ACPI
We now have signature check logic in grub which allows us to treat
files differently depending on their file type.

Treat a loaded device tree like an overlayed ACPI table.
Both describe hardware, so I suppose their threat level is the same.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 09d8eedbba RISC-V: Add to build system
This patch adds support for RISC-V to the grub build system. With this
patch, I can successfully build grub on RISC-V as a UEFI application.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 1edef90cf9 RISC-V: Add libgcc helpers for clz
Gcc may decide it wants to call helper functions to execute clz. Provide
them in our own copy of libgcc.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 8ce194d068 RISC-V: Add auxiliary files
To support a new architecture we need to provide a few helper functions
for memory, cache, timer, etc support.

This patch adds the remainders of those. Some bits are still disabled,
as I couldn't guarantee that we're always running on models / in modes
where the respective hardware is available.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 893ed83b2e RISC-V: Add awareness for RISC-V reloations
This patch adds awareness of RISC-V relocations throughout the grub tools
as well as dynamic linkage and elf->PE relocation conversion support.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf b3213ec755 RISC-V: Add Linux load logic
We currently only support to run grub on RISC-V as UEFI payload. Ideally,
we also only want to support running Linux underneath as UEFI payload.

Prepare that with some Linux boot stub code. Once the arm64 target is
generalized, we can hook into that one and gain boot functionality.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf da45838120 RISC-V: Add early startup code
On entry, we need to save the system table pointer as well as our image
handle. Add an early startup file that saves them and then brings us
into our main function.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 745da2e57b RISC-V: Add setjmp implementation
This patch adds a 32/64 capable setjmp implementation for RISC-V.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 483be6643f elf.h: Add RISC-V definitions
The RISC-V ABI document outlines ELF header structure and relocation
information. Pull the respective magic numbers into our elf header
so we can make use of them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 43608adc2e PE: Add RISC-V definitions
The PE format defines magic numbers as well as relocation identifiers for
RISC-V. Add them to our include file, so we can make use of them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf 785f28df0f efi: Rename armxx to arch
Some architectures want to boot Linux as plain UEFI binary. Today that
really only encompasses ARM and AArch64, but going forward more
architectures may adopt that model.

So rename our internal API accordingly.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Alexander Graf f7fbbbc622 mkimage: Clarify file alignment in efi case
There are a few spots in the PE generation code for EFI binaries that uses
the section alignment rather than file alignment, even though the alignment
is really only file bound.

Replace those cases with the file alignment constant instead.

Reported-by: Daniel Kiper <dkiper@net-space.pl>
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Julien ROBIN <julien.robin28@free.fr>
2020-09-21 16:43:54 -04:00
Alexander Graf c0064a1015 mkimage: Align efi sections on 4k boundary
There is UEFI firmware popping up in the wild now that implements stricter
permission checks using NX and write protect page table entry bits.

This means that firmware now may fail to load binaries if its individual
sections are not page aligned, as otherwise it can not ensure permission
boundaries.

So let's bump all efi section alignments up to 4k (EFI page size). That way
we will stay compatible going forward.

Unfortunately our internals can't deal very well with a mismatch of alignment
between the virtual and file offsets, so we have to also pad our target
binary a bit.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Julien ROBIN <julien.robin28@free.fr>
2020-09-21 16:43:54 -04:00
Alexander Graf 61b2290c0a mkimage: Use EFI32_HEADER_SIZE define in arm-efi case
The efi-arm case was defining its own header size calculation, even though it's
100% identical to the common EFI32_HEADER_SIZE definition.

So let's clean it up to use the common define.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Julien ROBIN <julien.robin28@free.fr>
2020-09-21 16:43:54 -04:00
Guillaume GARDET 94701ab4a5 arm: Move initrd upper to leave more space for kernel
This patch allows to have bigger kernels. If the kernel grows, then it will
overwrite the initrd when it is extracted.

Signed-off-by: Guillaume GARDET <guillaume.gardet@arm.com>
Acked-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Leif Lindholm afe3a6799e linux, efi, arm*, fdt: Break FDT extra allocation space out into a #define
A certain amount of dynamic space is required for the handover from
GRUB/Linux-EFI-stub. This entails things like initrd addresses,
address-cells entries and associated strings.

But move this into a proper centralised #define rather than live-code
it in the loader.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Cristian Ciocaltea 45fa163f8a uboot: Add the missing disk write operation support
uboot_disk_write() is currently lacking the write support
to storage devices because, historically, those devices did not
implement block_write() in U-Boot.

The solution has been tested using a patched U-Boot loading
and booting GRUB in a QEMU vexpress-a9 environment.
The disk write operations were triggered with GRUB's save_env
command.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Max Tottenham 019c0941b8 tpm: Fix bug in GRUB2 TPM module
The value of tpm_handle changes between successive calls to grub_tpm_handle_find(),
as instead of simply copying the stored pointer we end up taking the address of
said pointer when using the cached value of grub_tpm_handle.

This causes grub_efi_open_protocol() to return a nullptr in grub_tpm2_execute()
and grub_tpm2_log_event(). Said nullptr goes unchecked and
efi_call_5(tpm->hash_log_extend_event,...) ends up jumping to 0x0, Qemu crashes
once video ROM is reached at 0xb0000.

This patch seems to do the trick of fixing that bug, but we should also ensure
that all calls to grub_efi_open_protocol() are checked so that we don't start
executing low memory.

Signed-off-by: Max Tottenham <mtottenh@akamai.com>
Reviewed-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Colin Watson 140526af7d pgp: Fix emu build and tests after pgp module renaming
Commit b07feb8746 (verifiers: Rename
verify module to pgp module) renamed the "verify" module to "pgp", but
the GRUB_MOD_INIT and GRUB_MOD_FINI macros were left as "verify", which
broke the emu target build; and file_filter_test still referred to the
now non-existent "verify" module. Fix both of these.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Peter Große eb392eefde grub-mkconfig/20_linux_xen: Support multiple early initrd images
Add support for multiple, shared, early initrd images. These early
images will be loaded in the order declared, and all will be loaded
before the initrd image.

While many classes of data can be provided by early images, the
immediate use case would be for distributions to provide CPU
microcode to mitigate the Meltdown and Spectre vulnerabilities.

Xen has also support to load microcode updates provided as additional
modules by the bootloader.

There are two environment variables provided for declaring the early
images.

* GRUB_EARLY_INITRD_LINUX_STOCK is for the distribution declare
  images that are provided by the distribution or installed packages.
  If undeclared, this will default to a set of common microcode image
  names.

* GRUB_EARLY_INITRD_LINUX_CUSTOM is for user created images. User
  images will be loaded after the stock images.

These separate configurations allow the distribution and user to
declare different image sets without clobbering each other.

This also makes a minor update to ensure that UUID partition labels
stay disabled when no initrd image is found, even if early images are
present.

This is basically a copy of a698240d "grub-mkconfig/10_linux: Support
multiple early initrd images" by Matthew S. Turnbull.

Signed-off-by: Peter Große <pegro@friiks.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Heinrich Schuchardt e0d444d0bb grub-core/loader/efi/fdt.c: Do not copy random memory
We should not try to copy any memory area which is outside of the original
fdt. If this extra memory is controlled by a hypervisor this might end
with a crash.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Matthew Garrett c338629625 verifiers: Add TPM documentation
Describe the behaviour of GRUB when the TPM module is in use.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Matthew Garrett f4f4e3c715 verifiers: Core TPM support
Add support for performing basic TPM measurements. Right now this only
supports extending PCRs statically and only on UEFI. In future we might
want to have some sort of mechanism for choosing which events get logged
to which PCRs, but this seems like a good default policy and we can wait
to see whether anyone  has a use case before adding more complexity.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 16:43:54 -04:00
Matthew Garrett 8d6447d496 verifiers: Verify commands executed by grub
Pass all commands executed by GRUB to the verifiers layer. Most verifiers will
ignore this, but some (such as the TPM verifier) want to be able to measure and
log each command executed in order to ensure that the boot state is as expected.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 14:11:28 -04:00
Juergen Gross 90bb89f280 xen_pvh: Add support to configure
Support platform i386/xen_pvh in configure.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross ce8428f59e xen_pvh: Support grub-install for xen_pvh
Add xen_pvh support to grub-install.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 174c087008 xen_pvh: Support building a standalone image
Support mkimage for xen_pvh.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 0d20904338 xen: Use elfnote defines instead of plain numbers
In order to avoid using plain integers for the ELF notes use the
available Xen include instead.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Hans van Kranenburg 10279afb14 grub-module-verifier: Ignore all_video for xen_pvh
This solves the build failing with "Error: no symbol table and no
.moddeps section"

Also see:
- 6371e9c104
- https://savannah.gnu.org/bugs/?49012

Signed-off-by: Hans van Kranenburg <hans@knorrie.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 2510cdf71b xen_pvh: Add build runes for grub-core
Add the modifications to the build system needed to build a xen_pvh
grub.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross d87a8ebb48 xen: Init memory regions for PVH
Add all usable memory regions to grub memory management and add the
needed mmap iterate code, which will be used by grub core (e.g.
grub-core/lib/relocator.c or grub-core/mmap/mmap.c).

As we are running in 32-bit mode don't add memory above 4GB.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 036b001beb xen: Setup Xen specific data for PVH
Initialize the needed Xen specific data. This is:

- the Xen start of day page containing the console and Xenstore ring
  page PFN and event channel
- the grant table
- the shared info page

Write back the possibly modified memory map to the hypervisor in case
the guest is reading it from there again.

Set the RSDP address for the guest from the start_info page passed
as boot parameter.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross ad37d8a89e xen: Get memory map from hypervisor for PVH
Retrieve the memory map from the hypervisor and normalize it to contain
no overlapping entries and to be sorted by address.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross d0c68baa5b xen: Setup hypercall page for PVH
Add the needed code to setup the hypercall page for calling into the
Xen hypervisor.

Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
include/xen/arch-x86/xen.h

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 590dd77f55 xen: Add PVH boot entry code
Add the code for the Xen PVH mode boot entry.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 21d8017ace xen: Add basic hooks for PVH in current code
Add the hooks to current code needed for Xen PVH. They will be filled
with code later when the related functionality is being added.

loader/i386/linux.c needs to include machine/kernel.h now as it needs
to get GRUB_KERNEL_USE_RSDP_ADDR from there. This in turn requires to
add an empty kernel.h header for some i386 platforms (efi, coreboot,
ieee1275, xen) and for x86_64 efi.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:57:20 -04:00
Juergen Gross 08495ebb1c xen: Add PVH specific defines to offset.h
include/grub/offsets.h needs some defines for Xen PVH mode.

Add them. While at it line up the values in the surrounding lines to
start at the same column.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross fa57ea8463 xen: Modify grub_xen_ptr2mfn() for Xen PVH
grub_xen_ptr2mfn() returns the machine frame number for a given pointer
value. For Xen-PVH guests this is just the PFN. Add the PVH specific
variant.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross f06b0fd021 xen: Rearrange xen/init.c to prepare it for Xen PVH mode
Rearrange grub-core/kern/xen/init.c to prepare adding PVH mode support
to it. This includes putting some code under #ifdef GRUB_MACHINE_XEN
as it will not be used when running as PVH.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross ed6058883a xen: Add some dummy headers for PVH mode
With Xen PVH mode adding a new machine type the machine related headers
need to be present for the build to succeed. Most of the headers just
need to include the related common i386 headers. Add those to the tree.

Note that xen_pvh/int.h needs to include pc/int_types.h instead of
pc/int.h in order to avoid the definition of grub_bios_interrupt().

xen_pvh/memory.h needs to include coreboot/memory.h (like some other
<machine>/memory.h do as well) as this contains just the needed stubs.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross ef5fcec192 xen: Prepare common code for Xen PVH support
Some common code needs to be special cased for Xen PVH mode. This hits
mostly Xen PV mode specific areas.

Split include/grub/i386/pc/int_types.h off from
include/grub/i386/pc/int.h to support including this file later from
xen_pvh code without the grub_bios_interrupt definition.

Move definition of struct grub_e820_mmap_entry from
grub-core/mmap/i386/pc/mmap.c to include/grub/i386/memory.h in order
to make it usable from xen_pvh code.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross b85619206a xen: Carve out grant tab initialization into dedicated function
Initialize the grant tab in a dedicated function. This will enable
using it for PVH guests, too.

Call the new function from grub_machine_init() as this will later
be common between Xen PV and Xen PVH mode.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross 0a0cb415b8 loader/linux: Support passing RSDP address via boot params
Xen PVH guests will have the RSDP at an arbitrary address. Support that
by passing the RSDP address via the boot parameters to Linux.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Juergen Gross 560d7d4d2f xen: Add some Xen headers
In order to support grub2 in Xen PVH environment some additional Xen
headers are needed as grub2 will be started in PVH mode requiring to
use several HVM hypercalls and structures.

Add the needed headers from Xen 4.10 being the first Xen version with
full (not only experimental) PVH guest support.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Hans van Kranenburg <hans@knorrie.org>
2020-09-21 13:46:35 -04:00
Daniel Kiper c23b9068eb verifiers: ARM Xen fallout cleanup
ARM Xen fallout cleanup after commit ca0a4f689 (verifiers: File type for
fine-grained signature-verification controlling).

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:35 -04:00
Daniel Kiper 8d889850ef verifiers: Xen fallout cleanup
Xen fallout cleanup after commit ca0a4f689 (verifiers: File type for
fine-grained signature-verification controlling).

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:35 -04:00
Eric Snowberg 10656801a7 ofnet: Fix build regression in grub_ieee1275_parse_bootpath()
The grub_ieee1275_parse_bootpath() function (commit a661a32, ofnet: Initialize
structs in bootpath parser) introduces a build regression on SPARC:

cc1: warnings being treated as errors
net/drivers/ieee1275/ofnet.c: In function 'grub_ieee1275_parse_bootpath':
net/drivers/ieee1275/ofnet.c:156: error: missing initializer
net/drivers/ieee1275/ofnet.c:156: error: (near initialization for 'client_addr.type')
net/drivers/ieee1275/ofnet.c:156: error: missing initializer
net/drivers/ieee1275/ofnet.c:156: error: (near initialization for 'gateway_addr.type')
net/drivers/ieee1275/ofnet.c:156: error: missing initializer
net/drivers/ieee1275/ofnet.c:156: error: (near initialization for 'subnet_mask.type')
net/drivers/ieee1275/ofnet.c:157: error: missing initializer
net/drivers/ieee1275/ofnet.c:157: error: (near initialization for 'hw_addr.type')
make[3]: *** [net/drivers/ieee1275/ofnet_module-ofnet.o] Error 1

Initialize the entire structure.

More info can be found here:
  http://lists.gnu.org/archive/html/grub-devel/2018-03/msg00034.html

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:35 -04:00
Nick Terrell 572e56b789 btrfs: Add zstd support to grub btrfs
- Adds zstd support to the btrfs module.
- Adds a test case for btrfs zstd support.
- Changes top_srcdir to srcdir in the btrfs module's lzo include
  following comments from Daniel Kiper about the zstd include.

Tested on Ubuntu-18.04 with a btrfs /boot partition with and without zstd
compression. A test case was also added to the test suite that fails before
the patch, and passes after.

Signed-off-by: Nick Terrell <terrelln@fb.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:35 -04:00
Nick Terrell d0b38cbc3b zstd: Import upstream zstd-1.3.6
- Import zstd-1.3.6 from upstream
- Add zstd's module.c file
- Add the zstd module to Makefile.core.def

Import zstd-1.3.6 from upstream [1]. Only the files need for decompression
are imported. I used the latest zstd release, which includes patches [2] to
build cleanly in GRUB.

I included the script used to import zstd-1.3.6 below at the bottom of the
commit message.

Upstream zstd commit hash: 4fa456d7f12f8b27bd3b2f5dfd4f46898cb31c24
Upstream zstd commit name: Merge pull request #1354 from facebook/dev

Zstd requires some posix headers, which it gets from posix_wrap.
This can be checked by inspecting the .Po files generated by automake,
which contain the header dependencies. After building run the command
`cat grub-core/lib/zstd/.deps-core/*.Po` to see the dependencies [3].
The only OS dependencies are:

- stddef.h, which is already a dependency in posix_wrap, and used for size_t
  by lzo and xz.
- stdarg.h, which comes from the grub/misc.h header, and we don't use in zstd.

All the types like uint64_t are typedefed to grub_uint64_t under the hood.
The only exception is size_t, which comes from stddef.h. This is already the
case for lzo and xz. I don't think there are any cross-compilation concerns,
because cross-compilers provide their own system headers (and it would already
be broken).

[1] https://github.com/facebook/zstd/releases/tag/v1.3.6
[2] https://github.com/facebook/zstd/pull/1344
[3] https://gist.github.com/terrelln/7a16b92f5a1b3aecf980f944b4a966c4

```

curl -L -O https://github.com/facebook/zstd/releases/download/v1.3.6/zstd-1.3.6.tar.gz
curl -L -O https://github.com/facebook/zstd/releases/download/v1.3.6/zstd-1.3.6.tar.gz.sha256
sha256sum --check zstd-1.3.6.tar.gz.sha256
tar xzf zstd-1.3.6.tar.gz

SRC_LIB="zstd-1.3.6/lib"
DST_LIB="grub-core/lib/zstd"
rm -rf $DST_LIB
mkdir -p $DST_LIB
cp $SRC_LIB/zstd.h $DST_LIB/
cp $SRC_LIB/common/*.[hc] $DST_LIB/
cp $SRC_LIB/decompress/*.[hc] $DST_LIB/
rm $DST_LIB/{pool.[hc],threading.[hc]}
rm -rf zstd-1.3.6*
echo SUCCESS!
```

Signed-off-by: Nick Terrell <terrelln@fb.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Michael Chang 84138630f1 verifiers: fix double close on pgp's sig file descriptor
An error emerged as when I was testing the verifiers branch, so instead
of putting it in pgp prefix, the verifiers is used to reflect what the
patch is based on.

While running verify_detached, grub aborts with error.

verify_detached /@/.snapshots/1/snapshot/boot/grub/grub.cfg
/@/.snapshots/1/snapshot/boot/grub/grub.cfg.sig

alloc magic is broken at 0x7beea660: 0
Aborted. Press any key to exit.

The error is caused by sig file descriptor been closed twice, first time
in grub_verify_signature() to which it is passed as parameter. Second in
grub_cmd_verify_signature() or in whichever opens the sig file
descriptor. The second close is not consider as bug to me either, as in
common rule of what opens a file has to close it to avoid file
descriptor leakage.

After all the design of grub_verify_signature() makes it difficult to keep
a good trace on opened file descriptor from it's caller. Let's refine
the application interface to accept file path rather than descriptor, in
this way the caller doesn't have to care about closing the descriptor by
delegating it to grub_verify_signature() with full tracing to opened
file descriptor by itself.

Also making it clear that sig descriptor is not referenced in error
returning path of grub_verify_signature_init(), so it can be closed
directly by it's caller. This also makes delegating it to
grub_pubkey_close() infeasible to help in relieving file descriptor
leakage as it has to depend on uncertainty of ctxt fields in error
returning path.

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Lee Jones 07bd90075e generic/blocklist: Fix implicit declaration of function grub_file_filter_disable_compression()
grub_file_filter_disable_compression() no longer exists.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Lee Jones 50f3273673 arm64/xen: Fix too few arguments to function grub_create_loader_cmdline()
Without this fix, building xen_boot.c omits:

loader/arm64/xen_boot.c: In function ‘xen_boot_binary_load’:
loader/arm64/xen_boot.c:370:7: error: too few arguments to function ‘grub_create_loader_cmdline’
       grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
       ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from loader/arm64/xen_boot.c:36:0:
../include/grub/lib/cmdline.h:29:12: note: declared here
 grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf,

Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Leif Lindholm 495e3d518b arm-uboot, ia64, sparc64: Fix up grub_file_open() calls
The verifiers framework changed the grub_file_open() interface, breaking all
non-x86 linux loaders. Add file types to the grub_file_open() calls to make
them build again.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Leif Lindholm 8738ab40c5 arm64/efi: Fix breakage caused by verifiers
- add variable "err" (used but not defined),
  - add GRUB_FILE_TYPE_LINUX_KERNEL to grub_file_open() call.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Leif Lindholm 0ca4bfae54 grub-core/loader/efi/fdt.c: Fixup grub_file_open() call
The verifiers framework changed the API of grub_file_open(), but did not
fix up all users. Add the file type GRUB_FILE_TYPE_DEVICE_TREE_IMAGE
to the "devicetree" command handler call.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Leif Lindholm 31932beeb4 include/grub/file.h: Add device tree file type
The API change of grub_file_open() for adding verifiers did not include
a type for device tree blobs. Add GRUB_FILE_TYPE_DEVICE_TREE_IMAGE to
the grub_file_type enum.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Leif Lindholm 4310866a14 include/grub/verify.h: Add include guard
verify.h was added without include guards. This means compiling anything
including both include/grub/verify.h and include/grub/lib/cmdline.h fails
(at least grub-core/loader/arm64/linux.c.

Add the necessary include guard.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Matthew Daley a0a7a57cd7 mkimage: Pad DTBs to target-specific pointer size
Device tree (DTB) lengths are being padded to a multiple of 4 bytes
rather than the target-specific pointer size. This causes objects
following OBJ_TYPE_DTB objects to be incorrectly parsed during GRUB
execution on arm64.

Fix by using ALIGN_ADDR(), not ALIGN_UP().

Signed-by-off: Matthew Daley <mattd@bugfuzz.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Colin Watson 3e0fa5c063 Cope with / being on a ZFS root dataset
If / is on the root dataset in a ZFS pool, then ${bootfs} will be set to
"/" (whereas if it is on a non-root dataset, there will be no trailing
slash).  Passing "root=ZFS=${rpool}/" will fail to boot, but
"root=ZFS=${rpool}" works fine, so strip the trailing slash.

Fixes: https://savannah.gnu.org/bugs/?52746

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Tested-by: Fejes József <jozsef.fejes@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Paul Menzel 91ac8687a9 unix/platform: Initialize variable to fix grub-install on UEFI system
On a UEFI system, were no boot entry *grub* is present, currently,
`grub-install` fails with an error.

    $ efibootmgr
    BootCurrent: 0000
    Timeout: 0 seconds
    BootOrder: 0001,0006,0003,0004,0005
    Boot0001  Diskette Drive
    Boot0003* USB Storage Device
    Boot0004* CD/DVD/CD-RW Drive
    Boot0005  Onboard NIC
    Boot0006* WDC WD2500AAKX-75U6AA0
    $ sudo grub-install /dev/sda
    Installing for x86_64-efi platform.
    grub-install: error: efibootmgr failed to register the boot entry: Unknown error 22020.

The error code is always different, and the error message (incorrectly)
points to efibootmgr.

But, the error is in GRUB’s function
`grub_install_remove_efi_entries_by_distributor()`, where the variable
`rc` for the return value, is uninitialized and never set, when no boot
entry for the distributor is found.

The content of that uninitialized variable is then returned as the error
code of efibootmgr.

Set the variable to 0, so that success is returned, when no entry needs
to be deleted.

Tested on Dell OptiPlex 7010 with firmware A28.

    $ sudo ./grub-install /dev/sda
    Installing for x86_64-efi platform.
    Installation finished. No error reported.

[1]: https://github.com/rhboot/efibootmgr/issues/100

Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:46:34 -04:00
Daniel Kiper 81072e718a efi: Add EFI shim lock verifier
This module provides shim lock verification for various kernels
if UEFI secure boot is enabled on a machine.

It is recommended to put this module into GRUB2 standalone image
(avoid putting iorw and memrw modules into it; they are disallowed
if UEFI secure boot is enabled). However, it is also possible to use
it as a normal module. Though such configurations are more fragile
and less secure due to various limitations.

If the module is loaded and UEFI secure boot is enabled then:
  - module itself cannot be unloaded (persistent module),
  - the iorw and memrw modules cannot be loaded,
  - if the iorw and memrw modules are loaded then
    machine boot is disabled,
  - GRUB2 defers modules and ACPI tables verification to
    other verifiers.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Daniel Kiper 1cb4edf4ef dl: Add support for persistent modules
This type of modules cannot be unloaded. This is useful if a given
functionality, e.g. UEFI secure boot shim signature verification, should
not be disabled if it was enabled at some point in time. Somebody may
say that we can use standalone GRUB2 here. That is true. However, the
code is not so big nor complicated hence it make sense to support
modularized configs too.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Vladimir Serbinenko 29e76e7402 verifiers: Add the documentation
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Daniel Kiper 0663d355e3 verifiers: Rename verify module to pgp module
Just for clarity. No functional change.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Daniel Kiper 708ae9f524 verifiers: Add possibility to defer verification to other verifiers
This way if a verifier requires verification of a given file it can defer task
to another verifier (another authority) if it is not able to do it itself. E.g.
shim_lock verifier, posted as a subsequent patch, is able to verify only PE
files. This means that it is not able to verify any of GRUB2 modules which have
to be trusted on UEFI systems with secure boot enabled. So, it can defer
verification to other verifier, e.g. PGP one.

I silently assume that other verifiers are trusted and will do good job for us.
Or at least they will not do any harm.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Vladimir Serbinenko 0f20a51812 verifiers: Add possibility to verify kernel and modules command lines
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:46:34 -04:00
Vladimir Serbinenko 03a713b7ab verifiers: Framework core
Verifiers framework provides core file verification functionality which
can be used by various security mechanisms, e.g., UEFI secure boot, TPM,
PGP signature verification, etc.

The patch contains PGP code changes and probably they should be extracted
to separate patch for the sake of clarity.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:31:01 -04:00
Vladimir Serbinenko aebe31c375 verifiers: File type for fine-grained signature-verification controlling
Let's provide file type info to the I/O layer. This way verifiers
framework and its users will be able to differentiate files and verify
only required ones.

This is preparatory patch.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:29:05 -04:00
Daniel Kiper e1bc2b23f1 bufio: Use grub_size_t instead of plain int for size
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 83985ac0bf btrfs: Add RAID 6 recovery for a btrfs filesystem
Add the RAID 6 recovery, in order to use a RAID 6 filesystem even if some
disks (up to two) are missing. This code use the md RAID 6 code already
present in grub.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 72a2af67ff btrfs: Make more generic the code for RAID 6 rebuilding
The original code which handles the recovery of a RAID 6 disks array
assumes that all reads are multiple of 1 << GRUB_DISK_SECTOR_BITS and it
assumes that all the I/O is done via the struct grub_diskfilter_segment.
This is not true for the btrfs code. In order to reuse the native
grub_raid6_recover() code, it is modified to not call
grub_diskfilter_read_node() directly, but to call an handler passed
as an argument.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 979c4ced63 btrfs: Add support for recovery for a RAID 5 btrfs profiles
Add support for recovery for a RAID 5 btrfs profile. In addition
it is added some code as preparatory work for RAID 6 recovery code.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 4725d77e97 btrfs: Refactor the code that read from disk
Move the code in charge to read the data from disk into a separate
function. This helps to separate the error handling logic (which
depends on the different raid profiles) from the read from disk
logic. Refactoring this code increases the general readability too.

This is a preparatory patch, to help the adding of the RAID 5/6 recovery code.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli ba1f90d4f6 btrfs: Move logging code in grub_btrfs_read_logical()
A portion of the logging code is moved outside of internal for(;;). The part
that is left inside is the one which depends on the internal for(;;) index.

This is a preparatory patch. The next one will refactor the code inside
the for(;;) into an another function.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 41b8d7ba50 btrfs: Avoid a rescan for a device which was already not found
Currently read from missing device triggers rescan. However, it is never
recorded that the device is missing. So, each read of a missing device
triggers rescan again and again. This behavior causes a lot of unneeded
rescans leading to huge slowdowns.

This patch fixes above mentioned issue. Information about missing devices
is stored in the data->devices_attached[] array as NULL value in dev
member. Rescan is triggered only if no information is found for a given
device. This means that only first time read triggers rescan.

The patch drops premature return. This way data->devices_attached[] is
filled even when a given device is missing.

Signed-off-by: Goffredo Baroncelli <kreikack@inwind.it>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 3f086df7ea btrfs: Move the error logging from find_device() to its caller
The caller knows better if this error is fatal or not, i.e. another disk is
available or not.

This is a preparatory patch.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli f962796697 btrfs: Add helper to check the btrfs header
This helper is used in a few places to help the debugging. As
conservative approach the error is only logged.
This does not impact the error handling.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Goffredo Baroncelli 3d822ff9b3 btrfs: Add support for reading a filesystem with a RAID 5 or RAID 6 profile
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Michael Chang 5a0a15c05b msdos: Fix overflow in converting partition start and length into 512B blocks
When booting from NVME SSD with 4k sector size, it fails with the message.

error: attempt to read or write outside of partition.

This patch fixes the problem by fixing overflow in converting partition start
and length into 512B blocks.

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Mihai Moldovan d3b1d4c188 osdep/linux: Convert partition start to disk sector length
When reading data off a disk, sector values are based on the disk sector
length.

Within grub_util_fd_open_device(), the start of the partition was taken
directly from grub's partition information structure, which uses the
internal sector length (currently 512b), but never transformed to the
disk's sector length.

Subsequent calculations were all wrong for devices that have a diverging
sector length and the functions eventually skipped to the wrong stream
location, reading invalid data.

Signed-off-by: Mihai Moldovan <ionic@ionic.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Adam Williamson 4f9642a479 python: Use AM_PATH_PYTHON to determine interpreter for gentpl.py
gentpl.py is python2/3-agnostic, but there's no way to cause it
to be run with any interpreter other than 'python', it's just
hard-coded into Makefile.common that way. Adjust that to use
AM_PATH_PYTHON (provided by automake) to find an interpreter
and run gentpl.py with that instead. This makes grub buildable
when `python` does not exist (but rather `python3` or `python2`
or `python2.7`, etc.) Minimum version is set to 2.6 as this is
the first version with `__future__.print_function` available.

Note, AM_PATH_PYTHON respects the PYTHON environment variable
and will treat its value as the *only* candidate for a valid
interpreter if it is set - when PYTHON is set, AM_PATH_PYTHON
will not try to find any alternative interpreter, it will only
check whether the interpreter set as the value of PYTHON meets
the requirements and use it if so or fail if not. This means
that when using grub's `autogen.sh`, as it too uses the value
of the PYTHON environment variable (and if it is not set, just
sets it to 'python') you cannot rely on AM_PATH_PYTHON
interpreter discovery. If your desired Python interpreter is
not just 'python', you must set the PYTHON environment variable,
e.g. 'PYTHON=/usr/local/bin/python3 ./autogen.sh'. The specified
interpreter will then be used both by autogen.sh itself and by
the autotools-driven build scripts.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Colin Watson e17136e52b 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>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Colin Watson f08b3133e5 build: Capitalise *freetype_* variables
Using FREETYPE_CFLAGS and FREETYPE_LIBS is more in line with the naming
scheme used by pkg-config macros.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Julian Andres Klode 03c594e6fa ofnet: Initialize structs in bootpath parser
Code later on checks if variables inside the struct are
0 to see if they have been set, like if there were addresses
in the bootpath.

The variables were not initialized however, so the check
might succeed with uninitialized data, and a new interface
with random addresses and the same name is added. This causes
$net_default_mac to point to the random one, so, for example,
using that variable to load per-mac config files fails.

Bug-Ubuntu: https://bugs.launchpad.net/bugs/1785859

Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
dann frazier fafecb1c12 grub-reboot: Warn when "for the next boot only" promise cannot be kept
The "for the next boot only" property of grub-reboot is dependent upon
GRUB being able to clear the next_entry variable in the environment
block. However, GRUB cannot write to devices using the diskfilter
and lvm abstractions.

Ref: https://lists.gnu.org/archive/html/grub-devel/2009-12/msg00276.html
Ref: https://bugs.launchpad.net/bugs/788298

Signed-off-by: dann frazier <dann.frazier@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Cao jin 27dd2885e1 relocator16: Comments update
Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Paul Menzel 3866c1c8a0 ahci: Increase time-out from 10 s to 32 s
This is a cryptographically signed message in MIME format.

Date: Thu, 9 Aug 2018 07:27:35 +0200

Currently, the GRUB payload for coreboot does not detect the Western
Digital hard disk WDC WD20EARS-60M AB51 connected to the ASRock E350M1,
as that takes over ten seconds to spin up.

```
disk/ahci.c:533: port 0, err: 0
disk/ahci.c:539: port 0, err: 0
disk/ahci.c:543: port 0, err: 0
disk/ahci.c:549: port 0, offset: 120, tfd:80, CMD: 6016
disk/ahci.c:552: port 0, err: 0
disk/ahci.c:563: port 0, offset: 120, tfd:80, CMD: 6016
disk/ahci.c:566: port: 0, err: 0
disk/ahci.c:593: port 0 is busy
disk/ahci.c:621: cleaning up failed devs
```

GRUB detects the drive, when either unloading the module *ahci*, and
then loading it again, or when doing a warm reset.

As the ten second time-out is too short, increase it to 32 seconds,
used by SeaBIOS. which detects the drive successfully.

The AHCI driver in libpayload uses 30 seconds, and that time-out was
added in commit 354066e1 (libpayload: ahci: Increase timeout for
signature reading) with the description below.

> We can't read the drives signature before it's ready, i.e. spun up.
> So set the timeout to the standard 30s. Also put a notice on the
> console, so the user knows why the signature reading failed.

Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Cao jin 3cf4158e6c linux16: Code cleanup
1. move relocator related code more close to each other
2. use variable "len" since it has correct assignment, and keep coding
style with upper code

Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:29:05 -04:00
Colin Watson eaf9cd2402 tests: Fix qemu options for UHCI test
qemu 2.12 removed the -usbdevice option.  Use a more modern spelling
instead, in line with other USB-related tests.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Colin Watson d5ec27a424 tests: Disable sercon in SeaBIOS
SeaBIOS 1.11.0 added support for VGA emulation over a serial port, which
interferes with grub-shell.  Turn it off.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Peter Jones 65fdb2de04 grub-module-verifier: Report the filename or modname in errors
Make it so that when grub-module-verifier complains of an issue, it tells you
which module the issue was with.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Peter Jones 380ce92d70 configure: Fix an 8 year old typo
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 1f245b31a8 loader/multiboot_mbi2: Use central copy of grub_efi_find_mmap_size()
Delete local copy of function to determine required buffer size for the
UEFI memory map, use helper in kern/efi/mm.c.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 330dadc2bb loader/ia64/linux: Use central copy of grub_efi_find_mmap_size()
Delete local copy of function to determine required buffer size for the
UEFI memory map, use helper in kern/efi/mm.c.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 2a9d0f04ba loader/i386/linux: Use central copy of grub_efi_find_mmap_size()
Delete local copy of function to determine required buffer size for the
UEFI memory map, use helper in kern/efi/mm.c.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 26dc1a3ff6 i386: Don't include lib/i386/reset.c in EFI builds
Commit 0ba90a7f01 ("efi: Move grub_reboot() into kernel") broke
the build on i386-efi - genmoddep.awk bails out with message
  grub_reboot in reboot is duplicated in kernel
This is because both lib/i386/reset.c and kern/efi/efi.c now provide
this function.

Rather than explicitly list each i386 platform variant in
Makefile.core.def, include the contents of lib/i386/reset.c only when
GRUB_MACHINE_EFI is not set.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 25133dfcda efi: Restrict arm/arm64 linux loader initrd placement
The 32-bit arm Linux kernel is built as a zImage, which self-decompresses
down to near start of RAM. In order for an initrd/initramfs to be
accessible, it needs to be placed within the first ~768MB of RAM.
The initrd loader built into the kernel EFI stub restricts this down to
512MB for simplicity - so enable the same restriction in grub.

For arm64, the requirement is within a 1GB aligned 32GB window also
covering the (runtime) kernel image. Since the EFI stub loader itself
will attempt to relocate to near start of RAM, force initrd to be loaded
completely within the first 32GB of RAM.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm c8e16df67f arm: Delete unused efi support from loader/arm
The 32-bit arm efi port now shares the 64-bit linux loader, so delete
the now unused bits from the 32-bit linux loader.

This in turn leaves the grub-core/kern/arm/efi/misc.c unused, so
delete that too.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 619d60b56d arm/efi: Switch to arm64 linux loader
The arm64 and arm linux kernel EFI-stub support presents pretty much
identical interfaces, so the same linux loader source can be used for
both architectures.

Switch 32-bit ARM UEFI platforms over to the existing EFI-stub aware
loader initially developed for arm64.

This *WILL* stop non-efistub Linux kernels from booting on arm-efi.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm ba3da3c002 arm64/linux/loader: Rename functions and macros and move to common headers
In preparation for using the linux loader for 32-bit and 64-bit platforms,
rename grub_arm64*/GRUB_ARM64* to grub_armxx*/GRUB_ARMXX*.

Move prototypes for now-common functions to efi/efi.h.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm af26eb0e1a efi: Add grub_efi_get_ram_base() function for arm64
Since ARM platforms do not have a common memory map, add a helper
function that finds the lowest address region with the EFI_MEMORY_WB
attribute set in the UEFI memory map.

Required for the arm64 efi linux loader to restrict the initrd
location to where it will be accessible by the kernel at runtime.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 2217e7c7ff efi: Add central copy of grub_efi_find_mmap_size
There are several implementations of this function in the tree.
Add a central version in grub-core/efi/mm.c.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Arindam Nath 8db0a305e4 i386/linux: Add support for ext_lfb_base
The EFI Graphics Output Protocol can return a 64-bit
linear frame buffer address in some firmware/BIOS
implementations. We currently only store the lower
32-bits in the lfb_base. This will eventually be
passed to Linux kernel and the efifb driver will
incorrectly interpret the framebuffer address as
32-bit address.

The Linux kernel has already added support to handle
64-bit linear framebuffer address in the efifb driver
since quite some time now.

This patch adds the support for 64-bit linear frame
buffer address in GRUB to address the above mentioned
scenario.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 0abda83427 commands/file: Use definitions from arm64/linux.h
Clean up code for matching IS_ARM64 slightly by making use of struct
linux_arm64_kernel_header and GRUB_LINUX_ARM64_MAGIC_SIGNATURE.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm c110582e72 commands/file: Use definitions from arm/linux.h
Clean up code for matching IS_ARM slightly by making use of struct
linux_arm_kernel_header and GRUB_LINUX_ARM_MAGIC_SIGNATURE.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Hans de Goede 14a3a29839 efi/console: Fix the "enter" key not working on x86 tablets
Most 8" or 7" x86 Windows 10 tablets come with volume up/down buttons and
a power-button. In their UEFI these are almost always mapped to arrow
up/down and enter.

Pressing the volume buttons (sometimes by accident) will stop the
menu countdown, but the power-button / "enter" key was not being recognized
as enter, so the user would be stuck at the grub menu.

The problem is that these tablets send scan_code 13 or 0x0d for the
power-button, which officialy maps to the F3 key. They also set
unicode_char to 0x0d.

This commit recognizes the special case of both scan_code and unicode_char
being set to 0x0d and treats this as an enter key press.

This fixes things getting stuck at the grub-menu and allows the user
to choice a grub-menu entry using the buttons on the tablet.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Cao jin 4c1c1629ed grub-setup: Debug message cleanup
Variable "root" is initialized after root device probing and is null in
current place, so, drop it.

Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Denis 'GNUtoo' Carikli 3c3ddc9b92 multiboot_elfxx.c: Fix compilation by fixing undeclared variable
Without that fix we have:
  In file included from ../../include/grub/command.h:25:0,
                   from ../../grub-core/loader/multiboot.c:30:
  ../../grub-core/loader/multiboot_elfxx.c: In function 'grub_multiboot_load_elf64':
  ../../grub-core/loader/multiboot_elfxx.c:130:28: error: 'relocatable' undeclared (first use in this function)
     "load_base_addr=0x%x\n", relocatable,

This happens due to mistake in the commit 14ec665
(mbi: Use per segment a separate relocator chunk).

So, let's fix it.

Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm 5c6a46110d efi/fdt: Set address/size cells to 2 for empty tree
When booting an arm* system on UEFI with an empty device tree (currently
only when hardware description comes from ACPI), we don't currently set
default to 1 cell (32 bits).

Set both of these properties, to 2 cells (64 bits), to resolve issues
with kexec on some platforms.

This change corresponds with linux kernel commit ae8a442dfdc4
("efi/libstub/arm*: Set default address and size cells values for an empty dtb")
and ensures booting through grub does not behave differently from booting
the stub loader directly.

See also https://patchwork.kernel.org/patch/9561201/

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Leif Lindholm acbea29048 fdt: Move prop_entry_size to fdt.h
To be able to resuse the prop_entry_size macro, move it to
<grub/fdt.h> and rename it grub_fdt_prop_entry_size.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Will Thompson b3b77678f4 grub-fs-tester: Fix losetup race
If something else on the system is using loopback devices, then the
device that's free at the call to `losetup -f` may not be free in the
following call to try to use it. Instead, find and use the first free
loopback device in a single call to losetup.

Signed-off-by: Will Thompson <wjt@endlessm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Alexander Boettcher 20f2a065e0 mbi: Use per segment a separate relocator chunk
Instead of setting up a all comprising relocator chunk for all segments,
use per segment a separate relocator chunk.

Currently, if the ELF is non-relocatable, a single relocator chunk will
comprise memory (between the segments) which gets overridden by the relst()
invocation of the movers code in grub_relocator16/32/64_boot().

The overridden memory may contain reserved ranges like VGA memory or ACPI
tables, which may lead to crashes or at least to strange boot behaviour.

Signed-off-by: Alexander Boettcher <alexander.boettcher@genode-labs.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Daniel Kiper 3d02f21e51 templates: Add missing "]"
Commit 51be337 (templates: Update grub script template files)
lacked one "]", so, add it.

Reported-by: Philip <philm@manjaro.org>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Daniel Kiper 14ed7207b1 xfs: Accept filesystem with sparse inodes
The sparse inode metadata format became a mkfs.xfs default in
xfsprogs-4.16.0, and such filesystems are now rejected by grub as
containing an incompatible feature.

In essence, this feature allows xfs to allocate inodes into fragmented
freespace.  (Without this feature, if xfs could not allocate contiguous
space for 64 new inodes, inode creation would fail.)

In practice, the disk format change is restricted to the inode btree,
which as far as I can tell is not used by grub.  If all you're doing
today is parsing a directory, reading an inode number, and converting
that inode number to a disk location, then ignoring this feature
should be fine, so I've added it to XFS_SB_FEAT_INCOMPAT_SUPPORTED

I did some brief testing of this patch by hacking up the regression
tests to completely fragment freespace on the test xfs filesystem, and
then write a large-ish number of inodes to consume any existing
contiguous 64-inode chunk.  This way any files the grub tests add and
traverse would be in such a fragmented inode allocation.  Tests passed,
but I'm not sure how to cleanly integrate that into the test harness.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Chris Murphy <lists@colorremedies.com>
2020-09-21 13:19:10 -04:00
Oleg Solovyov 47c9b9d69d grub-probe: Don't skip /dev/mapper/dm-* devices
This patch ensures that grub-probe will find the root device placed in
/dev/mapper/dm-[0-9]+-.* e.g. device named /dev/mapper/dm-0-luks will be
found and grub.cfg will be updated properly, enabling the system to boot.

Signed-off-by: Oleg Solovyov <mcpain@altlinux.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Michael Chang a09de36b3c bufio: Round up block size to power of 2
Rounding up the bufio->block_size to meet power of 2 to facilitate next_buf
calculation in grub_bufio_read().

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Nicholas Vinson d86ee9b3e3 templates: Update grub script template files
Update grub-mkconfig.in and 10_linux.in to support grub-probe's new
partuuid target.  Update grub.texi documentation.  The following table
shows how GRUB_DISABLE_LINUX_UUID, GRUB_DISABLE_LINUX_PARTUUID, and
initramfs detection interact:

Initramfs  GRUB_DISABLE_LINUX_PARTUUID  GRUB_DISABLE_LINUX_UUID  Linux Root
detected   Set                          Set                      ID Method

false      false                        false                    part UUID
false      false                        true                     part UUID
false      true                         false                    dev name
false      true                         true                     dev name
true       false                        false                    fs UUID
true       false                        true                     part UUID
true       true                         false                    fs UUID
true       true                         true                     dev name

Note: GRUB_DISABLE_LINUX_PARTUUID and GRUB_DISABLE_LINUX_UUID equate to
      'false' when unset or set to any value other than 'true'.
      GRUB_DISABLE_LINUX_PARTUUID defaults to 'true'.

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Nicholas Vinson 1c8769611f grub-probe: Add PARTUUID detection support
Add PARTUUID detection support grub-probe for MBR and GPT partition schemes.

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Nicholas Vinson e6cc6f328a disk: Update grub_gpt_partentry
Rename grub_gpt_part_type to grub_gpt_part_guid and update grub_gpt_partentry
to use this type for both the partition type GUID string and the partition GUID
string entries.  This change ensures that the two GUID fields are handled more
consistently and helps to simplify the changes needed to add Linux partition
GUID support.

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 13:19:10 -04:00
Nicholas Vinson 7ea9c0d396 grub-probe: Centralize GUID prints
Define print_gpt_guid(), so there is a central function for printing
GUID strings.  This change is a precursor for later patches which rely
on this logic.

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:43:53 -04:00
Olaf Hering 5884993495 grub-install: Locale depends on nls
With --disable-nls no locales exist.

Avoid runtime error by moving code that copies locales into its own
function. Return early in case nls was disabled. That way the compiler
will throw away unreachable code, no need to put preprocessor
conditionals everywhere to avoid warnings about unused code.

Fix memleak by freeing srcf and dstf.
Convert tabs to spaces in moved code.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:43:53 -04:00
Cao jin 5378b6a6fa diskboot: Trivial correction on stale comments
diskboot.img now is loaded at 0x8000 and is jumped to with 0:0x8000.

Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:43:53 -04:00
Jaegeuk Kim 203047c756 fs: Add F2FS support
"F2FS (Flash-Friendly File System) is flash-friendly file system which was merged
into Linux kernel v3.8 in 2013.

The motive for F2FS was to build a file system that from the start, takes into
account the characteristics of NAND flash memory-based storage devices (such as
solid-state disks, eMMC, and SD cards).

F2FS was designed on a basis of a log-structured file system approach, which
remedies some known issues of the older log structured file systems, such as
the snowball effect of wandering trees and high cleaning overhead. In addition,
since a NAND-based storage device shows different characteristics according to
its internal geometry or flash memory management scheme (such as the Flash
Translation Layer or FTL), it supports various parameters not only for
configuring on-disk layout, but also for selecting allocation and cleaning
algorithm.", quote by https://en.wikipedia.org/wiki/F2FS.

The source codes for F2FS are available from:

http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git
http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git

This patch has been integrated in OpenMandriva Lx 3.
  https://www.openmandriva.org/

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Pete Batard <pete@akeo.ie>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:43:53 -04:00
Michael Chang e416c1036f Fix packed-not-aligned error on GCC 8
When building with GCC 8, there are several errors regarding packed-not-aligned.

./include/grub/gpt_partition.h:79:1: error: alignment 1 of ‘struct grub_gpt_partentry’ is less than 8 [-Werror=packed-not-aligned]

This patch fixes the build error by cleaning up the ambiguity of placing
aligned structure in a packed one. In "struct grub_btrfs_time" and "struct
grub_gpt_part_type", the aligned attribute seems to be superfluous, and also
has to be packed, to ensure the structure is bit-to-bit mapped to the format
laid on disk. I think we could blame to copy and paste error here for the
mistake. In "struct efi_variable", we have to use grub_efi_packed_guid_t, as
the name suggests. :)

Signed-off-by: Michael Chang <mchang@suse.com>
Tested-by: Michael Chang <mchang@suse.com>
Tested-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:43:53 -04:00
mike.travis@hpe.com 77dd0afe57 efi/uga: Fix PCIe LER when GRUB2 accesses non-enabled MMIO data from VGA
A GPU inserted into a PCIe I/O slot disappears during system startup.
The problem centers around GRUB and a specific VGA init function in
efi_uga.c. This causes an LER (Link Error Recorvery) because the MMIO
memory has not been enabled before attempting access.

The fix is to add the same coding used in other VGA drivers, specifically
to add a check to insure that it is indeed a VGA controller. And then
enable the MMIO address space with the specific bits.

Signed-off-by: Mike Travis <mike.travis@hpe.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg a5b5432211 ieee1275: NULL pointer dereference in grub_machine_get_bootlocation()
Read from NULL pointer canon in function grub_machine_get_bootlocation().
Function grub_ieee1275_canonicalise_devname() may return NULL.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg b0beba9f20 ieee1275: split up grub_machine_get_bootlocation
Split up some of the functionality in grub_machine_get_bootlocation into
grub_ieee1275_get_boot_dev.  This will allow for code reuse in a follow on
patch.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
C. Masloch b59db4f484 chainloader: patch in BPB's sectors_per_track and num_heads
These fields must reflect the ROM-BIOS's geometry for CHS-based
loaders to correctly load their next stage. Most loaders do not
query the ROM-BIOS (Int13.08), relying on the BPB fields to hold
the correct values already.

Tested with lDebug booted in qemu via grub2's
FreeDOS direct loading support, refer to
https://bitbucket.org/ecm/ldosboot + https://bitbucket.org/ecm/ldebug
(For this test, lDebug's iniload.asm must be assembled with
-D_QUERY_GEOMETRY=0 to leave the BPB values provided by grub.)

Signed-off-by: C. Masloch <pushbx@38.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Matthew S. Turnbull b57c2a10af grub-mkconfig/10_linux: Support multiple early initrd images
Add support for multiple, shared, early initrd images. These early
images will be loaded in the order declared, and all will be loaded
before the initrd image.

While many classes of data can be provided by early images, the
immediate use case would be for distributions to provide CPU
microcode to mitigate the Meltdown and Spectre vulnerabilities.

There are two environment variables provided for declaring the early
images.

* GRUB_EARLY_INITRD_LINUX_STOCK is for the distribution declare
  images that are provided by the distribution or installed packages.
  If undeclared, this will default to a set of common microcode image
  names.

* GRUB_EARLY_INITRD_LINUX_CUSTOM is for user created images. User
  images will be loaded after the stock images.

These separate configurations allow the distribution and user to
declare different image sets without clobbering each other.

This also makes a minor update to ensure that UUID partition labels
stay disabled when no initrd image is found, even if early images are
present.

This is a continuation of a previous patch published by Christian
Hesse in 2016:
http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00025.html

Down stream Gentoo bug:
https://bugs.gentoo.org/645088

Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Signed-off-by: Matthew S. Turnbull <sparky@bluefang-logic.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 910b40a582 mkimage: fix build regression in grub_mkimage_load_image
The grub_mkimage_load_image function (commit 7542af6, mkimage: refactor a bunch
of section data into a struct.) introduces a build regression on SPARC:

  cc1: warnings being treated as errors
  In file included from util/grub-mkimage32.c:23:
  util/grub-mkimagexx.c: In function 'grub_mkimage_load_image32':
  util/grub-mkimagexx.c:1968: error: missing initializer
  util/grub-mkimagexx.c:1968: error: (near initialization for 'smd.sections')
  make[2]: *** [util/grub_mkimage-grub-mkimage32.o] Error 1

Initialize the entire section_metadata structure.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
dann frazier 6b95a221a9 Revert "Keep the native terminal active when enabling gfxterm"
This can cause an issue where GRUB is trying to display both a text and
graphical menu on the display at the same time, resulting in a flickering
effect when e.g. scrolling quickly through a menu (LP: #1752767).

Revert for now while we look for a better solution for the original issue.

This reverts commit 52ef7b23f5.

Signed-off-by: dann frazier <dann.frazier@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg b515d4fc28 sparc64: #blocks64 disk node method
Return the 64bit number of blocks of storage associated with the device or
instance. Where a "block" is a unit of storage consisting of the number of
bytes returned by the package's "block-size" method. If the size cannot be
determined, or if the number of blocks exceeds the range return -1.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg b2193b8ef2 sparc64: #blocks disk node method
Return the number of blocks of storage associated with the device or
instance. Where a "block" is a unit of storage consisting of the number
of bytes returned by the package's "block-size" method. If the size cannot
be determined, the #blocks method returns the maximum unsigned integer
(which, because of Open Firmware's assumption of two's complement arithmetic,
is equivalent to the signed number -1). If the number of blocks exceeds
the range of an unsigned number, return 0 to alert the caller to try
the #blocks64 command.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 0d9cea1c53 ieee1275: block-size deblocker support method
IEEE Std 1275-1994 Standard for Boot (Initialization Configuration)
Firmware: Core Requirements and Practices

3.8.3 deblocker support package

Any package that uses the "deblocker" support package must define
the following method, which the deblocker uses as a low-level
interface to the device

block-size ( -- block-len ) Return "granularity" for accesses to this
device.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Daniel Kiper efa8a2c2a1 ieee1275: no-data-command bus specific method
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.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg d86e5dc33b ieee1275: set-address bus specific method
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:

 set-address ( unit# target# -- )
   Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which
   subsequent commands apply.

This function is for devices with #address-cells == 2

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 8d68e13b22 ieee1275: encode-unit command for 4 addr cell devs
Convert physical address to text unit-string.

Convert phys.lo ... phys-high, the numerical representation, to unit-string,
the text string representation of a physical address within the address
space defined by this device node. The number of cells in the list
phys.lo ... phys.hi is determined by the value of the #address-cells property
of this node.

This function is for devices with #address-cells == 4

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 856004c85b ieee1275: decode-unit command for 4 addr cell devs
decode-unit ( addr len -- phys.lo ... phys.hi )

Convert text unit-string to physical address.

Convert unit-string, the text string representation, to phys.lo ... phys.hi,
the numerical representation of a physical address within the address space
defined by this device node. The number of cells in the list
phys.lo ... phys.hi is determined by the value of the #address-cells
property of this node.

This function is for devices with #address-cells == 4

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 21b89650ec sparc64: Limit nvme of_path_of_nvme to just SPARC
Limit NVMe of_path_of_nvme to just SPARC hardware for now.  It has been
found that non-Open Firmware hardware platforms can some how access
this function.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
John Paul Adrian Glaubitz 455dda2544 ieee1275: Fix crash in of_path_of_nvme when of_path is empty
The of_path_of_nvme function (commit 2391d57, ieee1275: add nvme
support within ofpath) introduced a functional regression:

On systems which are not based on Open Firmware but have at
least one NVME device, find_obppath will return NULL and thus
trying to append the disk name to of_path will result in a
crash.

The proper behavior of of_path_of_nvme is, however, to just
return NULL in such cases, like other users of find_obppath,
such as of_path_of_scsi.

Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones a74a47aad3 .mod files: Strip annobin annotations and .eh_frame, and their relocations
This way debuginfo built from the .module will still include this
information, but the final result won't have the data we don't actually
need in the modules, either on-disk, loaded at runtime, or in prebuilt
images.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones b9b9002952 mkimage: avoid copying relocations for sections that won't be copied.
Some versions of gcc include a plugin called "annobin", and in some
build systems this is enabled by default.  This plugin creates special
ELF note sections to track which ABI-breaking features are used by a
binary, as well as a series of relocations to annotate where.

If grub is compiled with this feature, then when grub-mkimage translates
the binary to another file format which does not strongly associate
relocation data with sections (i.e. when platform is *-efi), these
relocations appear to be against the .text section rather than the
original note section.  When the binary is loaded by the PE runtime
loader, hilarity ensues.

This issue is not necessarily limited to the annobin, but could arise
any time there are relocations in sections that are not represented in
grub-mkimage's output.

This patch seeks to avoid this issue by only including relocations that
refer to sections which will be included in the final binary.

As an aside, this should also obviate the need to avoid -funwind-tables,
-fasynchronous-unwind-tables, and any sections similar to .eh_frame in
the future.  I've tested it on x86-64-efi with the following gcc command
line options (as recorded by -grecord-gcc-flags), but I still need to
test the result on some other platforms that have been problematic in
the past (especially ARM Aarch64) before I feel comfortable making
changes to the configure.ac bits:

GNU C11 7.2.1 20180116 (Red Hat 7.2.1-7) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -mno-stack-arg-probe -mcmodel=large -mno-red-zone -m64 -mtune=generic -march=x86-64 -g3 -Os -freg-struct-return -fno-stack-protector -ffreestanding -funwind-tables -fasynchronous-unwind-tables -fno-strict-aliasing -fstack-clash-protection -fno-ident -fplugin=annobin

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones 37359c2a80 mkimage: refactor a bunch of section data into a struct.
This basically moves a bunch of the section information we pass around a
lot into a struct, and passes a pointer to a single one of those
instead.

This shouldn't change the binary file output or the "grub-mkimage -v"
output in any way.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones c9196cc89f mkimage: make locate_sections() set up vaddresses as well.
This puts both kinds of address initialization at the same place, and also lets
us iterate through the section list one time fewer.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones 333cbd25a2 mkimage: rename a couple of things to be less confusing later.
This renames some things:

- the "strtab" and "strtab_section" in relocate_symbols are changed to "symtab"
  instead, so as to be less confusing when "strtab" is moved to a struct in a
  later patch.

- The places where we pass section_vaddresses to functions are changed to also
  be called section_vaddresses"inside those functions, so I get less confused
  when I put addresses and vaddresses in a struct in a later patch.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones 2b48bc8656 mkimage: make it easier to run syntax checkers on grub-mkimagexx.c
This makes it so you can treat grub-mkimagexx.c as a file you can build
directly, so syntax checkers like vim's "syntastic" plugin, which uses
"gcc -x c -fsyntax-only" to build it, will work.

One still has to do whatever setup is required to make it pick the right
include dirs, which -W options we use, etc., but this makes it so you
can do the checking on the file you're editing, rather than on a
different file.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Peter Jones d4821938f5 aout.h: Fix missing include.
grub_aout_load() has a grub_file_t parameter, and depending on what order
includes land in, it's sometimes not defined.  This patch explicitly adds
file.h to aout.h so that it will always be defined.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Joakim Bech 09737b803f ieee1275: fix build regression in of_path_of_nvme
The of_path_of_nvme function (commit 2391d57, ieee1275: add nvme
support within ofpath) introduced a build regression:
    grub-core/osdep/linux/ofpath.c:365:21: error: comparison between pointer
    and zero character constant [-Werror=pointer-compare]
       if ((digit_string != '\0') && (*part_end == 'p'))

Update digit_string to compare against the char instead of the pointer.

Signed-off-by: Joakim Bech <joakim.bech@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm 7bc672fbbf arm: make linux.h safe to include for non-native builds
<grub/machine/loader.h> (for machine arm/efi) and
<grub/machine/kernel.h> (for machine arm/coreboot) will not always
resolve (and will likely not be valid to) if pulled in when building
non-native commands, such as host tools or the "file" command.
So explicitly include them with their expanded pathnames.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm 4b17e63148 arm: switch linux loader to linux_arm_kernel_header struct
Use kernel header struct and magic definition to align (and coexist) with
i386/arm64 ports.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm d8472e190c arm64: align linux kernel magic macro naming with i386
Change GRUB_ARM64_LINUX_MAGIC to GRUB_LINUX_ARM64_MAGIC_SIGNATURE.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm 324bbebdb7 arm64: align linux kernel header struct naming with i386
Rename struct grub_arm64_linux_kernel_header -> linux_arm64_kernel_header.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm 103779a19e i386: make struct linux_kernel_header architecture specific
struct linux_kernel_header -> struct linux_i386_kernel_header

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm 1901a159bd make GRUB_LINUX_MAGIC_SIGNATURE architecture-specific
Rename GRUB_LINUX_MAGIC_SIGNATURE GRUB_LINUX_I386_MAGIC_SIGNATURE,
to be usable in code that supports more than one image type.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm f0ffa15cd5 Make arch-specific linux.h include guards architecture unique
Replace uses of GRUB_LINUX_MACHINE_HEADER and GRUB_LINUX_CPU_HEADER
with GRUB_<arch>_LINUX_HEADER include guards to prevent issues when
including more than one of them.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Leif Lindholm e5ae7a2704 arm64/efi: move EFI_PAGE definitions to efi/memory.h
The EFI page definitions and macros are generic and should not be confined
to arm64 headers - so move to efi/memory.h.
Also add EFI_PAGE_SIZE macro.

Update loader sources to reflect new header location.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Colin Watson 9363f738ba libgcrypt: Import replacement CRC operations
The CRC implementation imported from libgcrypt 1.5.3 is arguably
non-free, due to being encumbered by the restrictive Internet Society
licence on RFCs (see e.g. https://wiki.debian.org/NonFreeIETFDocuments).
Fortunately, libgcrypt has since replaced it with a version that is both
reportedly better-optimised and doesn't suffer from this encumbrance.

The ideal solution would be to update to a new version of libgcrypt, and
I spent some time trying to do that.  However, util/import_gcry.py
requires complex modifications to cope with the new version, and I
stalled part-way through; furthermore, GRUB's libgcrypt tree already
contains some backports of upstream changes.  Rather than allowing the
perfect to be the enemy of the good, I think it's best to backport this
single change to at least sort out the licensing situation.  Doing so
won't make things any harder for a future wholesale upgrade.

This commit is mostly a straightforward backport of
https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=06e122baa3321483a47bbf82fd2a4540becfa0c9,
but I also imported bufhelp.h from libgcrypt 1.7.0 (newer versions
required further changes elsewhere).

I've tested that "hashsum -h crc32" still produces correct output for a
variety of files on both i386-pc and x86_64-emu targets.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 3d1069e2e2 ieee1275: add nvme support within ofpath
Add NVMe support within ofpath.

The Open Firmware text representation for a NVMe device contains the
Namespace ID. An invalid namespace ID is one whose value is zero or whose
value is greater than the value reported by the Number of Namespaces (NN)
field in the Identify Controller data structure.  At the moment  only a
single Namespace is supported, therefore the value is currently hard coded
to one.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Daniel Kiper 5826e32c37 chainloader: Fix wrong break condition (must be AND not, OR)
The definition of bpb's num_total_sectors_16 and num_total_sectors_32
is that either the 16-bit field is non-zero and is used (in which case
eg mkfs.fat sets the 32-bit field to zero), or it is zero and the
32-bit field is used. Therefore, a BPB is invalid only if *both*
fields are zero; having one field as zero and the other as non-zero is
the case to be expected. (Indeed, according to Microsoft's specification
one of the fields *must* be zero, and the other non-zero.)

This affects all users of grub_chainloader_patch_bpb which are in
chainloader.c, freedos.c, and ntldr.c

Some descriptions of the semantics of these two fields:

https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html

  The old 2-byte fields "total number of sectors" and "number of
  sectors per FAT" are now zero; this information is now found in
  the new 4-byte fields.

(Here given in the FAT32 EBPB section but the total sectors 16/32 bit
fields semantic is true of FAT12 and FAT16 too.)

https://wiki.osdev.org/FAT#BPB_.28BIOS_Parameter_Block.29

  19 | 2 | The total sectors in the logical volume. If this value is 0,
  it means there are more than 65535 sectors in the volume, and the actual
  count is stored in "Large Sectors (bytes 32-35).

  32 | 4 | Large amount of sector on media. This field is set if there
  are more than 65535 sectors in the volume.

(Doesn't specify what the "large" field is set to when unused, but as
mentioned mkfs.fat sets it to zero then.)

https://technet.microsoft.com/en-us/library/cc976796.aspx

  0x13 | WORD | 0x0000 |
  Small Sectors . The number of sectors on the volume represented in 16
  bits (< 65,536). For volumes larger than 65,536 sectors, this field
  has a value of zero and the Large Sectors field is used instead.

  0x20 | DWORD | 0x01F03E00 |
  Large Sectors . If the value of the Small Sectors field is zero, this
  field contains the total number of sectors in the FAT16 volume. If the
  value of the Small Sectors field is not zero, the value of this field
  is zero.

https://staff.washington.edu/dittrich/misc/fatgen103.pdf page 10

  BPB_TotSec16 | 19 | 2 |
  This field is the old 16-bit total count of sectors on the volume.
  This count includes the count of all sectors in all four regions of the
  volume. This field can be 0; if it is 0, then BPB_TotSec32 must be
  non-zero. For FAT32 volumes, this field must be 0. For FAT12 and
  FAT16 volumes, this field contains the sector count, and
  BPB_TotSec32 is 0 if the total sector count “fits” (is less than
  0x10000).

  BPB_TotSec32 | 32 | 4 |
  This field is the new 32-bit total count of sectors on the volume.
  This count includes the count of all sectors in all four regions of the
  volume. This field can be 0; if it is 0, then BPB_TotSec16 must be
  non-zero. For FAT32 volumes, this field must be non-zero. For
  FAT12/FAT16 volumes, this field contains the sector count if
  BPB_TotSec16 is 0 (count is greater than or equal to 0x10000).

(This specifies that an unused BPB_TotSec32 field is set to zero.)

By the way fix offsets in include/grub/fat.h.

Tested with lDebug booted in qemu via grub2's
FreeDOS direct loading support, refer to
https://bitbucket.org/ecm/ldosboot + https://bitbucket.org/ecm/ldebug

Signed-off-by: C. Masloch <pushbx@38.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Steve McIntyre 0b6bd057c0 Make grub-install check for errors from efibootmgr
Code is currently ignoring errors from efibootmgr, giving users
clearly bogus output like:

        Setting up grub-efi-amd64 (2.02~beta3-4) ...
        Installing for x86_64-efi platform.
        Could not delete variable: No space left on device
        Could not prepare Boot variable: No space left on device
        Installation finished. No error reported.

and then potentially unbootable systems. If efibootmgr fails, grub-install
should know that and report it!

We've been using similar patch in Debian now for some time, with no ill effects.

Signed-off-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 984c022638 sparc64: fix OF path names for sun4v systems
Fix the Open Firmware (OF) path property for sun4v SPARC systems.
These platforms do not have a /sas/ within their path. Over time
different OF addressing schemes have been supported. There
is no generic addressing scheme that works across every HBA.

It looks that this functionality will not work if you try to cross-install
SPARC GRUB2 binary using e.g. x86 grub-install. By default it should work.
However, we will also have other issues here, like lack of access to OF
firmware/paths, which make such configs unusable anyway. So, let's leave
this patch as is for time being. If somebody cares then he/she should fix
the issue(s) at some point.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg d1ff22fc5a sparc64: Add blocklist GPT support for SPARC
Add block-list GPT support for SPARC.  The OBP "load" and "boot" methods
are partition aware and neither command can see the partition table. Also
neither command can address the entire physical disk. When the install
happens, grub generates the block-list entries based on the beginning of the
physical disk, not the beginning of the partition. This patch fixes the
block-list entries so they match what OBP expects during boot for a GPT disk.

T5 and above now supports GPT as well as VTOC.

This patch has been tested on T5-2 and newer SPARC systems.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Stefan Fritsch d97d20da82 ahci: Improve error handling
Check the error bits in the interrupt status register. According to the
AHCI 1.2 spec, "Interrupt sources that are disabled (‘0’) are still
reflected in the status registers.", so this should work even though
grub uses polling

This fixes the following problem on a Fujitsu E744 laptop:

Sometimes there is a very long delay (up to several minutes) when
booting from hard disk. It seems accessing the DVD drive (which has no
disk inserted) sometimes fails with some errors, which leads to each
access being stalled until the 20s timeout triggers. This seems to
happen when grub is trying to read filesystem/partition data.

The problem is that the command_issue bit that is checked in the loop is
only reset if the "HBA receives a FIS which clears the BSY, DRQ, and ERR
bits for the command", but the ERR bit is never cleared. Therefore
command_issue is never reset and grub waits for the timeout.

The relevant bit in our case is the Task File Error Status (TFES), which
is equivalent to the ERR bit 0 in tfd. But this patch also checks
the other error bits except for the "Interface non-fatal error status"
bit.

Signed-off-by: Stefan Fritsch <fritsch@genua.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
dann frazier 0aa1f2febd Keep the native terminal active when enabling gfxterm
grub-mkconfig will set GRUB_TERMINAL_OUTPUT to "gfxterm" unless the user
has overridden it. On EFI systems, this will stop output from going to the
default "console" terminal. When the EFI fw console is configured to output to
both serial and video, this will cause GRUB to only display on video - while
continuing to accept input from both video and serial.

Instead of switching from "console" to "gfxterm", let's output to both.

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Julien Grall 43d7414af7 arm64/xen: Add missing #address-cells and #size-cells properties
The properties #address-cells and #size-cells are used to know the
number of cells for ranges provided by "regs". If they don't exist, the
value are resp. 2 and 1.

Currently, when multiboot nodes are created it is assumed that #address-cells
and #size-cells are exactly 2. However, they are never set by GRUB and
will result to later failure when the device-tree is generated by GRUB
or contain different values.

To prevent this failure, create the both properties in the chosen nodes.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Jordan Glover 57988555fb grub-mkconfig: Fix detecting .sig files as system images
grub-mkconfig detects detached RSA signatures for kernel images used for
signature checking as valid images and adds them to grub.cfg as separate
menu entries. This patch adds .sig extension to common blacklist.

Signed-off-by: Jordan Glover <Golden_Miller83@protonmail.ch>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 0659ce8313 ieee1275: Fix segfault in grub-ofpathname
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg f7d95b92f3 grub-install: Fix memory leak
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Eric Snowberg 4aeba29569 ls: prevent double open
Prevent a double open.  This can cause problems with some ieee1275
devices, causing the system to hang.  The double open can occur
as follows:

grub_ls_list_files (char *dirname, int longlist, int all, int human)
       dev = grub_device_open (device_name);
       dev remains open while:
       grub_normal_print_device_info (device_name);
                dev = grub_device_open (name);

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
David E. Box bee9cdaa2b tsc: Change default tsc calibration method to pmtimer on EFI systems
On efi systems, make pmtimer based tsc calibration the default over the
pit. This prevents Grub from hanging on Intel SoC systems that power gate
the pit.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Alexander Graf 8838ac368e efi: Free malloc regions on exit
When we exit grub, we don't free all the memory that we allocated earlier
for our heap region. This can cause problems with setups where you try
to descend the boot order using "exit" entries, such as PXE -> HD boot
scenarios.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:16:25 -04:00
Alexander Graf e224ee31c0 efi: Move grub_reboot() into kernel
The reboot function calls machine_fini() and then reboots the system.
Currently it lives in lib/ which means it gets compiled into the
reboot module which lives on the heap.

In a following patch, I want to free the heap on machine_fini()
though, so we would free the memory that the code is running in. That
obviously breaks with smarter UEFI implementations.

So this patch moves it into the core. That way we ensure that all
code running after machine_fini() in the UEFI case is running from
memory that got allocated (and gets deallocated) by the UEFI core.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:02:37 -04:00
Konrad Rzeszutek Wilk e8a9a2a1aa Use grub-file to figure out whether multiboot2 should be used for Xen.gz
The multiboot2 is much more preferable than multiboot. Especiall
if booting under EFI where multiboot does not have the functionality
to pass ImageHandler.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:02:37 -04:00
Konrad Rzeszutek Wilk 90d8ca6970 Fix util/grub.d/20_linux_xen.in: Add xen_boot command support for aarch64
Commit d33045ce7f introduced
the support for this, but it does not work under x86 (as it stops
20_linux_xen from running).

The 20_linux_xen is run under a shell and any exits from within it:

(For example on x86):
+ /usr/bin/grub2-file --is-arm64-efi /boot/xen-4.9.0.gz
[root@tst063 grub]# echo $?
1

will result in 20_linux_xen exiting without continuing
and also causing grub2-mkconfig to stop processing.

As in:

 [root@tst063 grub]# ./grub-mkconfig | tail
 Generating grub configuration file ...
 Found linux image: /boot/vmlinuz-4.13.0-0.rc5.git1.1.fc27.x86_64
 Found initrd image: /boot/initramfs-4.13.0-0.rc5.git1.1.fc27.x86_64.img
 Found linux image: /boot/vmlinuz-0-rescue-ec082ee24aea41b9b16aca52a6d10cc2
 Found initrd image: /boot/initramfs-0-rescue-ec082ee24aea41b9b16aca52a6d10cc2.img
 		echo	'Loading Linux 0-rescue-ec082ee24aea41b9b16aca52a6d10cc2 ...'
 		linux	/vmlinuz-0-rescue-ec082ee24aea41b9b16aca52a6d10cc2 root=/dev/mapper/fedora_tst063-root ro single
 		echo	'Loading initial ramdisk ...'
 		initrd	/initramfs-0-rescue-ec082ee24aea41b9b16aca52a6d10cc2.img
 	}
 }

 ### END /usr/local/etc/grub.d/10_linux ###

 ### BEGIN /usr/local/etc/grub.d/20_linux_xen ###

 root@tst063 grub]#

And no more.

This patch wraps the invocation of grub-file to be a in subshell
and to process the return value in a conditional. That fixes
the issue.

RH-BZ 1486002: grub2-mkconfig does not work if xen.gz is installed.

CC: Fu Wei <fu.wei@linaro.org>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 46159d35d3 Fix compilation for x86_64-efi. 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 219603c2e6 Add a file missing in multiboot2 commit. 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 3badaefe7f gzio: fix unaligned access 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 8995efd22b grub-fs-tester: Fix bashism 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 86b8024d5d Regenerate checksum.h with newer unifont.
Old link is broken. New unifont is
http://ftp.de.debian.org/debian/pool/main/u/unifont/xfonts-unifont_9.0.06-2_all.deb
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 621f536e94 printf_unit_test: Disable Wformat-truncation on GCC >= 7
We intentionally pass NULL as argument to format, hence disable the warning.
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 69c4c683b4 qemu, coreboot, multiboot: Change linking address to 0x9000.
It's common for distros to use a defective ld which links at 0x9000. Instead
of fighting it, just move link target to 0x9000.
2020-09-21 12:02:37 -04:00
Stefan Fritsch 8ce806120b Implement checksum verification for gunzip
This implements the crc32 check for the gzip format. Support for zlib's
adler checksum is not included, yet.
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 88a43b3f8c xfs: Don't attempt to iterate over empty directory.
Reported by: Tuomas Tynkkynen
2020-09-21 12:02:37 -04:00
Patrick Steinhardt 2da5f067f4 unix exec: avoid atexit handlers when child exits
The `grub_util_exec_redirect_all` helper function can be used to
spawn an executable and redirect its output to some files. After calling
`fork()`, the parent will wait for the child to terminate with
`waitpid()` while the child prepares its file descriptors, environment
and finally calls `execvp()`. If something in the children's setup
fails, it will stop by calling `exit(127)`.

Calling `exit()` will cause any function registered via `atexit()` to be
executed, which is usually the wrong thing to do in a child. And
actually, one can easily observe faulty behaviour on musl-based systems
without modprobe(8) installed: executing `grub-install --help` will call
`grub_util_exec_redirect_all` with "modprobe", which obviously fails if
modprobe(8) is not installed. Due to the child now exiting and invoking
the `atexit()` handlers, it will clean up some data structures of the
parent and cause it to be deadlocked in the `waitpid()` syscall.

The issue can easily be fixed by calling `_exit(127)` instead, which is
especially designed to be called when the atexit-handlers should not be
executed.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 2074525ba5 arc: Do not create spurious variable grub_arc_memory_type_t. 2020-09-21 12:02:37 -04:00
Xuan Guo cf12641347 Set have_exec to y on cygwin so we have grub_mkrescue. 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko aa6226fefb enforcing fixup 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko f6c8225f8c multiboot fixup 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko fcf791ab27 linux fixup 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 874a8f13cc yylex: Explicilty cast fprintf to void.
It's needed to avoid warning on recent GCC.
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 384d3e5b84 genmoddep: Check that no modules provide the same symbol.
The semantics of 2 modules providing the same symbol are undefined. So
ensure that it doesn't happen.
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 547d8201cf Fix symbols appearing in several modules in linux*.
If same symbol is provided by 2 modules its semantics are undefined.
Avoid this by depending rather than double-including files.
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko ec4630c2b5 multiboot: disentangle multiboot and multiboot2.
Previously we had multiboot and multiboot2 declaring the same symbols.
This can potentially lead to aliasing and strange behaviours when e.g.
module instead of module2 is used with multiboot2.

Bug: #51137
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko aa34f69d5d hdparm: Depend on hexdump rather than having a second copy of hexdump. 2020-09-21 12:02:37 -04:00
Vladimir Serbinenko ebb62ba084 grub.texi: Fix typo
Reported by: 	Ori Avtalion <saltyhorse>
2020-09-21 12:02:37 -04:00
Pete Batard 0f6ca5ecf9 io: add a GRUB_GZ prefix to gzio specific defines
* This is done to avoid a conflict with a PACKED define in the EDK2
2020-09-21 12:02:37 -04:00
Pete Batard 5ba09fb415 core: use GRUB_TERM_ definitions when handling term characters
* Also use hex value for GRUB_TERM_ESC as '\e' is not in the C standard and is not understood by some compilers
2020-09-21 12:02:37 -04:00
Leif Lindholm 5f294d3b9e efi: change heap allocation type to GRUB_EFI_LOADER_CODE
With upcoming changes to EDK2, allocations of type EFI_LOADER_DATA may
not return regions with execute ability. Since modules are loaded onto
the heap, change the heap allocation type to GRUB_EFI_LOADER_CODE in
order to permit execution on systems with this feature enabled.

Closes: 50420

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
2020-09-21 12:02:37 -04:00
Leif Lindholm 01f3dcc70a arm64 linux loader: improve type portability
In preparation for turning this into a common loader for 32-bit and 64-bit
platforms, ensure the code will compile cleanly for either.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
2020-09-21 12:02:37 -04:00
Leif Lindholm 793b90c851 efi: Add GRUB_PE32_MAGIC definition
Add a generic GRUB_PE32_MAGIC definition for the PE 'MZ' tag and delete
the existing one in arm64/linux.h.

Update arm64 Linux loader to use this new definition.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
2020-09-21 12:02:37 -04:00
Leif Lindholm 30f13fbfa6 efi: move fdt helper library
There is nothing ARM64 (or even ARM) specific about the efi fdt helper
library, which is used for locating or overriding a firmware-provided
devicetree in a UEFI system - so move it to loader/efi for reuse.

Move the fdtload.h include file to grub/efi and update path to
efi/fdtload.h in source code referring to it.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
2020-09-21 12:02:37 -04:00
Vladimir Serbinenko 6825a1d3f1 Remove grub_efi_allocate_pages.
grub_efi_allocate_pages Essentially does 2 unrelated things:
* Allocate at fixed address.
* Allocate at any address.

To switch between 2 different functions it uses address == 0 as magic
value which is wrong as 0 is a perfectly valid fixed adress to allocate at.
2020-09-21 12:02:37 -04:00
Leif Lindholm 22619f1593 efi: refactor grub_efi_allocate_pages
Expose a new function, grub_efi_allocate_pages_real(), making it possible
to specify allocation type and memory type as supported by the UEFI
AllocatePages boot service.

Make grub_efi_allocate_pages() a consumer of the new function,
maintaining its old functionality.

Also delete some left-around #if 1/#else blocks in the affected
functions.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 184d71d527 Fail if xorriso failed.
If xorriso failed most likely we didn't generate a meaningful image.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 1fd3a7f048 mkrescue: Check xorriso presence before doing anything else.
mkrescue can't do anything useful without xorriso, so abort early if it's
not available.
2020-09-21 11:32:45 -04:00
Pali Rohár 682b3134b6 * grub-core/fs/udf.c: Add support for UUID
Use same algorithm as in libblkid from util-linux v2.30.

1. Take first 16 bytes from UTF-8 encoded string of VolumeSetIdentifier
2. If all bytes are hexadecimal digits, convert to lowercase and use as UUID
3. If first 8 bytes are not all hexadecimal digits, convert those 8 bytes
   to their hexadecimal representation, resulting in 16 bytes for UUID
4. Otherwise, compose UUID from two parts:
   1. part: converted first 8 bytes (which are hexadecimal digits) to lowercase
   2. part: encoded following 4 bytes to their hexadecimal representation (16 bytes)

So UUID would always have 16 hexadecimal digits in lowercase variant.

According to UDF specification, first 16 Unicode characters of
VolumeSetIdentifier should be unique value and first 8 should be
hexadecimal characters.

In most cases all 16 characters are hexadecimal, but e.g. MS Windows
format.exe set only first 8 as hexadecimal and remaining as fixed
(non-unique) which violates specification.
2020-09-21 11:32:45 -04:00
Pali Rohár ab444c54a7 udf: Fix reading label, lvd.ident is dstring
UDF dstring has stored length in the last byte of buffer. Therefore last
byte is not part of recorded characters. And empty string in dstring is
encoded as empty buffer, including first byte (compression id).
2020-09-21 11:32:45 -04:00
Pete Batard e2296e205e zfs: remove size_t typedef and use grub_size_t instead
* Prevents some toolchains from issuing a warning on size_t redef.
2020-09-21 11:32:45 -04:00
Rob Clark a74336596f Fix a segfault in lsefi
when protocols_per_handle returns error, we can't use the pointers we
passed to it, and that includes trusting num_protocols.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 21b3d3efee fdt: silence clang warning. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 0c4852ea0e arm-efi: Fix compilation 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 8efa8a0e94 ehci: Fix compilation on i386 2020-09-21 11:32:45 -04:00
phcoder a4d4008588 cache: Fix compilation for ppc, sparc and arm64 2020-09-21 11:32:45 -04:00
phcoder 8d54a08733 ehci: Fix compilation for amd64 2020-09-21 11:32:45 -04:00
Eric Biggers 4aaa6b639d Allow GRUB to mount ext2/3/4 filesystems that have the encryption feature.
On such a filesystem, inodes may have EXT4_ENCRYPT_FLAG set.
For a regular file, this means its contents are encrypted; for a
directory, this means the filenames in its directory entries are
encrypted; and for a symlink, this means its target is encrypted.  Since
GRUB cannot decrypt encrypted contents or filenames, just issue an error
if it would need to do so.  This is sufficient to allow unencrypted boot
files to co-exist with encrypted files elsewhere on the filesystem.

(Note that encrypted regular files and symlinks will not normally be
encountered outside an encrypted directory; however, it's possible via
hard links, so they still need to be handled.)

Tested by booting from an ext4 /boot partition on which I had run
'tune2fs -O encrypt'.  I also verified that the expected error messages
are printed when trying to access encrypted directories, files, and
symlinks from the GRUB command line.  Also ran 'sudo ./grub-fs-tester
ext4_encrypt'; note that this requires e2fsprogs v1.43+ and Linux v4.1+.

Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-09-21 11:32:45 -04:00
Eric Snowberg da4e8334b2 sparc64: Don't use devspec to determine the OBP path
Don't use devspec to determine the OBP path on SPARC hardware.  Within all
versions of Linux on SPARC, the devspec returns one of three values:
"none", "vnet-port", or "vdisk".  Unlike on PPC, none of these values
are useful in determining the OBP path.

Before this patch grub-ofpathname always returned the wrong value
for a virtual disk. For example:

% grub-ofpathname /dev/vdiskc2
vdisk/disk@2:b

After this patch it now returns the correct value:

% grub-ofpathname /dev/vdiskc2
/virtual-devices@100/channel-devices@200/disk@2:b

Orabug: 24459765

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Fu Wei 6e329bec23 arm64: Update the introduction of Xen boot commands in docs/grub.texi
delete: xen_linux, xen_initrd, xen_xsm
add: xen_module

This update bases on
    commit 0edd750e50
    Author: Vladimir Serbinenko <phcoder@gmail.com>
    Date:   Fri Jan 22 10:18:47 2016 +0100

        xen_boot: Remove obsolete module type distinctions.

Also bases on the module loading mechanism of Xen code:
488c2a8 docs/arm64: clarify the documention for loading XSM support
67831c4 docs/arm64: update the documentation for loading XSM support
ca32012 xen/arm64: check XSM Magic from the second unknown module.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Fu Wei 911910089b util/grub.d/20_linux_xen.in: Add xen_boot command support for aarch64
This patch adds the support of xen_boot command for aarch64:
    xen_hypervisor
    xen_module
These two commands are only for aarch64, since it has its own protocol and
commands to boot xen hypervisor and Dom0, but not multiboot.

For other architectures, they are still using multiboot and module
commands.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Fu Wei 3418e2bd52 arm64: Add "--nounzip" option support in xen_module command
This patch adds "--nounzip" option support in order to
be compatible with the module command of multiboot on other architecture,
by this way we can simplify grub-mkconfig support code.

This patch also allow us to use zip compressed module(like Linux kernel
for Dom0).

Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Julien Grall bf4d71848f arm64/xen_boot: Fix Xen boot using GRUB2 on AARCH64
Xen is currently crashing because of malformed compatible property for
the boot module. This is because the property string is not
null-terminated as requested by the ePAR spec.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Tested-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Eric Snowberg 53d00ac6ef sparc64: Close cdboot ihandle
The ihandle is left open with a cd-core image.  This will cause a delay
booting grub from a virtual cdrom in a LDOM.  It will also cause problems
as Linux boots, since it expects the ihandle to be closed during init.

Orabug: 25911275

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 6ff34a6a81 at_keyboard: Fix falco chromebook case.
EC is slow, so we need few delays for it to toggle the bits correctly.

Command to enable clock and keyboard were not sent.
2020-09-21 11:32:45 -04:00
Julius Werner 4ffbbeca95 coreboot: Changed cbmemc to support updated console format from coreboot. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 4ff15188e3 Missing parts of previous commit 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 366dee1f7f arm_coreboot: Add Chromebook keyboard driver. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko aad5863e98 rk3288_spi: Add SPI driver 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko eaa55f4a23 fdtbus: Add ability to send/receive messages on parent busses. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 212c93aa36 Fix bug on FDT nodes with compatible property 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 25a88d14dd arm_coreboot: Support EHCI. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 56c0a46068 ehci: Split core code from PCI part.
On ARM often EHCI is present without PCI and just declared in device
tree. So splitcore from PCI part.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko d4529d5d02 arm_coreboot: Support DMA.
This is needed to support USB and some other busses.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 5e1a343a37 arm_coreboot: Support loading linux images. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko f09c41cfa9 arm_coreboot: Support grub-mkstandalone. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko f66206989f arm_coreboot: Support keyboard for vexpress. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 7948b1a398 at_keyboard: Split protocol from controller code.
On vexpress controller is different but protocol is the same, so reuse the
code.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko ed5c6e9385 arm-coreboot: Export FDT routines.
We need to use them from modules as well.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 7b6c1ca1ac arm-coreboot: Support for vexpress timer. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 1895c3806b Add support for device-tree-based drivers. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko aa7585d04b arm-coreboot: Start new port. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 2f061fac71 Rename uboot/datetime to dummy/datetime.
It's just a stub and is not UBoot-specific.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko ff7416a848 Rename uboot/halt.c to dummy/halt.c.
It's not U-Boot specific and it's a stub.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 9ec5094213 coreboot: Split parts that are platform-independent.
We currently assume that coreboot is always i386, it's no longer the case,
so split i386-coreboot parts from generic coreboot code.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 25cd7a7df9 Refactor arm-uboot code to make it genereic.
arm-coreboot startup code can be very similar to arm-uboot but current code has
U-Boot specific references. So split U-Boot part from generic part.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 587d1e78c9 mkimage: Pass layout to mkimage_generate_elfXX rather than some fields.
This allows easier extension of this function without having too long of
arguments list.
2020-09-21 11:32:45 -04:00
Paulo Flabiano Smorigo 5696d56d33 Add Virtual LAN support.
This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows
multiple VLANs in a bridged network to share the same physical network link
but maintain isolation:

http://en.wikipedia.org/wiki/IEEE_802.1Q

* grub-core/net/ethernet.c: Add check, get, and set vlan tag id.
* grub-core/net/drivers/ieee1275/ofnet.c: Get vlan tag id from bootargs.
* grub-core/net/arp.c: Add check.
* grub-core/net/ip.c: Likewise.
* include/grub/net/arp.h: Add vlantag attribute.
* include/grub/net/ip.h: Likewise.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 99ab28563b strtoull: Fix behaviour on chars between '9' and 'a'.
Reported by: Aaron Miller <aaronmiller@fb.com>
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 61f4f2d4ef Add strtoull test. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko a567ab3d9e Fix shebang for termux.
Termux doesn't have a /bin/sh. So we needto use $SHELL.
Keep /bin/sh as much as possible.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 9919fb0e9f Add termux path to dict. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 72876e750d po: Use @SHELL@ rather than /bin/sh.
/bin/sh might not exist.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 01415074da Use $(SHELL) rather than /bin/sh.
/bin/sh doesn't exist under termux.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 4152833f0c Support lseek64.
Android doesn't have 64-bit off_t, so use off64_t instead.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 7171645366 Don't retrieve fstime when it's not useful. 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko b03f255546 support busybox date.
Busybox date doesn't understand weekdays in -d input,
so strip them beforehand.
2020-09-21 11:32:45 -04:00
Vladimir Serbinenko e6b2fcc9d8 fs-tester: make sh-compatible 2020-09-21 11:32:45 -04:00
Vladimir Serbinenko 427e4ff91a Remove bashisms from tests.
Those tests don't actually need bash. Just use common shebang.
2020-09-21 11:19:14 -04:00
Vladimir Serbinenko d3bccdbd12 Bump version to 2.03 2020-09-21 11:19:14 -04:00
Dongsu Park 7ee80206a6
Merge pull request #1 from flatcar-linux/dongsu/merge-2.02-coreos
Merge upstream 2.02-coreos branch 2019-10-24
2019-10-25 15:29:15 +02:00
H.J. Lu 1c4dc293df x86-64: Treat R_X86_64_PLT32 as R_X86_64_PC32
Starting from binutils commit bd7ab16b4537788ad53521c45469a1bdae84ad4a:

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=bd7ab16b4537788ad53521c45469a1bdae84ad4a

x86-64 assembler generates R_X86_64_PLT32, instead of R_X86_64_PC32, for
32-bit PC-relative branches.  Grub2 should treat R_X86_64_PLT32 as
R_X86_64_PC32.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit 842c390469)
2019-10-24 16:59:37 +02:00
Michael Chang 721b4677ab Fix packed-not-aligned error on GCC 8
When building with GCC 8, there are several errors regarding packed-not-aligned.

./include/grub/gpt_partition.h:79:1: error: alignment 1 of ‘struct grub_gpt_partentry’ is less than 8 [-Werror=packed-not-aligned]

This patch fixes the build error by cleaning up the ambiguity of placing
aligned structure in a packed one. In "struct grub_btrfs_time" and "struct
grub_gpt_part_type", the aligned attribute seems to be superfluous, and also
has to be packed, to ensure the structure is bit-to-bit mapped to the format
laid on disk. I think we could blame to copy and paste error here for the
mistake. In "struct efi_variable", we have to use grub_efi_packed_guid_t, as
the name suggests. :)

Signed-off-by: Michael Chang <mchang@suse.com>
Tested-by: Michael Chang <mchang@suse.com>
Tested-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit 563b1da6e6)
2019-10-24 16:59:37 +02:00
Luca Bruno 750c71975e loader/i386: fix out of bound memory copy on non-UEFI linux
Ref: https://bugzilla.opensuse.org/show_bug.cgi?id=1029187
Ref: https://build.opensuse.org/package/rdiff/openSUSE:Factory/grub2?linkrev=base&rev=159
2019-10-24 16:59:37 +02:00
David Michael d3fd939f18
Merge pull request #48 from arm64b/build-issue-fixing
TPM: build issue fixing
2017-11-08 21:59:01 -05:00
Dennis Chen 63818e7800 Remove the deprecated 'Event' struct
'Event' struct will be not used any more, instead we use the
'TCG_PCR_EVENT', so this patch remove the older 'Event' data struct.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
2017-11-08 09:45:39 +00:00
Dennis Chen 7cf67f22fd Fix the build issue in TPM module
The original code use deprecated 'Event' data structure with the wrong
member variable names, which result in the build error. This patch
fix it by using 'TCG_PCR_EVENT'.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
2017-11-08 09:28:49 +00:00
Dennis Chen c3bd5d1b36 Prototype fixing for (*hash_log_extend_event)
According to the section 6.6.1 'Prototype' in 'TCG EFI Protocol Spec',
the 3rd parameter of the (*hash_log_extend_event) should be
'EFI_PHYSICAL_ADDRESS' which is 'grub_efi_physical_address_t' in the
real implementation. So this patch drop the pointer mark '*' from this
prototype.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
2017-11-08 09:13:00 +00:00
David Michael 84a4fd2f4c Merge pull request #47 from 1337ninja/dev
Fix use after free
2017-09-26 21:29:37 -07:00
1337ninja 1624d0ffc6 Fix use after free 2017-07-09 18:38:15 +05:30
David Michael 6782f6d431 Merge pull request #46 from dm0-/sync
Merge with the upstream 2.02 release branch
2017-04-27 18:50:28 -07:00
David Michael f89e1cf69a Merge branch 'gnu' into sync 2017-04-27 12:05:22 -07:00
Benjamin Gilbert ccf8c4a280 Merge pull request #45 from bgilbert/grub-amd64
Fix missing VERITY_HASH_OFFSET on amd64
2017-01-30 13:38:46 -08:00
Benjamin Gilbert 490d38ffc0 Fix missing VERITY_HASH_OFFSET on amd64 2017-01-30 13:25:51 -08:00
Michael Marineau e2e860614f Merge pull request #42 from glevand/for-merge-arm64-verity
Add arm64 verity support
2017-01-25 18:18:01 -08:00
Geoff Levand dc2eaa5855 loader: Add arm64 verity
Signed-off-by: Geoff Levand <geoff@infradead.org>
2017-01-25 14:54:46 -08:00
Geoff Levand c9bd29e124 loader: verity-hash.h fixups
o Add some comments.
o Change image buffer type to (const void *).
o Add new macro VERITY_CMDLINE_LENGTH.

Signed-off-by: Geoff Levand <geoff@infradead.org>
2017-01-25 14:54:46 -08:00
Geoff Levand 57fca7d1a3 loader: Move verity-hash.h to include
Signed-off-by: Geoff Levand <geoff@infradead.org>
2017-01-25 14:54:46 -08:00
David Michael ff8d967eff Merge pull request #44 from dm0-/sync
Merge with upstream master
2017-01-24 12:00:11 -08:00
David Michael e576eb0cbc Merge remote-tracking branch 'upstream/master' 2017-01-23 14:02:45 -08:00
Michael Marineau bca61d04a0 Merge pull request #41 from marineam/xen
Add support for our verity hash scheme under Xen
2016-10-19 20:53:58 -07:00
Michael Marineau bcd7fb9fd2 loader: add support for passing verity hash to xen kernels
This only supports DomU Linux bzImage, ignoring bare ELF images and
Dom0 Xen+Linux but those cases are not applicable to us on CoreOS.
2016-10-19 15:18:06 -07:00
Michael Marineau dab6a0f0c3 loader: validate cmdline string length before appending verity arg 2016-10-19 14:12:55 -07:00
Matthew Garrett 6d3b1dc72b Merge pull request #40 from mjg59/tpm_error_fix
Make TPM errors less fatal
2016-10-13 15:27:09 -07:00
Matthew Garrett bf25cda14e Make TPM errors less fatal
Handle TPM errors, and stop trying to use the TPM once we hit one.
2016-10-13 14:01:52 -07:00
Michael Marineau 5962f7d5e7 Merge pull request #39 from marineam/weird-disk-size
Tolerate systems that report different disk sizes in firmware and OS
2016-09-23 12:32:56 -07:00
Michael Marineau 44f54cbf43 gpt: write backup GPT first, skip if inaccessible.
Writing the primary GPT before the backup may lead to a confusing
situation: booting a freshly updated system could consistently fail and
next boot will fall back to the old system if writing the primary works
but writing the backup fails. If the backup is written first and fails
the primary is left in the old state so the next boot will re-try and
possibly fail in the exact same way. Making that repeatable should make
it easier for users to identify the error.

Additionally if the firmware and OS disagree on the disk size, making
the backup inaccessible to GRUB, then just skip writing the backup.
When this happens the automatic call to `coreos-setgoodroot` after boot
will take care of repairing the backup.
2016-09-23 12:25:53 -07:00
Michael Marineau e4d25afd18 gpt: prefer disk size from header over firmware
The firmware and the OS may disagree on the disk configuration and size.
Although such a setup should be avoided users are unlikely to know about
the problem, assuming everything behaves like the OS. Tolerate this as
best we can and trust the reported on-disk location over the firmware
when looking for the backup GPT. If the location is inaccessible report
the error as best we can and move on.
2016-09-23 12:25:53 -07:00
Michael Marineau d5ba259c89 Merge pull request #38 from marineam/cleanup
gpt: various cleanup and error handling improvements
2016-09-22 13:31:55 -07:00
Michael Marineau 8f7045ee19 gpt: rename and update documentation for grub_gpt_update
The function now does more than just recompute checksums so give it a
more general name to reflect that.
2016-09-22 11:58:44 -07:00
Michael Marineau 7cd866bd2d gpt: report all revalidation errors
Before returning an error that the primary or backup GPT is invalid push
the existing error onto the stack so the user will be told what is bad.
2016-09-22 11:57:29 -07:00
Michael Marineau 5342b880f4 gpt: read entries table at the same time as the header
I personally think this reads easier. Also has the side effect of
directly comparing the primary and backup tables instead of presuming
they are equal if the crc32 matches.
2016-09-21 16:34:36 -07:00
Michael Marineau f24685b22e gpt: include backup-in-sync check in revalidation 2016-09-21 16:34:36 -07:00
Michael Marineau d2f9096444 gpt: always revalidate when recomputing checksums
This ensures all code modifying GPT data include the same sanity check
that repair does. If revalidation fails the status flags are left in the
appropriate state.
2016-09-21 16:34:36 -07:00
Michael Marineau 427fdc58e1 gpt: selectively update fields during repair
Just a little cleanup/refactor to skip touching data we don't need to.
2016-09-21 16:34:36 -07:00
Michael Marineau 1f5d29420c gpt: be more careful about relocating backup header
The header was being relocated without checking the new location is
actually safe. If the BIOS thinks the disk is smaller than the OS then
repair may relocate the header into allocated space, failing the final
validation check. So only move it if the disk has grown.

Additionally, if the backup is valid then we can assume its current
location is good enough and leave it as-is.
2016-09-21 16:34:36 -07:00
Michael Marineau de8d29ef89 gpt: check header and entries status bits together
Use the new status function which checks *_HEADER_VALID and
*_ENTRIES_VALID bits together. It doesn't make sense for the header and
entries bits to mismatch so don't allow for it.
2016-09-21 13:50:06 -07:00
Michael Marineau d57c41e8f5 Merge pull request #37 from marineam/enum
gpt: do not use an enum for status bit values
2016-09-21 13:26:57 -07:00
Michael Marineau 962db6c639 gpt: do not use an enum for status bit values 2016-09-21 13:24:55 -07:00
Michael Marineau 34abfb37e7 Merge pull request #36 from marineam/repair
Fix gptrepair's status bit checking
2016-09-21 13:14:13 -07:00
Michael Marineau f4e09602dc gpt: allow repair function to noop
Simplifies usage a little.
2016-09-21 13:12:31 -07:00
Michael Marineau 3dda6a863a gpt: use inline functions for checking status bits
This should prevent bugs like 6078f836 and 4268f3da.
2016-09-21 13:12:03 -07:00
Michael Marineau 4268f3da52 gptrepair: fix status checking
None of these status bit checks were correct. Fix and simplify.
2016-09-20 13:29:07 -07:00
Michael Marineau 40e2f6fd35 Merge pull request #35 from marineam/fix-table
gpt: fix partition table indexing and validation
2016-09-02 17:05:08 -07:00
Vito Caputo 92b5bd1ce3 gpt: add helper for picking a valid header
Eliminate some repetition in primary vs. backup header acquisition.
2016-09-02 17:04:13 -07:00
Michael Marineau bf127238ee gpt: fix partition table indexing and validation
Portions of the code attempted to handle the fact that GPT entries on
disk may be larger than the currently defined struct while others
assumed the data could be indexed by the struct size directly. This
never came up because no utility uses a size larger than 128 bytes but
for the sake of safety we need to do this by the spec.
2016-09-02 17:04:13 -07:00
Michael Marineau 87dfbf34c4 Merge pull request #33 from marineam/repair-corruption
Fix gptprio to properly detect and repair corruption
2016-08-22 19:40:21 -07:00
Michael Marineau f9fe0d781a Merge pull request #34 from marineam/extended-validation
Add stricter validation of GPT headers
2016-08-22 19:39:30 -07:00
Michael Marineau b2ca30d335 fix checking alternate_lba 2016-08-22 18:30:56 -07:00
Michael Marineau c68fcd3b1a gpt: refuse to write to sector 0 2016-08-22 17:51:48 -07:00
Michael Marineau 8278022a0b gpt: improve validation of GPT headers
Adds basic validation of all the disk locations in the headers, reducing
the chance of corrupting weird locations on disk.
2016-08-22 17:51:48 -07:00
Michael Marineau 6078f83638 gpt: properly detect and repair invalid tables
GPT_BOTH_VALID is 4 bits so simple a boolean check is not sufficient.
This broken condition allowed gptprio to trust bogus disk locations in
headers that were marked invalid causing arbitrary disk corruption.
2016-08-22 17:33:17 -07:00
Michael Marineau 4d91c78833 gptprio_test: check GPT is repaired when appropriate 2016-08-22 17:33:17 -07:00
Michael Marineau 6bc5c77bd5 gptrepair_test: fix typo in cleanup trap 2016-08-22 17:33:17 -07:00
Michael Marineau 1c205c2c4d Merge pull request #31 from marineam/verbose-debug
Add verbose debug logging to biosdisk and gpt
2016-08-22 17:22:34 -07:00
Michael Marineau c2f5fde6ab gpt: add verbose debug logging 2016-08-22 13:02:29 -07:00
Michael Marineau d38d2d0fb1 biosdisk: add verbose debug logging 2016-08-22 13:02:29 -07:00
Michael Marineau 3d1efb83ed Merge pull request #32 from marineam/tpm
tpm: fix warnings when compiling for platforms other than pc and efi
2016-08-22 12:53:07 -07:00
Michael Marineau 2de6ebf196 tpm: fix warnings when compiling for platforms other than pc and efi 2016-08-21 18:45:02 -07:00
Michael Marineau a7b0b20c87 Merge pull request #30 from marineam/fwcfg
fwconfig: fix unused argument warning
2016-08-21 11:21:47 -07:00
Michael Marineau 9a8cd5a16a fwconfig: fix unused argument warning 2016-08-20 17:54:47 -07:00
Michael Marineau 2ff7bd91eb Merge pull request #29 from marineam/big-bad-disk
gpt: do not use disk sizes GRUB will reject as invalid later on
2016-07-25 16:05:48 -07:00
Nick Owens d4602dd67f Merge pull request #28 from mischief/client-arch
net: add client arch and fix user class/terminator
2016-07-25 15:55:23 -07:00
Michael Marineau a8ad608425 gpt: do not use disk sizes GRUB will reject as invalid later on
GRUB assumes that no disk is ever larger than 1EiB and rejects
reads/writes to such locations. Unfortunately this is not conveyed in
the usual way with the special GRUB_DISK_SIZE_UNKNOWN value.
2016-07-25 15:35:01 -07:00
Nick Owens fbf65674a4 net: add client arch and fix user class/terminator
send client arch in bootp requests, for now BIOS and x64/aarch64 EFI is
supported.

fix a bug introduced in 4d5d7be005 where
user class was encoded improperly, although this didn't seem to have any
detrimental effects.

properly insert an option terminator.
2016-07-08 15:39:04 -07:00
Nick Owens a1724dace5 Merge pull request #27 from mischief/cmddevice
set cmddevice when cmdpath is set
2016-06-01 14:08:23 -07:00
Nick Owens 5470929309 set cmddevice when cmdpath is set 2016-06-01 13:55:45 -07:00
Nick Owens 68ae3c416b Merge pull request #26 from mischief/getenv-efi
grub-core: enable getenv for all efi targets
2016-04-14 15:03:43 -07:00
Nick Owens 70b45a45b9 grub-core: enable getenv for all efi targets 2016-04-14 14:47:39 -07:00
mjg59 ad906495e1 Merge pull request #25 from mjg59/tpm
Fix event log prefix
2016-03-29 21:29:47 -07:00
Matthew Garrett aab446306b Fix event log prefix
We're not passing the prefixed version of the description to the event log.
Fix that.
2016-03-29 15:36:49 -07:00
mjg59 a067b998e0 Merge pull request #24 from mjg59/coreos
Netboot updates
2016-03-24 15:12:06 -07:00
Matthew Garrett 954fd730ca Allow protocol to be separated from host with a semicolon
Some DHCP servers (such as dnsmasq) tokenise parameters with commas, making
it impossible to pass boot files with commas in them. Allow using a semicolon
to separate the protocol from host if a comma wasn't found.
2016-03-24 13:47:19 -07:00
Matthew Garrett 75b4826d15 Tag the bootp request as a DHCP discover 2016-03-24 13:46:54 -07:00
Matthew Garrett ec0051a569 Don't allocate a new address buffer if we receive multiple responses
The current logic in the DNS resolution code allocates an address buffer
based on the number of addresses in the response packet. If we receive
multiple response packets in response to a single query packet, this means
that we will reallocate a new buffer large enough for only the addresses in
that specific packet, discarding any previous results in the process. Worse,
we still keep track of the *total* number of addresses resolved in response
to this query, not merely the number in the packet being currently processed.
Use realloc() rather than malloc() to avoid overwriting the existing data,
and allocate a buffer large enough for the total set of addresses rather
than merely the number in this specific response.
2016-03-24 13:46:42 -07:00
mjg59 e1b2b265af Merge pull request #23 from mjg59/coreos
TPM fixes
2016-03-24 10:26:40 -07:00
Matthew Garrett bb3473d7c8 Rework TPM measurements
Rework TPM measurements to use fewer PCRs. After discussion with upstream,
it's preferable to avoid using so many PCRs. Instead, measure into PCRs 8
and 9 but use a prefix in the event log to indicate which subsystem carried
out the measurements.
2016-03-23 17:03:43 -07:00
Matthew Garrett c2eee36ec0 Fix boot when there's no TPM
If the firmware has TPM support but has no TPM, we're jumping to core.img
without popping the registers back onto the stack. Fix that.
2016-03-23 17:02:52 -07:00
mjg59 4ccc609994 Merge pull request #22 from mjg59/netboot
Add various small patches to improve netboot support
2016-01-08 15:42:13 -08:00
mjg59 b29d1d3258 Merge pull request #21 from mjg59/smbios
Add smbios command
2016-01-08 15:41:17 -08:00
Matthew Garrett 4d5d7be005 Send a user class identifier in bootp requests
It's helpful to determine that a request was sent by grub in order to permit
the server to provide different information at different stages of the boot
process. Send GRUB2 as a type 77 DHCP option when sending bootp packets in
order to make this possible.
2016-01-08 14:25:52 -08:00
Matthew Garrett 78db6bcf33 Allow non-default ports for HTTP requests
Add support for passing ports in HTTP requests. This takes the form of:
(http,serverip:portnum)/file
2016-01-07 17:27:15 -08:00
Matthew Garrett 297e11980b Allow passing of trusted keys via variables
Add support for adding gpg keys to the trusted database with a new command
called "trust_var". This takes the contents of a variable (in ascii-encoded
hex) and interprets it as a gpg public key.
2016-01-07 15:33:36 -08:00
Matthew Garrett 73746f0367 Fix hex representation of binary variable contents
The getenv code was mishandling the conversion of binary to hex. Grub's
sprintf() doesn't seem to support the full set of format conversions, so
fix this in the nasty way.
2016-01-07 15:31:36 -08:00
Matthew Garrett 92e46cccf1 Add smbios command
Incorporate the smbios command from
https://raw.githubusercontent.com/dm0-/gnuxc/master/patches/grub-2.02~beta2-smbios-module.patch
so we can extract the machine UUID and serial number.
2016-01-06 12:46:22 -08:00
mjg59 d4bc2bf02f Merge pull request #20 from mjg59/master
Add TPM measurement support
2016-01-05 15:32:28 -08:00
Matthew Garrett a0e69405e2 Measure multiboot images and modules 2016-01-05 14:35:17 -08:00
Matthew Garrett b47b5685b5 Measure commands
Measure each command executed by grub, which includes script execution.
2016-01-05 14:35:17 -08:00
Matthew Garrett 2d410729e9 Measure the kernel commandline
Measure the kernel commandline to ensure that it hasn't been modified
2016-01-05 14:35:17 -08:00
Matthew Garrett 20e355fd5a Measure kernel and initrd on BIOS systems
Measure the kernel and initrd when loaded on BIOS systems
2016-01-05 14:35:17 -08:00
Matthew Garrett 738f6f09b3 Rework linux16 command
We want a single buffer that contains the entire kernel image in order to
perform a TPM measurement. Allocate one and copy the entire kernel int it
before pulling out the individual blocks later on.
2016-01-05 14:35:17 -08:00
Matthew Garrett a2599ab047 Rework linux command
We want a single buffer that contains the entire kernel image in order to
perform a TPM measurement. Allocate one and copy the entire kernel into it
before pulling out the individual blocks later on.
2016-01-05 14:35:17 -08:00
Matthew Garrett 1e32d63145 Add BIOS boot measurement
Measure the on-disk grub core on BIOS systems - unlike UEFI, the firmware
can't do this stage for us.
2016-01-05 14:35:17 -08:00
Matthew Garrett f22ee4487c Measure kernel + initrd
Measure the kernel and initrd when loaded on UEFI systems
2016-01-05 14:35:17 -08:00
Matthew Garrett 858f763466 Core TPM support
Add support for performing basic TPM measurements. Right now this only
supports extending PCRs statically and only on UEFI and BIOS systems, but
will measure all modules as they're loaded.
2016-01-05 14:35:05 -08:00
Matthew Garrett 76fb8e4341 Fix race in EFI validation
The Secure Boot code currently reads the kernel from disk, validates the
signature and then reads it from disk again. A sufficiently exciting storage
device could modify the kernel between these two events and trigger the
execution of an untrusted kernel. Avoid re-reading it in order to ensure
this isn't a problem, and in the process speed up boot by not reading the
kernel twice.
2016-01-05 14:14:54 -08:00
Michael Marineau fcefc6bbc5 Merge pull request #19 from marineam/merge
Merge upstream GRUB changes
2015-12-22 17:30:18 -08:00
Michael Marineau 286f1b63df Merge branch 'master' of git://git.savannah.gnu.org/grub 2015-12-17 12:01:00 -08:00
Michael Marineau c81cf64a40 Revert "linguas: use en_US as UTF-8 locale, C.UTF-8 is not a standard locale."
This reverts commit 28b0af948e.
Superseded by a39137aefe upstream.
2015-12-17 12:00:03 -08:00
mjg59 0b93603645 Merge pull request #16 from mjg59/qemu_fwcfg
Add fwconfig command
2015-11-21 12:33:55 -08:00
Matthew Garrett 4042e13fec Add fwconfig command
Add a command to read values from the qemu fwcfg store. This allows data
to be passed from the qemu command line to grub.

Example use:

echo '(hd0,1)' >rootdev
qemu -fw_cfg opt/rootdev,file=rootdev

fwconfig opt/rootdev root
2015-11-20 11:26:00 -08:00
Alex Crawford 9a794d4652 Merge pull request #15 from crawford/disk-uuid
gpt: add search by disk uuid command
2015-08-31 19:09:42 -07:00
Alex Crawford 53a4e99990 gpt: add search by disk uuid command 2015-08-31 16:20:37 -07:00
Alex Crawford a8c24e86d0 gpt: minor cleanup 2015-08-31 15:23:39 -07:00
Michael Marineau 91391dc52b Merge pull request #14 from coreos/gnu
Merge upstream GRUB changes
2015-08-13 13:32:56 -07:00
Michael Marineau d9823e47bc Merge pull request #13 from marineam/lecrc32
gpt: clean up little-endian crc32 computation
2015-07-31 16:24:02 -07:00
Michael Marineau c7c750ecc2 Merge upstream changes as of April 29th 2015-07-31 15:41:48 -07:00
Michael Marineau c78ed0bff4 gpt: clean up little-endian crc32 computation
- Remove problematic cast from *uint8_t to *uint32_t (alignment issue).
 - Remove dynamic allocation and associated error handling paths.
 - Match parameter ordering to existing grub_crypto_hash function.
2015-07-31 15:19:41 -07:00
mjg59 adf8c776a1 Merge pull request #10 from mjg59/master
Pass through data from the kernel binary to the kernel
2015-06-29 16:36:56 -07:00
Matthew Garrett e5ee3e8fa5 Add verity hash passthrough
Read the verity hash from the kernel binary and pass it to the running
system via the kernel command line
2015-06-23 13:15:53 -07:00
mjg59 19c075a7ac Merge pull request #8 from mjg59/master
Add some more secure boot infrastructure to grub
2015-04-22 16:02:19 -07:00
Matthew Garrett 2755ecd157 Add efi getenv command
Add a command to obtain the contents of EFI firmware variables.
2015-04-22 13:08:26 -07:00
Matthew Garrett 9b669efb38 Fail validation if we can't find shim and Secure Boot is enabled
If grub is signed with a key that's in the trusted EFI keyring, an attacker
can point a boot entry at grub rather than at shim and grub will fail to
locate the shim verification protocol. This would then allow booting an
arbitrary kernel image. Fail validation if Secure Boot is enabled and we
can't find the shim protocol in order to prevent this.
2015-04-22 12:47:49 -07:00
Colin Watson 25850cfd50 Don't allow insmod when secure boot is enabled.
Hi,

Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine
as far as it goes.  However, the insmod command is not the only way that
modules can be loaded.  In particular, the 'normal' command, which
implements the usual GRUB menu and the fully-featured command prompt,
will implicitly load commands not currently loaded into memory.  This
permits trivial Secure Boot violations by writing commands implementing
whatever you want to do and pointing $prefix at the malicious code.

I'm currently test-building this patch (replacing your current
grub-2.00-no-insmod-on-sb.patch), but this should be more correct.  It
moves the check into grub_dl_load_file.
2015-04-22 12:47:49 -07:00
Michael Marineau 4f35e11003 Merge pull request #7 from marineam/gptprio
Generic GPT partition search commands
2014-12-05 16:46:27 -08:00
Michael Marineau c70627bc9f gpt: add search by partition label and uuid commands
Builds on the existing filesystem search code. Only for GPT right now.
2014-11-27 18:49:24 -08:00
Michael Marineau 9c61d9bc2c tests: add some partitions to the gpt unit test data 2014-11-27 16:39:07 -08:00
Michael Marineau daa4fbd477 gpt: switch partition names to a 16 bit type
In UEFI/GPT strings are UTF-16 so use a uint16 to make dealing with the
string practical.
2014-11-27 16:39:07 -08:00
Michael Marineau 13761c8675 gpt: move gpt guid printing function to common library 2014-11-27 16:39:07 -08:00
Michael Marineau b97f2fa47e Merge pull request #6 from coreos/gnu
Merge upstream GRUB changes
2014-11-23 17:58:18 -07:00
Michael Marineau d385aa5755 Merge pull request #5 from marineam/gptprio
Initial implementaiton of the gptprio 'next' command for grub.
2014-11-23 15:59:43 -07:00
Michael Marineau e49d5b587e gpt: new gptprio.next command for selecting priority based partitions
Basic usage would look something like this:

    gptprio.next -d usr_dev -u usr_uuid
    linuxefi ($usr_dev)/boot/vmlinuz mount.usr=PARTUUID=$usr_uuid

After booting the system should set the 'successful' bit on the
partition that was used.
2014-11-23 15:39:57 -07:00
Michael Marineau d3c2759e83 gpt: split out checksum recomputation
For basic data modifications the full repair function is overkill.
2014-11-15 13:32:37 -08:00
Michael Marineau 6278c3e75f gpt: add a new generic GUID type
In order to do anything with partition GUIDs they need to be stored in a
proper structure like the partition type GUIDs. Additionally add an
initializer macro to simplify defining both GUID types.
2014-11-15 13:32:37 -08:00
Michael Marineau 7ed934533c Merge pull request #4 from marineam/secure
Add support for linuxefi
2014-11-06 12:29:18 -08:00
Matthew Garrett 0de7775230 Add support for linuxefi 2014-11-05 20:40:53 -08:00
Michael Marineau 6cee30ef82 Merge pull request #2 from marineam/gptprio
GPT write support and repair command
2014-10-21 13:52:22 -07:00
Michael Marineau 051545ddf0 gpt: add write function and gptrepair command
The first hint of something practical, a command that can restore any of
the GPT structures from the alternate location. New test case must run
under QEMU because the loopback device used by the other unit tests does
not support writing.
2014-10-20 14:10:47 -07:00
Michael Marineau 478458d404 gpt: add new repair function to sync up primary and backup tables. 2014-10-20 13:54:58 -07:00
Michael Marineau dc6076187e gpt: consolidate crc32 computation code
The gcrypt API is overly verbose, wrap it up in a helper function to
keep this rather common operation easy to use.
2014-10-20 13:54:58 -07:00
Michael Marineau 4dd009a6fb gpt: record size of of the entries table
The size of the entries table will be needed later when writing it back
to disk. Restructure the entries reading code to flow a little better.
2014-10-20 13:54:58 -07:00
Michael Marineau 3b2674aef7 gpt: rename misnamed header location fields
The header location fields refer to 'this header' and 'alternate header'
respectively, not 'primary header' and 'backup header'. The previous
field names are backwards for the backup header.
2014-10-20 13:52:55 -07:00
Michael Marineau 7ac3d8a7bf Merge pull request #3 from marineam/tests
tests: fix path to words file on Gentoo/CoreOS
2014-10-20 11:49:35 -07:00
Michael Marineau e726b8b78d tests: fix path to words file on Gentoo/CoreOS
By default there isn't a linux.words file, but there is words.
2014-10-19 20:44:34 -07:00
Michael Marineau 4324e84c12 Merge pull request #1 from marineam/gptprio
Begin new GPT implementation for GRUB2
2014-10-18 13:57:17 -07:00
Michael Marineau f82f65f338 gpt: start new GPT module
This module is a new implementation for reading GUID Partition Tables
which is much stricter than the existing part_gpt module and exports GPT
data directly instead of the generic grub_partition structure. It will
be the basis for modules that need to read/write/update GPT data.

The current code does nothing more than read and verify the table.
2014-10-18 13:54:54 -07:00
Michael Marineau 28b0af948e linguas: use en_US as UTF-8 locale, C.UTF-8 is not a standard locale.
Apparently some distros like Debian provide C.UTF-8 but it isn't
actually fully supported by glibc and thus is not available on all
systems, neither Gentoo nor Fedora provide it.

https://sourceware.org/bugzilla/show_bug.cgi?id=17318
2014-10-14 12:20:26 -07:00
769 changed files with 35274 additions and 67323 deletions

35
.gitignore vendored
View File

@ -1,3 +1,4 @@
*~
00_header
10_*
20_linux_xen
@ -6,11 +7,13 @@
41_custom
*.1
*.8
ABOUT-NLS
aclocal.m4
ahci_test
ascii.bitmaps
ascii.h
autom4te.cache
build-aux
build-grub-gen-asciih
build-grub-gen-widthspec
build-grub-mkfont
@ -42,6 +45,8 @@ gensymlist.sh
gentrigtables
gentrigtables.exe
gettext_strings_test
gpt_unit_test
/gnulib
grub-bin2h
/grub-bios-setup
/grub-bios-setup.exe
@ -134,6 +139,7 @@ help_test
*.image.exe
include/grub/cpu
include/grub/machine
INSTALL.grub
install-sh
lib/libgcrypt-grub
libgrub_a_init.c
@ -142,6 +148,7 @@ libgrub_a_init.c
lzocompress_test
*.marker
Makefile
/m4
*.mod
mod-*.c
missing
@ -155,7 +162,11 @@ pata_test
*.pp
po/*.mo
po/grub.pot
po/Makefile.in.in
po/Makevars
po/Makevars.template
po/POTFILES
po/Rules-quot
po/stamp-po
printf_test
priority_queue_unit_test
@ -202,25 +213,7 @@ grub-core/*.module.exe
grub-core/*.pp
grub-core/kernel.img.bin
util/bash-completion.d/grub
grub-core/gnulib/alloca.h
grub-core/gnulib/arg-nonnull.h
grub-core/gnulib/c++defs.h
grub-core/gnulib/charset.alias
grub-core/gnulib/configmake.h
grub-core/gnulib/float.h
grub-core/gnulib/getopt.h
grub-core/gnulib/langinfo.h
grub-core/gnulib/ref-add.sed
grub-core/gnulib/ref-del.sed
grub-core/gnulib/stdio.h
grub-core/gnulib/stdlib.h
grub-core/gnulib/string.h
grub-core/gnulib/strings.h
grub-core/gnulib/sys
grub-core/gnulib/unistd.h
grub-core/gnulib/warn-on-use.h
grub-core/gnulib/wchar.h
grub-core/gnulib/wctype.h
grub-core/lib/gnulib
grub-core/rs_decoder.h
widthspec.bin
widthspec.h
@ -239,10 +232,6 @@ po/POTFILES-shell.in
/grub-render-label
/grub-glue-efi.exe
/grub-render-label.exe
grub-core/gnulib/locale.h
grub-core/gnulib/unitypes.h
grub-core/gnulib/uniwidth.h
build-aux/test-driver
/garbage-gen
/garbage-gen.exe
/grub-fs-tester

108
.travis.yml Normal file
View File

@ -0,0 +1,108 @@
# SPDX-License-Identifier: GPL-3.0+
# Originally Copyright Roger Meier <r.meier@siemens.com>
# Adapted for GRUB by Alexander Graf <agraf@suse.de>
#
# Build GRUB on Travis CI - https://www.travis-ci.org/
#
dist: xenial
language: c
addons:
apt:
packages:
- libsdl1.2-dev
- lzop
- ovmf
- python
- qemu-system
- unifont
env:
global:
# Include all cross toolchain paths, so we can just call them later down.
- PATH=/tmp/qemu-install/bin:/tmp/grub/bin:/usr/bin:/bin:/tmp/cross/gcc-8.1.0-nolibc/aarch64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/arm-linux-gnueabi/bin:/tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/mips64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/powerpc64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv32-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/sparc64-linux/bin
before_script:
# Install necessary toolchains based on $CROSS_TARGETS variable.
- mkdir /tmp/cross
# These give us binaries like /tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin/ia64-linux-gcc
- for i in $CROSS_TARGETS; do
( cd /tmp/cross; wget -t 3 -O - https://mirrors.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-$i.tar.xz | tar xJ );
done
script:
# Comments must be outside the command strings below, or the Travis parser
# will get confused.
- ./autogen.sh
# Build all selected GRUB targets.
- for target in $GRUB_TARGETS; do
plat=${target#*-};
arch=${target%-*};
[ "$arch" = "arm64" ] && arch=aarch64-linux;
[ "$arch" = "arm" ] && arch=arm-linux-gnueabi;
[ "$arch" = "ia64" ] && arch=ia64-linux;
[ "$arch" = "mipsel" ] && arch=mips64-linux;
[ "$arch" = "powerpc" ] && arch=powerpc64-linux;
[ "$arch" = "riscv32" ] && arch=riscv32-linux;
[ "$arch" = "riscv64" ] && arch=riscv64-linux;
[ "$arch" = "sparc64" ] && arch=sparc64-linux;
echo "Building $target";
mkdir obj-$target;
JOBS=`getconf _NPROCESSORS_ONLN 2> /dev/null || echo 1`;
[ "$JOBS" == 1 ] || JOBS=$(($JOBS + 1));
( cd obj-$target && ../configure --target=$arch --with-platform=$plat --prefix=/tmp/grub && make -j$JOBS && make -j$JOBS install ) &> log || ( cat log; false );
done
# Our test canary.
- echo -e "insmod echo\\ninsmod reboot\\necho hello world\\nreboot" > grub.cfg
# Assemble images and possibly run them.
- for target in $GRUB_TARGETS; do grub-mkimage -c grub.cfg -p / -O $target -o grub-$target echo reboot normal; done
# Run images we know how to run.
- if [[ "$GRUB_TARGETS" == *"x86_64-efi"* ]]; then qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -m 512 -no-reboot -nographic -net nic -net user,tftp=.,bootfile=grub-x86_64-efi | tee grub.log && grep "hello world" grub.log; fi
matrix:
include:
# Each env setting here is a dedicated build.
- name: "x86_64"
env:
- GRUB_TARGETS="x86_64-efi x86_64-xen"
- name: "i386"
env:
- GRUB_TARGETS="i386-coreboot i386-efi i386-ieee1275 i386-multiboot i386-pc i386-qemu i386-xen i386-xen_pvh"
- name: "powerpc"
env:
- GRUB_TARGETS="powerpc-ieee1275"
- CROSS_TARGETS="powerpc64-linux"
- name: "sparc64"
env:
- GRUB_TARGETS="sparc64-ieee1275"
- CROSS_TARGETS="sparc64-linux"
- name: "ia64"
env:
- GRUB_TARGETS="ia64-efi"
- CROSS_TARGETS="ia64-linux"
- name: "mips"
env:
- GRUB_TARGETS="mips-arc mipsel-arc mipsel-qemu_mips mips-qemu_mips"
- CROSS_TARGETS="mips64-linux"
- name: "arm"
env:
- GRUB_TARGETS="arm-coreboot arm-efi arm-uboot"
- CROSS_TARGETS="arm-linux-gnueabi"
- name: "arm64"
env:
- GRUB_TARGETS="arm64-efi"
- CROSS_TARGETS="aarch64-linux"
- name: "riscv32"
env:
- GRUB_TARGETS="riscv32-efi"
- CROSS_TARGETS="riscv32-linux"
- name: "riscv64"
env:
- GRUB_TARGETS="riscv64-efi"
- CROSS_TARGETS="riscv64-linux"

223
ABOUT-NLS
View File

@ -1,223 +0,0 @@
1 Notes on the Free Translation Project
***************************************
Free software is going international! The Free Translation Project is
a way to get maintainers of free software, translators, and users all
together, so that free software will gradually become able to speak many
languages. A few packages already provide translations for their
messages.
If you found this `ABOUT-NLS' file inside a distribution, you may
assume that the distributed package does use GNU `gettext' internally,
itself available at your nearest GNU archive site. But you do _not_
need to install GNU `gettext' prior to configuring, installing or using
this package with messages translated.
Installers will find here some useful hints. These notes also
explain how users should proceed for getting the programs to use the
available translations. They tell how people wanting to contribute and
work on translations can contact the appropriate team.
When reporting bugs in the `intl/' directory or bugs which may be
related to internationalization, you should tell about the version of
`gettext' which is used. The information can be found in the
`intl/VERSION' file, in internationalized packages.
1.1 Quick configuration advice
==============================
If you want to exploit the full power of internationalization, you
should configure it using
./configure --with-included-gettext
to force usage of internationalizing routines provided within this
package, despite the existence of internationalizing capabilities in the
operating system where this package is being installed. So far, only
the `gettext' implementation in the GNU C library version 2 provides as
many features (such as locale alias, message inheritance, automatic
charset conversion or plural form handling) as the implementation here.
It is also not possible to offer this additional functionality on top
of a `catgets' implementation. Future versions of GNU `gettext' will
very likely convey even more functionality. So it might be a good idea
to change to GNU `gettext' as soon as possible.
So you need _not_ provide this option if you are using GNU libc 2 or
you have installed a recent copy of the GNU gettext package with the
included `libintl'.
1.2 INSTALL Matters
===================
Some packages are "localizable" when properly installed; the programs
they contain can be made to speak your own native language. Most such
packages use GNU `gettext'. Other packages have their own ways to
internationalization, predating GNU `gettext'.
By default, this package will be installed to allow translation of
messages. It will automatically detect whether the system already
provides the GNU `gettext' functions. If not, the included GNU
`gettext' library will be used. This library is wholly contained
within this package, usually in the `intl/' subdirectory, so prior
installation of the GNU `gettext' package is _not_ required.
Installers may use special options at configuration time for changing
the default behaviour. The commands:
./configure --with-included-gettext
./configure --disable-nls
will, respectively, bypass any pre-existing `gettext' to use the
internationalizing routines provided within this package, or else,
_totally_ disable translation of messages.
When you already have GNU `gettext' installed on your system and run
configure without an option for your new package, `configure' will
probably detect the previously built and installed `libintl.a' file and
will decide to use this. This might not be desirable. You should use
the more recent version of the GNU `gettext' library. I.e. if the file
`intl/VERSION' shows that the library which comes with this package is
more recent, you should use
./configure --with-included-gettext
to prevent auto-detection.
The configuration process will not test for the `catgets' function
and therefore it will not be used. The reason is that even an
emulation of `gettext' on top of `catgets' could not provide all the
extensions of the GNU `gettext' library.
Internationalized packages usually have many `po/LL.po' files, where
LL gives an ISO 639 two-letter code identifying the language. Unless
translations have been forbidden at `configure' time by using the
`--disable-nls' switch, all available translations are installed
together with the package. However, the environment variable `LINGUAS'
may be set, prior to configuration, to limit the installed set.
`LINGUAS' should then contain a space separated list of two-letter
codes, stating which languages are allowed.
1.3 Using This Package
======================
As a user, if your language has been installed for this package, you
only have to set the `LANG' environment variable to the appropriate
`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
and `CC' is an ISO 3166 two-letter country code. For example, let's
suppose that you speak German and live in Germany. At the shell
prompt, merely execute `setenv LANG de_DE' (in `csh'),
`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
This can be done from your `.login' or `.profile' file, once and for
all.
You might think that the country code specification is redundant.
But in fact, some languages have dialects in different countries. For
example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
country code serves to distinguish the dialects.
The locale naming convention of `LL_CC', with `LL' denoting the
language and `CC' denoting the country, is the one use on systems based
on GNU libc. On other systems, some variations of this scheme are
used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
locales supported by your system for your language by running the
command `locale -a | grep '^LL''.
Not all programs have translations for all languages. By default, an
English message is shown in place of a nonexistent translation. If you
understand other languages, you can set up a priority list of languages.
This is done through a different environment variable, called
`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
for the purpose of message handling, but you still need to have `LANG'
set to the primary language; this is required by other parts of the
system libraries. For example, some Swedish users who would rather
read translations in German than English for when Swedish is not
available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
Special advice for Norwegian users: The language code for Norwegian
bokma*l changed from `no' to `nb' recently (in 2003). During the
transition period, while some message catalogs for this language are
installed under `nb' and some older ones under `no', it's recommended
for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
older translations are used.
In the `LANGUAGE' environment variable, but not in the `LANG'
environment variable, `LL_CC' combinations can be abbreviated as `LL'
to denote the language's main dialect. For example, `de' is equivalent
to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
(Portuguese as spoken in Portugal) in this context.
1.4 Translating Teams
=====================
For the Free Translation Project to be a success, we need interested
people who like their own language and write it well, and who are also
able to synergize with other translators speaking the same language.
Each translation team has its own mailing list. The up-to-date list of
teams can be found at the Free Translation Project's homepage,
`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
area.
If you'd like to volunteer to _work_ at translating messages, you
should become a member of the translating team for your own language.
The subscribing address is _not_ the same as the list itself, it has
`-request' appended. For example, speakers of Swedish can send a
message to `sv-request@li.org', having this message body:
subscribe
Keep in mind that team members are expected to participate
_actively_ in translations, or at solving translational difficulties,
rather than merely lurking around. If your team does not exist yet and
you want to start one, or if you are unsure about what to do or how to
get started, please write to `translation@iro.umontreal.ca' to reach the
coordinator for all translator teams.
The English team is special. It works at improving and uniformizing
the terminology in use. Proven linguistic skills are praised more than
programming skills, here.
1.5 Available Packages
======================
Languages are not equally supported in all packages. The following
matrix shows the current state of internationalization, as of October
2006. The matrix shows, in regard of each package, for which languages
PO files have been submitted to translation coordination, with a
translation percentage of at least 50%.
# Matrix here is removed!
Some counters in the preceding matrix are higher than the number of
visible blocks let us expect. This is because a few extra PO files are
used for implementing regional variants of languages, or language
dialects.
For a PO file in the matrix above to be effective, the package to
which it applies should also have been internationalized and
distributed as such by its maintainer. There might be an observable
lag between the mere existence a PO file and its wide availability in a
distribution.
If October 2006 seems to be old, you may fetch a more recent copy of
this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
matrix with full percentage details can be found at
`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
1.6 Using `gettext' in new packages
===================================
If you are writing a freely available program and want to
internationalize it you are welcome to use GNU `gettext' in your
package. Of course you have to respect the GNU Library General Public
License which covers the use of the GNU `gettext' library. This means
in particular that even non-free programs can use `libintl' as a shared
library, whereas only free software can use `libintl' as a static
library or use modified versions of `libintl'.
Once the sources are changed appropriately and the setup can handle
the use of `gettext' the only thing missing are the translations. The
Free Translation Project is also available for packages which are not
developed inside the GNU project. Therefore the information given above
applies also for every other Free Software Project. Contact
`translation@iro.umontreal.ca' to make the `.pot' files available to
the translation teams.

22
INSTALL
View File

@ -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,15 +53,15 @@ 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
need the following.
* Python 2.6 or later
* Autoconf 2.60 or later
* Automake 1.10.1 or later
* Autoconf 2.63 or later
* Automake 1.11 or later
Prerequisites for make-check:
@ -101,10 +102,11 @@ The simplest way to compile this package is:
2. Skip this and following step if you use release tarball and proceed to
step 4. If you want translations type `./linguas.sh'.
3. Type `./autogen.sh'.
3. Type `./bootstrap'.
* autogen.sh uses python. By default invocation is "python" but can be
overriden by setting variable $PYTHON.
* autogen.sh (called by bootstrap) uses python. By default the
invocation is "python", but it can be overridden by setting the
variable $PYTHON.
4. Type `./configure' to configure the package for your system.
If you're using `csh' on an old version of System V, you might
@ -158,8 +160,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 +178,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 +186,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).

View File

@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = subdir-objects -Wno-portability
DEPDIR = .deps-util
SUBDIRS = grub-core/gnulib .
SUBDIRS = grub-core/lib/gnulib .
if COND_real_platform
SUBDIRS += grub-core
endif
@ -71,7 +71,7 @@ endif
starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/starfield/boot_menu_c.png $(srcdir)/themes/starfield/boot_menu_e.png $(srcdir)/themes/starfield/boot_menu_ne.png $(srcdir)/themes/starfield/boot_menu_n.png $(srcdir)/themes/starfield/boot_menu_nw.png $(srcdir)/themes/starfield/boot_menu_se.png $(srcdir)/themes/starfield/boot_menu_s.png $(srcdir)/themes/starfield/boot_menu_sw.png $(srcdir)/themes/starfield/boot_menu_w.png $(srcdir)/themes/starfield/slider_c.png $(srcdir)/themes/starfield/slider_n.png $(srcdir)/themes/starfield/slider_s.png $(srcdir)/themes/starfield/starfield.png $(srcdir)/themes/starfield/terminal_box_c.png $(srcdir)/themes/starfield/terminal_box_e.png $(srcdir)/themes/starfield/terminal_box_ne.png $(srcdir)/themes/starfield/terminal_box_n.png $(srcdir)/themes/starfield/terminal_box_nw.png $(srcdir)/themes/starfield/terminal_box_se.png $(srcdir)/themes/starfield/terminal_box_s.png $(srcdir)/themes/starfield/terminal_box_sw.png $(srcdir)/themes/starfield/terminal_box_w.png $(srcdir)/themes/starfield/theme.txt $(srcdir)/themes/starfield/README $(srcdir)/themes/starfield/COPYING.CC-BY-SA-3.0
build-grub-mkfont$(BUILD_EXEEXT): util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/misc.c util/misc.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(build_freetype_cflags) $(build_freetype_libs)
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS)
CLEANFILES += build-grub-mkfont$(BUILD_EXEEXT)
garbage-gen$(BUILD_EXEEXT): util/garbage-gen.c
@ -80,11 +80,11 @@ CLEANFILES += garbage-gen$(BUILD_EXEEXT)
EXTRA_DIST += util/garbage-gen.c
build-grub-gen-asciih$(BUILD_EXEEXT): util/grub-gen-asciih.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror
CLEANFILES += build-grub-gen-asciih$(BUILD_EXEEXT)
build-grub-gen-widthspec$(BUILD_EXEEXT): util/grub-gen-widthspec.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror
CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT)
if COND_STARFIELD
@ -422,9 +422,10 @@ BOOTCHECK_TIMEOUT=180
bootcheck: $(BOOTCHECKS)
if COND_i386_coreboot
FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst)
default_payload.elf: grub-mkstandalone grub-mkimage FORCE
test -f $@ && rm $@ || true
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(shell cat grub-core/fs.lst) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
endif
endif
@ -476,6 +477,11 @@ EXTRA_DIST += ChangeLog ChangeLog-2015
syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg
# Mimic simplify_filename from grub-core/lib/syslinux_parse.c, so that we
# can predict its behaviour in tests. We have to pre-substitute this before
# calling config.status, as config.status offers no reliable way to hook in
# a command between setting ac_abs_top_srcdir and emitting output files.
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=$@:-
simplified_abs_top_srcdir=`echo "$(abs_top_srcdir)" | sed 's,//,/,g; s,/\./,/,g; :loop; s,/[^/][^/]*/\.\.\(/\|$$\),\1,; t loop'`; \
sed "s,@simplified_abs_top_srcdir@,$$simplified_abs_top_srcdir,g" $(srcdir)/tests/syslinux/ubuntu10.04_grub.cfg.in | $(top_builddir)/config.status --file=$@:-
CLEANFILES += tests/syslinux/ubuntu10.04_grub.cfg

View File

@ -54,7 +54,7 @@ library = {
library = {
name = libgrubmods.a;
cflags = '-fno-builtin -Wno-undef';
cppflags = '-I$(top_srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -DMINILZO_HAVE_CONFIG_H';
cppflags = '-I$(srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -I$(srcdir)/grub-core/lib/zstd -DMINILZO_HAVE_CONFIG_H';
common_nodist = grub_script.tab.c;
common_nodist = grub_script.yy.c;
@ -99,6 +99,7 @@ library = {
common = grub-core/fs/ext2.c;
common = grub-core/fs/fat.c;
common = grub-core/fs/exfat.c;
common = grub-core/fs/f2fs.c;
common = grub-core/fs/fshelp.c;
common = grub-core/fs/hfs.c;
common = grub-core/fs/hfsplus.c;
@ -164,6 +165,15 @@ library = {
common = grub-core/lib/xzembed/xz_dec_bcj.c;
common = grub-core/lib/xzembed/xz_dec_lzma2.c;
common = grub-core/lib/xzembed/xz_dec_stream.c;
common = grub-core/lib/zstd/debug.c;
common = grub-core/lib/zstd/entropy_common.c;
common = grub-core/lib/zstd/error_private.c;
common = grub-core/lib/zstd/fse_decompress.c;
common = grub-core/lib/zstd/huf_decompress.c;
common = grub-core/lib/zstd/module.c;
common = grub-core/lib/zstd/xxhash.c;
common = grub-core/lib/zstd/zstd_common.c;
common = grub-core/lib/zstd/zstd_decompress.c;
};
program = {
@ -188,7 +198,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBLZMA)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_PKGLIBDIR=\"$(pkglibdir)\"';
@ -205,7 +215,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -220,7 +230,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -235,7 +245,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -251,7 +261,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -274,7 +284,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -290,7 +300,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) -lfuse';
condition = COND_GRUB_MOUNT;
};
@ -302,14 +312,14 @@ program = {
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
cflags = '$(freetype_cflags)';
cflags = '$(FREETYPE_CFLAGS)';
cppflags = '-DGRUB_MKFONT=1';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(freetype_libs)';
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(FREETYPE_LIBS)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_GRUB_MKFONT;
};
@ -327,7 +337,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -349,7 +359,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = libgrubgcry.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup';
};
@ -369,7 +379,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = libgrubgcry.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup';
};
@ -385,7 +395,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -400,7 +410,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -415,7 +425,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -542,7 +552,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_HAVE_EXEC;
@ -589,7 +599,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -628,7 +638,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -664,7 +674,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -774,6 +784,12 @@ script = {
common = tests/xfs_test.in;
};
script = {
testcase;
name = f2fs_test;
common = tests/f2fs_test.in;
};
script = {
testcase;
name = nilfs2_test;
@ -1159,6 +1175,18 @@ script = {
common = tests/grub_cmd_tr.in;
};
script = {
testcase;
name = gptrepair_test;
common = tests/gptrepair_test.in;
};
script = {
testcase;
name = gptprio_test;
common = tests/gptprio_test.in;
};
script = {
testcase;
name = file_filter_test;
@ -1188,7 +1216,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1203,7 +1231,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1218,7 +1246,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1234,7 +1262,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_HAVE_CXX;
};
@ -1250,6 +1278,25 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
program = {
testcase;
name = gpt_unit_test;
common = tests/gpt_unit_test.c;
common = tests/lib/unit_test.c;
common = grub-core/commands/search_part_label.c;
common = grub-core/commands/search_part_uuid.c;
common = grub-core/commands/search_disk_uuid.c;
common = grub-core/disk/host.c;
common = grub-core/kern/emu/hostfs.c;
common = grub-core/lib/gpt.c;
common = grub-core/tests/lib/test.c;
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1265,7 +1312,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1283,7 +1330,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1299,7 +1346,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1317,7 +1364,7 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
@ -1346,6 +1393,6 @@ program = {
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};

18
NEWS
View File

@ -1,3 +1,21 @@
New in 2.04:
* GCC 8 and 9 support.
* Gnulib integration overhaul.
* RISC-V support.
* Xen PVH support.
* Native UEFI secure boot support.
* UEFI TPM driver.
* New IEEE 1275 obdisk driver.
* Btrfs RAID 5 and RIAD 6 support.
* PARTUUID support.
* VLAN support.
* Native DHCP support.
* Many ARM and ARM64 fixes.
* Many SPARC fixes.
* Many IEEE 1275 fixes.
* ...and tons of other fixes and cleanups...
New in 2.02:
* New/improved filesystem and disk support:

View File

@ -2,13 +2,18 @@
set -e
if [ ! -e grub-core/lib/gnulib/stdlib.in.h ]; then
echo "Gnulib not yet bootstrapped; run ./bootstrap instead." >&2
exit 1
fi
# Set ${PYTHON} to plain 'python' if not set already
: ${PYTHON:=python}
export LC_COLLATE=C
unset LC_ALL
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' |sort > po/POTFILES.in
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -iname './grub-core/lib/gnulib/*' |sort > po/POTFILES.in
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
echo "Importing unicode..."
@ -82,6 +87,17 @@ done
echo "Saving timestamps..."
echo timestamp > stamp-h.in
echo "Running autoreconf..."
autoreconf -vi
if [ -z "$FROM_BOOTSTRAP" ]; then
# Unaided autoreconf is likely to install older versions of many files
# than the ones provided by Gnulib, but in most cases this won't matter
# very much. This mode is provided so that you can run ./autogen.sh to
# regenerate the GRUB build system in an unpacked release tarball (perhaps
# after patching it), even on systems that don't have access to
# gnulib.git.
echo "Running autoreconf..."
cp -a INSTALL INSTALL.grub
autoreconf -vif
mv INSTALL.grub INSTALL
fi
exit 0

1073
bootstrap Executable file

File diff suppressed because it is too large Load Diff

91
bootstrap.conf Normal file
View File

@ -0,0 +1,91 @@
# Bootstrap configuration.
# Copyright (C) 2006-2019 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263
# gnulib modules used by this package.
# mbswidth is used by gnulib-fix-width.diff's changes to argp rather than
# directly.
gnulib_modules="
argp
error
fnmatch
getdelim
getline
gettext-h
gitlog-to-changelog
mbswidth
progname
realloc-gnu
regex
save-cwd
"
gnulib_tool_option_extras="\
--no-conditional-dependencies \
--no-vc-files \
"
gnulib_name=libgnu
source_base=grub-core/lib/gnulib
gnulib_extra_files="
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
"
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--from-code=UTF-8\\\
'
checkout_only_file=
copy=true
vc_ignore=
SKIP_PO=t
# Build prerequisites
buildreq="\
autoconf 2.63
automake 1.11
gettext 0.18.3
git 1.5.5
tar -
"
# bootstrap doesn't give us a reasonable way to stop Automake from
# overwriting this, so we just copy our version aside and put it back later.
cp -a INSTALL INSTALL.grub
bootstrap_post_import_hook () {
set -e
for patchname in fix-null-deref fix-width no-abort; do
patch -d grub-core/lib/gnulib -p2 \
< "grub-core/lib/gnulib-patches/$patchname.patch"
done
FROM_BOOTSTRAP=1 ./autogen.sh
set +e # bootstrap expects this
}
bootstrap_epilogue () {
mv INSTALL.grub INSTALL
}

View File

@ -1,690 +0,0 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2013 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
;;
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
nagfor*)
wl='-Wl,-Wl,,'
;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
xl* | bgxl* | bgf* | mpixl*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ F* | *Sun*Fortran*)
wl=
;;
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
newsos6)
;;
*nto* | *qnx*)
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
case $cc_basename in
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
wl='-Qoption ld '
;;
*)
wl='-Wl,'
;;
esac
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
haiku*)
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
:
else
ld_shlibs=no
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
*nto* | *qnx*)
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
case "$host_cpu" in
powerpc*)
library_names_spec='$libname$shrext' ;;
m68k)
library_names_spec='$libname.a' ;;
esac
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
haiku*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
*nto* | *qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
tpf*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

View File

@ -1,432 +0,0 @@
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
& eval 'exec perl -wS "$0" $argv:q'
if 0;
# Convert git log output to ChangeLog format.
my $VERSION = '2012-07-29 06:11'; # UTC
# The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook
# do its job. Otherwise, update this string manually.
# Copyright (C) 2008-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Written by Jim Meyering
use strict;
use warnings;
use Getopt::Long;
use POSIX qw(strftime);
(my $ME = $0) =~ s|.*/||;
# use File::Coda; # http://meyering.net/code/Coda/
END {
defined fileno STDOUT or return;
close STDOUT and return;
warn "$ME: failed to close standard output: $!\n";
$? ||= 1;
}
sub usage ($)
{
my ($exit_code) = @_;
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
if ($exit_code != 0)
{
print $STREAM "Try '$ME --help' for more information.\n";
}
else
{
print $STREAM <<EOF;
Usage: $ME [OPTIONS] [ARGS]
Convert git log output to ChangeLog format. If present, any ARGS
are passed to "git log". To avoid ARGS being parsed as options to
$ME, they may be preceded by '--'.
OPTIONS:
--amend=FILE FILE maps from an SHA1 to perl code (i.e., s/old/new/) that
makes a change to SHA1's commit log text or metadata.
--append-dot append a dot to the first line of each commit message if
there is no other punctuation or blank at the end.
--no-cluster never cluster commit messages under the same date/author
header; the default is to cluster adjacent commit messages
if their headers are the same and neither commit message
contains multiple paragraphs.
--srcdir=DIR the root of the source tree, from which the .git/
directory can be derived.
--since=DATE convert only the logs since DATE;
the default is to convert all log entries.
--format=FMT set format string for commit subject and body;
see 'man git-log' for the list of format metacharacters;
the default is '%s%n%b%n'
--strip-tab remove one additional leading TAB from commit message lines.
--strip-cherry-pick remove data inserted by "git cherry-pick";
this includes the "cherry picked from commit ..." line,
and the possible final "Conflicts:" paragraph.
--help display this help and exit
--version output version information and exit
EXAMPLE:
$ME --since=2008-01-01 > ChangeLog
$ME -- -n 5 foo > last-5-commits-to-branch-foo
SPECIAL SYNTAX:
The following types of strings are interpreted specially when they appear
at the beginning of a log message line. They are not copied to the output.
Copyright-paperwork-exempt: Yes
Append the "(tiny change)" notation to the usual "date name email"
ChangeLog header to mark a change that does not require a copyright
assignment.
Co-authored-by: Joe User <user\@example.com>
List the specified name and email address on a second
ChangeLog header, denoting a co-author.
Signed-off-by: Joe User <user\@example.com>
These lines are simply elided.
In a FILE specified via --amend, comment lines (starting with "#") are ignored.
FILE must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1 (alone on
a line) referring to a commit in the current project, and CODE refers to one
or more consecutive lines of Perl code. Pairs must be separated by one or
more blank line.
Here is sample input for use with --amend=FILE, from coreutils:
3a169f4c5d9159283548178668d2fae6fced3030
# fix typo in title:
s/all tile types/all file types/
1379ed974f1fa39b12e2ffab18b3f7a607082202
# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself.
# Change the author to be Paul. Note the escaped "@":
s,Jim .*>,Paul Eggert <eggert\\\@cs.ucla.edu>,
EOF
}
exit $exit_code;
}
# If the string $S is a well-behaved file name, simply return it.
# If it contains white space, quotes, etc., quote it, and return the new string.
sub shell_quote($)
{
my ($s) = @_;
if ($s =~ m![^\w+/.,-]!)
{
# Convert each single quote to '\''
$s =~ s/\'/\'\\\'\'/g;
# Then single quote the string.
$s = "'$s'";
}
return $s;
}
sub quoted_cmd(@)
{
return join (' ', map {shell_quote $_} @_);
}
# Parse file F.
# Comment lines (starting with "#") are ignored.
# F must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1
# (alone on a line) referring to a commit in the current project, and
# CODE refers to one or more consecutive lines of Perl code.
# Pairs must be separated by one or more blank line.
sub parse_amend_file($)
{
my ($f) = @_;
open F, '<', $f
or die "$ME: $f: failed to open for reading: $!\n";
my $fail;
my $h = {};
my $in_code = 0;
my $sha;
while (defined (my $line = <F>))
{
$line =~ /^\#/
and next;
chomp $line;
$line eq ''
and $in_code = 0, next;
if (!$in_code)
{
$line =~ /^([0-9a-fA-F]{40})$/
or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"),
$fail = 1, next;
$sha = lc $1;
$in_code = 1;
exists $h->{$sha}
and (warn "$ME: $f:$.: duplicate SHA1\n"),
$fail = 1, next;
}
else
{
$h->{$sha} ||= '';
$h->{$sha} .= "$line\n";
}
}
close F;
$fail
and exit 1;
return $h;
}
# git_dir_option $SRCDIR
#
# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR
# is undef). Return as a list (0 or 1 element).
sub git_dir_option($)
{
my ($srcdir) = @_;
my @res = ();
if (defined $srcdir)
{
my $qdir = shell_quote $srcdir;
my $cmd = "cd $qdir && git rev-parse --show-toplevel";
my $qcmd = shell_quote $cmd;
my $git_dir = qx($cmd);
defined $git_dir
or die "$ME: cannot run $qcmd: $!\n";
$? == 0
or die "$ME: $qcmd had unexpected exit code or signal ($?)\n";
chomp $git_dir;
push @res, "--git-dir=$git_dir/.git";
}
@res;
}
{
my $since_date;
my $format_string = '%s%n%b%n';
my $amend_file;
my $append_dot = 0;
my $cluster = 1;
my $strip_tab = 0;
my $strip_cherry_pick = 0;
my $srcdir;
GetOptions
(
help => sub { usage 0 },
version => sub { print "$ME version $VERSION\n"; exit },
'since=s' => \$since_date,
'format=s' => \$format_string,
'amend=s' => \$amend_file,
'append-dot' => \$append_dot,
'cluster!' => \$cluster,
'strip-tab' => \$strip_tab,
'strip-cherry-pick' => \$strip_cherry_pick,
'srcdir=s' => \$srcdir,
) or usage 1;
defined $since_date
and unshift @ARGV, "--since=$since_date";
# This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
# that makes a correction in the log or attribution of that commit.
my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {};
my @cmd = ('git',
git_dir_option $srcdir,
qw(log --log-size),
'--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV);
open PIPE, '-|', @cmd
or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n"
. "(Is your Git too old? Version 1.5.1 or later is required.)\n");
my $prev_multi_paragraph;
my $prev_date_line = '';
my @prev_coauthors = ();
while (1)
{
defined (my $in = <PIPE>)
or last;
$in =~ /^log size (\d+)$/
or die "$ME:$.: Invalid line (expected log size):\n$in";
my $log_nbytes = $1;
my $log;
my $n_read = read PIPE, $log, $log_nbytes;
$n_read == $log_nbytes
or die "$ME:$.: unexpected EOF\n";
# Extract leading hash.
my ($sha, $rest) = split ':', $log, 2;
defined $sha
or die "$ME:$.: malformed log entry\n";
$sha =~ /^[0-9a-fA-F]{40}$/
or die "$ME:$.: invalid SHA1: $sha\n";
# If this commit's log requires any transformation, do it now.
my $code = $amend_code->{$sha};
if (defined $code)
{
eval 'use Safe';
my $s = new Safe;
# Put the unpreprocessed entry into "$_".
$_ = $rest;
# Let $code operate on it, safely.
my $r = $s->reval("$code")
or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n";
# Note that we've used this entry.
delete $amend_code->{$sha};
# Update $rest upon success.
$rest = $_;
}
# Remove lines inserted by "git cherry-pick".
if ($strip_cherry_pick)
{
$rest =~ s/^\s*Conflicts:\n.*//sm;
$rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
}
my @line = split "\n", $rest;
my $author_line = shift @line;
defined $author_line
or die "$ME:$.: unexpected EOF\n";
$author_line =~ /^(\d+) (.*>)$/
or die "$ME:$.: Invalid line "
. "(expected date/author/email):\n$author_line\n";
# Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
# `(tiny change)' annotation.
my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line)
? ' (tiny change)' : '');
my $date_line = sprintf "%s %s$tiny\n",
strftime ("%F", localtime ($1)), $2;
my @coauthors = grep /^Co-authored-by:.*$/, @line;
# Omit meta-data lines we've already interpreted.
@line = grep !/^(?:Signed-off-by:[ ].*>$
|Co-authored-by:[ ]
|Copyright-paperwork-exempt:[ ]
)/x, @line;
# Remove leading and trailing blank lines.
if (@line)
{
while ($line[0] =~ /^\s*$/) { shift @line; }
while ($line[$#line] =~ /^\s*$/) { pop @line; }
}
# Record whether there are two or more paragraphs.
my $multi_paragraph = grep /^\s*$/, @line;
# Format 'Co-authored-by: A U Thor <email@example.com>' lines in
# standard multi-author ChangeLog format.
for (@coauthors)
{
s/^Co-authored-by:\s*/\t /;
s/\s*</ </;
/<.*?@.*\..*>/
or warn "$ME: warning: missing email address for "
. substr ($_, 5) . "\n";
}
# If clustering of commit messages has been disabled, if this header
# would be different from the previous date/name/email/coauthors header,
# or if this or the previous entry consists of two or more paragraphs,
# then print the header.
if ( ! $cluster
|| $date_line ne $prev_date_line
|| "@coauthors" ne "@prev_coauthors"
|| $multi_paragraph
|| $prev_multi_paragraph)
{
$prev_date_line eq ''
or print "\n";
print $date_line;
@coauthors
and print join ("\n", @coauthors), "\n";
}
$prev_date_line = $date_line;
@prev_coauthors = @coauthors;
$prev_multi_paragraph = $multi_paragraph;
# If there were any lines
if (@line == 0)
{
warn "$ME: warning: empty commit message:\n $date_line\n";
}
else
{
if ($append_dot)
{
# If the first line of the message has enough room, then
if (length $line[0] < 72)
{
# append a dot if there is no other punctuation or blank
# at the end.
$line[0] =~ /[[:punct:]\s]$/
or $line[0] .= '.';
}
}
# Remove one additional leading TAB from each line.
$strip_tab
and map { s/^\t// } @line;
# Prefix each non-empty line with a TAB.
@line = map { length $_ ? "\t$_" : '' } @line;
print "\n", join ("\n", @line), "\n";
}
defined ($in = <PIPE>)
or last;
$in ne "\n"
and die "$ME:$.: unexpected line:\n$in";
}
close PIPE
or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
# FIXME-someday: include $PROCESS_STATUS in the diagnostic
# Complain about any unused entry in the --amend=F specified file.
my $fail = 0;
foreach my $sha (keys %$amend_code)
{
warn "$ME:$amend_file: unused entry: $sha\n";
$fail = 1;
}
exit $fail;
}
# Local Variables:
# mode: perl
# indent-tabs-mode: nil
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "my $VERSION = '"
# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "'; # UTC"
# End:

View File

@ -1,10 +0,0 @@
#if !defined _Noreturn && __STDC_VERSION__ < 201112
# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
|| 0x5110 <= __SUNPRO_C)
# define _Noreturn __attribute__ ((__noreturn__))
# elif 1200 <= _MSC_VER
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn
# endif
#endif

View File

@ -1,26 +0,0 @@
/* A C macro for declaring that specific arguments must not be NULL.
Copyright (C) 2009-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
that the values passed as arguments n, ..., m must be non-NULL pointers.
n = 1 stands for the first argument, n = 2 for the second argument etc. */
#ifndef _GL_ARG_NONNULL
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
# else
# define _GL_ARG_NONNULL(params)
# endif
#endif

View File

@ -1,271 +0,0 @@
/* C++ compatible function declaration macros.
Copyright (C) 2010-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GL_CXXDEFS_H
#define _GL_CXXDEFS_H
/* The three most frequent use cases of these macros are:
* For providing a substitute for a function that is missing on some
platforms, but is declared and works fine on the platforms on which
it exists:
#if @GNULIB_FOO@
# if !@HAVE_FOO@
_GL_FUNCDECL_SYS (foo, ...);
# endif
_GL_CXXALIAS_SYS (foo, ...);
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
* For providing a replacement for a function that exists on all platforms,
but is broken/insufficient and needs to be replaced on some platforms:
#if @GNULIB_FOO@
# if @REPLACE_FOO@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef foo
# define foo rpl_foo
# endif
_GL_FUNCDECL_RPL (foo, ...);
_GL_CXXALIAS_RPL (foo, ...);
# else
_GL_CXXALIAS_SYS (foo, ...);
# endif
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
* For providing a replacement for a function that exists on some platforms
but is broken/insufficient and needs to be replaced on some of them and
is additionally either missing or undeclared on some other platforms:
#if @GNULIB_FOO@
# if @REPLACE_FOO@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef foo
# define foo rpl_foo
# endif
_GL_FUNCDECL_RPL (foo, ...);
_GL_CXXALIAS_RPL (foo, ...);
# else
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
_GL_FUNCDECL_SYS (foo, ...);
# endif
_GL_CXXALIAS_SYS (foo, ...);
# endif
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
*/
/* _GL_EXTERN_C declaration;
performs the declaration with C linkage. */
#if defined __cplusplus
# define _GL_EXTERN_C extern "C"
#else
# define _GL_EXTERN_C extern
#endif
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
declares a replacement function, named rpl_func, with the given prototype,
consisting of return type, parameters, and attributes.
Example:
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
_GL_ARG_NONNULL ((1)));
*/
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
declares the system function, named func, with the given prototype,
consisting of return type, parameters, and attributes.
Example:
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
_GL_ARG_NONNULL ((1)));
*/
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
_GL_EXTERN_C rettype func parameters_and_attributes
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
declares a C++ alias called GNULIB_NAMESPACE::func
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
Example:
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
*/
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
rettype (*const func) parameters = ::rpl_func; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
except that the C function rpl_func may have a slightly different
declaration. A cast is used to silence the "invalid conversion" error
that would otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
rettype (*const func) parameters = \
reinterpret_cast<rettype(*)parameters>(::rpl_func); \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
declares a C++ alias called GNULIB_NAMESPACE::func
that redirects to the system provided function func, if GNULIB_NAMESPACE
is defined.
Example:
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
*/
#if defined __cplusplus && defined GNULIB_NAMESPACE
/* If we were to write
rettype (*const func) parameters = ::func;
like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
better (remove an indirection through a 'static' pointer variable),
but then the _GL_CXXALIASWARN macro below would cause a warning not only
for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static rettype (*func) parameters = ::func; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
except that the C function func may have a slightly different declaration.
A cast is used to silence the "invalid conversion" error that would
otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static rettype (*func) parameters = \
reinterpret_cast<rettype(*)parameters>(::func); \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
except that the C function is picked among a set of overloaded functions,
namely the one with rettype2 and parameters2. Two consecutive casts
are used to silence the "cannot find a match" and "invalid conversion"
errors that would otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
/* The outer cast must be a reinterpret_cast.
The inner cast: When the function is defined as a set of overloaded
functions, it works as a static_cast<>, choosing the designated variant.
When the function is defined as a single variant, it works as a
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
namespace GNULIB_NAMESPACE \
{ \
static rettype (*func) parameters = \
reinterpret_cast<rettype(*)parameters>( \
(rettype2(*)parameters2)(::func)); \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIASWARN (func);
causes a warning to be emitted when ::func is used but not when
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
variants. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIASWARN(func) \
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN_1(func,namespace) \
_GL_CXXALIASWARN_2 (func, namespace)
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_WARN_ON_USE (func, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN_2(func,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN(func) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
causes a warning to be emitted when the given overloaded variant of ::func
is used but not when GNULIB_NAMESPACE::func is used. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
#endif /* _GL_CXXDEFS_H */

View File

@ -1,109 +0,0 @@
/* A C macro for emitting warnings if a function is used.
Copyright (C) 2010-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
for FUNCTION which will then trigger a compiler warning containing
the text of "literal string" anywhere that function is called, if
supported by the compiler. If the compiler does not support this
feature, the macro expands to an unused extern declaration.
This macro is useful for marking a function as a potential
portability trap, with the intent that "literal string" include
instructions on the replacement function that should be used
instead. However, one of the reasons that a function is a
portability trap is if it has the wrong signature. Declaring
FUNCTION with a different signature in C is a compilation error, so
this macro must use the same type as any existing declaration so
that programs that avoid the problematic FUNCTION do not fail to
compile merely because they included a header that poisoned the
function. But this implies that _GL_WARN_ON_USE is only safe to
use if FUNCTION is known to already have a declaration. Use of
this macro implies that there must not be any other macro hiding
the declaration of FUNCTION; but undefining FUNCTION first is part
of the poisoning process anyway (although for symbols that are
provided only via a macro, the result is a compilation error rather
than a warning containing "literal string"). Also note that in
C++, it is only safe to use if FUNCTION has no overloads.
For an example, it is possible to poison 'getline' by:
- adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
[getline]) in configure.ac, which potentially defines
HAVE_RAW_DECL_GETLINE
- adding this code to a header that wraps the system <stdio.h>:
#undef getline
#if HAVE_RAW_DECL_GETLINE
_GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
"not universally present; use the gnulib module getline");
#endif
It is not possible to directly poison global variables. But it is
possible to write a wrapper accessor function, and poison that
(less common usage, like &environ, will cause a compilation error
rather than issue the nice warning, but the end result of informing
the developer about their portability problem is still achieved):
#if HAVE_RAW_DECL_ENVIRON
static char ***rpl_environ (void) { return &environ; }
_GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
# undef environ
# define environ (*rpl_environ ())
#endif
*/
#ifndef _GL_WARN_ON_USE
# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
/* A compiler attribute is available in gcc versions 4.3.0 and later. */
# define _GL_WARN_ON_USE(function, message) \
extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
/* Verify the existence of the function. */
# define _GL_WARN_ON_USE(function, message) \
extern __typeof__ (function) function
# else /* Unsupported. */
# define _GL_WARN_ON_USE(function, message) \
_GL_WARN_EXTERN_C int _gl_warn_on_use
# endif
#endif
/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
is like _GL_WARN_ON_USE (function, "string"), except that the function is
declared with the given prototype, consisting of return type, parameters,
and attributes.
This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
not work in this case. */
#ifndef _GL_WARN_ON_USE_CXX
# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes \
__attribute__ ((__warning__ (msg)))
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
/* Verify the existence of the function. */
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes
# else /* Unsupported. */
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
_GL_WARN_EXTERN_C int _gl_warn_on_use
# endif
#endif
/* _GL_WARN_EXTERN_C declaration;
performs the declaration with C linkage. */
#ifndef _GL_WARN_EXTERN_C
# if defined __cplusplus
# define _GL_WARN_EXTERN_C extern "C"
# else
# define _GL_WARN_EXTERN_C extern
# endif
#endif

View File

@ -66,7 +66,7 @@ platformdir = $(pkglibdir)/$(target_cpu)-$(platform)
starfielddir = $(pkgdatadir)/themes/starfield
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib
CFLAGS_POSIX = -fno-builtin
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
@ -86,9 +86,11 @@ CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST
CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \
$(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \
$(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST)
$(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) \
$(CPPFLAGS_FDT_LIST)
# Define these variables to calm down automake
@ -126,11 +128,11 @@ BUILT_SOURCES =
.PRECIOUS: $(top_srcdir)/Makefile.util.am
$(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def
python $^ > $@.new || (rm -f $@.new; exit 1)
$(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@
.PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am
$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def
if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi
python $^ > $@.new || (rm -f $@.new; exit 1)
if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./bootstrap manually." >&2; exit 1; fi
$(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@

View File

@ -28,10 +28,9 @@ EXTRA_DIST += grub-core/gensymlist.sh
EXTRA_DIST += grub-core/genemuinit.sh
EXTRA_DIST += grub-core/genemuinitheader.sh
EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff
EXTRA_DIST += grub-core/gnulib-fix-width.diff
EXTRA_DIST += grub-core/gnulib-no-abort.diff
EXTRA_DIST += grub-core/gnulib-no-gets.diff
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch
EXTRA_DIST += grub-core/lib/libgcrypt
EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic

View File

@ -31,7 +31,7 @@ dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
dnl used for the target type. See INSTALL for full list of variables.
AC_INIT([GRUB],[2.02],[bug-grub@gnu.org])
AC_INIT([GRUB],[2.04],[bug-grub@gnu.org])
AC_CONFIG_AUX_DIR([build-aux])
@ -45,11 +45,15 @@ save_program_prefix="${program_prefix}"
AC_CANONICAL_TARGET
program_prefix="${save_program_prefix}"
AM_INIT_AUTOMAKE([1.10.1])
AC_PREREQ(2.60)
AM_INIT_AUTOMAKE([1.11])
AC_PREREQ(2.63)
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])
@ -100,6 +104,12 @@ case "$target_cpu" in
aarch64*)
target_cpu=arm64
;;
riscv32*)
target_cpu=riscv32
;;
riscv64*)
target_cpu=riscv64
;;
esac
# Specify the platform (such as firmware).
@ -123,6 +133,8 @@ if test "x$with_platform" = x; then
ia64-*) platform=efi ;;
arm-*) platform=uboot ;;
arm64-*) platform=efi ;;
riscv32-*) platform=efi ;;
riscv64-*) platform=efi ;;
*)
AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
platform=none
@ -147,6 +159,7 @@ case "$target_cpu"-"$platform" in
i386-efi) ;;
x86_64-efi) ;;
i386-xen) ;;
i386-xen_pvh) ;;
x86_64-xen) ;;
i386-pc) ;;
i386-multiboot) ;;
@ -167,8 +180,11 @@ case "$target_cpu"-"$platform" in
mipsel-fuloong) platform=loongson ;;
mipsel-loongson) ;;
arm-uboot) ;;
arm-coreboot) ;;
arm-efi) ;;
arm64-efi) ;;
riscv32-efi) ;;
riscv64-efi) ;;
*-emu) ;;
*-none) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
@ -203,7 +219,8 @@ case "$host_os" in
esac
case "$host_os" in
cygwin | windows* | mingw32*) have_exec=n ;;
cygwin) have_exec=y ;;
windows* | mingw32*) have_exec=n ;;
aros*) have_exec=n ;;
*) have_exec=y;;
esac
@ -213,6 +230,7 @@ case "$platform" in
multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;;
ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
@ -275,7 +293,7 @@ fi
AC_SUBST(bootdirname)
AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname",
[Default boot directory name]")
[Default boot directory name])
AC_ARG_WITH([grubdir],
AS_HELP_STRING([--with-grubdir=DIR],
@ -335,6 +353,7 @@ gl_EARLY
AC_PROG_CXX
AM_PROG_CC_C_O
AM_PROG_AS
AM_PATH_PYTHON([2.6])
# Must be GCC.
test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
@ -343,6 +362,7 @@ AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no)
AC_GNU_SOURCE
AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.18.3])
AC_SYS_LARGEFILE
# Identify characteristics of the host architecture.
@ -373,7 +393,10 @@ case "$host_os" in
;;
*)
AC_CHECK_SIZEOF(off_t)
test x"$ac_cv_sizeof_off_t" = x8 || AC_MSG_ERROR([Large file support is required]);;
if test x"$ac_cv_sizeof_off_t" != x8 ; then
AC_CHECK_SIZEOF(off64_t)
test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required])
fi;;
esac
if test x$USE_NLS = xno; then
@ -456,6 +479,16 @@ case "$build_os" in
esac
AC_SUBST(BUILD_EXEEXT)
# In some build environments like termux /bin/sh is not a valid
# shebang. Use $SHELL instead if it's executable and /bin/sh isn't
BUILD_SHEBANG=/bin/sh
for she in /bin/sh "$SHELL"; do
if test -x "$she" ; then
BUILD_SHEBANG="$she"
fi
done
AC_SUBST(BUILD_SHEBANG)
# For gnulib.
gl_INIT
@ -806,6 +839,16 @@ if test x"$platform" != xemu ; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
fi
if test "x$target_cpu" = xriscv32; then
CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
fi
if test "x$target_cpu" = xriscv64; then
CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
fi
if test "x$target_cpu" = xia64; then
CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
@ -1121,7 +1164,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
LDFLAGS="$TARGET_LDFLAGS"
if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
# Use large model to support 4G memory
AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
CFLAGS="$TARGET_CFLAGS -mcmodel=large"
@ -1131,7 +1174,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
])
if test "x$grub_cv_cc_mcmodel" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
elif test "$target_cpu" = sparc64; then
elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
fi
fi
@ -1185,12 +1228,12 @@ if test "x$target_cpu" = xarm; then
fi
AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [
CFLAGS="$TARGET_CFLAGS -Qn -Werror"
CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_qn=yes],
[grub_cv_target_cc_qn=no])])
if test "x$grub_cv_target_cc_qn" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -Qn"
TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments"
fi
#
@ -1352,7 +1395,7 @@ AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY)
if test "$platform" != emu; then
AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [
SAVED_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
CPPFLAGS="$TARGET_CPPFLAGS -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
#include <stddef.h>
int va_arg_func (int fixed, va_list args);]], [[]])],
@ -1493,29 +1536,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 +1563,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 +1592,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 +1625,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"
@ -1893,6 +1920,7 @@ AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform =
AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen])
AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh])
AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen])
AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
@ -1905,9 +1933,14 @@ AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot])
AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ])
AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ])
AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi])
AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi])
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
@ -1982,7 +2015,7 @@ fi
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([grub-core/Makefile])
AC_CONFIG_FILES([grub-core/gnulib/Makefile])
AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile])
AC_CONFIG_FILES([po/Makefile.in])
AC_CONFIG_FILES([docs/Makefile])
AC_CONFIG_FILES([util/bash-completion.d/Makefile])

View File

@ -77,6 +77,7 @@ This edition documents version @value{VERSION}.
* Coding style::
* Finding your way around::
* Contributing Changes::
* Updating External Code::
* Porting::
* Error Handling::
* Stack and heap size::
@ -84,6 +85,7 @@ This edition documents version @value{VERSION}.
* Video Subsystem::
* PFF2 Font File Format::
* Graphical Menu Software Design::
* Verifiers framework::
* Copying This Manual:: Copying This Manual
* Index::
@end menu
@ -181,38 +183,44 @@ If a macro is global, its name must be prefixed with GRUB_ and must consist of o
@section Comments
All comments shall be C-style comments, of the form @samp{/* @dots{} */}.
Comments shall be placed only on a line by themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes.
A comment can be placed immediately preceding the entity it describes or it
can be placed together with code, variable declarations, or other non-comment
entities. However, it is recommended to not mix various forms especially in
types/structs descriptions.
Acceptable:
@example
/* The page # that is the front buffer. */
/* The page # that is the front buffer. */
int displayed_page;
/* The page # that is the back buffer. */
int render_page;
@end example
Unacceptable:
@example
int displayed_page; /* The page # that is the front buffer. */
int render_page; /* The page # that is the back buffer. */
int render_page; /* The page # that is the back buffer. */
@end example
@node Multi-Line Comments
@section Multi-Line Comments
Comments spanning multiple lines shall be formatted with all lines after the first aligned with the first line.
Asterisk characters should not be repeated a the start of each subsequent line.
Comments spanning multiple lines shall be formatted with all lines after the
first aligned with the first line. Asterisk characters should be repeated at
the start of each subsequent line.
Acceptable:
@example
/* This is a comment
which spans multiple lines.
It is long. */
/*
* This is a comment
* which spans multiple lines.
* It is long.
*/
@end example
Unacceptable:
@example
/* This is a comment
which spans multiple lines.
It is long. */
@end example
@example
/*
* This is a comment
@ -220,7 +228,16 @@ Unacceptable:
* It is long. */
@end example
The opening @samp{/*} and closing @samp{*/} should be placed together on a line with text.
@example
/* This is a comment
* which spans multiple lines.
* It is long.
*/
@end example
In particular first unacceptable form makes comment difficult to distinguish
from the code itself. Especially if it contains the code snippets and/or is
long. So, its usage is disallowed.
@node Finding your way around
@chapter Finding your way around
@ -465,6 +482,69 @@ If your intention is to just get started, please do not submit a inclusion
request. Instead, please subscribe to the mailing list, and communicate first
(e.g. sending a patch, asking a question, commenting on another message...).
@node Updating External Code
@chapter Updating external code
GRUB includes some code from other projects, and it is sometimes necessary
to update it.
@menu
* Gnulib::
@end menu
@node Gnulib
@section Gnulib
Gnulib is a source code library that provides basic functionality to
programs and libraries. Many software packages make use of Gnulib
to avoid reinventing the portability wheel.
GRUB imports Gnulib using its @command{bootstrap} utility, identifying a
particular Git commit in @file{bootstrap.conf}. To upgrade to a new Gnulib
commit, set @code{GNULIB_REVISION} in @file{bootstrap.conf} to the new commit
ID, then run @kbd{./bootstrap} and whatever else you need to make sure it
works. Check for changes to Gnulib's @file{NEWS} file between the old and new
commits; in some cases it will be necessary to adjust GRUB to match. You may
also need to update the patches in @file{grub-core/lib/gnulib-patches/}.
To add a new Gnulib module or remove one that is no longer needed, change
@code{gnulib_modules} in @file{bootstrap.conf}. Again, run @kbd{./bootstrap}
and whatever else you need to make sure it works.
Bootstrapping from an older distribution containing gettext version < 0.18.3,
will require a patch similar to this to be applied first before running the
@command{./bootstrap} utility:
@example
diff --git a/bootstrap.conf b/bootstrap.conf
index 988dda0..a3193a9 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -67,7 +67,7 @@ SKIP_PO=t
buildreq="\
autoconf 2.63
automake 1.11
-gettext 0.18.3
+gettext 0.17
git 1.5.5
tar -
"
diff --git a/configure.ac b/configure.ac
index 08b518f..99f5b36 100644
--- a/configure.ac
+++ b/configure.ac
@@ -362,7 +362,7 @@ AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no)
AC_GNU_SOURCE
AM_GNU_GETTEXT([external])
-AM_GNU_GETTEXT_VERSION([0.18.3])
+AM_GNU_GETTEXT_VERSION([0.17])
AC_SYS_LARGEFILE
# Identify characteristics of the host architecture.
@end example
@node Porting
@chapter Porting
@ -671,7 +751,7 @@ is already present and you'll need to make it follow the existant code paths
for your platform adding adjustments if necessary. When done compile:
@example
./autogen.sh
./bootstrap
./configure --target=$cpu --with-platform=$platform TARGET_CC=.. OBJCOPY=... STRIP=...
make > /dev/null
@end example
@ -1949,6 +2029,63 @@ the graphics mode that was in use before @code{grub_video_setup()} was called
might fix some of the problems.
@node Verifiers framework
@chapter Verifiers framework
To register your own verifier call @samp{grub_verifier_register} with a structure
pointing to your functions.
The interface is inspired by the hash interface with @samp{init}/@samp{write}/@samp{fini}.
There are essentially 2 ways of using it, hashing and whole-file verification.
With the hashing approach:
During @samp{init} you decide whether you want to check the given file and init context.
In @samp{write} you update your hashing state.
In @samp{fini} you check that the hash matches the expected value/passes some check/...
With whole-file verification:
During @samp{init} you decide whether you want to check the given file and init context.
In @samp{write} you verify the file and return an error if it fails.
You don't have @samp{fini}.
Additional @samp{verify_string} receives various strings like kernel parameters
to verify. Returning no error means successful verification and an error stops
the current action.
Detailed description of the API:
Every time a file is opened your @samp{init} function is called with file descriptor
and file type. Your function can have the following outcomes:
@itemize
@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_DEFER_AUTH}.
In this case verification is deferred to other active verifiers. Verification
fails if nobody cares or selected verifier fails.
@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}.
In this case your verifier will not be called anymore and it is assumed to have
skipped verification.
@item returning no error and not setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}
In this case verification is done as described in the following section.
@item returning an error. Then opening of the file will fail due to failed verification.
@end itemize
In the third case your @samp{write} will be called with chunks of the file. If
you need the whole file in a single chunk then during @samp{init} set the bit
@samp{GRUB_VERIFY_FLAGS_SINGLE_CHUNK} in @samp{*flags}. During @samp{init} you
may set @samp{*context} if you need additional context. At every iteration you
may return an error and the file will be considered as having failed the
verification. If you return no error then verification continues.
Optionally at the end of the file @samp{fini}, if it exists, is called with just
the context. If you return no error during any of @samp{init}, @samp{write} and
@samp{fini} then the file is considered as having succeded verification.
@node Copying This Manual
@appendix Copying This Manual

View File

@ -360,8 +360,9 @@ blocklist notation. The currently supported filesystem types are @dfn{Amiga
Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS},
@dfn{BtrFS} (including raid0, raid1, raid10, gzip and lzo),
@dfn{cpio} (little- and big-endian bin, odc and newc variants),
@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{exFAT}, @dfn{HFS},
@dfn{HFS+}, @dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files),
@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32},
@dfn{exFAT}, @dfn{F2FS}, @dfn{HFS}, @dfn{HFS+},
@dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files),
@dfn{JFS}, @dfn{Minix fs} (versions 1, 2 and 3), @dfn{nilfs2},
@dfn{NTFS} (including compression), @dfn{ReiserFS}, @dfn{ROMFS},
@dfn{Amiga Smart FileSystem (SFS)}, @dfn{Squash4}, @dfn{tar}, @dfn{UDF},
@ -1213,10 +1214,11 @@ GRUB is configured using @file{grub.cfg}, usually located under
need to write the whole thing by hand.
@menu
* Simple configuration:: Recommended for most users
* Shell-like scripting:: For power users and developers
* Multi-boot manual config:: For non-standard multi-OS scenarios
* Embedded configuration:: Embedding a configuration file into GRUB
* Simple configuration:: Recommended for most users
* Root Identifcation Heuristics:: Summary on how the root file system is identified.
* Shell-like scripting:: For power users and developers
* Multi-boot manual config:: For non-standard multi-OS scenarios
* Embedded configuration:: Embedding a configuration file into GRUB
@end menu
@ -1398,6 +1400,25 @@ for all respectively normal entries.
The values of these options replace the values of @samp{GRUB_CMDLINE_LINUX}
and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux and Xen menu entries.
@item GRUB_EARLY_INITRD_LINUX_CUSTOM
@itemx GRUB_EARLY_INITRD_LINUX_STOCK
List of space-separated early initrd images to be loaded from @samp{/boot}.
This is for loading things like CPU microcode, firmware, ACPI tables, crypto
keys, and so on. These early images will be loaded in the order declared,
and all will be loaded before the actual functional initrd image.
@samp{GRUB_EARLY_INITRD_LINUX_STOCK} is for your distribution to declare
images that are provided by the distribution. It should not be modified
without understanding the consequences. They will be loaded first.
@samp{GRUB_EARLY_INITRD_LINUX_CUSTOM} is for your custom created images.
The default stock images are as follows, though they may be overridden by
your distribution:
@example
intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio
@end example
@item GRUB_DISABLE_LINUX_UUID
Normally, @command{grub-mkconfig} will generate menu entries that use
universally-unique identifiers (UUIDs) to identify the root filesystem to
@ -1405,6 +1426,17 @@ the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is
usually more reliable, but in some cases it may not be appropriate. To
disable the use of UUIDs, set this option to @samp{true}.
@item GRUB_DISABLE_LINUX_PARTUUID
If @command{grub-mkconfig} cannot identify the root filesystem via its
universally-unique indentifier (UUID), @command{grub-mkconfig} can use the UUID
of the partition containing the filesystem to identify the root filesystem to
the Linux kernel via a @samp{root=PARTUUID=...} kernel parameter. This is not
as reliable as using the filesystem UUID, but is more reliable than using the
Linux device names. When @samp{GRUB_DISABLE_LINUX_PARTUUID} is set to
@samp{false}, the Linux kernel version must be 2.6.37 (3.10 for systems using
the MSDOS partition scheme) or newer. This option defaults to @samp{true}. To
enable the use of partition UUIDs, set this option to @samp{false}.
@item GRUB_DISABLE_RECOVERY
If this option is set to @samp{true}, disable the generation of recovery
mode menu entries.
@ -1536,6 +1568,53 @@ edit the scripts in @file{/etc/grub.d} directly.
menu entries; simply type the menu entries you want to add at the end of
that file, making sure to leave at least the first two lines intact.
@node Root Identifcation Heuristics
@section Root Identifcation Heuristics
If the target operating system uses the Linux kernel, @command{grub-mkconfig}
attempts to identify the root file system via a heuristic algoirthm. This
algorithm selects the identification method of the root file system by
considering three factors. The first is if an initrd for the target operating
system is also present. The second is @samp{GRUB_DISABLE_LINUX_UUID} and if set
to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file
system by its UUID. The third is @samp{GRUB_DISABLE_LINUX_PARTUUID} and if set
to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file
system via the UUID of its enclosing partition. If the variables are assigned
any other value, that value is considered equivalent to @samp{false}. The
variables are also considered to be set to @samp{false} if they are not set.
When booting, the Linux kernel will delegate the task of mounting the root
filesystem to the initrd. Most initrd images determine the root file system by
checking the Linux kernel's command-line for the @samp{root} key and use its
value as the identification method of the root file system. To improve the
reliability of booting, most initrd images also allow the root file system to be
identified by its UUID. Because of this behavior, the @command{grub-mkconfig}
command will set @samp{root} to @samp{root=UUID=...} to provide the initrd with
the filesystem UUID of the root file system.
If no initrd is detected or @samp{GRUB_DISABLE_LINUX_UUID} is set to @samp{true}
then @command{grub-command} will identify the root filesystem by setting the
kernel command-line variable @samp{root} to @samp{root=PARTUUID=...} unless
@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}. If
@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true},
@command{grub-command} will identify by its Linux device name.
The following table summarizes the behavior of the @command{grub-mkconfig}
command.
@multitable {detected} {GRUB_DISABLE_LINUX_PARTUUID} {GRUB_DISABLE_LINUX_UUID} {Linux Root}
@headitem Initrd detected @tab GRUB_DISABLE_LINUX_PARTUUID Set To @tab GRUB_DISABLE_LINUX_UUID Set To @tab Linux Root ID Method
@item false @tab false @tab false @tab part UUID
@item false @tab false @tab true @tab part UUID
@item false @tab true @tab false @tab dev name
@item false @tab true @tab true @tab dev name
@item true @tab false @tab false @tab fs UUID
@item true @tab false @tab true @tab part UUID
@item true @tab true @tab false @tab fs UUID
@item true @tab true @tab true @tab dev name
@end multitable
Remember, @samp{GRUB_DISABLE_LINUX_PARTUUID} and @samp{GRUB_DISABLE_LINUX_UUID}
are also considered to be set to @samp{false} when they are unset.
@node Shell-like scripting
@section Writing full configuration files directly
@ -3852,6 +3931,7 @@ you forget a command, you can run the command @command{help}
* play:: Play a tune
* probe:: Retrieve device info
* pxe_unload:: Unload the PXE environment
* rdmsr:: Read values from model-specific registers
* read:: Read user input
* reboot:: Reboot your computer
* regexp:: Test if regular expression matches string
@ -3864,6 +3944,7 @@ you forget a command, you can run the command @command{help}
* sha256sum:: Compute or check SHA256 hash
* sha512sum:: Compute or check SHA512 hash
* sleep:: Wait for a specified number of seconds
* smbios:: Retrieve SMBIOS information
* source:: Read a configuration file in same context
* test:: Check file types and compare values
* true:: Do nothing, successfully
@ -3873,11 +3954,10 @@ you forget a command, you can run the command @command{help}
@comment * vbeinfo:: List available video modes
* verify_detached:: Verify detached digital signature
* videoinfo:: List available video modes
@comment * xen_*:: Xen boot commands
* xen_hypervisor:: Load xen hypervisor binary
* xen_linux:: Load dom0 kernel for xen hypervisor
* xen_initrd:: Load dom0 initrd for dom0 kernel
* xen_xsm:: Load xen security module for xen hypervisor
@comment * xen_*:: Xen boot commands for AArch64
* wrmsr:: Write values to model-specific registers
* xen_hypervisor:: Load xen hypervisor binary (only on AArch64)
* xen_module:: Load xen modules for xen hypervisor (only on AArch64)
@end menu
@ -4645,7 +4725,7 @@ range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal).
When enabled, this hides the selected partition by setting the @dfn{hidden}
bit in its partition type code; when disabled, unhides the selected
partition by clearing this bit. This is useful only when booting DOS or
Wwindows and multiple primary FAT partitions exist in one disk. See also
Windows and multiple primary FAT partitions exist in one disk. See also
@ref{DOS/Windows}.
@end table
@end deffn
@ -4708,6 +4788,24 @@ This command is only available on PC BIOS systems.
@end deffn
@node rdmsr
@subsection rdmsr
@deffn Command: rdmsr 0xADDR [-v VARNAME]
Read a model-specific register at address 0xADDR. If the parameter
@option{-v} is used and an environment variable @var{VARNAME} is
given, set that environment variable to the value that was read.
Please note that on SMP systems, reading from a MSR that has a
scope per hardware thread, implies that the value that is returned
only applies to the particular cpu/core/thread that runs the command.
Also, if you specify a reserved or unimplemented MSR address, it will
cause a general protection exception (which is not currently being handled)
and the system will reboot.
@end deffn
@node read
@subsection read
@ -4986,6 +5084,74 @@ if timeout was interrupted by @key{ESC}.
@end deffn
@node smbios
@subsection smbios
@deffn Command smbios @
[@option{--type} @var{type}] @
[@option{--handle} @var{handle}] @
[@option{--match} @var{match}] @
(@option{--get-byte} | @option{--get-word} | @option{--get-dword} | @
@option{--get-qword} | @option{--get-string} | @option{--get-uuid}) @
@var{offset} @
[@option{--set} @var{variable}]
Retrieve SMBIOS information.
The @command{smbios} command returns the value of a field in an SMBIOS
structure. The following options determine which structure to select.
@itemize @bullet
@item
Specifying @option{--type} will select structures with a matching
@var{type}. The type can be any integer from 0 to 255.
@item
Specifying @option{--handle} will select structures with a matching
@var{handle}. The handle can be any integer from 0 to 65535.
@item
Specifying @option{--match} will select structure number @var{match} in the
filtered list of structures; e.g. @code{smbios --type 4 --match 2} will select
the second Process Information (Type 4) structure. The list is always ordered
the same as the hardware's SMBIOS table. The match number must be a positive
integer. If unspecified, the first matching structure will be selected.
@end itemize
The remaining options determine which field in the selected SMBIOS structure to
return. Only one of these options may be specified at a time.
@itemize @bullet
@item
When given @option{--get-byte}, return the value of the byte
at @var{offset} bytes into the selected SMBIOS structure.
@item
When given @option{--get-word}, return the value of the word (two bytes)
at @var{offset} bytes into the selected SMBIOS structure.
@item
When given @option{--get-dword}, return the value of the dword (four bytes)
at @var{offset} bytes into the selected SMBIOS structure.
@item
When given @option{--get-qword}, return the value of the qword (eight bytes)
at @var{offset} bytes into the selected SMBIOS structure.
@item
When given @option{--get-string}, return the string with its index found
at @var{offset} bytes into the selected SMBIOS structure.
@item
When given @option{--get-uuid}, return the value of the UUID (sixteen bytes)
at @var{offset} bytes into the selected SMBIOS structure.
@end itemize
The default action is to print the value of the requested field to the console,
but a variable name can be specified with @option{--set} to store the value
instead of printing it.
For example, this will store and then display the system manufacturer's name.
@example
smbios --type 1 --get-string 4 --set system_manufacturer
echo $system_manufacturer
@end example
@end deffn
@node source
@subsection source
@ -5146,6 +5312,21 @@ successfully. If validation fails, it is set to a non-zero value.
List available video modes. If resolution is given, show only matching modes.
@end deffn
@node wrmsr
@subsection wrmsr
@deffn Command: wrmsr 0xADDR 0xVALUE
Write a 0xVALUE to a model-specific register at address 0xADDR.
Please note that on SMP systems, writing to a MSR that has a scope
per hardware thread, implies that the value that is written
only applies to the particular cpu/core/thread that runs the command.
Also, if you specify a reserved or unimplemented MSR address, it will
cause a general protection exception (which is not currently being handled)
and the system will reboot.
@end deffn
@node xen_hypervisor
@subsection xen_hypervisor
@ -5153,32 +5334,22 @@ List available video modes. If resolution is given, show only matching modes.
Load a Xen hypervisor binary from @var{file}. The rest of the line is passed
verbatim as the @dfn{kernel command-line}. Any other binaries must be
reloaded after using this command.
This command is only available on AArch64 systems.
@end deffn
@node xen_linux
@subsection xen_linux
@node xen_module
@subsection xen_module
@deffn Command xen_linux file [arguments]
Load a dom0 kernel image for xen hypervisor at the booting process of xen.
@deffn Command xen_module [--nounzip] file [arguments]
Load a module for xen hypervisor at the booting process of xen.
The rest of the line is passed verbatim as the module command line.
Modules should be loaded in the following order:
- dom0 kernel image
- dom0 ramdisk if present
- XSM policy if present
This command is only available on AArch64 systems.
@end deffn
@node xen_initrd
@subsection xen_initrd
@deffn Command xen_initrd file
Load a initrd image for dom0 kernel at the booting process of xen.
@end deffn
@node xen_xsm
@subsection xen_xsm
@deffn Command xen_xsm file
Load a xen security module for xen hypervisor at the booting process of xen.
See @uref{http://wiki.xen.org/wiki/XSM} for more detail.
@end deffn
@node Networking commands
@section The list of networking commands
@ -5368,7 +5539,7 @@ NTFS, JFS, UDF, HFS+, exFAT, long filenames in FAT, Joliet part of
ISO9660 are treated as UTF-16 as per specification. AFS and BFS are read
as UTF-8, again according to specification. BtrFS, cpio, tar, squash4, minix,
minix2, minix3, ROMFS, ReiserFS, XFS, ext2, ext3, ext4, FAT (short names),
RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed
F2FS, RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed
to be UTF-8. This might be false on systems configured with legacy charset
but as long as the charset used is superset of ASCII you should be able to
access ASCII-named files. And it's recommended to configure your system to use
@ -5477,6 +5648,8 @@ environment variables and commands are listed in the same order.
@menu
* Authentication and authorisation:: Users and access control
* Using digital signatures:: Booting digitally signed code
* UEFI secure boot and shim:: Booting digitally signed PE files
* Measured Boot:: Measuring boot components
@end menu
@node Authentication and authorisation
@ -5639,6 +5812,57 @@ or BIOS) configuration to cause the machine to boot from a different
(attacker-controlled) device. GRUB is at best only one link in a
secure boot chain.
@node UEFI secure boot and shim
@section UEFI secure boot and shim support
The GRUB, except the @command{chainloader} command, works with the UEFI secure
boot and the shim. This functionality is provided by the shim_lock module. It
is recommend to build in this and other required modules into the @file{core.img}.
All modules not stored in the @file{core.img} and the ACPI tables for the
@command{acpi} command have to be signed, e.g. using PGP. Additionally, the
@command{iorw}, the @command{memrw} and the @command{wrmsr} commands are
prohibited if the UEFI secure boot is enabled. This is done due to
security reasons. All above mentioned requirements are enforced by the
shim_lock module. And itself it is a persistent module which means that
it cannot be unloaded if it was loaded into the memory.
@node Measured Boot
@section Measuring boot components
If the tpm module is loaded and the platform has a Trusted Platform Module
installed, GRUB will log each command executed and each file loaded into the
TPM event log and extend the PCR values in the TPM correspondingly. All events
will be logged into the PCR described below with a type of EV_IPL and an
event description as described below.
@multitable @columnfractions 0.3 0.1 0.6
@headitem Event type @tab PCR @tab Description
@item Command
@tab 8
@tab All executed commands (including those from configuration files) will be
logged and measured as entered with a prefix of ``grub_cmd: ``
@item Kernel command line
@tab 8
@tab Any command line passed to a kernel will be logged and measured as entered
with a prefix of ``kernel_cmdline: ''
@item Module command line
@tab 8
@tab Any command line passed to a kernel module will be logged and measured as
entered with a prefix of ``module_cmdline: ``
@item Files
@tab 9
@tab Any file read by GRUB will be logged and measured with a descriptive text
corresponding to the filename.
@end multitable
GRUB will not measure its own @file{core.img} - it is expected that firmware
will carry this out. GRUB will also not perform any measurements until the
tpm module is loaded. As such it is recommended that the tpm module be built
into @file{core.img} in order to avoid a potential gap in measurement between
@file{core.img} being loaded and the tpm module being loaded.
Measured boot is currently only supported on EFI platforms.
@node Platform limitations
@chapter Platform limitations
@ -5711,6 +5935,8 @@ to install to is specified, UUID is used instead as well.
@item USB @tab yes @tab yes @tab yes @tab yes
@item chainloader @tab local @tab yes @tab yes @tab no
@item cpuid @tab partial @tab partial @tab partial @tab partial
@item rdmsr @tab partial @tab partial @tab partial @tab partial
@item wrmsr @tab partial @tab partial @tab partial @tab partial
@item hints @tab guess @tab guess @tab guess @tab guess
@item PCI @tab yes @tab yes @tab yes @tab yes
@item badram @tab yes @tab yes @tab yes @tab yes
@ -5730,6 +5956,8 @@ to install to is specified, UUID is used instead as well.
@item USB @tab yes @tab yes @tab yes @tab no
@item chainloader @tab local @tab local @tab no @tab local
@item cpuid @tab partial @tab partial @tab partial @tab no
@item rdmsr @tab partial @tab partial @tab partial @tab no
@item wrmsr @tab partial @tab partial @tab partial @tab no
@item hints @tab guess @tab guess @tab good @tab guess
@item PCI @tab yes @tab yes @tab yes @tab no
@item badram @tab yes @tab yes @tab no @tab yes
@ -5749,6 +5977,8 @@ to install to is specified, UUID is used instead as well.
@item USB @tab yes @tab no @tab no @tab no
@item chainloader @tab yes @tab no @tab no @tab no
@item cpuid @tab no @tab no @tab no @tab no
@item rdmsr @tab no @tab no @tab no @tab no
@item wrmsr @tab no @tab no @tab no @tab no
@item hints @tab good @tab good @tab good @tab no
@item PCI @tab yes @tab no @tab no @tab no
@item badram @tab yes (*) @tab no @tab no @tab no
@ -5768,6 +5998,8 @@ to install to is specified, UUID is used instead as well.
@item USB @tab N/A @tab yes @tab no
@item chainloader @tab yes @tab no @tab yes
@item cpuid @tab no @tab no @tab yes
@item rdmsr @tab no @tab no @tab yes
@item wrmsr @tab no @tab no @tab yes
@item hints @tab guess @tab no @tab no
@item PCI @tab no @tab no @tab no
@item badram @tab yes (*) @tab no @tab no
@ -5968,6 +6200,7 @@ Required files are:
@menu
* GRUB only offers a rescue shell::
* Firmware stalls instead of booting GRUB::
@end menu
@ -6038,6 +6271,17 @@ support has not yet been added to GRUB.
@end itemize
@node Firmware stalls instead of booting GRUB
@section Firmware stalls instead of booting GRUB
The EFI implementation of some older MacBook laptops stalls when it gets
presented a grub-mkrescue ISO image for x86_64-efi target on an USB stick.
Affected are models of year 2010 or earlier. Workaround is to zeroize the
bytes 446 to 461 of the EFI partition, where mformat has put a partition table
entry which claims partition start at block 0. This change will not hamper
bootability on other machines.
@node Invoking grub-install
@chapter Invoking grub-install

View File

@ -28,10 +28,11 @@ import re
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
"i386_xen", "x86_64_xen",
"i386_xen", "x86_64_xen", "i386_xen_pvh",
"mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ]
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
"arm_coreboot", "riscv32_efi", "riscv64_efi" ]
GROUPS = {}
@ -44,14 +45,18 @@ GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ]
GROUPS["arm64"] = [ "arm64_efi" ]
GROUPS["riscv32"] = [ "riscv32_efi" ]
GROUPS["riscv64"] = [ "riscv64_efi" ]
# Groups based on firmware
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ]
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi",
"riscv32_efi", "riscv64_efi" ]
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
GROUPS["uboot"] = [ "arm_uboot" ]
GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ]
# emu is a special case so many core functionality isn't needed on this platform
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
@ -61,24 +66,24 @@ GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips",
"sparc64_ieee1275", "powerpc_ieee1275"]
GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi");
GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
GROUPS["usb"] = GROUPS["pci"]
GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"]
# If gfxterm is main output console integrate it into kernel
GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot" ]
GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ]
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
# Similar for terminfo
GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
# Flattened Device Trees (FDT)
GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ]
GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ]
# Needs software helpers for division
# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"]
GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"]
GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)

View File

@ -92,6 +92,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/tpm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
if COND_i386_pc
@ -101,7 +102,20 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_xen_pvh
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
endif
if COND_i386_efi
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
@ -111,8 +125,9 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
endif
if COND_i386_coreboot
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
@ -122,6 +137,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif
if COND_i386_multiboot
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif
@ -132,6 +148,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_ieee1275
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
@ -140,6 +157,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_xen
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
@ -158,6 +176,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
endif
if COND_x86_64_efi
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
@ -239,8 +258,21 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
endif
if COND_arm_coreboot
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h
endif
if COND_arm_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
@ -253,6 +285,18 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif
if COND_riscv32_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif
if COND_riscv64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
@ -278,7 +322,7 @@ BUILT_SOURCES += symlist.h
symlist.c: symlist.h gensymlist.sh
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
cat symlist.p | /bin/sh $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
rm -f symlist.p
CLEANFILES += symlist.c
BUILT_SOURCES += symlist.c
@ -358,6 +402,16 @@ terminal.lst: $(MARKER_FILES)
platform_DATA += terminal.lst
CLEANFILES += terminal.lst
fdt.lst: $(MARKER_FILES)
(for pp in $^; do \
b=`basename $$pp .marker`; \
sed -n \
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
done) | sort -u > $@
platform_DATA += fdt.lst
CLEANFILES += fdt.lst
parttool.lst: $(MARKER_FILES)
(for pp in $^; do \
b=`basename $$pp .marker`; \

View File

@ -65,20 +65,28 @@ kernel = {
arm64_efi_ldflags = '-Wl,-r,-d';
arm64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
riscv32_efi_ldflags = '-Wl,-r,-d';
riscv32_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
riscv64_efi_ldflags = '-Wl,-r,-d';
riscv64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
i386_coreboot_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
i386_multiboot_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
i386_ieee1275_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_ieee1275_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x10000';
i386_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000';
mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
@ -92,12 +100,15 @@ kernel = {
emu_cppflags = '$(CPPFLAGS_GNULIB)';
arm_uboot_ldflags = '-Wl,-r,-d';
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
arm_coreboot_ldflags = '-Wl,-r,-d';
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_startup = kern/i386/pc/startup.S;
i386_efi_startup = kern/i386/efi/startup.S;
x86_64_efi_startup = kern/x86_64/efi/startup.S;
i386_xen_startup = kern/i386/xen/startup.S;
x86_64_xen_startup = kern/x86_64/xen/startup.S;
i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S;
i386_qemu_startup = kern/i386/qemu/startup.S;
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
i386_coreboot_startup = kern/i386/coreboot/startup.S;
@ -105,9 +116,12 @@ kernel = {
mips_startup = kern/mips/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
arm_uboot_startup = kern/arm/uboot/startup.S;
arm_uboot_startup = kern/arm/startup.S;
arm_coreboot_startup = kern/arm/startup.S;
arm_efi_startup = kern/arm/efi/startup.S;
arm64_efi_startup = kern/arm64/efi/startup.S;
riscv32_efi_startup = kern/riscv/efi/startup.S;
riscv64_efi_startup = kern/riscv/efi/startup.S;
common = kern/command.c;
common = kern/corecmd.c;
@ -126,6 +140,7 @@ kernel = {
common = kern/rescue_parser.c;
common = kern/rescue_reader.c;
common = kern/term.c;
common = kern/tpm.c;
noemu = kern/compiler-rt.c;
noemu = kern/mm.c;
@ -149,6 +164,21 @@ kernel = {
uboot = kern/uboot/init.c;
uboot = kern/uboot/hw.c;
uboot = term/uboot/console.c;
arm_uboot = kern/arm/uboot/init.c;
arm_uboot = kern/arm/uboot/uboot.S;
arm_coreboot = kern/arm/coreboot/init.c;
arm_coreboot = kern/arm/coreboot/timer.c;
arm_coreboot = kern/arm/coreboot/coreboot.S;
arm_coreboot = lib/fdt.c;
arm_coreboot = bus/fdt.c;
arm_coreboot = term/ps2.c;
arm_coreboot = term/arm/pl050.c;
arm_coreboot = term/arm/cros.c;
arm_coreboot = term/arm/cros_ec.c;
arm_coreboot = bus/spi/rk3288_spi.c;
arm_coreboot = commands/keylayouts.c;
arm_coreboot = kern/arm/coreboot/dma.c;
terminfoinkernel = term/terminfo.c;
terminfoinkernel = term/tparm.c;
@ -159,12 +189,13 @@ kernel = {
i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
i386_xen_pvh = kern/i386/dl.c;
i386_coreboot = kern/i386/coreboot/init.c;
i386_multiboot = kern/i386/coreboot/init.c;
i386_qemu = kern/i386/qemu/init.c;
i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c;
i386_coreboot = video/i386/coreboot/cbfb.c;
coreboot = video/coreboot/cbfb.c;
efi = disk/efi/efidisk.c;
efi = kern/efi/efi.c;
@ -173,6 +204,7 @@ kernel = {
efi = term/efi/console.c;
efi = kern/acpi.c;
efi = kern/efi/acpi.c;
efi = kern/efi/tpm.c;
i386_coreboot = kern/i386/pc/acpi.c;
i386_multiboot = kern/i386/pc/acpi.c;
i386_coreboot = kern/acpi.c;
@ -204,6 +236,14 @@ kernel = {
xen = disk/xen/xendisk.c;
xen = commands/boot.c;
i386_xen_pvh = commands/boot.c;
i386_xen_pvh = disk/xen/xendisk.c;
i386_xen_pvh = kern/i386/tsc.c;
i386_xen_pvh = kern/i386/xen/tsc.c;
i386_xen_pvh = kern/i386/xen/pvh.c;
i386_xen_pvh = kern/xen/init.c;
i386_xen_pvh = term/xen/console.c;
ia64_efi = kern/ia64/efi/startup.S;
ia64_efi = kern/ia64/efi/init.c;
ia64_efi = kern/ia64/dl.c;
@ -211,22 +251,30 @@ kernel = {
ia64_efi = kern/ia64/cache.c;
arm_efi = kern/arm/efi/init.c;
arm_efi = kern/arm/efi/misc.c;
arm_efi = kern/efi/fdt.c;
arm64_efi = kern/arm64/efi/init.c;
arm64_efi = kern/efi/fdt.c;
riscv32_efi = kern/riscv/efi/init.c;
riscv32_efi = kern/efi/fdt.c;
riscv64_efi = kern/riscv/efi/init.c;
riscv64_efi = kern/efi/fdt.c;
i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c;
i386_pc = kern/i386/pc/tpm.c;
i386_pc = term/i386/pc/console.c;
i386_qemu = bus/pci.c;
i386_qemu = kern/vga_init.c;
i386_qemu = kern/i386/qemu/mmap.c;
i386_coreboot = kern/i386/coreboot/mmap.c;
coreboot = kern/coreboot/mmap.c;
i386_coreboot = kern/i386/coreboot/cbtable.c;
coreboot = kern/coreboot/cbtable.c;
arm_coreboot = kern/arm/coreboot/cbtable.c;
i386_multiboot = kern/i386/multiboot_mmap.c;
@ -238,6 +286,7 @@ kernel = {
mips_qemu_mips = term/ns8250.c;
mips_qemu_mips = term/serial.c;
mips_qemu_mips = term/at_keyboard.c;
mips_qemu_mips = term/ps2.c;
mips_qemu_mips = commands/boot.c;
mips_qemu_mips = commands/keylayouts.c;
mips_qemu_mips = term/i386/pc/vga_text.c;
@ -253,6 +302,7 @@ kernel = {
mips_loongson = bus/pci.c;
mips_loongson = kern/mips/loongson/init.c;
mips_loongson = term/at_keyboard.c;
mips_loongson = term/ps2.c;
mips_loongson = commands/boot.c;
mips_loongson = term/serial.c;
mips_loongson = video/sm712.c;
@ -270,6 +320,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;
@ -284,6 +335,14 @@ kernel = {
arm64 = kern/arm64/dl.c;
arm64 = kern/arm64/dl_helper.c;
riscv32 = kern/riscv/cache.c;
riscv32 = kern/riscv/cache_flush.S;
riscv32 = kern/riscv/dl.c;
riscv64 = kern/riscv/cache.c;
riscv64 = kern/riscv/cache_flush.S;
riscv64 = kern/riscv/dl.c;
emu = disk/host.c;
emu = kern/emu/cache_s.S;
emu = kern/emu/hostdisk.c;
@ -339,7 +398,7 @@ program = {
ldadd = 'kernel.exec$(EXEEXT)';
ldadd = '$(MODULE_FILES)';
ldadd = 'gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
@ -351,7 +410,7 @@ program = {
emu_nodist = symlist.c;
ldadd = 'kernel.exec$(EXEEXT)';
ldadd = 'gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu;
};
@ -369,8 +428,14 @@ image = {
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)';
i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big';
sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000';
/* The entry point for a.out binaries on sparc64 starts
at 0x4000. Since we are writing the 32 bytes long a.out
header in the assembly code ourselves, we need to tell
the linker to adjust the start of the text segment to
0x4000 - 0x20 = 0x3fe0.
*/
sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0';
sparc64_ieee1275_objcopyflags = '-O binary';
objcopyflags = '-O binary';
enable = i386_pc;
@ -399,8 +464,10 @@ image = {
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S;
sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big';
sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000';
/* See comment for sparc64_ieee1275_ldflags above. */
sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0';
sparc64_ieee1275_objcopyflags = '-O binary';
sparc64_ieee1275_cppflags = '-DCDBOOT=1';
objcopyflags = '-O binary';
@ -574,7 +641,10 @@ module = {
module = {
name = ehci;
common = bus/usb/ehci.c;
arm_coreboot = bus/usb/ehci-fdt.c;
pci = bus/usb/ehci-pci.c;
enable = pci;
enable = arm_coreboot;
};
module = {
@ -641,6 +711,7 @@ module = {
module = {
name = cbtable;
common = kern/i386/coreboot/cbtable.c;
common = kern/coreboot/cbtable.c;
enable = i386_pc;
enable = i386_efi;
enable = i386_qemu;
@ -671,7 +742,7 @@ module = {
name = regexp;
common = commands/regexp.c;
common = commands/wildcard.c;
common = gnulib/regex.c;
common = lib/gnulib/regex.c;
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
};
@ -754,6 +825,9 @@ module = {
enable = arm_efi;
enable = arm64_efi;
enable = arm_uboot;
enable = arm_coreboot;
enable = riscv32_efi;
enable = riscv64_efi;
};
module = {
@ -775,6 +849,7 @@ module = {
name = cpuid;
common = commands/i386/cpuid.c;
enable = x86;
enable = i386_xen_pvh;
enable = i386_xen;
enable = x86_64_xen;
};
@ -816,11 +891,32 @@ module = {
enable = x86_64_efi;
};
module = {
name = getenv;
common = commands/efi/getenv.c;
enable = efi;
};
module = {
name = gptsync;
common = commands/gptsync.c;
};
module = {
name = gptrepair;
common = commands/gptrepair.c;
};
module = {
name = gptprio;
common = commands/gptprio.c;
};
module = {
name = gpt;
common = lib/gpt.c;
};
module = {
name = halt;
nopc = commands/halt.c;
@ -834,27 +930,27 @@ module = {
i386_coreboot = lib/i386/halt.c;
i386_qemu = lib/i386/halt.c;
xen = lib/xen/halt.c;
i386_xen_pvh = lib/xen/halt.c;
efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c;
emu = lib/emu/halt.c;
uboot = lib/uboot/halt.c;
uboot = lib/dummy/halt.c;
arm_coreboot = lib/dummy/halt.c;
};
module = {
name = reboot;
i386 = lib/i386/reboot.c;
i386 = lib/i386/reboot_trampoline.S;
ia64_efi = lib/efi/reboot.c;
x86_64_efi = lib/efi/reboot.c;
arm_efi = lib/efi/reboot.c;
arm64_efi = lib/efi/reboot.c;
powerpc_ieee1275 = lib/ieee1275/reboot.c;
sparc64_ieee1275 = lib/ieee1275/reboot.c;
mips_arc = lib/mips/arc/reboot.c;
mips_loongson = lib/mips/loongson/reboot.c;
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
xen = lib/xen/reboot.c;
i386_xen_pvh = lib/xen/reboot.c;
uboot = lib/uboot/reboot.c;
arm_coreboot = lib/dummy/reboot.c;
common = commands/reboot.c;
};
@ -864,16 +960,26 @@ module = {
};
module = {
name = verify;
common = commands/verify.c;
name = pgp;
common = commands/pgp.c;
cflags = '$(CFLAGS_POSIX)';
cppflags = '-I$(srcdir)/lib/posix_wrap';
};
module = {
name = verifiers;
common = commands/verifiers.c;
};
module = {
name = shim_lock;
common = commands/efi/shim_lock.c;
enable = x86_64_efi;
};
module = {
name = hdparm;
common = commands/hdparm.c;
common = lib/hexdump.c;
enable = pci;
enable = mips_qemu_mips;
};
@ -998,6 +1104,21 @@ module = {
common = commands/search_label.c;
};
module = {
name = search_part_uuid;
common = commands/search_part_uuid.c;
};
module = {
name = search_part_label;
common = commands/search_part_label.c;
};
module = {
name = search_disk_uuid;
common = commands/search_disk_uuid.c;
};
module = {
name = setpci;
common = commands/setpci.c;
@ -1015,6 +1136,21 @@ module = {
common = commands/sleep.c;
};
module = {
name = smbios;
common = commands/smbios.c;
efi = commands/efi/smbios.c;
i386_pc = commands/i386/pc/smbios.c;
i386_coreboot = commands/i386/pc/smbios.c;
i386_multiboot = commands/i386/pc/smbios.c;
enable = efi;
enable = i386_pc;
enable = i386_coreboot;
enable = i386_multiboot;
};
module = {
name = suspend;
ieee1275 = commands/ieee1275/suspend.c;
@ -1237,12 +1373,27 @@ module = {
common = fs/bfs.c;
};
module = {
name = zstd;
common = lib/zstd/debug.c;
common = lib/zstd/entropy_common.c;
common = lib/zstd/error_private.c;
common = lib/zstd/fse_decompress.c;
common = lib/zstd/huf_decompress.c;
common = lib/zstd/module.c;
common = lib/zstd/xxhash.c;
common = lib/zstd/zstd_common.c;
common = lib/zstd/zstd_decompress.c;
cflags = '$(CFLAGS_POSIX) -Wno-undef';
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd';
};
module = {
name = btrfs;
common = fs/btrfs.c;
common = lib/crc.c;
cflags = '$(CFLAGS_POSIX) -Wno-undef';
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H';
};
module = {
@ -1290,6 +1441,11 @@ module = {
common = fs/exfat.c;
};
module = {
name = f2fs;
common = fs/f2fs.c;
};
module = {
name = fshelp;
common = fs/fshelp.c;
@ -1517,12 +1673,18 @@ module = {
x86 = lib/i386/relocator16.S;
x86 = lib/i386/relocator32.S;
x86 = lib/i386/relocator64.S;
i386_xen_pvh = lib/i386/relocator16.S;
i386_xen_pvh = lib/i386/relocator32.S;
i386_xen_pvh = lib/i386/relocator64.S;
i386 = lib/i386/relocator_asm.S;
i386_xen_pvh = lib/i386/relocator_asm.S;
x86_64 = lib/x86_64/relocator_asm.S;
i386_xen = lib/i386/relocator_asm.S;
x86_64_xen = lib/x86_64/relocator_asm.S;
x86 = lib/i386/relocator.c;
x86 = lib/i386/relocator_common_c.c;
i386_xen_pvh = lib/i386/relocator.c;
i386_xen_pvh = lib/i386/relocator_common_c.c;
ieee1275 = lib/ieee1275/relocator.c;
efi = lib/efi/relocator.c;
mips = lib/mips/relocator_asm.S;
@ -1541,6 +1703,7 @@ module = {
enable = mips;
enable = powerpc;
enable = x86;
enable = i386_xen_pvh;
enable = xen;
};
@ -1548,12 +1711,14 @@ module = {
name = datetime;
cmos = lib/cmos_datetime.c;
efi = lib/efi/datetime.c;
uboot = lib/uboot/datetime.c;
uboot = lib/dummy/datetime.c;
arm_coreboot = lib/dummy/datetime.c;
sparc64_ieee1275 = lib/ieee1275/datetime.c;
powerpc_ieee1275 = lib/ieee1275/datetime.c;
sparc64_ieee1275 = lib/ieee1275/cmos.c;
powerpc_ieee1275 = lib/ieee1275/cmos.c;
xen = lib/xen/datetime.c;
i386_xen_pvh = lib/xen/datetime.c;
mips_arc = lib/arc/datetime.c;
enable = noemu;
@ -1571,6 +1736,7 @@ module = {
extra_dist = lib/ia64/longjmp.S;
extra_dist = lib/arm/setjmp.S;
extra_dist = lib/arm64/setjmp.S;
extra_dist = lib/riscv/setjmp.S;
};
module = {
@ -1601,8 +1767,6 @@ module = {
module = {
name = linux16;
common = loader/i386/pc/linux.c;
common = loader/linux.c;
common = lib/cmdline.c;
enable = x86;
};
@ -1637,24 +1801,24 @@ module = {
cppflags = "-DGRUB_USE_MULTIBOOT2";
common = loader/multiboot.c;
common = lib/cmdline.c;
common = loader/multiboot_mbi2.c;
enable = x86;
enable = i386_xen_pvh;
enable = mips;
};
module = {
name = multiboot;
common = loader/multiboot.c;
common = lib/cmdline.c;
x86 = loader/i386/multiboot_mbi.c;
i386_xen_pvh = loader/i386/multiboot_mbi.c;
extra_dist = loader/multiboot_elfxx.c;
enable = x86;
enable = i386_xen_pvh;
};
module = {
name = xen_boot;
common = lib/cmdline.c;
arm64 = loader/arm64/xen_boot.c;
enable = arm64;
};
@ -1662,14 +1826,20 @@ module = {
module = {
name = linux;
x86 = loader/i386/linux.c;
i386_xen_pvh = loader/i386/linux.c;
xen = loader/i386/xen.c;
i386_pc = lib/i386/pc/vesa_modes_table.c;
i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
ia64_efi = loader/ia64/efi/linux.c;
arm = loader/arm/linux.c;
arm_coreboot = loader/arm/linux.c;
arm_efi = loader/arm64/linux.c;
arm_uboot = loader/arm/linux.c;
arm64 = loader/arm64/linux.c;
riscv32 = loader/riscv/linux.c;
riscv64 = loader/riscv/linux.c;
common = loader/linux.c;
common = lib/cmdline.c;
enable = noemu;
@ -1677,7 +1847,7 @@ module = {
module = {
name = fdt;
arm64 = loader/arm64/fdt.c;
efi = loader/efi/fdt.c;
common = lib/fdt.c;
enable = fdt;
};
@ -1733,6 +1903,14 @@ module = {
enable = x86_64_efi;
};
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;
@ -1749,6 +1927,8 @@ module = {
common = mmap/mmap.c;
x86 = mmap/i386/uppermem.c;
x86 = mmap/i386/mmap.c;
i386_xen_pvh = mmap/i386/uppermem.c;
i386_xen_pvh = mmap/i386/mmap.c;
i386_pc = mmap/i386/pc/mmap.c;
i386_pc = mmap/i386/pc/mmap_helper.S;
@ -1758,9 +1938,12 @@ module = {
mips = mmap/mips/uppermem.c;
enable = x86;
enable = i386_xen_pvh;
enable = ia64_efi;
enable = arm_efi;
enable = arm64_efi;
enable = riscv32_efi;
enable = riscv64_efi;
enable = mips;
};
@ -1869,6 +2052,7 @@ module = {
module = {
name = at_keyboard;
common = term/at_keyboard.c;
common = term/ps2.c;
enable = x86;
};
@ -1961,6 +2145,11 @@ module = {
common = tests/example_functional_test.c;
};
module = {
name = strtoull_test;
common = tests/strtoull_test.c;
};
module = {
name = setjmp_test;
common = tests/setjmp_test.c;
@ -1991,6 +2180,7 @@ module = {
name = legacy_password_test;
common = tests/legacy_password_test.c;
enable = i386_pc;
enable = i386_xen_pvh;
enable = i386_efi;
enable = x86_64_efi;
enable = emu;
@ -2189,6 +2379,7 @@ module = {
xen = lib/i386/pc/vesa_modes_table.c;
enable = i386_pc;
enable = i386_xen_pvh;
enable = i386_efi;
enable = x86_64_efi;
enable = emu;
@ -2232,10 +2423,12 @@ module = {
module = {
name = backtrace;
x86 = lib/i386/backtrace.c;
i386_xen_pvh = lib/i386/backtrace.c;
i386_xen = lib/i386/backtrace.c;
x86_64_xen = lib/i386/backtrace.c;
common = lib/backtrace.c;
enable = x86;
enable = i386_xen_pvh;
enable = i386_xen;
enable = x86_64_xen;
};
@ -2334,6 +2527,13 @@ module = {
common = commands/testspeed.c;
};
module = {
name = tpm;
common = commands/tpm.c;
efi = commands/efi/tpm.c;
enable = x86_64_efi;
};
module = {
name = tr;
common = commands/tr.c;
@ -2355,3 +2555,18 @@ module = {
common = loader/i386/xen_file64.c;
extra_dist = loader/i386/xen_fileXX.c;
};
module = {
name = rdmsr;
common = commands/i386/rdmsr.c;
enable = x86;
};
module = {
name = wrmsr;
common = commands/i386/wrmsr.c;
enable = x86;
};
module = {
name = fwconfig;
common = commands/fwconfig.c;
enable = x86;
};

View File

@ -24,11 +24,14 @@
* defines for the code go here
*/
#define TPM 1
/* Print message string */
#define MSG(x) movw $x, %si; call LOCAL(message)
#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
.macro floppy
#ifndef TPM
part_start:
LOCAL(probe_values):
@ -85,6 +88,7 @@ fd_probe_error_string: .asciz "Floppy"
movb MACRO_DOLLAR(79), %ch
jmp LOCAL(final_init)
#endif
.endm
.macro scratch
@ -255,6 +259,7 @@ real_start:
/* set %si to the disk address packet */
movw $disk_address_packet, %si
#ifndef TPM
/* check if LBA is supported */
movb $0x41, %ah
movw $0x55aa, %bx
@ -274,6 +279,7 @@ real_start:
andw $1, %cx
jz LOCAL(chs_mode)
#endif
LOCAL(lba_mode):
xorw %ax, %ax
@ -317,6 +323,9 @@ LOCAL(lba_mode):
jmp LOCAL(copy_buffer)
LOCAL(chs_mode):
#ifdef TPM
jmp LOCAL(general_error)
#else
/*
* Determine the hard disk geometry from the BIOS!
* We do this first, so that LS-120 IDE floppies work correctly.
@ -428,7 +437,7 @@ setup_sectors:
jc LOCAL(read_error)
movw %es, %bx
#endif /* TPM */
LOCAL(copy_buffer):
/*
* We need to save %cx and %si because the startup code in
@ -451,6 +460,25 @@ LOCAL(copy_buffer):
popw %ds
popa
#ifdef TPM
pusha
movw $0xBB00, %ax /* TCG_StatusCheck */
int $0x1A
test %eax, %eax
jnz boot /* No TPM or TPM deactivated */
movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */
movw $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di
xorl %esi, %esi
movl $0x41504354, %ebx /* TCPA */
movl $0x200, %ecx /* Measure 512 bytes */
movl $0x8, %edx /* PCR 8 */
int $0x1A
boot:
popa
#endif
/* boot kernel */
jmp *(LOCAL(kernel_address))

View File

@ -19,6 +19,8 @@
#include <grub/symbol.h>
#include <grub/machine/boot.h>
#define TPM 1
/*
* defines for the code go here
*/
@ -37,8 +39,8 @@
start:
_start:
/*
* _start is loaded at 0x2000 and is jumped to with
* CS:IP 0:0x2000 in kernel.
* _start is loaded at 0x8000 and is jumped to with
* CS:IP 0:0x8000 in kernel.
*/
/*
@ -58,6 +60,21 @@ _start:
/* this sets up for the first run through "bootloop" */
movw $LOCAL(firstlist), %di
#ifdef TPM
/* clear EAX to remove potential garbage */
xorl %eax, %eax
/* 8(%di) = number of sectors to read */
movw 8(%di), %ax
/* Multiply number of sectors to read with 512 bytes. EAX is 32bit
* which is large enough to hold values of up to 4GB. I doubt there
* will ever be a core.img larger than that. ;-) */
shll $9, %eax
/* write result to bytes_to_measure var */
movl %eax, bytes_to_measure
#endif
/* save the sector number of the second sector in %ebp */
movl (%di), %ebp
@ -295,6 +312,29 @@ LOCAL(copy_buffer):
/* END OF MAIN LOOP */
LOCAL(bootit):
#ifdef TPM
pusha
movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */
movw $0x0, %bx
movw %bx, %es
/* We've already measured the first 512 bytes, now measure the rest */
xorl %edi, %edi
movw $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200), %di
movl $0x41504354, %ebx /* EBX = "TCPA" */
/* %ecx = The length, in bytes, of the buffer to measure */
movl $bytes_to_measure, %esi
movl (%esi), %ecx
xorl %esi, %esi
movl $0x9, %edx /* PCR 9 */
int $0x1A
popa
#endif
/* print a newline */
MSG(notification_done)
popw %dx /* this makes sure %dl is our "boot" drive */
@ -329,6 +369,10 @@ geometry_error_string: .asciz "Geom"
read_error_string: .asciz "Read"
general_error_string: .asciz " Error"
#ifdef TPM
bytes_to_measure: .long 0
#endif
/*
* message: write the string pointed to by %si
*

View File

@ -118,7 +118,16 @@ LOCAL (codestart):
#include "../../../kern/i386/realmode.S"
/*
*
* This is a workaround for clang adding a section containing only .addrsig
* Since clang itself is unable to assemble this pseudo-opcode, just replace
* it with .text
*
*/
#define addrsig text
#include <rs_decoder.h>
#undef addrsig
.text

View File

@ -21,6 +21,24 @@
.text
.align 4
/*
* We're writing the a.out header ourselves as newer
* upstream versions of binutils no longer support
* the a.out format on sparc64.
*
* The boot loader fits into 512 bytes with 32 bytes
* used for the a.out header, hence the text segment
* size is 512 - 32. There is no data segment and no
* code relocation, thus those fields remain zero.
*/
.word 0x1030107 /* Magic number. */
.word 512 - GRUB_BOOT_AOUT_HEADER_SIZE /* Size of text segment. */
.word 0 /* Size of initialized data. */
.word 0 /* Size of uninitialized data. */
.word 0 /* Size of symbol table || checksum. */
.word _start /* Entry point. */
.word 0 /* Size of text relocation. */
.word 0 /* Size of data relocation. */
.globl _start
_start:
/* OF CIF entry point arrives in %o4 */
@ -30,7 +48,7 @@ pic_base:
#ifndef CDBOOT
/* The offsets to these locations are defined by the
* GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
* GRUB_BOOT_MACHINE_foo macros in include/grub/sparc64/ieee1275/boot.h,
* and grub-setup uses this to patch these next three values as needed.
*
* The boot_path will be the OF device path of the partition where the
@ -40,10 +58,14 @@ pic_base:
*
* After loading in that block we will execute it by jumping to the
* load address plus the size of the prepended A.OUT header (32 bytes).
*
* Since this assembly code includes the 32 bytes long a.out header,
* we need to move the actual code entry point forward by the size
* of the a.out header, i.e. += GRUB_BOOT_AOUT_HEADER_SIZE.
*/
.org GRUB_BOOT_MACHINE_BOOT_DEVPATH
.org GRUB_BOOT_MACHINE_BOOT_DEVPATH + GRUB_BOOT_AOUT_HEADER_SIZE
boot_path:
.org GRUB_BOOT_MACHINE_KERNEL_BYTE
.org GRUB_BOOT_MACHINE_KERNEL_BYTE + GRUB_BOOT_AOUT_HEADER_SIZE
boot_path_end:
kernel_byte: .xword (2 << 9)
kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
@ -52,7 +74,7 @@ kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
#define boot_path_end (_start + 1024)
#include <grub/offsets.h>
.org 8
.org 8 + GRUB_BOOT_AOUT_HEADER_SIZE
kernel_byte: .xword (2 << 9)
kernel_size: .word 512
kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
@ -69,6 +91,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 +239,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

256
grub-core/bus/fdt.c Normal file
View File

@ -0,0 +1,256 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2016 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/fdtbus.h>
#include <grub/fdt.h>
#include <grub/term.h>
static const void *dtb;
static grub_size_t root_address_cells, root_size_cells;
/* Pointer to this symbol signals invalid mapping. */
char grub_fdtbus_invalid_mapping[1];
struct grub_fdtbus_dev *devs;
struct grub_fdtbus_driver *drivers;
int
grub_fdtbus_is_compatible (const char *compat_string,
const struct grub_fdtbus_dev *dev)
{
grub_size_t compatible_size;
const char *compatible = grub_fdt_get_prop (dtb, dev->node, "compatible",
&compatible_size);
if (!compatible)
return 0;
const char *compatible_end = compatible + compatible_size;
while (compatible < compatible_end)
{
if (grub_strcmp (compat_string, compatible) == 0)
return 1;
compatible += grub_strlen (compatible) + 1;
}
return 0;
}
static void
fdtbus_scan (struct grub_fdtbus_dev *parent)
{
int node;
for (node = grub_fdt_first_node (dtb, parent ? parent->node : 0); node >= 0;
node = grub_fdt_next_node (dtb, node))
{
struct grub_fdtbus_dev *dev;
struct grub_fdtbus_driver *driver;
dev = grub_zalloc (sizeof (*dev));
if (!dev)
{
grub_print_error ();
return;
}
dev->node = node;
dev->next = devs;
dev->parent = parent;
devs = dev;
FOR_LIST_ELEMENTS(driver, drivers)
if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev))
{
grub_dprintf ("fdtbus", "Attaching %s\n", driver->compatible);
if (driver->attach (dev) == GRUB_ERR_NONE)
{
grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
dev->driver = driver;
break;
}
grub_print_error ();
}
fdtbus_scan (dev);
}
}
void
grub_fdtbus_register (struct grub_fdtbus_driver *driver)
{
struct grub_fdtbus_dev *dev;
grub_dprintf ("fdtbus", "Registering %s\n", driver->compatible);
grub_list_push (GRUB_AS_LIST_P (&drivers),
GRUB_AS_LIST (driver));
for (dev = devs; dev; dev = dev->next)
if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev))
{
grub_dprintf ("fdtbus", "Attaching %s (%p)\n", driver->compatible, dev);
if (driver->attach (dev) == GRUB_ERR_NONE)
{
grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
dev->driver = driver;
}
grub_print_error ();
}
}
void
grub_fdtbus_unregister (struct grub_fdtbus_driver *driver)
{
grub_list_remove (GRUB_AS_LIST (driver));
struct grub_fdtbus_dev *dev;
for (dev = devs; dev; dev = dev->next)
if (dev->driver == driver)
{
if (driver->detach)
driver->detach(dev);
dev->driver = 0;
}
}
void
grub_fdtbus_init (const void *dtb_in, grub_size_t size)
{
if (!dtb_in || grub_fdt_check_header (dtb_in, size) < 0)
grub_fatal ("invalid FDT");
dtb = dtb_in;
const grub_uint32_t *prop = grub_fdt_get_prop (dtb, 0, "#address-cells", 0);
if (prop)
root_address_cells = grub_be_to_cpu32 (*prop);
else
root_address_cells = 1;
prop = grub_fdt_get_prop (dtb, 0, "#size-cells", 0);
if (prop)
root_size_cells = grub_be_to_cpu32 (*prop);
else
root_size_cells = 1;
fdtbus_scan (0);
}
static int
get_address_cells (const struct grub_fdtbus_dev *dev)
{
const grub_uint32_t *prop;
if (!dev)
return root_address_cells;
prop = grub_fdt_get_prop (dtb, dev->node, "#address-cells", 0);
if (prop)
return grub_be_to_cpu32 (*prop);
return 1;
}
static int
get_size_cells (const struct grub_fdtbus_dev *dev)
{
const grub_uint32_t *prop;
if (!dev)
return root_size_cells;
prop = grub_fdt_get_prop (dtb, dev->node, "#size-cells", 0);
if (prop)
return grub_be_to_cpu32 (*prop);
return 1;
}
static grub_uint64_t
get64 (const grub_uint32_t *reg, grub_size_t cells)
{
grub_uint64_t val = 0;
if (cells >= 1)
val = grub_be_to_cpu32 (reg[cells - 1]);
if (cells >= 2)
val |= ((grub_uint64_t) grub_be_to_cpu32 (reg[cells - 2])) << 32;
return val;
}
static volatile void *
translate (const struct grub_fdtbus_dev *dev, const grub_uint32_t *reg)
{
volatile void *ret;
const grub_uint32_t *ranges;
grub_size_t ranges_size, cells_per_mapping;
grub_size_t parent_address_cells, child_address_cells, child_size_cells;
grub_size_t nmappings, i;
if (dev == 0)
{
grub_uint64_t val;
val = get64 (reg, root_address_cells);
if (sizeof (void *) == 4 && (val >> 32))
return grub_fdtbus_invalid_mapping;
return (void *) (grub_addr_t) val;
}
ranges = grub_fdt_get_prop (dtb, dev->node, "ranges", &ranges_size);
if (!ranges)
return grub_fdtbus_invalid_mapping;
if (ranges_size == 0)
return translate (dev->parent, reg);
parent_address_cells = get_address_cells (dev->parent);
child_address_cells = get_address_cells (dev);
child_size_cells = get_size_cells (dev);
cells_per_mapping = parent_address_cells + child_address_cells + child_size_cells;
nmappings = ranges_size / 4 / cells_per_mapping;
for (i = 0; i < nmappings; i++)
{
const grub_uint32_t *child_addr = &ranges[i * cells_per_mapping];
const grub_uint32_t *parent_addr = child_addr + child_address_cells;
grub_uint64_t child_size = get64 (parent_addr + parent_address_cells, child_size_cells);
if (child_address_cells > 2 && grub_memcmp (reg, child_addr, (child_address_cells - 2) * 4) != 0)
continue;
if (get64 (reg, child_address_cells) < get64 (child_addr, child_address_cells))
continue;
grub_uint64_t offset = get64 (reg, child_address_cells) - get64 (child_addr, child_address_cells);
if (offset >= child_size)
continue;
ret = translate (dev->parent, parent_addr);
if (grub_fdtbus_is_mapping_valid (ret))
ret = (volatile char *) ret + offset;
return ret;
}
return grub_fdtbus_invalid_mapping;
}
volatile void *
grub_fdtbus_map_reg (const struct grub_fdtbus_dev *dev, int regno, grub_size_t *size)
{
grub_size_t address_cells, size_cells;
address_cells = get_address_cells (dev->parent);
size_cells = get_size_cells (dev->parent);
const grub_uint32_t *reg = grub_fdt_get_prop (dtb, dev->node, "reg", 0);
if (size && size_cells)
*size = reg[(address_cells + size_cells) * regno + address_cells];
if (size && !size_cells)
*size = 0;
return translate (dev->parent, reg + (address_cells + size_cells) * regno);
}
const char *
grub_fdtbus_get_name (const struct grub_fdtbus_dev *dev)
{
return grub_fdt_get_nodename (dtb, dev->node);
}
const void *
grub_fdtbus_get_prop (const struct grub_fdtbus_dev *dev,
const char *name,
grub_uint32_t *len)
{
return grub_fdt_get_prop (dtb, dev->node, name, len);
}
const void *
grub_fdtbus_get_fdt (void)
{
return dtb;
}

View File

@ -0,0 +1,103 @@
/*
* GRUB -- GRand Unified Bootloader
*
* Copyright (C) 2012 Google Inc.
* Copyright (C) 2016 Free Software Foundation, Inc.
*
* This is based on depthcharge code.
*
* 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/mm.h>
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/fdtbus.h>
#include <grub/machine/kernel.h>
static grub_err_t
spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz)
{
const grub_uint8_t *ptr = data, *end = ptr + sz;
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[2] = 0;
spi[1] = sz - 1;
spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19);
spi[2] = 1;
while (ptr < end)
{
while (spi[9] & 2);
spi[256] = *ptr++;
}
while (spi[9] & 1);
return GRUB_ERR_NONE;
}
static grub_err_t
spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz)
{
grub_uint8_t *ptr = data, *end = ptr + sz;
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[2] = 0;
spi[1] = sz - 1;
spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18);
spi[2] = 1;
while (ptr < end)
{
while (spi[9] & 8);
*ptr++ = spi[512];
}
while (spi[9] & 1);
return GRUB_ERR_NONE;
}
static grub_err_t
spi_start (const struct grub_fdtbus_dev *dev)
{
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[3] = 1;
return GRUB_ERR_NONE;
}
static void
spi_stop (const struct grub_fdtbus_dev *dev)
{
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[3] = 0;
}
static grub_err_t
spi_attach(const struct grub_fdtbus_dev *dev)
{
if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0)))
return GRUB_ERR_IO;
return GRUB_ERR_NONE;
}
static struct grub_fdtbus_driver spi =
{
.compatible = "rockchip,rk3288-spi",
.attach = spi_attach,
.send = spi_send,
.receive = spi_receive,
.start = spi_start,
.stop = spi_stop,
};
void
grub_rk3288_spi_init (void)
{
grub_fdtbus_register (&spi);
}

View File

@ -0,0 +1,45 @@
/* ehci.c - EHCI Support. */
/*
* 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/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/usb.h>
#include <grub/fdtbus.h>
static grub_err_t
ehci_attach(const struct grub_fdtbus_dev *dev)
{
grub_dprintf ("ehci", "Found generic-ehci\n");
grub_ehci_init_device (grub_fdtbus_map_reg (dev, 0, 0));
return 0;
}
struct grub_fdtbus_driver ehci =
{
.compatible = "generic-ehci",
.attach = ehci_attach
};
void
grub_ehci_pci_scan (void)
{
grub_fdtbus_register (&ehci);
}

View File

@ -0,0 +1,208 @@
/* ehci.c - EHCI Support. */
/*
* 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/pci.h>
#include <grub/cpu/pci.h>
#include <grub/cs5536.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/usb.h>
#define GRUB_EHCI_PCI_SBRN_REG 0x60
#define GRUB_EHCI_ADDR_MEM_MASK (~0xff)
/* USBLEGSUP bits and related OS OWNED byte offset */
enum
{
GRUB_EHCI_BIOS_OWNED = (1 << 16),
GRUB_EHCI_OS_OWNED = (1 << 24)
};
/* PCI iteration function... */
static int
grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
{
volatile grub_uint32_t *regs;
grub_uint32_t base, base_h;
grub_uint32_t eecp_offset;
grub_uint32_t usblegsup = 0;
grub_uint64_t maxtime;
grub_uint32_t interf;
grub_uint32_t subclass;
grub_uint32_t class;
grub_uint8_t release;
grub_uint32_t class_code;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
if (pciid == GRUB_CS5536_PCIID)
{
grub_uint64_t basereg;
basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
{
/* Shouldn't happen. */
grub_dprintf ("ehci", "No EHCI address is assigned\n");
return 0;
}
base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
}
else
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an EHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x20)
return 0;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
/* Check Serial Bus Release Number */
addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
release = grub_pci_read_byte (addr);
if (release != 0x20)
{
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
release);
return 0;
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
/* Determine EHCI EHCC registers base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
base_h = grub_pci_read (addr);
/* Stop if registers are mapped above 4G - GRUB does not currently
* work with registers mapped above 4G */
if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
&& (base_h != 0))
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
return 0;
}
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapped\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
regs = grub_pci_device_map_range (dev,
(base & GRUB_EHCI_ADDR_MEM_MASK),
0x100);
/* Is there EECP ? */
eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff;
/* Determine and change ownership. */
/* EECP offset valid in HCCPARAMS */
/* Ownership can be changed via EECP only */
if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)
{
grub_pci_address_t pciaddr_eecp;
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
usblegsup = grub_pci_read (pciaddr_eecp);
if (usblegsup & GRUB_EHCI_BIOS_OWNED)
{
grub_boot_time ("Taking ownership of EHCI controller");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
/* Wait for finish of ownership change, EHCI specification
* doesn't say how long it can take... */
maxtime = grub_get_time_ms () + 1000;
while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
&& (grub_get_time_ms () < maxtime));
if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
/* Change ownership in "hard way" - reset BIOS ownership */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
}
else if (usblegsup & GRUB_EHCI_OS_OWNED)
/* XXX: What to do in this case - nothing ? Can it happen ? */
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
else
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
/* XXX: What to do in this case ? Can it happen ?
* Is code below correct ? */
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
/* Disable SMI, just to be sure. */
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
grub_pci_write (pciaddr_eecp, 0);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
grub_ehci_init_device (regs);
return 0;
}
void
grub_ehci_pci_scan (void)
{
grub_pci_iterate (grub_ehci_pci_iter, NULL);
}

View File

@ -22,13 +22,10 @@
#include <grub/usb.h>
#include <grub/usbtrans.h>
#include <grub/misc.h>
#include <grub/pci.h>
#include <grub/cpu/pci.h>
#include <grub/cpu/io.h>
#include <grub/time.h>
#include <grub/loader.h>
#include <grub/cs5536.h>
#include <grub/disk.h>
#include <grub/dma.h>
#include <grub/cache.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -39,8 +36,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
* - is not supporting interrupt transfers
*/
#define GRUB_EHCI_PCI_SBRN_REG 0x60
/* Capability registers offsets */
enum
{
@ -54,7 +49,6 @@ enum
#define GRUB_EHCI_EECP_MASK (0xff << 8)
#define GRUB_EHCI_EECP_SHIFT 8
#define GRUB_EHCI_ADDR_MEM_MASK (~0xff)
#define GRUB_EHCI_POINTER_MASK (~0x1f)
/* Capability register SPARAMS bits */
@ -85,13 +79,6 @@ enum
#define GRUB_EHCI_QH_EMPTY 1
/* USBLEGSUP bits and related OS OWNED byte offset */
enum
{
GRUB_EHCI_BIOS_OWNED = (1 << 16),
GRUB_EHCI_OS_OWNED = (1 << 24)
};
/* Operational registers offsets */
enum
{
@ -455,9 +442,10 @@ grub_ehci_reset (struct grub_ehci *e)
sync_all_caches (e);
grub_dprintf ("ehci", "reset\n");
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
GRUB_EHCI_CMD_HC_RESET
| grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
GRUB_EHCI_CMD_HC_RESET);
/* Ensure command is written */
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
/* XXX: How long time could take reset of HC ? */
@ -473,116 +461,24 @@ grub_ehci_reset (struct grub_ehci *e)
}
/* PCI iteration function... */
static int
grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
void
grub_ehci_init_device (volatile void *regs)
{
grub_uint8_t release;
grub_uint32_t class_code;
grub_uint32_t interf;
grub_uint32_t subclass;
grub_uint32_t class;
grub_uint32_t base, base_h;
struct grub_ehci *e;
grub_uint32_t eecp_offset;
grub_uint32_t fp;
int i;
grub_uint32_t usblegsup = 0;
grub_uint64_t maxtime;
grub_uint32_t n_ports;
grub_uint8_t caplen;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
if (pciid == GRUB_CS5536_PCIID)
{
grub_uint64_t basereg;
basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
{
/* Shouldn't happen. */
grub_dprintf ("ehci", "No EHCI address is assigned\n");
return 0;
}
base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
}
else
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an EHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x20)
return 0;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
/* Check Serial Bus Release Number */
addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
release = grub_pci_read_byte (addr);
if (release != 0x20)
{
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
release);
return 0;
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
/* Determine EHCI EHCC registers base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
base_h = grub_pci_read (addr);
/* Stop if registers are mapped above 4G - GRUB does not currently
* work with registers mapped above 4G */
if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
&& (base_h != 0))
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
return 0;
}
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapped\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
}
/* Allocate memory for the controller and fill basic values. */
e = grub_zalloc (sizeof (*e));
if (!e)
return 1;
return;
e->framelist_chunk = NULL;
e->td_chunk = NULL;
e->qh_chunk = NULL;
e->iobase_ehcc = grub_pci_device_map_range (dev,
(base & GRUB_EHCI_ADDR_MEM_MASK),
0x100);
e->iobase_ehcc = regs;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n",
grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n",
@ -598,7 +494,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
if (caplen & (sizeof (grub_uint32_t) - 1))
{
grub_dprintf ("ehci", "Unaligned caplen\n");
return 0;
return;
}
e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc
+ (caplen / sizeof (grub_uint32_t)));
@ -608,8 +504,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
#endif
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK) + caplen);
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llxx\n",
(unsigned long long) (grub_addr_t) e->iobase_ehcc + caplen);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
@ -625,10 +521,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
/* Is there EECP ? */
eecp_offset = (grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS)
& GRUB_EHCI_EECP_MASK) >> GRUB_EHCI_EECP_SHIFT;
/* Check format of data structures requested by EHCI */
/* XXX: In fact it is not used at any place, it is prepared for future
* This implementation uses 32-bits pointers only */
@ -732,65 +624,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n");
/* Determine and change ownership. */
/* EECP offset valid in HCCPARAMS */
/* Ownership can be changed via EECP only */
if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)
{
grub_pci_address_t pciaddr_eecp;
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
usblegsup = grub_pci_read (pciaddr_eecp);
if (usblegsup & GRUB_EHCI_BIOS_OWNED)
{
grub_boot_time ("Taking ownership of EHCI controller");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
/* Wait for finish of ownership change, EHCI specification
* doesn't say how long it can take... */
maxtime = grub_get_time_ms () + 1000;
while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
&& (grub_get_time_ms () < maxtime));
if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
/* Change ownership in "hard way" - reset BIOS ownership */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
}
else if (usblegsup & GRUB_EHCI_OS_OWNED)
/* XXX: What to do in this case - nothing ? Can it happen ? */
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
else
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
/* XXX: What to do in this case ? Can it happen ?
* Is code below correct ? */
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
/* Disable SMI, just to be sure. */
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
grub_pci_write (pciaddr_eecp, 0);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
/* Now we can setup EHCI (maybe...) */
/* Check if EHCI is halted and halt it if not */
@ -863,8 +696,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llx\n",
(unsigned long long) (grub_addr_t) regs);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
@ -880,7 +713,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
return 0;
return;
fail:
if (e)
@ -894,7 +727,7 @@ fail:
}
grub_free (e);
return 0;
return;
}
static int
@ -1891,12 +1724,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
}
}
static void
grub_ehci_inithw (void)
{
grub_pci_iterate (grub_ehci_pci_iter, NULL);
}
static grub_err_t
grub_ehci_restore_hw (void)
{
@ -1997,7 +1824,7 @@ GRUB_MOD_INIT (ehci)
grub_stop_disk_firmware ();
grub_boot_time ("Initing EHCI hardware");
grub_ehci_inithw ();
grub_ehci_pci_scan ();
grub_boot_time ("Registering EHCI driver");
grub_usb_controller_dev_register (&usb_controller);
grub_boot_time ("EHCI driver registered");

View File

@ -18,7 +18,7 @@
*/
#include <grub/dl.h>
#include <grub/pci.h>
#include <grub/dma.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/usb.h>

View File

@ -635,7 +635,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
grub_size_t size;
char *buf;
file = grub_file_open (args[i]);
file = grub_file_open (args[i], GRUB_FILE_TYPE_ACPI_TABLE);
if (! file)
{
free_tables ();

View File

@ -121,8 +121,8 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
grub_file_filter_disable_compression ();
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! file)
return grub_errno;

View File

@ -56,7 +56,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_CAT);
if (! file)
return grub_errno;

View File

@ -45,8 +45,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0],
args[1]);
file1 = grub_file_open (args[0]);
file2 = grub_file_open (args[1]);
file1 = grub_file_open (args[0], GRUB_FILE_TYPE_CMP);
file2 = grub_file_open (args[1], GRUB_FILE_TYPE_CMP);
if (! file1 || ! file2)
goto cleanup;

View File

@ -0,0 +1,153 @@
/* getenv.c - retrieve EFI variables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 2014 CoreOS, 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/efi/efi.h>
#include <grub/dl.h>
#include <grub/env.h>
#include <grub/err.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/misc.h>
#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
static const struct grub_arg_option options_getenv[] = {
{"var-name", 'e', 0,
N_("Environment variable to query"),
N_("VARNAME"), ARG_TYPE_STRING},
{"var-guid", 'g', 0,
N_("GUID of environment variable to query"),
N_("GUID"), ARG_TYPE_STRING},
{"binary", 'b', 0,
N_("Read binary data and represent it as hex"),
0, ARG_TYPE_NONE},
{0, 0, 0, 0, 0, 0}
};
enum options_getenv
{
GETENV_VAR_NAME,
GETENV_VAR_GUID,
GETENV_BINARY,
};
static grub_err_t
grub_cmd_getenv (grub_extcmd_context_t ctxt, int argc, char **args)
{
struct grub_arg_list *state = ctxt->state;
char *envvar = NULL, *guid = NULL, *bindata = NULL, *data = NULL;
grub_size_t datasize;
grub_efi_guid_t efi_var_guid;
grub_efi_boolean_t binary = state[GETENV_BINARY].set;
unsigned int i;
if (!state[GETENV_VAR_NAME].set || !state[GETENV_VAR_GUID].set)
{
grub_error (GRUB_ERR_INVALID_COMMAND, N_("-e and -g are required"));
goto done;
}
if (argc != 1)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
goto done;
}
envvar = state[GETENV_VAR_NAME].arg;
guid = state[GETENV_VAR_GUID].arg;
if (grub_strlen(guid) != 36 ||
guid[8] != '-' ||
guid[13] != '-' ||
guid[18] != '-' ||
guid[23] != '-')
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid GUID"));
goto done;
}
/* Forgive me father for I have sinned */
guid[8] = 0;
efi_var_guid.data1 = grub_strtoul(guid, NULL, 16);
guid[13] = 0;
efi_var_guid.data2 = grub_strtoul(guid + 9, NULL, 16);
guid[18] = 0;
efi_var_guid.data3 = grub_strtoul(guid + 14, NULL, 16);
efi_var_guid.data4[7] = grub_strtoul(guid + 34, NULL, 16);
guid[34] = 0;
efi_var_guid.data4[6] = grub_strtoul(guid + 32, NULL, 16);
guid[32] = 0;
efi_var_guid.data4[5] = grub_strtoul(guid + 30, NULL, 16);
guid[30] = 0;
efi_var_guid.data4[4] = grub_strtoul(guid + 28, NULL, 16);
guid[28] = 0;
efi_var_guid.data4[3] = grub_strtoul(guid + 26, NULL, 16);
guid[26] = 0;
efi_var_guid.data4[2] = grub_strtoul(guid + 24, NULL, 16);
guid[23] = 0;
efi_var_guid.data4[1] = grub_strtoul(guid + 21, NULL, 16);
guid[21] = 0;
efi_var_guid.data4[0] = grub_strtoul(guid + 19, NULL, 16);
data = grub_efi_get_variable(envvar, &efi_var_guid, &datasize);
if (!data || !datasize)
{
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable"));
goto done;
}
if (binary)
{
bindata = grub_zalloc(datasize * 2 + 1);
for (i=0; i<datasize; i++)
grub_snprintf(bindata + i*2, 3, "%02x", data[i] & 0xff);
if (grub_env_set (args[0], bindata))
goto done;
}
else if (grub_env_set (args[0], data))
{
goto done;
}
grub_errno = GRUB_ERR_NONE;
done:
grub_free(bindata);
grub_free(data);
return grub_errno;
}
static grub_extcmd_t cmd_getenv;
GRUB_MOD_INIT(getenv)
{
cmd_getenv = grub_register_extcmd ("getenv", grub_cmd_getenv, 0,
N_("-e envvar -g guidenv setvar"),
N_("Read a firmware environment variable"),
options_getenv);
}
GRUB_MOD_FINI(getenv)
{
grub_unregister_extcmd (cmd_getenv);
}

View File

@ -30,6 +30,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
static grub_efi_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
#define EBDA_SEG_ADDR 0x40e
#define LOW_MEM_ADDR 0x413
@ -93,7 +94,7 @@ static void
fake_bios_data (int use_rom)
{
unsigned i;
void *acpi, *smbios;
void *acpi, *smbios, *smbios3;
grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
@ -103,6 +104,7 @@ fake_bios_data (int use_rom)
acpi = 0;
smbios = 0;
smbios3 = 0;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_efi_packed_guid_t *guid =
@ -127,6 +129,11 @@ fake_bios_data (int use_rom)
smbios = grub_efi_system_table->configuration_table[i].vendor_table;
grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
}
else if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_guid_t)))
{
smbios3 = grub_efi_system_table->configuration_table[i].vendor_table;
grub_dprintf ("efi", "SMBIOS3: %p\n", smbios3);
}
}
*ebda_seg_ptr = FAKE_EBDA_SEG;
@ -137,8 +144,13 @@ fake_bios_data (int use_rom)
if (acpi)
grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
if ((use_rom) && (smbios))
grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
if (use_rom)
{
if (smbios)
grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios, 31);
if (smbios3)
grub_memcpy ((char *) SBIOS_ADDR + 32, (char *) smbios3, 24);
}
}
static grub_err_t
@ -169,7 +181,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
if (argc > 1)
{
file = grub_file_open (argv[1]);
file = grub_file_open (argv[1], GRUB_FILE_TYPE_VBE_DUMP);
if (! file)
return grub_errno;
@ -183,7 +195,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
file = grub_file_open (argv[0]);
file = grub_file_open (argv[0], GRUB_FILE_TYPE_VBE_DUMP);
if (! file)
return grub_errno;

View File

@ -109,8 +109,10 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
status = efi_call_3 (grub_efi_system_table->boot_services->protocols_per_handle,
handle, &protocols, &num_protocols);
if (status != GRUB_EFI_SUCCESS)
if (status != GRUB_EFI_SUCCESS) {
grub_printf ("Unable to retrieve protocols\n");
continue;
}
for (j = 0; j < num_protocols; j++)
{
for (k = 0; k < ARRAY_SIZE (known_protocols); k++)

View File

@ -48,6 +48,7 @@ static const struct guid_mapping guid_mappings[] =
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"},
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
{ GRUB_EFI_SMBIOS3_TABLE_GUID, "SMBIOS3"},
{ GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
{ GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
{ GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},

View File

@ -0,0 +1,142 @@
/*
* 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/>.
*
* EFI shim lock verifier.
*/
#include <grub/dl.h>
#include <grub/efi/efi.h>
#include <grub/err.h>
#include <grub/file.h>
#include <grub/misc.h>
#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_EFI_SHIM_LOCK_GUID \
{ 0x605dab50, 0xe046, 0x4300, \
{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
}
struct grub_efi_shim_lock_protocol
{
grub_efi_status_t
(*verify) (void *buffer, grub_uint32_t size);
};
typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
static grub_efi_shim_lock_protocol_t *sl;
/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
static grub_err_t
shim_lock_init (grub_file_t io, enum grub_file_type type,
void **context __attribute__ ((unused)),
enum grub_verify_flags *flags)
{
const char *b, *e;
int i;
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
if (!sl)
return GRUB_ERR_NONE;
switch (type & GRUB_FILE_TYPE_MASK)
{
case GRUB_FILE_TYPE_GRUB_MODULE:
/* Establish GRUB module name. */
b = grub_strrchr (io->name, '/');
e = grub_strrchr (io->name, '.');
b = b ? (b + 1) : io->name;
e = e ? e : io->name + grub_strlen (io->name);
e = (e > b) ? e : io->name + grub_strlen (io->name);
for (i = 0; disabled_mods[i]; i++)
if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
{
grub_error (GRUB_ERR_ACCESS_DENIED,
N_("module cannot be loaded in UEFI secure boot mode: %s"),
io->name);
return GRUB_ERR_ACCESS_DENIED;
}
/* Fall through. */
case GRUB_FILE_TYPE_ACPI_TABLE:
case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
*flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
return GRUB_ERR_NONE;
case GRUB_FILE_TYPE_LINUX_KERNEL:
case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
case GRUB_FILE_TYPE_BSD_KERNEL:
case GRUB_FILE_TYPE_XNU_KERNEL:
case GRUB_FILE_TYPE_PLAN9_KERNEL:
for (i = 0; disabled_mods[i]; i++)
if (grub_dl_get (disabled_mods[i]))
{
grub_error (GRUB_ERR_ACCESS_DENIED,
N_("cannot boot due to dangerous module in memory: %s"),
disabled_mods[i]);
return GRUB_ERR_ACCESS_DENIED;
}
*flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
/* Fall through. */
default:
return GRUB_ERR_NONE;
}
}
static grub_err_t
shim_lock_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
{
if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
return GRUB_ERR_NONE;
}
struct grub_file_verifier shim_lock =
{
.name = "shim_lock",
.init = shim_lock_init,
.write = shim_lock_write
};
GRUB_MOD_INIT(shim_lock)
{
sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
grub_verifier_register (&shim_lock);
if (!sl)
return;
grub_dl_set_persistent (mod);
}
GRUB_MOD_FINI(shim_lock)
{
grub_verifier_unregister (&shim_lock);
}

View File

@ -0,0 +1,59 @@
/* smbios.c - get smbios tables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2015 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/smbios.h>
#include <grub/misc.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
struct grub_smbios_eps *
grub_machine_smbios_get_eps (void)
{
unsigned i;
static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_efi_packed_guid_t *guid =
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t)))
return (struct grub_smbios_eps *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
}
struct grub_smbios_eps3 *
grub_machine_smbios_get_eps3 (void)
{
unsigned i;
static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_efi_packed_guid_t *guid =
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t)))
return (struct grub_smbios_eps3 *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
}

View File

@ -0,0 +1,333 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2018 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/>.
*
* EFI TPM support code.
*/
#include <grub/err.h>
#include <grub/i18n.h>
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/tpm.h>
#include <grub/mm.h>
#include <grub/tpm.h>
#include <grub/term.h>
typedef TCG_PCR_EVENT grub_tpm_event_t;
static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
static grub_efi_handle_t *grub_tpm_handle;
static grub_uint8_t grub_tpm_version;
static grub_int8_t tpm1_present = -1;
static grub_int8_t tpm2_present = -1;
static grub_efi_boolean_t
grub_tpm1_present (grub_efi_tpm_protocol_t *tpm)
{
grub_efi_status_t status;
TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
grub_uint32_t flags;
grub_efi_physical_address_t eventlog, lastevent;
if (tpm1_present != -1)
return (grub_efi_boolean_t) tpm1_present;
caps.Size = (grub_uint8_t) sizeof (caps);
status = efi_call_5 (tpm->status_check, tpm, &caps, &flags, &eventlog,
&lastevent);
if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag
|| !caps.TPMPresentFlag)
return tpm1_present = 0;
return tpm1_present = 1;
}
static grub_efi_boolean_t
grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm)
{
grub_efi_status_t status;
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
caps.Size = (grub_uint8_t) sizeof (caps);
if (tpm2_present != -1)
return (grub_efi_boolean_t) tpm2_present;
status = efi_call_2 (tpm->get_capability, tpm, &caps);
if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
return tpm2_present = 0;
return tpm2_present = 1;
}
static grub_efi_boolean_t
grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
grub_efi_uint8_t *protocol_version)
{
grub_efi_handle_t *handles;
grub_efi_uintn_t num_handles;
if (grub_tpm_handle != NULL)
{
*tpm_handle = grub_tpm_handle;
*protocol_version = grub_tpm_version;
return 1;
}
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
&num_handles);
if (handles && num_handles > 0)
{
grub_tpm_handle = handles[0];
*tpm_handle = handles[0];
grub_tpm_version = 1;
*protocol_version = 1;
return 1;
}
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
&num_handles);
if (handles && num_handles > 0)
{
grub_tpm_handle = handles[0];
*tpm_handle = handles[0];
grub_tpm_version = 2;
*protocol_version = 2;
return 1;
}
return 0;
}
static grub_err_t
grub_tpm1_execute (grub_efi_handle_t tpm_handle,
PassThroughToTPM_InputParamBlock *inbuf,
PassThroughToTPM_OutputParamBlock *outbuf)
{
grub_efi_status_t status;
grub_efi_tpm_protocol_t *tpm;
grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
grub_uint32_t outhdrsize =
sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (!grub_tpm1_present (tpm))
return 0;
/* UEFI TPM protocol takes the raw operand block, no param block header. */
status = efi_call_5 (tpm->pass_through_to_tpm, tpm,
inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
switch (status)
{
case GRUB_EFI_SUCCESS:
return 0;
case GRUB_EFI_DEVICE_ERROR:
return grub_error (GRUB_ERR_IO, N_("Command failed"));
case GRUB_EFI_INVALID_PARAMETER:
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
case GRUB_EFI_BUFFER_TOO_SMALL:
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Output buffer too small"));
case GRUB_EFI_NOT_FOUND:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
default:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
}
}
static grub_err_t
grub_tpm2_execute (grub_efi_handle_t tpm_handle,
PassThroughToTPM_InputParamBlock *inbuf,
PassThroughToTPM_OutputParamBlock *outbuf)
{
grub_efi_status_t status;
grub_efi_tpm2_protocol_t *tpm;
grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
grub_uint32_t outhdrsize =
sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (!grub_tpm2_present (tpm))
return 0;
/* UEFI TPM protocol takes the raw operand block, no param block header. */
status = efi_call_5 (tpm->submit_command, tpm,
inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
switch (status)
{
case GRUB_EFI_SUCCESS:
return 0;
case GRUB_EFI_DEVICE_ERROR:
return grub_error (GRUB_ERR_IO, N_("Command failed"));
case GRUB_EFI_INVALID_PARAMETER:
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
case GRUB_EFI_BUFFER_TOO_SMALL:
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Output buffer too small"));
case GRUB_EFI_NOT_FOUND:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
default:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
}
}
grub_err_t
grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf,
PassThroughToTPM_OutputParamBlock *outbuf)
{
grub_efi_handle_t tpm_handle;
grub_uint8_t protocol_version;
/* Absence of a TPM isn't a failure. */
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
return 0;
if (protocol_version == 1)
return grub_tpm1_execute (tpm_handle, inbuf, outbuf);
else
return grub_tpm2_execute (tpm_handle, inbuf, outbuf);
}
static grub_err_t
grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
grub_size_t size, grub_uint8_t pcr,
const char *description)
{
grub_tpm_event_t *event;
grub_efi_status_t status;
grub_efi_tpm_protocol_t *tpm;
grub_efi_physical_address_t lastevent;
grub_uint32_t algorithm;
grub_uint32_t eventnum = 0;
tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (!grub_tpm1_present (tpm))
return 0;
event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1);
if (!event)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
N_("cannot allocate TPM event buffer"));
event->PCRIndex = pcr;
event->EventType = EV_IPL;
event->EventSize = grub_strlen (description) + 1;
grub_memcpy (event->Event, description, event->EventSize);
algorithm = TCG_ALG_SHA;
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size,
algorithm, event, &eventnum, &lastevent);
switch (status)
{
case GRUB_EFI_SUCCESS:
return 0;
case GRUB_EFI_DEVICE_ERROR:
return grub_error (GRUB_ERR_IO, N_("Command failed"));
case GRUB_EFI_INVALID_PARAMETER:
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
case GRUB_EFI_BUFFER_TOO_SMALL:
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Output buffer too small"));
case GRUB_EFI_NOT_FOUND:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
default:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
}
}
static grub_err_t
grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
grub_size_t size, grub_uint8_t pcr,
const char *description)
{
EFI_TCG2_EVENT *event;
grub_efi_status_t status;
grub_efi_tpm2_protocol_t *tpm;
tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (!grub_tpm2_present (tpm))
return 0;
event =
grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1);
if (!event)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
N_("cannot allocate TPM event buffer"));
event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
event->Header.HeaderVersion = 1;
event->Header.PCRIndex = pcr;
event->Header.EventType = EV_IPL;
event->Size =
sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1;
grub_memcpy (event->Event, description, grub_strlen (description) + 1);
status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf,
(grub_uint64_t) size, event);
switch (status)
{
case GRUB_EFI_SUCCESS:
return 0;
case GRUB_EFI_DEVICE_ERROR:
return grub_error (GRUB_ERR_IO, N_("Command failed"));
case GRUB_EFI_INVALID_PARAMETER:
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
case GRUB_EFI_BUFFER_TOO_SMALL:
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Output buffer too small"));
case GRUB_EFI_NOT_FOUND:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
default:
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
}
}
grub_err_t
grub_tpm_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
const char *description)
{
grub_efi_handle_t tpm_handle;
grub_efi_uint8_t protocol_version;
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
return 0;
if (protocol_version == 1)
return grub_tpm1_log_event (tpm_handle, buf, size, pcr, description);
else
return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description);
}

View File

@ -27,6 +27,8 @@
#include <grub/elf.h>
#include <grub/xen_file.h>
#include <grub/efi/pe32.h>
#include <grub/arm/linux.h>
#include <grub/arm64/linux.h>
#include <grub/i386/linux.h>
#include <grub/xnu.h>
#include <grub/machoload.h>
@ -88,6 +90,10 @@ static const struct grub_arg_option options[] = {
N_("Check if FILE is ARM64 EFI file"), 0, 0},
{"is-arm-efi", 0, 0,
N_("Check if FILE is ARM EFI file"), 0, 0},
{"is-riscv32-efi", 0, 0,
N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0},
{"is-riscv64-efi", 0, 0,
N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0},
{"is-hibernated-hiberfil", 0, 0,
N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0},
{"is-x86_64-xnu", 0, 0,
@ -128,6 +134,7 @@ enum
IS_IA_EFI,
IS_ARM64_EFI,
IS_ARM_EFI,
IS_RISCV_EFI,
IS_HIBERNATED,
IS_XNU64,
IS_XNU32,
@ -163,7 +170,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
if (type == -1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified");
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL);
if (!file)
return grub_errno;
switch (type)
@ -383,21 +390,19 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
}
case IS_ARM_LINUX:
{
grub_uint32_t sig, sig_pi;
if (grub_file_read (file, &sig_pi, 4) != 4)
struct linux_arm_kernel_header lh;
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
break;
/* Raspberry pi. */
if (sig_pi == grub_cpu_to_le32_compile_time (0xea000006))
/* Short forward branch in A32 state (for Raspberry pi kernels). */
if (lh.code0 == grub_cpu_to_le32_compile_time (0xea000006))
{
ret = 1;
break;
}
if (grub_file_seek (file, 0x24) == (grub_size_t) -1)
break;
if (grub_file_read (file, &sig, 4) != 4)
break;
if (sig == grub_cpu_to_le32_compile_time (0x016f2818))
if (lh.magic ==
grub_cpu_to_le32_compile_time (GRUB_LINUX_ARM_MAGIC_SIGNATURE))
{
ret = 1;
break;
@ -406,13 +411,13 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
}
case IS_ARM64_LINUX:
{
grub_uint32_t sig;
struct linux_arm64_kernel_header lh;
if (grub_file_seek (file, 0x38) == (grub_size_t) -1)
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
break;
if (grub_file_read (file, &sig, 4) != 4)
break;
if (sig == grub_cpu_to_le32_compile_time (0x644d5241))
if (lh.magic ==
grub_cpu_to_le32_compile_time (GRUB_LINUX_ARM64_MAGIC_SIGNATURE))
{
ret = 1;
break;
@ -497,7 +502,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
case IS_X86_LINUX32:
case IS_X86_LINUX:
{
struct linux_kernel_header lh;
struct linux_i386_kernel_header lh;
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
break;
if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
@ -508,7 +513,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
/* FIXME: some really old kernels (< 1.3.73) will fail this. */
if (lh.header !=
grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE)
|| grub_le_to_cpu16 (lh.version) < 0x0200)
break;
@ -521,7 +526,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
/* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
still not support 32-bit boot. */
if (lh.header !=
grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE)
|| grub_le_to_cpu16 (lh.version) < 0x0203)
break;
@ -546,7 +551,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
case IS_XNU64:
case IS_XNU32:
{
macho = grub_macho_open (args[0], (type == IS_XNU64));
macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL,
(type == IS_XNU64));
if (!macho)
break;
/* FIXME: more checks? */
@ -570,6 +576,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
case IS_IA_EFI:
case IS_ARM64_EFI:
case IS_ARM_EFI:
case IS_RISCV_EFI:
{
char signature[4];
grub_uint32_t pe_offset;
@ -615,7 +622,13 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
&& coff_head.machine !=
grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED))
break;
if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI)
if (type == IS_RISCV_EFI
&& coff_head.machine !=
grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_RISCV64))
/* TODO: Determine bitness dynamically */
break;
if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI ||
type == IS_RISCV_EFI)
{
struct grub_pe64_optional_header o64;
if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))

View File

@ -0,0 +1,122 @@
/* fwconfig.c - command to read config from qemu fwconfig */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2015 CoreOS, 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/extcmd.h>
#include <grub/env.h>
#include <grub/cpu/io.h>
#include <grub/i18n.h>
#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define SELECTOR 0x510
#define DATA 0x511
#define SIGNATURE_INDEX 0x00
#define DIRECTORY_INDEX 0x19
static grub_extcmd_t cmd_read_fwconfig;
struct grub_qemu_fwcfgfile {
grub_uint32_t size;
grub_uint16_t select;
grub_uint16_t reserved;
char name[56];
};
static const struct grub_arg_option options[] =
{
{0, 'v', 0, N_("Save read value into variable VARNAME."),
N_("VARNAME"), ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_fwconfig (grub_extcmd_context_t ctxt __attribute__ ((unused)),
int argc, char **argv)
{
grub_uint32_t i, j, value = 0;
struct grub_qemu_fwcfgfile file;
char fwsig[4], signature[4] = { 'Q', 'E', 'M', 'U' };
if (argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
/* Verify that we have meaningful hardware here */
grub_outw(SIGNATURE_INDEX, SELECTOR);
for (i=0; i<sizeof(fwsig); i++)
fwsig[i] = grub_inb(DATA);
if (grub_memcmp(fwsig, signature, sizeof(signature)) != 0)
return grub_error (GRUB_ERR_BAD_DEVICE, N_("invalid fwconfig hardware signature: got 0x%x%x%x%x"), fwsig[0], fwsig[1], fwsig[2], fwsig[3]);
/* Find out how many file entries we have */
grub_outw(DIRECTORY_INDEX, SELECTOR);
value = grub_inb(DATA) | grub_inb(DATA) << 8 | grub_inb(DATA) << 16 | grub_inb(DATA) << 24;
value = grub_be_to_cpu32(value);
/* Read the file description for each file */
for (i=0; i<value; i++)
{
for (j=0; j<sizeof(file); j++)
{
((char *)&file)[j] = grub_inb(DATA);
}
/* Check whether it matches what we're looking for, and if so read the file */
if (grub_strncmp(file.name, argv[0], sizeof(file.name)) == 0)
{
grub_uint32_t filesize = grub_be_to_cpu32(file.size);
grub_uint16_t location = grub_be_to_cpu16(file.select);
char *data = grub_malloc(filesize+1);
if (!data)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate buffer for data"));
grub_outw(location, SELECTOR);
for (j=0; j<filesize; j++)
{
data[j] = grub_inb(DATA);
}
data[filesize] = '\0';
grub_env_set (argv[1], data);
grub_free(data);
return 0;
}
}
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("couldn't find entry %s"), argv[0]);
}
GRUB_MOD_INIT(fwconfig)
{
cmd_read_fwconfig =
grub_register_extcmd ("fwconfig", grub_cmd_fwconfig, 0,
N_("PATH VAR"),
N_("Set VAR to the contents of fwconfig PATH"),
options);
}
GRUB_MOD_FINI(fwconfig)
{
grub_unregister_extcmd (cmd_read_fwconfig);
}

View File

@ -0,0 +1,223 @@
/* gptprio.c - manage priority based partition selection. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 2014 CoreOS, 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/device.h>
#include <grub/env.h>
#include <grub/err.h>
#include <grub/extcmd.h>
#include <grub/gpt_partition.h>
#include <grub/i18n.h>
#include <grub/misc.h>
GRUB_MOD_LICENSE ("GPLv3+");
static const struct grub_arg_option options_next[] = {
{"set-device", 'd', 0,
N_("Set a variable to the name of selected partition."),
N_("VARNAME"), ARG_TYPE_STRING},
{"set-uuid", 'u', 0,
N_("Set a variable to the GPT UUID of selected partition."),
N_("VARNAME"), ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
enum options_next
{
NEXT_SET_DEVICE,
NEXT_SET_UUID,
};
static unsigned int
grub_gptprio_priority (struct grub_gpt_partentry *entry)
{
return (unsigned int) grub_gpt_entry_attribute
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY, 4);
}
static unsigned int
grub_gptprio_tries_left (struct grub_gpt_partentry *entry)
{
return (unsigned int) grub_gpt_entry_attribute
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
}
static void
grub_gptprio_set_tries_left (struct grub_gpt_partentry *entry,
unsigned int tries_left)
{
grub_gpt_entry_set_attribute
(entry, tries_left, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
}
static unsigned int
grub_gptprio_successful (struct grub_gpt_partentry *entry)
{
return (unsigned int) grub_gpt_entry_attribute
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL, 1);
}
static grub_err_t
grub_find_next (const char *disk_name,
const grub_gpt_part_guid_t *part_type,
char **part_name, char **part_guid)
{
struct grub_gpt_partentry *part, *part_found = NULL;
grub_device_t dev = NULL;
grub_gpt_t gpt = NULL;
grub_uint32_t i, part_index;
dev = grub_device_open (disk_name);
if (!dev)
goto done;
gpt = grub_gpt_read (dev->disk);
if (!gpt)
goto done;
if (grub_gpt_repair (dev->disk, gpt))
goto done;
for (i = 0; (part = grub_gpt_get_partentry (gpt, i)) != NULL; i++)
{
if (grub_memcmp (part_type, &part->type, sizeof (*part_type)) == 0)
{
unsigned int priority, tries_left, successful, old_priority = 0;
priority = grub_gptprio_priority (part);
tries_left = grub_gptprio_tries_left (part);
successful = grub_gptprio_successful (part);
if (part_found)
old_priority = grub_gptprio_priority (part_found);
if ((tries_left || successful) && priority > old_priority)
{
part_index = i;
part_found = part;
}
}
}
if (!part_found)
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such partition"));
goto done;
}
if (grub_gptprio_tries_left (part_found))
{
unsigned int tries_left = grub_gptprio_tries_left (part_found);
grub_gptprio_set_tries_left (part_found, tries_left - 1);
if (grub_gpt_update (gpt))
goto done;
if (grub_gpt_write (dev->disk, gpt))
goto done;
}
*part_name = grub_xasprintf ("%s,gpt%u", disk_name, part_index + 1);
if (!*part_name)
goto done;
*part_guid = grub_gpt_guid_to_str (&part_found->guid);
if (!*part_guid)
goto done;
grub_errno = GRUB_ERR_NONE;
done:
grub_gpt_free (gpt);
if (dev)
grub_device_close (dev);
return grub_errno;
}
static grub_err_t
grub_cmd_next (grub_extcmd_context_t ctxt, int argc, char **args)
{
struct grub_arg_list *state = ctxt->state;
char *p, *root = NULL, *part_name = NULL, *part_guid = NULL;
/* TODO: Add a uuid parser and a command line flag for providing type. */
grub_gpt_part_guid_t part_type = GRUB_GPT_PARTITION_TYPE_USR_X86_64;
if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set)
{
grub_error (GRUB_ERR_INVALID_COMMAND, N_("-d and -u are required"));
goto done;
}
if (argc == 0)
root = grub_strdup (grub_env_get ("root"));
else if (argc == 1)
root = grub_strdup (args[0]);
else
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
goto done;
}
if (!root)
goto done;
/* To make using $root practical strip off the partition name. */
p = grub_strchr (root, ',');
if (p)
*p = '\0';
if (grub_find_next (root, &part_type, &part_name, &part_guid))
goto done;
if (grub_env_set (state[NEXT_SET_DEVICE].arg, part_name))
goto done;
if (grub_env_set (state[NEXT_SET_UUID].arg, part_guid))
goto done;
grub_errno = GRUB_ERR_NONE;
done:
grub_free (root);
grub_free (part_name);
grub_free (part_guid);
return grub_errno;
}
static grub_extcmd_t cmd_next;
GRUB_MOD_INIT(gptprio)
{
cmd_next = grub_register_extcmd ("gptprio.next", grub_cmd_next, 0,
N_("-d VARNAME -u VARNAME [DEVICE]"),
N_("Select next partition to boot."),
options_next);
}
GRUB_MOD_FINI(gptprio)
{
grub_unregister_extcmd (cmd_next);
}

View File

@ -0,0 +1,110 @@
/* gptrepair.c - verify and restore GPT info from alternate location. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 2014 CoreOS, 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/command.h>
#include <grub/device.h>
#include <grub/err.h>
#include <grub/gpt_partition.h>
#include <grub/i18n.h>
#include <grub/misc.h>
GRUB_MOD_LICENSE ("GPLv3+");
static char *
trim_dev_name (char *name)
{
grub_size_t len = grub_strlen (name);
if (len && name[0] == '(' && name[len - 1] == ')')
{
name[len - 1] = '\0';
name = name + 1;
}
return name;
}
static grub_err_t
grub_cmd_gptrepair (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_device_t dev = NULL;
grub_gpt_t gpt = NULL;
char *dev_name;
if (argc != 1 || !grub_strlen(args[0]))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
dev_name = trim_dev_name (args[0]);
dev = grub_device_open (dev_name);
if (!dev)
goto done;
if (!dev->disk)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
goto done;
}
gpt = grub_gpt_read (dev->disk);
if (!gpt)
goto done;
if (grub_gpt_both_valid (gpt))
{
grub_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name);
goto done;
}
if (!grub_gpt_primary_valid (gpt))
grub_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name);
if (!grub_gpt_backup_valid (gpt))
grub_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name);
if (grub_gpt_repair (dev->disk, gpt))
goto done;
if (grub_gpt_write (dev->disk, gpt))
goto done;
grub_printf_ (N_("Repaired GPT on %s\n"), dev_name);
done:
if (gpt)
grub_gpt_free (gpt);
if (dev)
grub_device_close (dev);
return grub_errno;
}
static grub_command_t cmd;
GRUB_MOD_INIT(gptrepair)
{
cmd = grub_register_command ("gptrepair", grub_cmd_gptrepair,
N_("DEVICE"),
N_("Verify and repair GPT on drive DEVICE."));
}
GRUB_MOD_FINI(gptrepair)
{
grub_unregister_command (cmd);
}

View File

@ -113,7 +113,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
hashlist = grub_file_open (hashfilename);
hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST);
if (!hashlist)
return grub_errno;
@ -141,17 +141,15 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
filename = grub_xasprintf ("%s/%s", prefix, p);
if (!filename)
return grub_errno;
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (filename);
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: GRUB_FILE_TYPE_NONE));
grub_free (filename);
}
else
{
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (p);
}
file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: GRUB_FILE_TYPE_NONE));
if (!file)
{
grub_file_close (hashlist);
@ -242,9 +240,9 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
grub_file_t file;
grub_err_t err;
unsigned j;
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (args[i]);
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: GRUB_FILE_TYPE_NONE));
if (!file)
{
if (!keep)

View File

@ -90,7 +90,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_file_t file;
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_HEXCAT);
if (! file)
return 0;

View File

@ -20,7 +20,7 @@
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/i386/coreboot/lbio.h>
#include <grub/coreboot/lbio.h>
#include <grub/i386/tsc.h>
GRUB_MOD_LICENSE ("GPLv3+");

View File

@ -20,7 +20,7 @@
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/i386/coreboot/lbio.h>
#include <grub/coreboot/lbio.h>
#include <grub/i386/tsc.h>
GRUB_MOD_LICENSE ("GPLv3+");

View File

@ -93,7 +93,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
grub_uint32_t tempo;
grub_file_t file;
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_AUDIO);
if (! file)
return grub_errno;

View File

@ -0,0 +1,50 @@
/* smbios.c - get smbios tables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2015 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/acpi.h>
#include <grub/smbios.h>
#include <grub/misc.h>
struct grub_smbios_eps *
grub_machine_smbios_get_eps (void)
{
grub_uint8_t *ptr;
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16)
if (grub_memcmp (ptr, "_SM_", 4) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
return (struct grub_smbios_eps *) ptr;
return 0;
}
struct grub_smbios_eps3 *
grub_machine_smbios_get_eps3 (void)
{
grub_uint8_t *ptr;
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16)
if (grub_memcmp (ptr, "_SM3_", 5) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
return (struct grub_smbios_eps3 *) ptr;
return 0;
}

View File

@ -0,0 +1,102 @@
/* rdmsr.c - Read CPU model-specific registers. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 Free Software Foundation, Inc.
* Based on gcc/gcc/config/i386/driver-i386.c
*
* 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/mm.h>
#include <grub/env.h>
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/i386/cpuid.h>
#include <grub/i386/rdmsr.h>
GRUB_MOD_LICENSE("GPLv3+");
static grub_extcmd_t cmd_read;
static const struct grub_arg_option options[] =
{
{0, 'v', 0, N_("Save read value into variable VARNAME."),
N_("VARNAME"), ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv)
{
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
grub_uint64_t value;
char *ptr;
char buf[sizeof("1122334455667788")];
/*
* The CPUID instruction should be used to determine whether MSRs
* are supported. (CPUID.01H:EDX[5] = 1)
*/
if (! grub_cpu_is_cpuid_supported ())
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
if (max_cpuid < 1)
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (1, a, b, c, features);
if (!(features & (1 << 5)))
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
grub_errno = GRUB_ERR_NONE;
ptr = argv[0];
addr = grub_strtoul (ptr, &ptr, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
if (*ptr != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
value = grub_msr_read (addr);
if (ctxt->state[0].set)
{
grub_snprintf (buf, sizeof(buf), "%llx", (unsigned long long) value);
grub_env_set (ctxt->state[0].arg, buf);
}
else
grub_printf ("0x%llx\n", (unsigned long long) value);
return GRUB_ERR_NONE;
}
GRUB_MOD_INIT(rdmsr)
{
cmd_read = grub_register_extcmd ("rdmsr", grub_cmd_msr_read, 0, N_("ADDR"),
N_("Read a CPU model specific register."),
options);
}
GRUB_MOD_FINI(rdmsr)
{
grub_unregister_extcmd (cmd_read);
}

View File

@ -0,0 +1,93 @@
/* wrmsr.c - Write CPU model-specific registers. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 Free Software Foundation, Inc.
* Based on gcc/gcc/config/i386/driver-i386.c
*
* 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/mm.h>
#include <grub/env.h>
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/i386/cpuid.h>
#include <grub/i386/wrmsr.h>
GRUB_MOD_LICENSE("GPLv3+");
static grub_command_t cmd_write;
static grub_err_t
grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv)
{
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
grub_uint64_t value;
char *ptr;
/*
* The CPUID instruction should be used to determine whether MSRs
* are supported. (CPUID.01H:EDX[5] = 1)
*/
if (!grub_cpu_is_cpuid_supported ())
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
if (max_cpuid < 1)
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (1, a, b, c, features);
if (!(features & (1 << 5)))
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
grub_errno = GRUB_ERR_NONE;
ptr = argv[0];
addr = grub_strtoul (ptr, &ptr, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
if (*ptr != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
ptr = argv[1];
value = grub_strtoull (ptr, &ptr, 0);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
if (*ptr != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
grub_msr_write (addr, value);
return GRUB_ERR_NONE;
}
GRUB_MOD_INIT(wrmsr)
{
cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"),
N_("Write a value to a CPU model specific register."));
}
GRUB_MOD_FINI(wrmsr)
{
grub_unregister_command (cmd_write);
}

View File

@ -40,7 +40,7 @@ static struct grub_keyboard_layout layout_us = {
/* 0x10 */ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
/* 0x18 */ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
/* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0',
/* 0x28 */ '\n', '\e', '\b', '\t', ' ', '-', '=', '[',
/* 0x28 */ '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[',
/* According to usage table 0x31 should be mapped to '/'
but testing with real keyboard shows that 0x32 is remapped to '/'.
Map 0x31 to 0.
@ -82,8 +82,8 @@ static struct grub_keyboard_layout layout_us = {
/* 0x10 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
/* 0x18 */ 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
/* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')',
/* 0x28 */ '\n' | GRUB_TERM_SHIFT, '\e' | GRUB_TERM_SHIFT,
/* 0x2a */ '\b' | GRUB_TERM_SHIFT, '\t' | GRUB_TERM_SHIFT,
/* 0x28 */ '\n' | GRUB_TERM_SHIFT, GRUB_TERM_ESC | GRUB_TERM_SHIFT,
/* 0x2a */ GRUB_TERM_BACKSPACE | GRUB_TERM_SHIFT, GRUB_TERM_TAB | GRUB_TERM_SHIFT,
/* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{',
/* According to usage table 0x31 should be mapped to '/'
but testing with real keyboard shows that 0x32 is remapped to '/'.
@ -220,7 +220,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
else
filename = argv[0];
file = grub_file_open (filename);
file = grub_file_open (filename, GRUB_FILE_TYPE_KEYBOARD_LAYOUT);
if (! file)
goto fail;

View File

@ -55,7 +55,7 @@ legacy_file (const char *filename)
if (!suffix)
return grub_errno;
file = grub_file_open (filename);
file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG);
if (! file)
{
grub_free (suffix);

View File

@ -44,7 +44,8 @@ static const struct grub_arg_option options[] =
PUBKEY filter (that insists upon properly signed files) as well. PUBKEY
filter is restored before the function returns. */
static grub_file_t
open_envblk_file (char *filename, int untrusted)
open_envblk_file (char *filename,
enum grub_file_type type)
{
grub_file_t file;
char *buf = 0;
@ -72,13 +73,7 @@ open_envblk_file (char *filename, int untrusted)
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
}
/* The filters that are disabled will be re-enabled by the call to
grub_file_open() after this particular file is opened. */
grub_file_filter_disable_compression ();
if (untrusted)
grub_file_filter_disable_pubkey ();
file = grub_file_open (filename);
file = grub_file_open (filename, type);
grub_free (buf);
return file;
@ -171,7 +166,10 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
whitelist.list = args;
/* state[0] is the -f flag; state[1] is the --skip-sig flag */
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, state[1].set);
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
GRUB_FILE_TYPE_LOADENV
| (state[1].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE));
if (! file)
return grub_errno;
@ -206,7 +204,10 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt,
grub_file_t file;
grub_envblk_t envblk;
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, 0);
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
GRUB_FILE_TYPE_LOADENV
| (state[1].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE));
if (! file)
return grub_errno;
@ -390,7 +391,8 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
1 /* allow untrusted */);
GRUB_FILE_TYPE_SAVEENV
| GRUB_FILE_TYPE_SKIP_SIGNATURE);
if (! file)
return grub_errno;

View File

@ -129,8 +129,8 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info,
/* XXX: For ext2fs symlinks are detected as files while they
should be reported as directories. */
grub_file_filter_disable_compression ();
file = grub_file_open (pathname);
file = grub_file_open (pathname, GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! file)
{
grub_errno = 0;
@ -201,6 +201,15 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
if (grub_errno == GRUB_ERR_UNKNOWN_FS)
grub_errno = GRUB_ERR_NONE;
#ifdef GRUB_MACHINE_IEEE1275
/*
* Close device to prevent a double open in grub_normal_print_device_info().
* Otherwise it may lead to hangs on some IEEE 1275 platforms.
*/
grub_device_close (dev);
dev = NULL;
#endif
grub_normal_print_device_info (device_name);
}
else if (fs)
@ -212,9 +221,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
};
if (longlist)
(fs->dir) (dev, path, print_files_long, &ctx);
(fs->fs_dir) (dev, path, print_files_long, &ctx);
else
(fs->dir) (dev, path, print_files, &ctx);
(fs->fs_dir) (dev, path, print_files, &ctx);
if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
&& path[grub_strlen (path) - 1] != '/')
@ -225,8 +234,8 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
struct grub_dirhook_info info;
grub_errno = 0;
grub_file_filter_disable_compression ();
file = grub_file_open (dirname);
file = grub_file_open (dirname, GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! file)
goto fail;

View File

@ -159,12 +159,12 @@ grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel)
*tail = 0;
ctx.dirname = tail + 1;
(fs->dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx);
(fs->fs_dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx);
}
else
{
ctx.dirname = path + 1;
(fs->dir) (dev, "/", find_inode, &ctx);
(fs->fs_dir) (dev, "/", find_inode, &ctx);
}
if (!ctx.found)
{

View File

@ -52,8 +52,8 @@ static struct
int key;
} hotkey_aliases[] =
{
{"backspace", '\b'},
{"tab", '\t'},
{"backspace", GRUB_TERM_BACKSPACE},
{"tab", GRUB_TERM_TAB},
{"delete", GRUB_TERM_KEY_DC},
{"insert", GRUB_TERM_KEY_INSERT},
{"f1", GRUB_TERM_KEY_F1},

View File

@ -43,7 +43,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (argv[0]);
file = grub_file_open (argv[0], GRUB_FILE_TYPE_CAT);
if (! file)
return grub_errno;
@ -137,6 +137,9 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
if (! mod)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
if (grub_dl_is_persistent (mod))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module");
if (grub_dl_unref (mod) <= 0)
grub_dl_unload (mod);

View File

@ -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:
@ -108,7 +109,7 @@ get_uuid (const char *name, char **uuid, int getnative)
grub_device_close (dev);
return grub_errno;
}
if (!fs->uuid || fs->uuid (dev, uuid) || !*uuid)
if (!fs->fs_uuid || fs->fs_uuid (dev, uuid) || !*uuid)
{
grub_device_close (dev);
@ -242,7 +243,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
if (! filename)
goto fail;
file = grub_file_open (filename);
file = grub_file_open (filename,
GRUB_FILE_TYPE_GRUB_MODULE);
grub_free (filename);
if (! file)
goto fail;

View File

@ -193,7 +193,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file;
file = grub_file_open (filename);
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST);
if (file)
{
char *buf = 0;

View File

@ -30,16 +30,10 @@
#include <grub/env.h>
#include <grub/kernel.h>
#include <grub/extcmd.h>
#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_verified
{
grub_file_t file;
void *buf;
};
typedef struct grub_verified *grub_verified_t;
enum
{
OPTION_SKIP_SIG = 0
@ -445,23 +439,27 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
return ret;
}
struct grub_pubkey_context
{
grub_file_t sig;
struct signature_v4_header v4;
grub_uint8_t v;
const gcry_md_spec_t *hash;
void *hash_context;
};
static grub_err_t
grub_verify_signature_real (char *buf, grub_size_t size,
grub_file_t f, grub_file_t sig,
struct grub_public_key *pkey)
grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig)
{
grub_size_t len;
grub_uint8_t v;
grub_uint8_t h;
grub_uint8_t t;
grub_uint8_t pk;
const gcry_md_spec_t *hash;
struct signature_v4_header v4;
grub_err_t err;
grub_size_t i;
gcry_mpi_t mpis[10];
grub_uint8_t type = 0;
grub_memset (ctxt, 0, sizeof (*ctxt));
err = read_packet_header (sig, &type, &len);
if (err)
return err;
@ -469,18 +467,18 @@ grub_verify_signature_real (char *buf, grub_size_t size,
if (type != 0x2)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v))
if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v))
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (v != 4)
if (ctxt->v != 4)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4))
if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4))
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
h = v4.hash;
t = v4.type;
pk = v4.pkeyalgo;
h = ctxt->v4.hash;
t = ctxt->v4.type;
pk = ctxt->v4.pkeyalgo;
if (t != 0)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
@ -491,183 +489,242 @@ grub_verify_signature_real (char *buf, grub_size_t size,
if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
hash = grub_crypto_lookup_md_by_name (hashes[h]);
if (!hash)
ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]);
if (!ctxt->hash)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
grub_dprintf ("crypt", "alive\n");
{
void *context = NULL;
unsigned char *hval;
grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub);
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
grub_uint8_t s;
grub_uint16_t unhashed_sub;
grub_ssize_t r;
grub_uint8_t hash_start[2];
gcry_mpi_t hmpi;
grub_uint64_t keyid = 0;
struct grub_public_subkey *sk;
grub_uint8_t *readbuf = NULL;
ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize);
if (!ctxt->hash_context)
return grub_errno;
context = grub_zalloc (hash->contextsize);
readbuf = grub_zalloc (READBUF_SIZE);
if (!context || !readbuf)
goto fail;
ctxt->hash->init (ctxt->hash_context);
ctxt->sig = sig;
hash->init (context);
if (buf)
hash->write (context, buf, size);
else
while (1)
{
r = grub_file_read (f, readbuf, READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
hash->write (context, readbuf, r);
}
return GRUB_ERR_NONE;
}
hash->write (context, &v, sizeof (v));
hash->write (context, &v4, sizeof (v4));
while (rem)
{
r = grub_file_read (sig, readbuf,
rem < READBUF_SIZE ? rem : READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
hash->write (context, readbuf, r);
rem -= r;
}
hash->write (context, &v, sizeof (v));
s = 0xff;
hash->write (context, &s, sizeof (s));
hash->write (context, &headlen, sizeof (headlen));
r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
if (r != sizeof (unhashed_sub))
goto fail;
static grub_err_t
grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size)
{
struct grub_pubkey_context *ctxt = ctxt_;
ctxt->hash->write (ctxt->hash_context, buf, size);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_verify_signature_real (struct grub_pubkey_context *ctxt,
struct grub_public_key *pkey)
{
gcry_mpi_t mpis[10];
grub_uint8_t pk = ctxt->v4.pkeyalgo;
grub_size_t i;
grub_uint8_t *readbuf = NULL;
unsigned char *hval;
grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub);
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
grub_uint8_t s;
grub_uint16_t unhashed_sub;
grub_ssize_t r;
grub_uint8_t hash_start[2];
gcry_mpi_t hmpi;
grub_uint64_t keyid = 0;
struct grub_public_subkey *sk;
readbuf = grub_malloc (READBUF_SIZE);
if (!readbuf)
goto fail;
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4));
while (rem)
{
grub_uint8_t *ptr;
grub_uint32_t l;
rem = grub_be_to_cpu16 (unhashed_sub);
if (rem > READBUF_SIZE)
r = grub_file_read (ctxt->sig, readbuf,
rem < READBUF_SIZE ? rem : READBUF_SIZE);
if (r < 0)
goto fail;
r = grub_file_read (sig, readbuf, rem);
if (r != rem)
if (r == 0)
break;
ctxt->hash->write (ctxt->hash_context, readbuf, r);
rem -= r;
}
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
s = 0xff;
ctxt->hash->write (ctxt->hash_context, &s, sizeof (s));
ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen));
r = grub_file_read (ctxt->sig, &unhashed_sub, sizeof (unhashed_sub));
if (r != sizeof (unhashed_sub))
goto fail;
{
grub_uint8_t *ptr;
grub_uint32_t l;
rem = grub_be_to_cpu16 (unhashed_sub);
if (rem > READBUF_SIZE)
goto fail;
r = grub_file_read (ctxt->sig, readbuf, rem);
if (r != rem)
goto fail;
for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
{
if (*ptr < 192)
l = *ptr++;
else if (*ptr < 255)
{
if (ptr + 1 >= readbuf + rem)
break;
l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
ptr += 2;
}
else
{
if (ptr + 5 >= readbuf + rem)
break;
l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
ptr += 5;
}
if (*ptr == 0x10 && l >= 8)
keyid = grub_get_unaligned64 (ptr + 1);
}
}
ctxt->hash->final (ctxt->hash_context);
grub_dprintf ("crypt", "alive\n");
hval = ctxt->hash->read (ctxt->hash_context);
if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
goto fail;
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
goto fail;
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig));
for (i = 0; i < pkalgos[pk].nmpisig; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l))
goto fail;
for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
{
if (*ptr < 192)
l = *ptr++;
else if (*ptr < 255)
{
if (ptr + 1 >= readbuf + rem)
break;
l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
ptr += 2;
}
else
{
if (ptr + 5 >= readbuf + rem)
break;
l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
ptr += 5;
}
if (*ptr == 0x10 && l >= 8)
keyid = grub_get_unaligned64 (ptr + 1);
}
grub_dprintf ("crypt", "alive\n");
lb = (grub_be_to_cpu16 (l) + 7) / 8;
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
goto fail;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
goto fail;
grub_dprintf ("crypt", "alive\n");
grub_memcpy (readbuf, &l, sizeof (l));
grub_dprintf ("crypt", "alive\n");
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
readbuf, lb + sizeof (grub_uint16_t), 0))
goto fail;
grub_dprintf ("crypt", "alive\n");
}
hash->final (context);
grub_dprintf ("crypt", "alive\n");
hval = hash->read (context);
if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
if (pkey)
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
else
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
if (!sk)
{
/* TRANSLATORS: %08x is 32-bit key id. */
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
keyid);
goto fail;
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
}
if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk))
goto fail;
if (!*pkalgos[pk].algo)
{
grub_dl_load (pkalgos[pk].module);
grub_errno = GRUB_ERR_NONE;
}
if (!*pkalgos[pk].algo)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
pkalgos[pk].module);
goto fail;
}
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
goto fail;
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig));
grub_free (readbuf);
for (i = 0; i < pkalgos[pk].nmpisig; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
goto fail;
grub_dprintf ("crypt", "alive\n");
lb = (grub_be_to_cpu16 (l) + 7) / 8;
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
goto fail;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
goto fail;
grub_dprintf ("crypt", "alive\n");
grub_memcpy (readbuf, &l, sizeof (l));
grub_dprintf ("crypt", "alive\n");
return GRUB_ERR_NONE;
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
readbuf, lb + sizeof (grub_uint16_t), 0))
goto fail;
grub_dprintf ("crypt", "alive\n");
}
fail:
grub_free (readbuf);
if (!grub_errno)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
return grub_errno;
}
if (pkey)
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
else
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
if (!sk)
{
/* TRANSLATORS: %08x is 32-bit key id. */
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
keyid);
goto fail;
}
static void
grub_pubkey_close_real (struct grub_pubkey_context *ctxt)
{
if (ctxt->sig)
grub_file_close (ctxt->sig);
if (ctxt->hash_context)
grub_free (ctxt->hash_context);
}
if (pkalgos[pk].pad (&hmpi, hval, hash, sk))
goto fail;
if (!*pkalgos[pk].algo)
{
grub_dl_load (pkalgos[pk].module);
grub_errno = GRUB_ERR_NONE;
}
if (!*pkalgos[pk].algo)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
pkalgos[pk].module);
goto fail;
}
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
goto fail;
grub_free (context);
grub_free (readbuf);
return GRUB_ERR_NONE;
fail:
grub_free (context);
grub_free (readbuf);
if (!grub_errno)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
return grub_errno;
}
static void
grub_pubkey_close (void *ctxt)
{
grub_pubkey_close_real (ctxt);
grub_free (ctxt);
}
grub_err_t
grub_verify_signature (grub_file_t f, grub_file_t sig,
grub_verify_signature (grub_file_t f, const char *fsig,
struct grub_public_key *pkey)
{
return grub_verify_signature_real (0, 0, f, sig, pkey);
grub_file_t sig;
grub_err_t err;
struct grub_pubkey_context ctxt;
grub_uint8_t *readbuf = NULL;
sig = grub_file_open (fsig,
GRUB_FILE_TYPE_SIGNATURE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (!sig)
return grub_errno;
err = grub_verify_signature_init (&ctxt, sig);
if (err)
{
grub_file_close (sig);
return err;
}
readbuf = grub_zalloc (READBUF_SIZE);
if (!readbuf)
goto fail;
while (1)
{
grub_ssize_t r;
r = grub_file_read (f, readbuf, READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
err = grub_pubkey_write (&ctxt, readbuf, r);
if (err)
return err;
}
grub_verify_signature_real (&ctxt, pkey);
fail:
grub_pubkey_close_real (&ctxt);
return grub_errno;
}
static grub_err_t
@ -680,10 +737,12 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
grub_file_filter_disable_compression ();
if (ctxt->state[OPTION_SKIP_SIG].set)
grub_file_filter_disable_pubkey ();
pkf = grub_file_open (args[0]);
pkf = grub_file_open (args[0],
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST
| GRUB_FILE_TYPE_NO_DECOMPRESS
| (ctxt->state[OPTION_SKIP_SIG].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE
: GRUB_FILE_TYPE_NONE));
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
@ -700,6 +759,78 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
return GRUB_ERR_NONE;
}
static grub_ssize_t
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
return len;
}
/* Filesystem descriptor. */
struct grub_fs pseudo_fs =
{
.name = "pseudo",
.fs_read = pseudo_read
};
static grub_err_t
grub_cmd_trust_var (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
struct grub_file pseudo_file;
const char *var;
char *data;
struct grub_public_key *pk = NULL;
unsigned int i, idx0, idx1;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
var = grub_env_get (args[0]);
if (!var)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown variable"));
data = grub_zalloc (grub_strlen (var) / 2);
if (!data)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate memory for key"));
/* For the want of sscanf() */
for (i = 0; i < grub_strlen (var); i += 2)
{
if (var[i] < 0x40)
idx0 = var[i] - 0x30;
else
idx0 = var[i] - 0x57;
if (var[i+1] < 0x40)
idx1 = var[i+1] - 0x30;
else
idx1 = var[i+1] - 0x57;
data[i/2] = ((idx0 << 4) & 0xf0) | (idx1 & 0x0f);
}
grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
pseudo_file.fs = &pseudo_fs;
pseudo_file.size = grub_strlen (var) / 2;
pseudo_file.data = data;
pk = grub_load_public_key (&pseudo_file);
if (!pk)
{
grub_free(data);
return grub_errno;
}
pk->next = grub_pk_trusted;
grub_pk_trusted = pk;
grub_free(data);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
@ -757,7 +888,7 @@ static grub_err_t
grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
int argc, char **args)
{
grub_file_t f = NULL, sig = NULL;
grub_file_t f = NULL;
grub_err_t err = GRUB_ERR_NONE;
struct grub_public_key *pk = NULL;
@ -771,10 +902,12 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
if (argc > 2)
{
grub_file_t pkf;
grub_file_filter_disable_compression ();
if (ctxt->state[OPTION_SKIP_SIG].set)
grub_file_filter_disable_pubkey ();
pkf = grub_file_open (args[2]);
pkf = grub_file_open (args[2],
GRUB_FILE_TYPE_PUBLIC_KEY
| GRUB_FILE_TYPE_NO_DECOMPRESS
| (ctxt->state[OPTION_SKIP_SIG].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE
: GRUB_FILE_TYPE_NONE));
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
@ -786,26 +919,15 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
grub_file_close (pkf);
}
grub_file_filter_disable_all ();
f = grub_file_open (args[0]);
f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
if (!f)
{
err = grub_errno;
goto fail;
}
grub_file_filter_disable_all ();
sig = grub_file_open (args[1]);
if (!sig)
{
err = grub_errno;
goto fail;
}
err = grub_verify_signature (f, sig, pk);
err = grub_verify_signature (f, args[1], pk);
fail:
if (sig)
grub_file_close (sig);
if (f)
grub_file_close (f);
if (pk)
@ -815,135 +937,53 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
static int sec = 0;
static void
verified_free (grub_verified_t verified)
{
if (verified)
{
grub_free (verified->buf);
grub_free (verified);
}
}
static grub_ssize_t
verified_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_verified_t verified = file->data;
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
return len;
}
static grub_err_t
verified_close (struct grub_file *file)
{
grub_verified_t verified = file->data;
grub_file_close (verified->file);
verified_free (verified);
file->data = 0;
/* device and name are freed by parent */
file->device = 0;
file->name = 0;
return grub_errno;
}
struct grub_fs verified_fs =
{
.name = "verified_read",
.read = verified_read,
.close = verified_close
};
static grub_file_t
grub_pubkey_open (grub_file_t io, const char *filename)
grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)),
void **context, enum grub_verify_flags *flags)
{
grub_file_t sig;
char *fsuf, *ptr;
grub_err_t err;
grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
grub_file_t ret;
grub_verified_t verified;
struct grub_pubkey_context *ctxt;
if (!sec)
return io;
if (io->device->disk &&
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
return io;
fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig"));
{
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
return GRUB_ERR_NONE;
}
fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig"));
if (!fsuf)
return NULL;
ptr = grub_stpcpy (fsuf, filename);
return grub_errno;
ptr = grub_stpcpy (fsuf, io->name);
grub_memcpy (ptr, ".sig", sizeof (".sig"));
grub_memcpy (curfilt, grub_file_filters_enabled,
sizeof (curfilt));
grub_file_filter_disable_all ();
sig = grub_file_open (fsuf);
grub_memcpy (grub_file_filters_enabled, curfilt,
sizeof (curfilt));
sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE);
grub_free (fsuf);
if (!sig)
return NULL;
return grub_errno;
ret = grub_malloc (sizeof (*ret));
if (!ret)
ctxt = grub_malloc (sizeof (*ctxt));
if (!ctxt)
{
grub_file_close (sig);
return NULL;
return grub_errno;
}
*ret = *io;
ret->fs = &verified_fs;
ret->not_easily_seekable = 0;
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"big file signature isn't implemented yet");
grub_file_close (sig);
grub_free (ret);
return NULL;
}
verified = grub_malloc (sizeof (*verified));
if (!verified)
{
grub_file_close (sig);
grub_free (ret);
return NULL;
}
verified->buf = grub_malloc (ret->size);
if (!verified->buf)
{
grub_file_close (sig);
grub_free (verified);
grub_free (ret);
return NULL;
}
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
filename);
grub_file_close (sig);
verified_free (verified);
grub_free (ret);
return NULL;
}
err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL);
grub_file_close (sig);
err = grub_verify_signature_init (ctxt, sig);
if (err)
{
verified_free (verified);
grub_free (ret);
return NULL;
grub_free (ctxt);
grub_file_close (sig);
return err;
}
verified->file = io;
ret->data = verified;
return ret;
*context = ctxt;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_pubkey_fini (void *ctxt)
{
return grub_verify_signature_real (ctxt, NULL);
}
static char *
@ -954,26 +994,19 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
return grub_strdup (sec ? "enforce" : "no");
}
static grub_ssize_t
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
return len;
}
/* Filesystem descriptor. */
struct grub_fs pseudo_fs =
struct grub_file_verifier grub_pubkey_verifier =
{
.name = "pseudo",
.read = pseudo_read
};
.name = "pgp",
.init = grub_pubkey_init,
.fini = grub_pubkey_fini,
.write = grub_pubkey_write,
.close = grub_pubkey_close,
};
static grub_extcmd_t cmd, cmd_trust;
static grub_command_t cmd_distrust, cmd_list;
static grub_command_t cmd_trust_var, cmd_distrust, cmd_list;
GRUB_MOD_INIT(verify)
GRUB_MOD_INIT(pgp)
{
const char *val;
struct grub_module_header *header;
@ -983,8 +1016,6 @@ GRUB_MOD_INIT(verify)
sec = 1;
else
sec = 0;
grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open);
grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
grub_env_export ("check_signatures");
@ -1024,19 +1055,25 @@ GRUB_MOD_INIT(verify)
N_("[-s|--skip-sig] PUBKEY_FILE"),
N_("Add PUBKEY_FILE to trusted keys."),
options);
cmd_trust_var = grub_register_command ("trust_var", grub_cmd_trust_var,
N_("PUBKEY_VAR"),
N_("Add the contents of PUBKEY_VAR to trusted keys."));
cmd_list = grub_register_command ("list_trusted", grub_cmd_list,
0,
N_("Show the list of trusted keys."));
cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
N_("PUBKEY_ID"),
N_("Remove PUBKEY_ID from trusted keys."));
grub_verifier_register (&grub_pubkey_verifier);
}
GRUB_MOD_FINI(verify)
GRUB_MOD_FINI(pgp)
{
grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY);
grub_verifier_unregister (&grub_pubkey_verifier);
grub_unregister_extcmd (cmd);
grub_unregister_extcmd (cmd_trust);
grub_unregister_command (cmd_trust_var);
grub_unregister_command (cmd_list);
grub_unregister_command (cmd_distrust);
}

View File

@ -113,10 +113,10 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[4].set)
{
char *uuid;
if (! fs->uuid)
if (! fs->fs_uuid)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("%s does not support UUIDs"), fs->name);
err = fs->uuid (dev, &uuid);
err = fs->fs_uuid (dev, &uuid);
if (err)
return err;
if (! uuid)
@ -134,11 +134,11 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[5].set)
{
char *label;
if (! fs->label)
if (! fs->fs_label)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("filesystem `%s' does not support labels"),
fs->name);
err = fs->label (dev, &label);
err = fs->fs_label (dev, &label);
if (err)
return err;
if (! label)

View File

@ -30,6 +30,10 @@
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
#if defined(DO_SEARCH_PART_UUID) || defined(DO_SEARCH_PART_LABEL) || \
defined(DO_SEARCH_DISK_UUID)
#include <grub/gpt_partition.h>
#endif
GRUB_MOD_LICENSE ("GPLv3+");
@ -66,7 +70,7 @@ iterate_device (const char *name, void *data)
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
return 1;
#ifdef DO_SEARCH_FS_UUID
#if defined(DO_SEARCH_FS_UUID) || defined(DO_SEARCH_DISK_UUID)
#define compare_fn grub_strcasecmp
#else
#define compare_fn grub_strcmp
@ -81,8 +85,8 @@ iterate_device (const char *name, void *data)
if (! buf)
return 1;
grub_file_filter_disable_compression ();
file = grub_file_open (buf);
file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (file)
{
found = 1;
@ -90,6 +94,63 @@ iterate_device (const char *name, void *data)
}
grub_free (buf);
}
#elif defined(DO_SEARCH_PART_UUID)
{
grub_device_t dev;
char *quid;
dev = grub_device_open (name);
if (dev)
{
if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
{
if (grub_strcasecmp (quid, ctx->key) == 0)
found = 1;
grub_free (quid);
}
grub_device_close (dev);
}
}
#elif defined(DO_SEARCH_PART_LABEL)
{
grub_device_t dev;
char *quid;
dev = grub_device_open (name);
if (dev)
{
if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
{
if (grub_strcmp (quid, ctx->key) == 0)
found = 1;
grub_free (quid);
}
grub_device_close (dev);
}
}
#elif defined(DO_SEARCH_DISK_UUID)
{
grub_device_t dev;
char *quid;
dev = grub_device_open (name);
if (dev)
{
if (grub_gpt_disk_uuid (dev, &quid) == GRUB_ERR_NONE)
{
if (grub_strcmp (quid, ctx->key) == 0)
found = 1;
grub_free (quid);
}
grub_device_close (dev);
}
}
#else
{
/* SEARCH_FS_UUID or SEARCH_LABEL */
@ -103,9 +164,9 @@ iterate_device (const char *name, void *data)
fs = grub_fs_probe (dev);
#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
#define read_fn fs_uuid
#else
#define read_fn label
#define read_fn fs_label
#endif
if (fs && fs->read_fn)
@ -313,8 +374,14 @@ static grub_command_t cmd;
#ifdef DO_SEARCH_FILE
GRUB_MOD_INIT(search_fs_file)
#elif defined(DO_SEARCH_PART_UUID)
GRUB_MOD_INIT(search_part_uuid)
#elif defined(DO_SEARCH_PART_LABEL)
GRUB_MOD_INIT(search_part_label)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_INIT(search_fs_uuid)
#elif defined (DO_SEARCH_DISK_UUID)
GRUB_MOD_INIT(search_disk_uuid)
#else
GRUB_MOD_INIT(search_label)
#endif
@ -327,8 +394,14 @@ GRUB_MOD_INIT(search_label)
#ifdef DO_SEARCH_FILE
GRUB_MOD_FINI(search_fs_file)
#elif defined(DO_SEARCH_PART_UUID)
GRUB_MOD_FINI(search_part_uuid)
#elif defined(DO_SEARCH_PART_LABEL)
GRUB_MOD_FINI(search_part_label)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_FINI(search_fs_uuid)
#elif defined (DO_SEARCH_DISK_UUID)
GRUB_MOD_FINI(search_disk_uuid)
#else
GRUB_MOD_FINI(search_label)
#endif

View File

@ -0,0 +1,5 @@
#define DO_SEARCH_DISK_UUID 1
#define FUNC_NAME grub_search_disk_uuid
#define COMMAND_NAME "search.disk_uuid"
#define HELP_MESSAGE N_("Search devices by disk UUID. If VARIABLE is specified, the first device found is set to a variable.")
#include "search.c"

View File

@ -0,0 +1,5 @@
#define DO_SEARCH_PART_LABEL 1
#define FUNC_NAME grub_search_part_label
#define COMMAND_NAME "search.part_label"
#define HELP_MESSAGE N_("Search devices by partition label. If VARIABLE is specified, the first device found is set to a variable.")
#include "search.c"

View File

@ -0,0 +1,5 @@
#define DO_SEARCH_PART_UUID 1
#define FUNC_NAME grub_search_part_uuid
#define COMMAND_NAME "search.part_uuid"
#define HELP_MESSAGE N_("Search devices by partition UUID. If VARIABLE is specified, the first device found is set to a variable.")
#include "search.c"

View File

@ -36,6 +36,12 @@ static const struct grub_arg_option options[] =
0, 0},
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
0, 0},
{"part-label", 'L', 0, N_("Search devices by a partition label."),
0, 0},
{"part-uuid", 'U', 0, N_("Search devices by a partition UUID."),
0, 0},
{"disk-uuid", 'U', 0, N_("Search devices by a disk UUID."),
0, 0},
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
N_("Set a variable to the first device found."), N_("VARNAME"),
ARG_TYPE_STRING},
@ -71,6 +77,9 @@ enum options
SEARCH_FILE,
SEARCH_LABEL,
SEARCH_FS_UUID,
SEARCH_PART_LABEL,
SEARCH_PART_UUID,
SEARCH_DISK_UUID,
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_HINT,
@ -186,6 +195,15 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
else if (state[SEARCH_FS_UUID].set)
grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
else if (state[SEARCH_PART_LABEL].set)
grub_search_part_label (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
else if (state[SEARCH_PART_UUID].set)
grub_search_part_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
else if (state[SEARCH_DISK_UUID].set)
grub_search_disk_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
else if (state[SEARCH_FILE].set)
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);

372
grub-core/commands/smbios.c Normal file
View File

@ -0,0 +1,372 @@
/* smbios.c - retrieve smbios information. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013,2014,2015 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/env.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/smbios.h>
GRUB_MOD_LICENSE ("GPLv3+");
/* Locate the SMBIOS entry point structure depending on the hardware. */
struct grub_smbios_eps *
grub_smbios_get_eps (void)
{
static struct grub_smbios_eps *eps = NULL;
if (eps != NULL)
return eps;
eps = grub_machine_smbios_get_eps ();
return eps;
}
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
struct grub_smbios_eps3 *
grub_smbios_get_eps3 (void)
{
static struct grub_smbios_eps3 *eps = NULL;
if (eps != NULL)
return eps;
eps = grub_machine_smbios_get_eps3 ();
return eps;
}
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
static struct {
grub_addr_t start;
grub_addr_t end;
grub_uint16_t structures;
} table_desc = {0, 0, 0};
/*
* These functions convert values from the various SMBIOS structure field types
* into a string formatted to be returned to the user. They expect that the
* structure and offset were already validated. The given buffer stores the
* newly formatted string if needed. When the requested data is successfully
* retrieved and formatted, the pointer to the string is returned; otherwise,
* NULL is returned on failure.
*/
static const char *
grub_smbios_format_byte (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset)
{
grub_snprintf (buffer, size, "%u", structure[offset]);
return (const char *)buffer;
}
static const char *
grub_smbios_format_word (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset)
{
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
grub_snprintf (buffer, size, "%u", value);
return (const char *)buffer;
}
static const char *
grub_smbios_format_dword (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset)
{
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT32_T, value);
return (const char *)buffer;
}
static const char *
grub_smbios_format_qword (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset)
{
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT64_T, value);
return (const char *)buffer;
}
/* The matching string pointer is returned directly to avoid extra copying. */
static const char *
grub_smbios_get_string (char *buffer __attribute__ ((unused)),
grub_size_t size __attribute__ ((unused)),
const grub_uint8_t *structure, grub_uint8_t offset)
{
const grub_uint8_t *ptr = structure + structure[1];
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
const grub_uint8_t referenced_string_number = structure[offset];
grub_uint8_t i;
/* A string referenced with zero is interpreted as unset. */
if (referenced_string_number == 0)
return NULL;
/* Search the string set. */
for (i = 1; *ptr != 0 && ptr < table_end; i++)
if (i == referenced_string_number)
{
const char *str = (const char *)ptr;
while (*ptr++ != 0)
if (ptr >= table_end)
return NULL; /* The string isn't terminated. */
return str;
}
else
while (*ptr++ != 0 && ptr < table_end);
/* The string number is greater than the number of strings in the set. */
return NULL;
}
static const char *
grub_smbios_format_uuid (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset)
{
const grub_uint8_t *f = structure + offset; /* little-endian fields */
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
grub_snprintf (buffer, size,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
return (const char *)buffer;
}
/* List the field formatting functions and the number of bytes they need. */
#define MAXIMUM_FORMAT_LENGTH (sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff"))
static const struct {
const char *(*format) (char *buffer, grub_size_t size,
const grub_uint8_t *structure, grub_uint8_t offset);
grub_uint8_t field_length;
} field_extractors[] = {
{grub_smbios_format_byte, 1},
{grub_smbios_format_word, 2},
{grub_smbios_format_dword, 4},
{grub_smbios_format_qword, 8},
{grub_smbios_get_string, 1},
{grub_smbios_format_uuid, 16}
};
/* List command options, with structure field getters ordered as above. */
#define FIRST_GETTER_OPT (3)
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
static const struct grub_arg_option options[] = {
{"type", 't', 0, N_("Match entries with the given type."),
N_("type"), ARG_TYPE_INT},
{"handle", 'h', 0, N_("Match entries with the given handle."),
N_("handle"), ARG_TYPE_INT},
{"match", 'm', 0, N_("Select a structure when several match."),
N_("match"), ARG_TYPE_INT},
{"get-byte", 'b', 0, N_("Get the byte's value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-word", 'w', 0, N_("Get two bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-string", 's', 0, N_("Get the string specified at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"set", '\0', 0, N_("Store the value in the given variable name."),
N_("variable"), ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
/*
* Return a matching SMBIOS structure.
*
* This method can use up to three criteria for selecting a structure:
* - The "type" field (use -1 to ignore)
* - The "handle" field (use -1 to ignore)
* - Which to return if several match (use 0 to ignore)
*
* The return value is a pointer to the first matching structure. If no
* structures match the given parameters, NULL is returned.
*/
static const grub_uint8_t *
grub_smbios_match_structure (const grub_int16_t type,
const grub_int32_t handle,
const grub_uint16_t match)
{
const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start;
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
grub_uint16_t structures = table_desc.structures;
grub_uint16_t structure_count = 0;
grub_uint16_t matches = 0;
while (ptr < table_end
&& ptr[1] >= 4 /* Valid structures include the 4-byte header. */
&& (structure_count++ < structures || structures == 0))
{
grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2);
grub_uint8_t structure_type = ptr[0];
if ((handle < 0 || handle == structure_handle)
&& (type < 0 || type == structure_type)
&& (match == 0 || match == ++matches))
return ptr;
else
{
ptr += ptr[1];
while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end);
}
if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE)
break;
}
return NULL;
}
static grub_err_t
grub_cmd_smbios (grub_extcmd_context_t ctxt,
int argc __attribute__ ((unused)),
char **argv __attribute__ ((unused)))
{
struct grub_arg_list *state = ctxt->state;
grub_int16_t type = -1;
grub_int32_t handle = -1;
grub_uint16_t match = 0;
grub_uint8_t offset = 0;
const grub_uint8_t *structure;
const char *value;
char buffer[MAXIMUM_FORMAT_LENGTH];
grub_int32_t option;
grub_int8_t field_type = -1;
grub_uint8_t i;
if (table_desc.start == 0)
return grub_error (GRUB_ERR_IO,
N_("the SMBIOS entry point structure was not found"));
/* Read the given filtering options. */
if (state[0].set)
{
option = grub_strtol (state[0].arg, NULL, 0);
if (option < 0 || option > 255)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the type must be between 0 and 255"));
type = (grub_int16_t)option;
}
if (state[1].set)
{
option = grub_strtol (state[1].arg, NULL, 0);
if (option < 0 || option > 65535)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the handle must be between 0 and 65535"));
handle = (grub_int32_t)option;
}
if (state[2].set)
{
option = grub_strtol (state[2].arg, NULL, 0);
if (option <= 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the match must be a positive integer"));
match = (grub_uint16_t)option;
}
/* Determine the data type of the structure field to retrieve. */
for (i = 0; i < ARRAY_SIZE(field_extractors); i++)
if (state[FIRST_GETTER_OPT + i].set)
{
if (field_type >= 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("only one --get option is usable at a time"));
field_type = i;
}
/* Require a choice of a structure field to return. */
if (field_type < 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("one of the --get options is required"));
/* Locate a matching SMBIOS structure. */
structure = grub_smbios_match_structure (type, handle, match);
if (structure == NULL)
return grub_error (GRUB_ERR_IO,
N_("no structure matched the given options"));
/* Ensure the requested byte offset is inside the structure. */
option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0);
if (option < 0 || option >= structure[1])
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("the given offset is outside the structure"));
/* Ensure the requested data type at the offset is inside the structure. */
offset = (grub_uint8_t)option;
if (offset + field_extractors[field_type].field_length > structure[1])
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("the field ends outside the structure"));
/* Format the requested structure field into a readable string. */
value = field_extractors[field_type].format (buffer, sizeof (buffer),
structure, offset);
if (value == NULL)
return grub_error (GRUB_ERR_IO,
N_("failed to retrieve the structure field"));
/* Store or print the formatted value. */
if (state[SETTER_OPT].set)
grub_env_set (state[SETTER_OPT].arg, value);
else
grub_printf ("%s\n", value);
return GRUB_ERR_NONE;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(smbios)
{
struct grub_smbios_eps3 *eps3;
struct grub_smbios_eps *eps;
if ((eps3 = grub_smbios_get_eps3 ()))
{
table_desc.start = (grub_addr_t)eps3->table_address;
table_desc.end = table_desc.start + eps3->maximum_table_length;
table_desc.structures = 0; /* SMBIOS3 drops the structure count. */
}
else if ((eps = grub_smbios_get_eps ()))
{
table_desc.start = (grub_addr_t)eps->intermediate.table_address;
table_desc.end = table_desc.start + eps->intermediate.table_length;
table_desc.structures = eps->intermediate.structures;
}
cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0,
N_("[-t type] [-h handle] [-m match] "
"(-b|-w|-d|-q|-s|-u) offset "
"[--set variable]"),
N_("Retrieve SMBIOS information."), options);
}
GRUB_MOD_FINI(smbios)
{
grub_unregister_extcmd (cmd);
}

View File

@ -133,15 +133,15 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx)
/* Fetch writing time. */
ctx->file_info.mtimeset = 0;
if (fs->mtime)
if (fs->fs_mtime)
{
if (! fs->mtime (dev, &ctx->file_info.mtime))
if (! fs->fs_mtime (dev, &ctx->file_info.mtime))
ctx->file_info.mtimeset = 1;
grub_errno = GRUB_ERR_NONE;
}
}
else
(fs->dir) (dev, path, find_file, ctx);
(fs->fs_dir) (dev, path, find_file, ctx);
grub_device_close (dev);
grub_free (path);
@ -355,8 +355,8 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn], "-s") == 0)
{
grub_file_t file;
grub_file_filter_disable_compression ();
file = grub_file_open (args[*argn + 1]);
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
update_val (file && (grub_file_size (file) != 0), &ctx);
if (file)
grub_file_close (file);

View File

@ -57,7 +57,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (argv[0]);
file = grub_file_open (argv[0], GRUB_FILE_TYPE_TESTLOAD);
if (! file)
return grub_errno;

View File

@ -61,7 +61,7 @@ grub_cmd_testspeed (grub_extcmd_context_t ctxt, int argc, char **args)
if (buffer == NULL)
return grub_errno;
file = grub_file_open (args[0]);
file = grub_file_open (args[0], GRUB_FILE_TYPE_TESTLOAD);
if (file == NULL)
goto quit;

102
grub-core/commands/tpm.c Normal file
View File

@ -0,0 +1,102 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2018 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/>.
*
* Core TPM support code.
*/
#include <grub/err.h>
#include <grub/i18n.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/tpm.h>
#include <grub/term.h>
#include <grub/verify.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
grub_err_t
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
const char *description)
{
return grub_tpm_log_event (buf, size, pcr, description);
}
static grub_err_t
grub_tpm_verify_init (grub_file_t io,
enum grub_file_type type __attribute__ ((unused)),
void **context, enum grub_verify_flags *flags)
{
*context = io->name;
*flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_tpm_verify_write (void *context, void *buf, grub_size_t size)
{
return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context);
}
static grub_err_t
grub_tpm_verify_string (char *str, enum grub_verify_string_type type)
{
const char *prefix = NULL;
char *description;
grub_err_t status;
switch (type)
{
case GRUB_VERIFY_KERNEL_CMDLINE:
prefix = "kernel_cmdline: ";
break;
case GRUB_VERIFY_MODULE_CMDLINE:
prefix = "module_cmdline: ";
break;
case GRUB_VERIFY_COMMAND:
prefix = "grub_cmd: ";
break;
}
description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1);
if (!description)
return grub_errno;
grub_memcpy (description, prefix, grub_strlen (prefix));
grub_memcpy (description + grub_strlen (prefix), str,
grub_strlen (str) + 1);
status =
grub_tpm_measure ((unsigned char *) str, grub_strlen (str),
GRUB_STRING_PCR, description);
grub_free (description);
return status;
}
struct grub_file_verifier grub_tpm_verifier = {
.name = "tpm",
.init = grub_tpm_verify_init,
.write = grub_tpm_verify_write,
.verify_string = grub_tpm_verify_string,
};
GRUB_MOD_INIT (tpm)
{
grub_verifier_register (&grub_tpm_verifier);
}
GRUB_MOD_FINI (tpm)
{
grub_verifier_unregister (&grub_tpm_verifier);
}

View File

@ -63,6 +63,11 @@ static const char *usb_devspeed[] =
"High"
};
#if __GNUC__ >= 9
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#endif
static grub_usb_err_t
grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
char **string)
@ -108,6 +113,10 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
return GRUB_USB_ERR_NONE;
}
#if __GNUC__ >= 9
#pragma GCC diagnostic pop
#endif
static void
usb_print_str (const char *description, grub_usb_device_t dev, int idx)
{

View File

@ -0,0 +1,228 @@
/*
* 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/>.
*
* Verifiers helper.
*/
#include <grub/file.h>
#include <grub/verify.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_file_verifier *grub_file_verifiers;
struct grub_verified
{
grub_file_t file;
void *buf;
};
typedef struct grub_verified *grub_verified_t;
static void
verified_free (grub_verified_t verified)
{
if (verified)
{
grub_free (verified->buf);
grub_free (verified);
}
}
static grub_ssize_t
verified_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_verified_t verified = file->data;
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
return len;
}
static grub_err_t
verified_close (struct grub_file *file)
{
grub_verified_t verified = file->data;
grub_file_close (verified->file);
verified_free (verified);
file->data = 0;
/* Device and name are freed by parent. */
file->device = 0;
file->name = 0;
return grub_errno;
}
struct grub_fs verified_fs =
{
.name = "verified_read",
.fs_read = verified_read,
.fs_close = verified_close
};
static grub_file_t
grub_verifiers_open (grub_file_t io, enum grub_file_type type)
{
grub_verified_t verified = NULL;
struct grub_file_verifier *ver;
void *context;
grub_file_t ret = 0;
grub_err_t err;
int defer = 0;
grub_dprintf ("verify", "file: %s type: %d\n", io->name, type);
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE
|| (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
|| (type & GRUB_FILE_TYPE_SKIP_SIGNATURE))
return io;
if (io->device->disk &&
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
return io;
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
{
enum grub_verify_flags flags = 0;
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
if (flags & GRUB_VERIFY_FLAGS_DEFER_AUTH)
{
defer = 1;
continue;
}
if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION))
break;
}
if (!ver)
{
if (defer)
{
grub_error (GRUB_ERR_ACCESS_DENIED,
N_("verification requested but nobody cares: %s"), io->name);
goto fail_noclose;
}
/* No verifiers wanted to verify. Just return underlying file. */
return io;
}
ret = grub_malloc (sizeof (*ret));
if (!ret)
{
goto fail;
}
*ret = *io;
ret->fs = &verified_fs;
ret->not_easily_seekable = 0;
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("big file signature isn't implemented yet"));
goto fail;
}
verified = grub_malloc (sizeof (*verified));
if (!verified)
{
goto fail;
}
verified->buf = grub_malloc (ret->size);
if (!verified->buf)
{
goto fail;
}
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
io->name);
goto fail;
}
err = ver->write (context, verified->buf, ret->size);
if (err)
goto fail;
err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE;
if (err)
goto fail;
if (ver->close)
ver->close (context);
FOR_LIST_ELEMENTS_NEXT(ver, grub_file_verifiers)
{
enum grub_verify_flags flags = 0;
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION ||
/* Verification done earlier. So, we are happy here. */
flags & GRUB_VERIFY_FLAGS_DEFER_AUTH)
continue;
err = ver->write (context, verified->buf, ret->size);
if (err)
goto fail;
err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE;
if (err)
goto fail;
if (ver->close)
ver->close (context);
}
verified->file = io;
ret->data = verified;
return ret;
fail:
ver->close (context);
fail_noclose:
verified_free (verified);
grub_free (ret);
return NULL;
}
grub_err_t
grub_verify_string (char *str, enum grub_verify_string_type type)
{
struct grub_file_verifier *ver;
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
{
grub_err_t err;
err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE;
if (err)
return err;
}
return GRUB_ERR_NONE;
}
GRUB_MOD_INIT(verifiers)
{
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
}
GRUB_MOD_FINI(verifiers)
{
grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY);
}

View File

@ -370,7 +370,7 @@ match_files (const char *prefix, const char *suffix, const char *end,
else
path = ctx.dir;
if (fs->dir (dev, path, match_files_iter, &ctx))
if (fs->fs_dir (dev, path, match_files_iter, &ctx))
goto fail;
grub_free (ctx.dir);
@ -452,7 +452,7 @@ check_file (const char *dir, const char *basename)
else
path = dir;
fs->dir (dev, path[0] ? path : "/", check_file_iter, &ctx);
fs->fs_dir (dev, path[0] ? path : "/", check_file_iter, &ctx);
if (grub_errno == 0 && basename[0] == 0)
ctx.found = 1;

View File

@ -82,6 +82,20 @@ enum grub_ahci_hba_port_command
GRUB_AHCI_HBA_PORT_CMD_FR = 0x4000,
};
enum grub_ahci_hba_port_int_status
{
GRUB_AHCI_HBA_PORT_IS_IFS = (1UL << 27),
GRUB_AHCI_HBA_PORT_IS_HBDS = (1UL << 28),
GRUB_AHCI_HBA_PORT_IS_HBFS = (1UL << 29),
GRUB_AHCI_HBA_PORT_IS_TFES = (1UL << 30),
};
#define GRUB_AHCI_HBA_PORT_IS_FATAL_MASK ( \
GRUB_AHCI_HBA_PORT_IS_IFS | \
GRUB_AHCI_HBA_PORT_IS_HBDS | \
GRUB_AHCI_HBA_PORT_IS_HBFS | \
GRUB_AHCI_HBA_PORT_IS_TFES)
struct grub_ahci_hba
{
grub_uint32_t cap;
@ -562,7 +576,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
grub_ahci_readwrite_real (dev, &parms2, 1, 1);*/
}
endtime = grub_get_time_ms () + 10000;
endtime = grub_get_time_ms () + 32000;
while (grub_get_time_ms () < endtime)
{
@ -1026,7 +1040,8 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
endtime = grub_get_time_ms () + (spinup ? 20000 : 20000);
while ((dev->hba->ports[dev->port].command_issue & 1))
if (grub_get_time_ms () > endtime)
if (grub_get_time_ms () > endtime ||
(dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK))
{
grub_dprintf ("ahci", "AHCI status <%x %x %x %x>\n",
dev->hba->ports[dev->port].command_issue,
@ -1034,7 +1049,10 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
dev->hba->ports[dev->port].intstatus,
dev->hba->ports[dev->port].task_file_data);
dev->hba->ports[dev->port].command_issue = 0;
err = grub_error (GRUB_ERR_IO, "AHCI transfer timed out");
if (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK)
err = grub_error (GRUB_ERR_IO, "AHCI transfer error");
else
err = grub_error (GRUB_ERR_IO, "AHCI transfer timed out");
if (!reset)
grub_ahci_reset_port (dev, 1);
break;

View File

@ -296,11 +296,11 @@ static struct grub_disk_dev grub_arcdisk_dev =
{
.name = "arcdisk",
.id = GRUB_DISK_DEVICE_ARCDISK_ID,
.iterate = grub_arcdisk_iterate,
.open = grub_arcdisk_open,
.close = grub_arcdisk_close,
.read = grub_arcdisk_read,
.write = grub_arcdisk_write,
.disk_iterate = grub_arcdisk_iterate,
.disk_open = grub_arcdisk_open,
.disk_close = grub_arcdisk_close,
.disk_read = grub_arcdisk_read,
.disk_write = grub_arcdisk_write,
.next = 0
};

View File

@ -510,11 +510,11 @@ static struct grub_disk_dev grub_atadisk_dev =
{
.name = "ATA",
.id = GRUB_DISK_DEVICE_ATA_ID,
.iterate = grub_ata_iterate,
.open = grub_ata_open,
.close = grub_ata_close,
.read = grub_ata_read,
.write = grub_ata_write,
.disk_iterate = grub_ata_iterate,
.disk_open = grub_ata_open,
.disk_close = grub_ata_close,
.disk_read = grub_ata_read,
.disk_write = grub_ata_write,
.next = 0
};

View File

@ -1015,13 +1015,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
static struct grub_disk_dev grub_cryptodisk_dev = {
.name = "cryptodisk",
.id = GRUB_DISK_DEVICE_CRYPTODISK_ID,
.iterate = grub_cryptodisk_iterate,
.open = grub_cryptodisk_open,
.close = grub_cryptodisk_close,
.read = grub_cryptodisk_read,
.write = grub_cryptodisk_write,
.disk_iterate = grub_cryptodisk_iterate,
.disk_open = grub_cryptodisk_open,
.disk_close = grub_cryptodisk_close,
.disk_read = grub_cryptodisk_read,
.disk_write = grub_cryptodisk_write,
#ifdef GRUB_UTIL
.memberlist = grub_cryptodisk_memberlist,
.disk_memberlist = grub_cryptodisk_memberlist,
#endif
.next = 0
};

View File

@ -228,9 +228,9 @@ scan_devices (const char *arname)
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
for (p = grub_disk_dev_list; p; p = p->next)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
&& p->disk_iterate)
{
if ((p->iterate) (scan_disk_hook, NULL, pull))
if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
return;
if (arname && is_lv_readable (find_lv (arname), 1))
return;
@ -311,9 +311,9 @@ grub_diskfilter_memberlist (grub_disk_t disk)
for (pull = 0; pv && pull < GRUB_DISK_PULL_MAX; pull++)
for (p = grub_disk_dev_list; pv && p; p = p->next)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
&& p->disk_iterate)
{
(p->iterate) (scan_disk_hook, NULL, pull);
(p->disk_iterate) (scan_disk_hook, NULL, pull);
while (pv && pv->disk)
pv = pv->next;
}
@ -1325,14 +1325,14 @@ static struct grub_disk_dev grub_diskfilter_dev =
{
.name = "diskfilter",
.id = GRUB_DISK_DEVICE_DISKFILTER_ID,
.iterate = grub_diskfilter_iterate,
.open = grub_diskfilter_open,
.close = grub_diskfilter_close,
.read = grub_diskfilter_read,
.write = grub_diskfilter_write,
.disk_iterate = grub_diskfilter_iterate,
.disk_open = grub_diskfilter_open,
.disk_close = grub_diskfilter_close,
.disk_read = grub_diskfilter_read,
.disk_write = grub_diskfilter_write,
#ifdef GRUB_UTIL
.memberlist = grub_diskfilter_memberlist,
.raidname = grub_diskfilter_getname,
.disk_memberlist = grub_diskfilter_memberlist,
.disk_raidname = grub_diskfilter_getname,
#endif
.next = 0
};

View File

@ -129,6 +129,9 @@ find_parent_device (struct grub_efidisk_data *devices,
return 0;
ldp = grub_efi_find_last_device_path (dp);
if (! ldp)
return 0;
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
ldp->length = sizeof (*ldp);
@ -159,6 +162,9 @@ is_child (struct grub_efidisk_data *child,
return 0;
ldp = grub_efi_find_last_device_path (dp);
if (! ldp)
return 0;
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
ldp->length = sizeof (*ldp);
@ -627,11 +633,11 @@ static struct grub_disk_dev grub_efidisk_dev =
{
.name = "efidisk",
.id = GRUB_DISK_DEVICE_EFIDISK_ID,
.iterate = grub_efidisk_iterate,
.open = grub_efidisk_open,
.close = grub_efidisk_close,
.read = grub_efidisk_read,
.write = grub_efidisk_write,
.disk_iterate = grub_efidisk_iterate,
.disk_open = grub_efidisk_open,
.disk_close = grub_efidisk_close,
.disk_read = grub_efidisk_read,
.disk_write = grub_efidisk_write,
.next = 0
};
@ -830,6 +836,9 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
{
grub_efi_device_path_t *dup_ldp;
dup_ldp = grub_efi_find_last_device_path (dup_dp);
if (! dup_ldp)
break;
if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))

View File

@ -84,11 +84,11 @@ static struct grub_disk_dev grub_host_dev =
/* The only important line in this file :-) */
.name = "host",
.id = GRUB_DISK_DEVICE_HOST_ID,
.iterate = grub_host_iterate,
.open = grub_host_open,
.close = grub_host_close,
.read = grub_host_read,
.write = grub_host_write,
.disk_iterate = grub_host_iterate,
.disk_open = grub_host_open,
.disk_close = grub_host_close,
.disk_read = grub_host_read,
.disk_write = grub_host_write,
.next = 0
};

View File

@ -278,10 +278,14 @@ grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
char name[10];
if (cd_drive && drive == cd_drive)
return hook ("cd", hook_data);
{
grub_dprintf ("biosdisk", "iterating cd\n");
return hook ("cd", hook_data);
}
grub_snprintf (name, sizeof (name),
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
grub_dprintf ("biosdisk", "iterating %s\n", name);
return hook (name, hook_data);
}
@ -301,7 +305,7 @@ grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
{
grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
grub_dprintf ("biosdisk", "Read error when probing drive 0x%2x\n", drive);
break;
}
@ -336,6 +340,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
int drive;
struct grub_biosdisk_data *data;
grub_dprintf ("biosdisk", "opening %s\n", name);
drive = grub_biosdisk_get_drive (name);
if (drive < 0)
return grub_errno;
@ -393,6 +399,11 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
(1 << disk->log_sector_size) < drp->bytes_per_sector;
disk->log_sector_size++);
}
grub_dprintf ("biosdisk",
"LBA total = 0x%llx block size = 0x%lx\n",
(unsigned long long) total_sectors,
1L << disk->log_sector_size);
}
}
}
@ -428,6 +439,9 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
if (! total_sectors)
total_sectors = ((grub_uint64_t) data->cylinders)
* data->heads * data->sectors;
grub_dprintf ("biosdisk", "C/H/S %lu/%lu/%lu\n",
data->cylinders, data->heads, data->sectors);
}
disk->total_sectors = total_sectors;
@ -440,12 +454,15 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
disk->data = data;
grub_dprintf ("biosdisk", "opening %s succeeded\n", name);
return GRUB_ERR_NONE;
}
static void
grub_biosdisk_close (grub_disk_t disk)
{
grub_dprintf ("biosdisk", "closing %s\n", disk->name);
grub_free (disk->data);
}
@ -577,6 +594,9 @@ static grub_err_t
grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
grub_dprintf ("biosdisk", "reading 0x%lx sectors at 0x%llx from %s\n",
(unsigned long) size, (unsigned long long) sector, disk->name);
while (size)
{
grub_size_t len;
@ -607,6 +627,9 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
{
struct grub_biosdisk_data *data = disk->data;
grub_dprintf ("biosdisk", "writing 0x%lx sectors at 0x%llx to %s\n",
(unsigned long) size, (unsigned long long) sector, disk->name);
if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
@ -637,11 +660,11 @@ static struct grub_disk_dev grub_biosdisk_dev =
{
.name = "biosdisk",
.id = GRUB_DISK_DEVICE_BIOSDISK_ID,
.iterate = grub_biosdisk_iterate,
.open = grub_biosdisk_open,
.close = grub_biosdisk_close,
.read = grub_biosdisk_read,
.write = grub_biosdisk_write,
.disk_iterate = grub_biosdisk_iterate,
.disk_open = grub_biosdisk_open,
.disk_close = grub_biosdisk_close,
.disk_read = grub_biosdisk_read,
.disk_write = grub_biosdisk_write,
.next = 0
};

View File

@ -223,11 +223,11 @@ static struct grub_disk_dev grub_nand_dev =
{
.name = "nand",
.id = GRUB_DISK_DEVICE_NAND_ID,
.iterate = grub_nand_iterate,
.open = grub_nand_open,
.close = grub_nand_close,
.read = grub_nand_read,
.write = grub_nand_write,
.disk_iterate = grub_nand_iterate,
.disk_open = grub_nand_open,
.disk_close = grub_nand_close,
.disk_read = grub_nand_read,
.disk_write = grub_nand_write,
.next = 0
};

File diff suppressed because it is too large Load Diff

View File

@ -615,11 +615,11 @@ static struct grub_disk_dev grub_ofdisk_dev =
{
.name = "ofdisk",
.id = GRUB_DISK_DEVICE_OFDISK_ID,
.iterate = grub_ofdisk_iterate,
.open = grub_ofdisk_open,
.close = grub_ofdisk_close,
.read = grub_ofdisk_read,
.write = grub_ofdisk_write,
.disk_iterate = grub_ofdisk_iterate,
.disk_open = grub_ofdisk_open,
.disk_close = grub_ofdisk_close,
.disk_read = grub_ofdisk_read,
.disk_write = grub_ofdisk_write,
.next = 0
};

View File

@ -135,7 +135,7 @@ msdos_has_ldm_partition (grub_disk_t dsk)
return has_ldm;
}
static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
static const grub_gpt_part_guid_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
/* Helper for gpt_ldm_sector. */
static int

View File

@ -92,7 +92,8 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (args[1]);
file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! file)
return grub_errno;
@ -221,10 +222,10 @@ static struct grub_disk_dev grub_loopback_dev =
{
.name = "loopback",
.id = GRUB_DISK_DEVICE_LOOPBACK_ID,
.iterate = grub_loopback_iterate,
.open = grub_loopback_open,
.read = grub_loopback_read,
.write = grub_loopback_write,
.disk_iterate = grub_loopback_iterate,
.disk_open = grub_loopback_open,
.disk_read = grub_loopback_read,
.disk_write = grub_loopback_write,
.next = 0
};

View File

@ -77,11 +77,11 @@ static struct grub_disk_dev grub_memdisk_dev =
{
.name = "memdisk",
.id = GRUB_DISK_DEVICE_MEMDISK_ID,
.iterate = grub_memdisk_iterate,
.open = grub_memdisk_open,
.close = grub_memdisk_close,
.read = grub_memdisk_read,
.write = grub_memdisk_write,
.disk_iterate = grub_memdisk_iterate,
.disk_open = grub_memdisk_open,
.disk_close = grub_memdisk_close,
.disk_read = grub_memdisk_read,
.disk_write = grub_memdisk_write,
.next = 0
};

View File

@ -74,14 +74,26 @@ mod_255 (unsigned x)
}
static grub_err_t
grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
char *buf, grub_disk_addr_t sector, grub_size_t size)
raid6_recover_read_node (void *data, int disknr,
grub_uint64_t sector,
void *buf, grub_size_t size)
{
struct grub_diskfilter_segment *array = data;
return grub_diskfilter_read_node (&array->nodes[disknr],
(grub_disk_addr_t)sector,
size >> GRUB_DISK_SECTOR_BITS, buf);
}
grub_err_t
grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p,
char *buf, grub_uint64_t sector, grub_size_t size,
int layout, raid_recover_read_t read_func)
{
int i, q, pos;
int bad1 = -1, bad2 = -1;
char *pbuf = 0, *qbuf = 0;
size <<= GRUB_DISK_SECTOR_BITS;
pbuf = grub_zalloc (size);
if (!pbuf)
goto quit;
@ -91,17 +103,17 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
goto quit;
q = p + 1;
if (q == (int) array->node_count)
if (q == (int) nstripes)
q = 0;
pos = q + 1;
if (pos == (int) array->node_count)
if (pos == (int) nstripes)
pos = 0;
for (i = 0; i < (int) array->node_count - 2; i++)
for (i = 0; i < (int) nstripes - 2; i++)
{
int c;
if (array->layout & GRUB_RAID_LAYOUT_MUL_FROM_POS)
if (layout & GRUB_RAID_LAYOUT_MUL_FROM_POS)
c = pos;
else
c = i;
@ -109,8 +121,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
bad1 = c;
else
{
if (! grub_diskfilter_read_node (&array->nodes[pos], sector,
size >> GRUB_DISK_SECTOR_BITS, buf))
if (!read_func (data, pos, sector, buf, size))
{
grub_crypto_xor (pbuf, pbuf, buf, size);
grub_raid_block_mulx (c, buf, size);
@ -128,7 +139,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
}
pos++;
if (pos == (int) array->node_count)
if (pos == (int) nstripes)
pos = 0;
}
@ -139,16 +150,14 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
if (bad2 < 0)
{
/* One bad device */
if ((! grub_diskfilter_read_node (&array->nodes[p], sector,
size >> GRUB_DISK_SECTOR_BITS, buf)))
if (!read_func (data, p, sector, buf, size))
{
grub_crypto_xor (buf, buf, pbuf, size);
goto quit;
}
grub_errno = GRUB_ERR_NONE;
if (grub_diskfilter_read_node (&array->nodes[q], sector,
size >> GRUB_DISK_SECTOR_BITS, buf))
if (read_func (data, q, sector, buf, size))
goto quit;
grub_crypto_xor (buf, buf, qbuf, size);
@ -160,14 +169,12 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
/* Two bad devices */
unsigned c;
if (grub_diskfilter_read_node (&array->nodes[p], sector,
size >> GRUB_DISK_SECTOR_BITS, buf))
if (read_func (data, p, sector, buf, size))
goto quit;
grub_crypto_xor (pbuf, pbuf, buf, size);
if (grub_diskfilter_read_node (&array->nodes[q], sector,
size >> GRUB_DISK_SECTOR_BITS, buf))
if (read_func (data, q, sector, buf, size))
goto quit;
grub_crypto_xor (qbuf, qbuf, buf, size);
@ -190,6 +197,15 @@ quit:
return grub_errno;
}
static grub_err_t
grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
char *buf, grub_disk_addr_t sector, grub_size_t size)
{
return grub_raid6_recover_gen (array, array->node_count, disknr, p, buf,
sector, size << GRUB_DISK_SECTOR_BITS,
array->layout, raid6_recover_read_node);
}
GRUB_MOD_INIT(raid6rec)
{
grub_raid6_init_table ();

View File

@ -747,11 +747,11 @@ static struct grub_disk_dev grub_scsi_dev =
{
.name = "scsi",
.id = GRUB_DISK_DEVICE_SCSI_ID,
.iterate = grub_scsi_iterate,
.open = grub_scsi_open,
.close = grub_scsi_close,
.read = grub_scsi_read,
.write = grub_scsi_write,
.disk_iterate = grub_scsi_iterate,
.disk_open = grub_scsi_open,
.disk_close = grub_scsi_close,
.disk_read = grub_scsi_read,
.disk_write = grub_scsi_write,
.next = 0
};

View File

@ -264,23 +264,33 @@ uboot_disk_read (struct grub_disk *disk,
}
static grub_err_t
uboot_disk_write (struct grub_disk *disk __attribute__ ((unused)),
grub_disk_addr_t sector __attribute__ ((unused)),
grub_size_t size __attribute__ ((unused)),
const char *buf __attribute__ ((unused)))
uboot_disk_write (struct grub_disk *disk,
grub_disk_addr_t offset, grub_size_t numblocks, const char *buf)
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"attempt to write (not supported)");
struct ubootdisk_data *d;
int retval;
d = disk->data;
retval = grub_uboot_dev_write (d->dev, buf, numblocks, offset);
grub_dprintf ("ubootdisk",
"retval=%d, numblocks=%d, sector=%llu\n",
retval, numblocks, (grub_uint64_t) offset);
if (retval != 0)
return grub_error (GRUB_ERR_IO, "U-Boot disk write error");
return GRUB_ERR_NONE;
}
static struct grub_disk_dev grub_ubootdisk_dev = {
.name = "ubootdisk",
.id = GRUB_DISK_DEVICE_UBOOTDISK_ID,
.iterate = uboot_disk_iterate,
.open = uboot_disk_open,
.close = uboot_disk_close,
.read = uboot_disk_read,
.write = uboot_disk_write,
.disk_iterate = uboot_disk_iterate,
.disk_open = uboot_disk_open,
.disk_close = uboot_disk_close,
.disk_read = uboot_disk_read,
.disk_write = uboot_disk_write,
.next = 0
};

View File

@ -249,11 +249,11 @@ grub_virtdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
static struct grub_disk_dev grub_virtdisk_dev = {
.name = "xen",
.id = GRUB_DISK_DEVICE_XEN,
.iterate = grub_virtdisk_iterate,
.open = grub_virtdisk_open,
.close = grub_virtdisk_close,
.read = grub_virtdisk_read,
.write = grub_virtdisk_write,
.disk_iterate = grub_virtdisk_iterate,
.disk_open = grub_virtdisk_open,
.disk_close = grub_virtdisk_close,
.disk_read = grub_virtdisk_read,
.disk_write = grub_virtdisk_write,
.next = 0
};

View File

@ -98,6 +98,7 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
break;
case R_X86_64_PC32:
case R_X86_64_PLT32:
err = grub_efiemu_write_value (addr,
*addr32 + rel->r_addend
+ sym.off

Some files were not shown because too many files have changed in this diff Show More