grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/3] grub efi memory map patch


From: bibo,mao
Subject: [PATCH 1/3] grub efi memory map patch
Date: Tue, 24 Oct 2006 14:58:43 +0800
User-agent: Thunderbird 1.5.0.7 (Windows/20060909)

This patch moves find_mmap_size from i386/efi/linux.c to
kern/efi/mm.c, and renamed as grub_efi_find_mmap_size, so that
other arch on EFI platform can use this function.

Also this function solves memory map too small problem,
on some EFI platform MEMORY_MAP_SIZE(0x1000) is a little smaller
than EFI memory map table.

any suggestion is welcome.

thanks
bibo,mao


diff -Nruap grub2.org/include/grub/efi/api.h grub2/include/grub/efi/api.h
--- grub2.org/include/grub/efi/api.h    2006-10-24 13:05:48.000000000 +0800
+++ grub2/include/grub/efi/api.h        2006-10-23 14:35:12.000000000 +0800
@@ -206,6 +206,13 @@ typedef grub_efi_intn_t grub_efi_status_
#define GRUB_EFI_WARN_WRITE_FAILURE     GRUB_EFI_WARNING_CODE (3)
#define GRUB_EFI_WARN_BUFFER_TOO_SMALL  GRUB_EFI_WARNING_CODE (4)

+#define GRUB_EFI_PAGE_SHIFT            12
+#define GRUB_EFI_PAGE_SIZE             (0x1UL << GRUB_EFI_PAGE_SHIFT)
+#define GRUB_EFI_PAGES(addr)           (addr >> GRUB_EFI_PAGE_SHIFT)
+#define GRUB_EFI_PAGES_UP(addr)        ((addr + GRUB_EFI_PAGE_SIZE - 1) >> 
GRUB_EFI_PAGE_SHIFT)
+#define PAGE_DOWN(addr)                ((addr) & (~(GRUB_EFI_PAGE_SIZE - 1)))
+#define PAGE_UP(addr)                  PAGE_DOWN(addr + GRUB_EFI_PAGE_SIZE - 1)
+
typedef void *grub_efi_handle_t;
typedef void *grub_efi_event_t;
typedef grub_efi_uint64_t grub_efi_lba_t;
diff -Nruap grub2.org/include/grub/efi/efi.h grub2/include/grub/efi/efi.h
--- grub2.org/include/grub/efi/efi.h    2006-10-24 13:05:48.000000000 +0800
+++ grub2/include/grub/efi/efi.h        2006-10-23 14:42:48.000000000 +0800
@@ -55,6 +55,7 @@ char *EXPORT_FUNC(grub_efi_get_filename)
grub_efi_device_path_t *
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void);

void grub_efi_mm_init (void);
void grub_efi_mm_fini (void);
diff -Nruap grub2.org/kern/efi/mm.c grub2/kern/efi/mm.c
--- grub2.org/kern/efi/mm.c     2006-10-24 13:05:48.000000000 +0800
+++ grub2/kern/efi/mm.c 2006-10-24 13:18:48.000000000 +0800
@@ -30,10 +30,6 @@
#define BYTES_TO_PAGES(bytes)   ((bytes) >> 12)
#define PAGES_TO_BYTES(pages)   ((pages) << 12)

