From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 19:15:54 +0000 (+0200) Subject: Reduce memory footprint on SGI by putting modules before the kernel X-Git-Tag: 2.00~1245 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b772baedcd8ef2a995f4bb0fc8ebc9157c21e9b7;p=thirdparty%2Fgrub.git 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. --- diff --git a/ChangeLog b/ChangeLog index d1f01e727..bf7d7d110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2011-05-17 Vladimir Serbinenko + + 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 Prevent potential loss of memory map by overwrite on qemu-mips. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 1c0b530a1..c717167cb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -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; diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 65a2dd59e..e6dfadaf9 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -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 diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 8ee965d74..514b481f6 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -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) { diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c index 3b08d5606..bfa08f56a 100644 --- a/grub-core/kern/mips/init.c +++ b/grub-core/kern/mips/init.c @@ -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; -} diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index f0f5c5874..bcef391b9 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -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; +} diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index e426b833d..2180b347a 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -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; +} diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 2654d744e..6220a8c33 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -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. */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 40c8a016b..af724096d 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -106,6 +106,7 @@ #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 @@ -115,16 +116,18 @@ #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 @@ -187,6 +190,7 @@ #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) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 5f35c1da0..5ae744a8e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -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);