]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Reduce memory footprint on SGI by putting modules before the kernel
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 17 May 2011 19:15:54 +0000 (21:15 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 17 May 2011 19:15:54 +0000 (21:15 +0200)
as opposed to after.

* grub-core/Makefile.core.def (kernel): Increase linking address.
(none_decompress): Likewise.
(xz_decompress): Likewise.
* grub-core/boot/mips/startup_raw.S: Use prewritten uncompression
address.
* grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory
layout change.
(grub_arch_modules_addr): New function.
* grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here...
* grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here
* grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and
here.
* grub-core/kern/mips/startup.S (total_size): Rename to ...
(grub_total_modules_size): ... this. Make global.
[GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss.
* include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR):
New definition.
(GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise.
(GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise.
(GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise.
(GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased.
* util/grub-mkimage.c (image_target_desc): New flag
PLATFORM_FLAGS_MODULES_BEFORE_KERNEL.
(image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc.
(generate_image): Handle images with modules before kernel.

ChangeLog
grub-core/Makefile.core.def
grub-core/boot/mips/startup_raw.S
grub-core/kern/mips/arc/init.c
grub-core/kern/mips/init.c
grub-core/kern/mips/loongson/init.c
grub-core/kern/mips/qemu_mips/init.c
grub-core/kern/mips/startup.S
include/grub/offsets.h
util/grub-mkimage.c

index d1f01e727871ecce0b9d506dbed1ba8b32f537fe..bf7d7d110e7d20bba00d686717754212de7b0989 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2011-05-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Reduce memory footprint on SGI by putting modules before the kernel
+       as opposed to after.
+
+       * grub-core/Makefile.core.def (kernel): Increase linking address.
+       (none_decompress): Likewise.
+       (xz_decompress): Likewise.
+       * grub-core/boot/mips/startup_raw.S: Use prewritten uncompression
+       address.
+       * grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory
+       layout change.
+       (grub_arch_modules_addr): New function.
+       * grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here...
+       * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here
+       * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and
+       here.
+       * grub-core/kern/mips/startup.S (total_size): Rename to ...
+       (grub_total_modules_size): ... this. Make global.
+       [GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss.
+       * include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR):
+       New definition.
+       (GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise.
+       (GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise.
+       (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise.
+       (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased.
+       * util/grub-mkimage.c (image_target_desc): New flag
+       PLATFORM_FLAGS_MODULES_BEFORE_KERNEL.
+       (image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc.
+       (generate_image): Handle images with modules before kernel.
+
 2011-05-17  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Prevent potential loss of memory map by overwrite on qemu-mips.
index 1c0b530a1b4573a818a3bea2857ff63348127429..c717167cb718ceea6f09166e33bcc5b4b816d574 100644 (file)
@@ -41,7 +41,7 @@ kernel = {
   mips_loongson_ldflags    = '-Wl,-Ttext,0x80200000';
   powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
   sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
-  mips_arc_ldflags    = '-Wl,-Ttext,0x8a000000';
+  mips_arc_ldflags    = '-Wl,-Ttext,0x8bd00000';
   mips_qemu_mips_ldflags    = '-Wl,-Ttext,0x80200000';
 
   mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK';
@@ -324,7 +324,7 @@ image = {
   objcopyflags = '-O binary';
   mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
   mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
-  mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000';
+  mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
   ldadd = '-lgcc';
   cflags = '-static-libgcc';
   enable = mips;
@@ -340,7 +340,7 @@ image = {
   objcopyflags = '-O binary';
   mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
   mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
-  mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000';
+  mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
   ldadd = '-lgcc';
   cflags = '-static-libgcc';
   enable = mips;
index 65a2dd59ea3f79046f4dd1a3c789098731ddd4ac..e6dfadaf9cc5b759293a3c25756f924e74a109bd 100644 (file)
@@ -44,6 +44,9 @@ compressed_size:
        . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
 uncompressed_size:
        .long 0
+       . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR
+uncompressed_addr:
+       .long 0
 codestart:
        /* Save our base.  */
        move $s0, $ra
@@ -221,8 +224,7 @@ cmdlinedone:
        subu $a0, $a0, $t0
        addu $a0, $a0, $s0
 
-       lui $a1, %hi(GRUB_MACHINE_LINK_ADDR)
-       addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR)
+       lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
        lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
        lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
        move $s1, $a1
index 8ee965d74ecef82089225852aea91ad11485ae9a..514b481f6338b122700600eb0c6030e8066639bd 100644 (file)
@@ -124,6 +124,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
     }
 }
 
+extern grub_uint32_t grub_total_modules_size;
+
 void
 grub_machine_init (void)
 {
@@ -148,8 +150,10 @@ grub_machine_init (void)
       start = ((grub_uint64_t) cur->start_page) << 12;
       end = ((grub_uint64_t) cur->num_pages)  << 12;
       end += start;
-      if ((grub_uint64_t) end > (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff))
-       end = (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff);
+      if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR
+                                 - grub_total_modules_size) & 0x1fffffff))
+       end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size)
+              & 0x1fffffff);
       if (end > start)
        grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000),
                             end - start);
@@ -160,6 +164,12 @@ grub_machine_init (void)
   grub_arcdisk_init ();
 }
 
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size;
+}
+
 void
 grub_machine_fini (void)
 {
index 3b08d5606b062d922ce88e0102e07bdc0f65c1c0..bfa08f56a9eafb8d03348b63643141ce11fc6a28 100644 (file)
@@ -42,11 +42,3 @@ grub_machine_set_prefix (void)
 {
   grub_env_set ("prefix", grub_prefix);
 }
-
-extern char _end[];
-
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  return (grub_addr_t) _end;
-}
index f0f5c587456e70fca021d3595fdbb63b67d7bf47..bcef391b96fb5e6927a4a43a42866c918f144f63 100644 (file)
@@ -257,3 +257,10 @@ grub_reboot (void)
   while (1);
 }
 
+extern char _end[];
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return (grub_addr_t) _end;
+}
index e426b833dc66063fa64f8d4f89d5bdad652e7b74..2180b347aa5a3d69080de2bd8113b40eeff20413 100644 (file)
@@ -60,3 +60,11 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
   hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE);
   return GRUB_ERR_NONE;
 }