-/* The size of a memory map obtained from the firmware. This must be
-   a multiplier of 4KB.  */
-#define MEMORY_MAP_SIZE        0x1000
-
/* Maintain the list of allocated pages.  */
struct allocated_page
{
@@ -335,6 +331,45 @@ print_memory_map (grub_efi_memory_descri
}
#endif

+/* Find the optimal number of pages for the memory map. */
+grub_efi_uintn_t
+grub_efi_find_mmap_size (void)
+{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0)
+    return mmap_size;
+ + mmap_size = GRUB_EFI_PAGE_SIZE;
+  while (1)
+    {
+      int ret;
+      grub_efi_memory_descriptor_t *mmap;
+      grub_efi_uintn_t desc_size;
+ + mmap = grub_efi_allocate_pages ( 0, GRUB_EFI_PAGES_UP(mmap_size));
+      if (! mmap)
+        return 0;
+ + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      grub_efi_free_pages ((grub_addr_t) mmap, GRUB_EFI_PAGES_UP(mmap_size));
+ + if (ret < 0)
+        grub_fatal ("cannot get memory map");
+      else if (ret > 0)
+        break;
+ + mmap_size += GRUB_EFI_PAGE_SIZE;
+    }
+ + /* Increase the size a bit for safety, because GRUB allocates more on
+     later, and EFI itself may allocate more.  */
+  mmap_size += GRUB_EFI_PAGE_SIZE;
+  mmap_size = PAGE_UP(mmap_size);
+ + return mmap_size;
+}
+
void
grub_efi_mm_init (void)
{
@@ -346,6 +381,8 @@ grub_efi_mm_init (void)
  grub_efi_uintn_t desc_size;
  grub_efi_uint64_t total_pages;
  grub_efi_uint64_t required_pages;
+  grub_efi_uintn_t memory_map_size;
+  int res;

  /* First of all, allocate pages to maintain allocations.  */
  allocated_pages
@@ -355,16 +392,20 @@ grub_efi_mm_init (void)

  grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
- /* Prepare a memory region to store two memory maps. */
-  memory_map = grub_efi_allocate_pages (0,
-                                       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+  /* Prepare a memory region to store two memory maps.  Obtain size of
+     memory map by passing a NULL buffer and a buffer size of
+     zero.  */
+  memory_map_size = grub_efi_find_mmap_size( );
+  memory_map = grub_efi_allocate_pages(0, 2 * PAGE_UP(memory_map_size));
+
  if (! memory_map)
    grub_fatal ("cannot allocate memory");

-  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+ filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, + PAGE_UP(memory_map_size));

  /* Obtain descriptors for available memory.  */
-  map_size = MEMORY_MAP_SIZE;
+  map_size = memory_map_size;

  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
    grub_fatal ("cannot get memory map");
@@ -405,8 +446,7 @@ grub_efi_mm_init (void)
#endif
/* Release the memory maps. */
-  grub_efi_free_pages ((grub_addr_t) memory_map,
-                      2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+  grub_efi_free_pages ((grub_addr_t) memory_map, 2 * PAGE_UP(memory_map_size));
}

void
diff -Nruap grub2.org/loader/i386/efi/linux.c grub2/loader/i386/efi/linux.c
--- grub2.org/loader/i386/efi/linux.c   2006-10-24 13:06:56.000000000 +0800
+++ grub2/loader/i386/efi/linux.c       2006-10-23 14:42:48.000000000 +0800
@@ -93,45 +93,6 @@ page_align (grub_size_t size)
  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
}

-/* Find the optimal number of pages for the memory map. Is it better to
-   move this code to efi/mm.c?  */
-static grub_efi_uintn_t
-find_mmap_size (void)
-{
-  static grub_efi_uintn_t mmap_size = 0;
-
-  if (mmap_size != 0)
-    return mmap_size;
- - mmap_size = (1 << 12);
-  while (1)
-    {
-      int ret;
-      grub_efi_memory_descriptor_t *mmap;
-      grub_efi_uintn_t desc_size;
- - mmap = grub_malloc (mmap_size);
-      if (! mmap)
-       return 0;
-
-      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
-      grub_free (mmap);
- - if (ret < 0)
-       grub_fatal ("cannot get memory map");
-      else if (ret > 0)
-       break;
-
-      mmap_size += (1 << 12);
-    }
-
-  /* Increase the size a bit for safety, because GRUB allocates more on
-     later, and EFI itself may allocate more.  */
-  mmap_size += (1 << 12);
-
-  return page_align (mmap_size);
-}
-
static void
free_pages (void)
{
@@ -167,7 +128,7 @@ allocate_pages (grub_size_t real_size, g
  /* Make sure that each size is aligned to a page boundary.  */
  real_size = page_align (real_size + GRUB_DISK_SECTOR_SIZE);
  prot_size = page_align (prot_size);
-  mmap_size = find_mmap_size ();
+  mmap_size = grub_efi_find_mmap_size ();

  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
                real_size, prot_size, mmap_size);
@@ -275,7 +236,7 @@ grub_linux_boot (void)
  grub_dprintf ("linux", "idt = %x:%x, gdt = %x:%x\n",
                (unsigned) idt_desc.limit, (unsigned) idt_desc.base,
                (unsigned) gdt_desc.limit, (unsigned) gdt_desc.base);
-  mmap_size = find_mmap_size ();
+  mmap_size = grub_efi_find_mmap_size ();
  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
                               &desc_size, &desc_version) <= 0)
    grub_fatal ("cannot get memory map");
@@ -616,7 +577,7 @@ grub_rescue_cmd_initrd (int argc, char *
  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12);
/* Find the highest address to put the initrd. */
-  mmap_size = find_mmap_size ();
+  mmap_size = grub_efi_find_mmap_size ();
  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
    grub_fatal ("cannot get memory map");





reply via email to

[Prev in Thread] Current Thread [Next in Thread]