Hi,

> > but not on arm.
> > So that should be fixable without too much effort.
> 
> I guess so.
> 
> I'll mention though that "just" for passing in the initrd, the DTB
> shouldn't be necessary, at least if the kernel is built with the EFI
> stub. Then "initrd=filename" can be passed on the kernel command line,
> and the EFI stub should load it, using UEFI services, from the same
> directory that the vmlinuz binary (= itself) came from.

Well, the kernel command line is passed via fdt too ...

Anyway, it's working.

cheers,
  Gerd

From 91c1e9a92a75e34da3aad8184b298654b30cdf6f Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kra...@redhat.com>
Date: Thu, 14 Jul 2016 08:16:06 +0200
Subject: [PATCH 1/2] arm: lookup devicetree via efi

arm64 already does this, arm should support it too.

Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 grub-core/loader/arm/linux.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index 5b39f02..106cfc3 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -221,6 +221,31 @@ failure:
   return grub_error (GRUB_ERR_BAD_ARGUMENT, "unable to prepare FDT");
 }
 
+#ifdef GRUB_MACHINE_EFI
+/* from ../arm64/fdt.c */
+static void *
+get_firmware_fdt (void)
+{
+  grub_efi_configuration_table_t *tables;
+  grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
+  void *firmware_fdt = NULL;
+  unsigned int i;
+
+  /* Look for FDT in UEFI config tables. */
+  tables = grub_efi_system_table->configuration_table;
+
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
+      {
+        firmware_fdt = tables[i].vendor_table;
+        grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
+        break;
+      }
+
+  return firmware_fdt;
+}
+#endif
+
 static grub_err_t
 linux_boot (void)
 {
@@ -237,6 +262,23 @@ linux_boot (void)
 		(char *) fdt_addr,
 		(char *) fdt_addr + 1);
 
+#ifdef GRUB_MACHINE_EFI
+  if (!fdt_valid) {
+    void *ptr = get_firmware_fdt();
+    int size = ptr ? grub_fdt_get_totalsize(ptr) : 0;
+    int extra = grub_strlen (linux_args) + 0x100;
+    if (ptr && size) {
+      fdt_addr = grub_efi_allocate_loader_memory (LINUX_FDT_PHYS_OFFSET, size + extra);
+      if (fdt_addr) {
+        grub_memcpy (fdt_addr, ptr, size);
+        fdt_valid = (fdt_addr && grub_fdt_check_header_nosize (fdt_addr) == 0);
+        grub_dprintf ("loader", "firmware fdt: memcpy(%p, %p, %d)\n",
+                      fdt_addr, ptr, size);
+      }
+    }
+  }
+#endif
+
   if (!fdt_valid && machine_type == GRUB_ARM_MACHINE_TYPE_FDT)
     return grub_error (GRUB_ERR_FILE_NOT_FOUND,
 		       N_("device tree must be supplied (see `devicetree' command)"));
-- 
1.8.3.1

From b311f8043c5718018c6d361092524d74208c458a Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kra...@redhat.com>
Date: Tue, 19 Jul 2016 14:14:26 +0200
Subject: [PATCH 2/2] arm: make room for larger devicetree

"qemu-system-arm -M virt" devicetree is > 64k.
Make sure we have enough space for it.

Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 grub-core/loader/arm/linux.c | 2 ++
 include/grub/arm/linux.h     | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index 106cfc3..5ac0014 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -49,9 +49,11 @@ typedef void (*kernel_entry_t) (int, unsigned long, void *);
 #define LINUX_ZIMAGE_OFFSET	0x24
 #define LINUX_ZIMAGE_MAGIC	0x016f2818
 
+#if 0 /* declared in include/grub/arm/linux.h */
 #define LINUX_PHYS_OFFSET        (0x00008000)
 #define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x02000000)
 #define LINUX_FDT_PHYS_OFFSET    (LINUX_INITRD_PHYS_OFFSET - 0x10000)
+#endif
 
 static grub_size_t
 get_atag_size (grub_uint32_t *atag)
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index 059dbba..deb8a9c 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -37,9 +37,9 @@
 # include <grub/machine/loader.h>
 /* On UEFI platforms - load the images at the lowest available address not
    less than *_PHYS_OFFSET from the first available memory location. */
-# define LINUX_PHYS_OFFSET        (0x00008000)
+# define LINUX_PHYS_OFFSET        (0x00020000)
 # define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x02000000)
-# define LINUX_FDT_PHYS_OFFSET    (LINUX_INITRD_PHYS_OFFSET - 0x10000)
+# define LINUX_FDT_PHYS_OFFSET    (LINUX_INITRD_PHYS_OFFSET - 0x20000)
 static inline grub_addr_t
 grub_arm_firmware_get_boot_data (void)
 {
-- 
1.8.3.1

Reply via email to