+
+extern char _end[];
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return (grub_addr_t) _end;
+}
index 2654d744efd45cb968027818eefafa31e3c38ef4..6220a8c331f5c708dd55108855cb5c6f8e5dbb96 100644 (file)
@@ -37,7 +37,7 @@ start:
         nop
 
        . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
-total_module_size:
+VARIABLE(grub_total_modules_size)
        .long 0
 
        . = _start + GRUB_KERNEL_MACHINE_PREFIX
@@ -84,6 +84,7 @@ cont:
 #endif
 
        /* Move the modules out of BSS.  */
+#ifndef GRUB_MACHINE_ARC
        lui $t2, %hi(__bss_start)
        addiu $t2, %lo(__bss_start)
        
@@ -113,6 +114,7 @@ modulesmovcont:
        b modulesmovcont
         addiu $t3, $t3, -1
 modulesmovdone:
+#endif
 
        /* Clean BSS.  */
        
index 40c8a016b5d75535facd2ccfedea9c8aa11d1638..af724096d7161c8fa96681904132fc758f3a5d6c 100644 (file)
 
 #define GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE          0x8
 #define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE        0xc
+#define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR        0x10
 
 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE    0x08
 #define GRUB_KERNEL_MIPS_LOONGSON_PREFIX               0x0c
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN  32
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE          0x8
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE        0xc
+#define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR        0x10
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE   0x08
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX              0x0c
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END          0x54
 
-#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR         0x8a000000
+#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR         0x8bd00000
 
 #define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN  32
 
 #define GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE          0x8
 #define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE        0xc
+#define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR        0x10
 
 #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08
 #define GRUB_KERNEL_MIPS_ARC_PREFIX            0x0c
 #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _KERNEL_IMAGE_SIZE)
 #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _COMPRESSED_SIZE)
 #define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_SIZE)
+#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_ADDR)
 
 #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX)
 #define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX_END)
index 5f35c1da00e0a2f212e0f42d0f462aeaf3f63fe2..5ae744a8e3f45f876f2b1f4de3b2a34e9996a841 100644 (file)
@@ -73,7 +73,8 @@ struct image_target_desc
     {
       PLATFORM_FLAGS_NONE = 0,
       PLATFORM_FLAGS_LZMA = 1,
-      PLATFORM_FLAGS_DECOMPRESSORS = 2
+      PLATFORM_FLAGS_DECOMPRESSORS = 2,
+      PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4,
     } flags;
   unsigned prefix;
   unsigned prefix_end;
@@ -426,7 +427,8 @@ struct image_target_desc image_targets[] =
       .voidp_sizeof = 4,
       .bigendian = 1,
       .id = IMAGE_MIPS_ARC, 
-      .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+      .flags = (PLATFORM_FLAGS_DECOMPRESSORS
+               | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL),
       .prefix = GRUB_KERNEL_MIPS_ARC_PREFIX,
       .prefix_end = GRUB_KERNEL_MIPS_ARC_PREFIX_END,
       .raw_size = 0,
@@ -781,27 +783,47 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
     grub_util_error (_("prefix is too long"));
   strcpy (kernel_img + image_target->prefix, prefix);
 
