e1531466e1
This change updates grub to the 2.04 release. The new release changed how grub is built, so the bootstrap and bootstrap.conf files have to be added to the dist-git. Also, the gitignore file changed so it has to be updated. Since the patches have been forward ported to 2.04, there's no need for a logic to maintain a patch with the delta between the release and the grub master branch. So the release-to-master.patch is dropped and no longer is updated by the do-rebase script. Also since gnulib isn't part of the grub repository anymore and cloned by the boostrap tool, a gnulib tarball is included as other source file and copied before calling the bootstrap tool. That way grub can be built even in builders that only have access to the sources lookaside cache. Resolves: rhbz#1727279 Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
299 lines
12 KiB
Diff
299 lines
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Peter Jones <pjones@redhat.com>
|
|
Date: Thu, 11 Jul 2019 14:38:57 +0200
|
|
Subject: [PATCH] arm/arm64 loader: Better memory allocation and error
|
|
messages.
|
|
|
|
On mustang, our memory map looks like:
|
|
|
|
Type Physical start - end #Pages Size Attributes
|
|
reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB
|
|
conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB
|
|
ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB
|
|
BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB
|
|
conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB
|
|
ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB
|
|
ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB
|
|
conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB
|
|
ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB
|
|
ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB
|
|
BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB
|
|
RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB
|
|
RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB
|
|
RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB
|
|
ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB
|
|
BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB
|
|
reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB
|
|
ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB
|
|
ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB
|
|
ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB
|
|
RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB
|
|
RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB
|
|
RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB
|
|
RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB
|
|
RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB
|
|
RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB
|
|
BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB
|
|
reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB
|
|
conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB
|
|
BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB
|
|
conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB
|
|
BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB
|
|
conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB
|
|
BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB
|
|
conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB
|
|
BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB
|
|
BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB
|
|
RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB
|
|
conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB
|
|
RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB
|
|
conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB
|
|
BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB
|
|
MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT
|
|
MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT
|
|
MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT
|
|
MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT
|
|
|
|
This patch adds a requirement when we're trying to find the base of ram, that
|
|
the memory we choose is actually /allocatable/ conventional memory, not merely
|
|
write-combining. On this machine that means we wind up with an allocation
|
|
around 0x4392XXXXXX, which is a reasonable address.
|
|
|
|
This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
|
|
tries to allocate again starting with the same max address it did the first
|
|
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
|
|
per-platform constraints on its given address are maintained.
|
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
---
|
|
grub-core/kern/efi/mm.c | 33 +++++++++++++-----
|
|
grub-core/loader/arm64/linux.c | 78 ++++++++++++++++++++++++++++++++----------
|
|
2 files changed, 84 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
|
index 15595a46e23..1b14fa0694c 100644
|
|
--- a/grub-core/kern/efi/mm.c
|
|
+++ b/grub-core/kern/efi/mm.c
|
|
@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
|
{
|
|
grub_efi_status_t status;
|
|
grub_efi_boot_services_t *b;
|
|
+ grub_efi_physical_address_t ret = address;
|
|
|
|
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
|
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
|
@@ -165,19 +166,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
|
}
|
|
|
|
b = grub_efi_system_table->boot_services;
|
|
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
|
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
|
|
if (status != GRUB_EFI_SUCCESS)
|
|
{
|
|
+ grub_dprintf ("efi",
|
|
+ "allocate_pages(%d, %d, 0x%0lx, 0x%016lx) = 0x%016lx\n",
|
|
+ alloctype, memtype, pages, address, status);
|
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
|
return NULL;
|
|
}
|
|
|
|
- if (address == 0)
|
|
+ if (ret == 0)
|
|
{
|
|
/* Uggh, the address 0 was allocated... This is too annoying,
|
|
so reallocate another one. */
|
|
- address = GRUB_EFI_MAX_USABLE_ADDRESS;
|
|
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
|
+ ret = address;
|
|
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
|
|
grub_efi_free_pages (0, pages);
|
|
if (status != GRUB_EFI_SUCCESS)
|
|
{
|
|
@@ -186,9 +190,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
|
}
|
|
}
|
|
|
|
- grub_efi_store_alloc (address, pages);
|
|
+ grub_efi_store_alloc (ret, pages);
|
|
|
|
- return (void *) ((grub_addr_t) address);
|
|
+ return (void *) ((grub_addr_t) ret);
|
|
}
|
|
|
|
void *
|
|
@@ -699,8 +703,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
|
|
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
|
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
|
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
|
- if (desc->attribute & GRUB_EFI_MEMORY_WB)
|
|
- *base_addr = grub_min (*base_addr, desc->physical_start);
|
|
+ {
|
|
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY &&
|
|
+ (desc->attribute & GRUB_EFI_MEMORY_WB))
|
|
+ {
|
|
+ *base_addr = grub_min (*base_addr, desc->physical_start);
|
|
+ grub_dprintf ("efi", "setting base_addr=0x%016lx\n", *base_addr);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ grub_dprintf ("efi", "ignoring address 0x%016lx\n", desc->physical_start);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS)
|
|
+ grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr);
|
|
|
|
grub_free(memory_map);
|
|
|
|
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
|
|
index 4c0a09c06de..8791b35b6fe 100644
|
|
--- a/grub-core/loader/arm64/linux.c
|
|
+++ b/grub-core/loader/arm64/linux.c
|
|
@@ -71,13 +71,15 @@ finalize_params_linux (void)
|
|
{
|
|
grub_efi_loaded_image_t *loaded_image = NULL;
|
|
int node, retval, len;
|
|
-
|
|
+ grub_err_t err = GRUB_ERR_NONE;
|
|
void *fdt;
|
|
|
|
fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
|
-
|
|
if (!fdt)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
|
if (node < 0)
|
|
@@ -88,17 +90,26 @@ finalize_params_linux (void)
|
|
*/
|
|
retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
|
|
if (retval)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(retval, "Could not find #address-cells");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
|
|
if (retval)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(retval, "Could not find #size-cells");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
|
}
|
|
|
|
if (node < 1)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(grub_errno, "failed to load chosen fdt node.");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
/* Set initrd info */
|
|
if (initrd_start && initrd_end > initrd_start)
|
|
@@ -109,15 +120,26 @@ finalize_params_linux (void)
|
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
|
initrd_start);
|
|
if (retval)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(retval, "Failed to set linux,initrd-start property");
|
|
+ goto failure;
|
|
+ }
|
|
+
|
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
|
initrd_end);
|
|
if (retval)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(retval, "Failed to set linux,initrd-end property");
|
|
+ goto failure;
|
|
+ }
|
|
}
|
|
|
|
- if (grub_fdt_install() != GRUB_ERR_NONE)
|
|
- goto failure;
|
|
+ retval = grub_fdt_install();
|
|
+ if (retval != GRUB_ERR_NONE)
|
|
+ {
|
|
+ err = grub_error(retval, "Failed to install fdt");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
|
fdt);
|
|
@@ -125,14 +147,20 @@ finalize_params_linux (void)
|
|
/* Convert command line to UCS-2 */
|
|
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
|
if (!loaded_image)
|
|
- goto failure;
|
|
+ {
|
|
+ err = grub_error(grub_errno, "Failed to install fdt");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
loaded_image->load_options_size = len =
|
|
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
|
loaded_image->load_options =
|
|
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
|
if (!loaded_image->load_options)
|
|
- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
|
+ {
|
|
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
|
+ goto failure;
|
|
+ }
|
|
|
|
loaded_image->load_options_size =
|
|
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
|
@@ -142,7 +170,7 @@ finalize_params_linux (void)
|
|
|
|
failure:
|
|
grub_fdt_unload();
|
|
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
|
+ return err;
|
|
}
|
|
|
|
static void
|
|
@@ -226,16 +254,28 @@ grub_linux_unload (void)
|
|
static void *
|
|
allocate_initrd_mem (int initrd_pages)
|
|
{
|
|
- grub_addr_t max_addr;
|
|
+ grub_addr_t max_addr = 0;
|
|
+ grub_err_t err;
|
|
+ void *ret;
|
|
|
|
- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
|
- return NULL;
|
|
+ err = grub_efi_get_ram_base (&max_addr);
|
|
+ if (err != GRUB_ERR_NONE)
|
|
+ {
|
|
+ grub_error (err, "grub_efi_get_ram_base() failed");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n",
|
|
+ max_addr, INITRD_MAX_ADDRESS_OFFSET);
|
|
|
|
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
|
+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages);
|
|
|
|
- return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
|
- GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
|
- GRUB_EFI_LOADER_DATA);
|
|
+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
|
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
|
+ GRUB_EFI_LOADER_DATA);
|
|
+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret);
|
|
+ return ret;
|
|
}
|
|
|
|
static grub_err_t
|