+  if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+      && (image_target->total_module_size != TARGET_NO_FIELD))
+    *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
+      = grub_host_to_target32 (total_module_size);
+
+  if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+    memmove (kernel_img + total_module_size, kernel_img, kernel_size);
+
   if (image_target->voidp_sizeof == 8)
     {
       /* Fill in the grub_module_info structure.  */
       struct grub_module_info64 *modinfo;
-      modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size);
+      if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+       modinfo = (struct grub_module_info64 *) kernel_img;
+      else
+       modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size);
       memset (modinfo, 0, sizeof (struct grub_module_info64));
       modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
       modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64));
       modinfo->size = grub_host_to_target_addr (total_module_size);
-      offset = kernel_size + sizeof (struct grub_module_info64);
+      if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+       offset = sizeof (struct grub_module_info64);
+      else
+       offset = kernel_size + sizeof (struct grub_module_info64);
     }
   else
     {
       /* Fill in the grub_module_info structure.  */
       struct grub_module_info32 *modinfo;
-      modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size);
+      if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+       modinfo = (struct grub_module_info32 *) kernel_img;
+      else
+       modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size);
       memset (modinfo, 0, sizeof (struct grub_module_info32));
       modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
       modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32));
       modinfo->size = grub_host_to_target_addr (total_module_size);
-      offset = kernel_size + sizeof (struct grub_module_info32);
+      if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+       offset = sizeof (struct grub_module_info32);
+      else
+       offset = kernel_size + sizeof (struct grub_module_info32);
     }
 
   for (p = path_list; p; p = p->next)
@@ -852,26 +874,27 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
       offset += config_size;
     }
 
-  if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
-      && (image_target->total_module_size != TARGET_NO_FIELD))
-    *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
-      = grub_host_to_target32 (total_module_size);
-
   grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
   compress_kernel (image_target, kernel_img, kernel_size + total_module_size,
                   &core_img, &core_size, comp);
+  free (kernel_img);
+
+  if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+    kernel_img = core_img + total_module_size;
+  else
+    kernel_img = core_img;
 
   grub_util_info ("the core size is 0x%x", core_size);
 
   if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) 
       && image_target->total_module_size != TARGET_NO_FIELD)
-    *((grub_uint32_t *) (core_img + image_target->total_module_size))
+    *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
       = grub_host_to_target32 (total_module_size);
   if (image_target->kernel_image_size != TARGET_NO_FIELD)
-    *((grub_uint32_t *) (core_img + image_target->kernel_image_size))
+    *((grub_uint32_t *) (kernel_img + image_target->kernel_image_size))
       = grub_host_to_target32 (kernel_size);
   if (image_target->compressed_size != TARGET_NO_FIELD)
-    *((grub_uint32_t *) (core_img + image_target->compressed_size))
+    *((grub_uint32_t *) (kernel_img + image_target->compressed_size))
       = grub_host_to_target32 (core_size - image_target->raw_size);
 
   /* If we included a drive in our prefix, let GRUB know it doesn't have to
@@ -879,9 +902,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
   if (image_target->install_dos_part != TARGET_NO_FIELD
       && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(')
     {
-      *((grub_int32_t *) (core_img + image_target->install_dos_part))
+      *((grub_int32_t *) (kernel_img + image_target->install_dos_part))
        = grub_host_to_target32 (-2);
-      *((grub_int32_t *) (core_img + image_target->install_bsd_part))
+      *((grub_int32_t *) (kernel_img + image_target->install_bsd_part))
        = grub_host_to_target32 (-2);
     }
 
@@ -915,6 +938,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
       *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE))
        = grub_host_to_target32 (kernel_size + total_module_size);
 
+      if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+       *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR))
+         = grub_host_to_target_addr (image_target->link_addr - total_module_size);
+      else
+       *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR))
+         = grub_host_to_target_addr (image_target->link_addr);
+
       full_size = core_size + decompress_size;
 
       full_img = xmalloc (full_size);
@@ -1199,7 +1229,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
        rom_img = xmalloc (rom_size);
        memset (rom_img, 0, rom_size);
 
-       *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
+       *((grub_int32_t *) (kernel_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
          = grub_host_to_target32 ((grub_uint32_t) -rom_size);
 
        memcpy (rom_img, core_img, core_size);
@@ -1380,8 +1410,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
        size_t program_size;
 
        program_size = ALIGN_ADDR (core_size);
-       target_addr = image_target->link_addr - ALIGN_UP(program_size, 1048576)
-         - (1 << 20);
+       target_addr = (image_target->link_addr 
+                      - ALIGN_UP(total_module_size + core_size, 1048576)
+                      - (1 << 20));
 
        ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section));
        grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section));
@@ -1553,7 +1584,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
     }
 
   grub_util_write_image (core_img, core_size, out);
-  free (kernel_img);
   free (core_img);
   free (kernel_path);