From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LgnuG-0002f6-P6 for mharc-grub-devel@gnu.org; Mon, 09 Mar 2009 18:25:08 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LgnuC-0002dM-36 for grub-devel@gnu.org; Mon, 09 Mar 2009 18:25:04 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lgnu9-0002ca-Qh for grub-devel@gnu.org; Mon, 09 Mar 2009 18:25:03 -0400 Received: from [199.232.76.173] (port=49213 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lgnu9-0002cB-1v for grub-devel@gnu.org; Mon, 09 Mar 2009 18:25:01 -0400 Received: from mail-bw0-f172.google.com ([209.85.218.172]:55635) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Lgnu7-0003P2-6Y for grub-devel@gnu.org; Mon, 09 Mar 2009 18:25:00 -0400 Received: by bwz20 with SMTP id 20so1287941bwz.42 for ; Mon, 09 Mar 2009 15:24:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type; bh=GzXSrSwj8rhd+NYpFHFe/0+Qkv0bHAeHimiqyzzEolM=; b=BJ3H3V6sqGG7l3DPviVnBrvNK0wtDfqGgmwG/qJz/E1oiu8PzqCTdPogNQEfrYdUyP 6UW4DW7EWhZK+DnobLeqVw/TQAhftPS/HjQpfctLqu7Wycbp/EgHF39paZixffIayobJ qAH8tsO08fhdnP/I3zX5L1+S1FZZ/QsUVvGAc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type; b=XUM9q/3pgWl7ZVvjL+eWz1NKmksWhuxzmGSqU7NgGKRGkMB50oY9McwwH1CKKoMXpo gJOd1TtE4q/2F8PAmd9iipzjE4izFMwxkQPrqKRVdfOyfNy/y/8SrhWeeR8Xksyq8SYK LUSdZqQKCpF0zpaxtTUqgZB5RGH3xmvDeAfNw= Received: by 10.86.29.8 with SMTP id c8mr3129164fgc.2.1236637495594; Mon, 09 Mar 2009 15:24:55 -0700 (PDT) Received: from ?192.168.1.2? (160-169.3-85.cust.bluewin.ch [85.3.169.160]) by mx.google.com with ESMTPS id 12sm4219082fgg.33.2009.03.09.15.24.54 (version=SSLv3 cipher=RC4-MD5); Mon, 09 Mar 2009 15:24:55 -0700 (PDT) Message-ID: <49B59736.5000708@gmail.com> Date: Mon, 09 Mar 2009 23:24:54 +0100 From: phcoder User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------050209050809010109000509" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] Put multiboot module after the kernel X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Mar 2009 22:25:04 -0000 This is a multi-part message in MIME format. --------------050209050809010109000509 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Hello. Here is the patch to load the modules in the space after the kernel. This patch isn't meant to be commited right now because it breaks loading huge modules (and solaris relies on it). For clean solution I'm waiting for Vesa Jääskeläinen's new memory allocator Second reason is that command line for kernel, bootloader version, mbi and so on should also be allocated the same way as the memory for modules. I will do everything this once new memory allocator is available -- Regards Vladimir 'phcoder' Serbinenko --------------050209050809010109000509 Content-Type: text/x-patch; name="vsta.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="vsta.diff" Index: loader/i386/multiboot.c =================================================================== --- loader/i386/multiboot.c (revision 2023) +++ loader/i386/multiboot.c (working copy) @@ -42,16 +42,60 @@ #include #include #include #include #include +static grub_err_t +grub_multiboot_unload (void); + +static inline void * +grub_multiboot_relocated (void *orig) +{ + return (((char *) orig) - grub_multiboot_payload_orig + + grub_multiboot_payload_dest); +} + extern grub_dl_t my_mod; static struct grub_multiboot_info *mbi, *mbi_dest; -static grub_addr_t entry; +struct grub_mod_list *modlist = 0; static char *playground = NULL; +/* Allocate space from multiboot_payload aligned at ALIGN*/ +static char * +grub_multiboot_memalign (grub_size_t align, grub_size_t size) +{ + grub_size_t align_overhead; + grub_off_t mbioff = (char *)mbi - playground; + char *ret; + align_overhead = align - (grub_multiboot_payload_dest + + grub_multiboot_payload_size) % align; + if (align_overhead == align) + align_overhead = 0; + + playground = grub_realloc (playground, RELOCATOR_SIZEOF (forward) + + grub_multiboot_payload_size + align_overhead + + size); + if (!playground) + { + grub_multiboot_unload (); + return 0; + } + + grub_multiboot_payload_orig + = (grub_uint32_t) (playground + RELOCATOR_SIZEOF (forward)); + mbi = (struct grub_multiboot_info *) (playground + mbioff); + ret = playground + RELOCATOR_SIZEOF (forward) + + grub_multiboot_payload_size + align_overhead; + grub_multiboot_payload_size += align_overhead + size; + return ret; +} + static grub_err_t grub_multiboot_boot (void) { + struct grub_mod_list *modlist2; + grub_addr_t entry; + char *back_dest; + grub_stop_floppy (); + /* Dirty hack VSTa overwrites the page following last module so put module + index further */ + grub_multiboot_memalign (1, 1048576); + + modlist2 = (struct grub_mod_list *) + grub_multiboot_memalign (1, mbi->mods_count + * sizeof (struct grub_mod_list)); + if (!modlist2) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate space for module index"); + grub_memcpy (modlist2, modlist, mbi->mods_count + * sizeof (struct grub_mod_list)); + mbi->mods_addr = (grub_uint32_t) grub_multiboot_relocated (modlist2); + + back_dest = grub_multiboot_memalign (1, RELOCATOR_SIZEOF(backward)); + + if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) + { + grub_memmove (playground, &grub_multiboot_forward_relocator, + RELOCATOR_SIZEOF(forward)); + entry = (grub_addr_t) playground; + } + else + { + grub_memmove (back_dest, &grub_multiboot_backward_relocator, + RELOCATOR_SIZEOF(backward)); + grub_multiboot_payload_size -= RELOCATOR_SIZEOF(backward); + entry = (grub_addr_t) grub_multiboot_payload_orig + + grub_multiboot_payload_size; + } + grub_multiboot_real_boot (entry, mbi_dest); /* Not reached. */ @@ -61,21 +140,11 @@ grub_multiboot_boot (void) static grub_err_t grub_multiboot_unload (void) { - if (mbi) - { - unsigned int i; - for (i = 0; i < mbi->mods_count; i++) - { - grub_free ((void *) - ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start); - grub_free ((void *) - ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline); - } - grub_free ((void *) mbi->mods_addr); - grub_free ((void *) mbi->cmdline); - grub_free (mbi); - } - + grub_free (playground); + grub_free (modlist); + + playground = 0; + modlist = 0; mbi = 0; grub_dl_unref (my_mod); @@ -283,7 +352,9 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_size += load_size; grub_multiboot_payload_dest = header->load_addr; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); + playground = grub_malloc (RELOCATOR_SIZEOF(forward) + + grub_multiboot_payload_size + + RELOCATOR_SIZEOF(backward)); if (! playground) goto fail; @@ -318,19 +389,7 @@ grub_multiboot (int argc, char *argv[]) mbi->mmap_addr = mmap_addr (grub_multiboot_payload_dest); mbi->flags |= MULTIBOOT_INFO_MEM_MAP; - if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) - { - grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward)); - entry = (grub_addr_t) playground; - } - else - { - grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size), - &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward)); - entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size; - } - - grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n", + grub_dprintf ("multiboot_loader", "mbi_dest=%p, dest=%p, size=0x%x, entry_offset=0x%x\n", mbi_dest, (void *) grub_multiboot_payload_dest, grub_multiboot_payload_size, grub_multiboot_payload_entry_offset); @@ -385,6 +444,7 @@ grub_module (int argc, char *argv[]) grub_file_t file = 0; grub_ssize_t size, len = 0; char *module = 0, *cmdline = 0, *p; + grub_uint32_t moduledest, cmdlinedest; int i; if (argc == 0) @@ -400,27 +460,13 @@ grub_module (int argc, char *argv[]) goto fail; } - file = grub_gzfile_open (argv[0], 1); - if (! file) - goto fail; - - size = grub_file_size (file); - module = grub_memalign (MULTIBOOT_MOD_ALIGN, size); - if (! module) - goto fail; - - if (grub_file_read (file, module, size) != size) - { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); - goto fail; - } - for (i = 0; i < argc; i++) len += grub_strlen (argv[i]) + 1; - cmdline = p = grub_malloc (len); + cmdline = p = grub_multiboot_memalign (1, len); if (! cmdline) goto fail; + cmdlinedest = (grub_uint32_t) grub_multiboot_relocated (cmdline); for (i = 0; i < argc; i++) { @@ -431,33 +477,46 @@ grub_module (int argc, char *argv[]) /* Remove the space after the last word. */ *(--p) = '\0'; + file = grub_gzfile_open (argv[0], 1); + if (! file) + goto fail; + + /* Specification doesn't require modules to be page-aligned however grub1 + does it and we want maximal compatibility */ + size = grub_file_size (file); + module = grub_multiboot_memalign (MULTIBOOT_MOD_ALIGN, size); + if (! module) + goto fail; + moduledest = (grub_uint32_t) grub_multiboot_relocated (module); + + if (grub_file_read (file, module, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + if (mbi->flags & MULTIBOOT_INFO_MODS) { - struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr; - modlist = grub_realloc (modlist, (mbi->mods_count + 1) * sizeof (struct grub_mod_list)); if (! modlist) goto fail; - mbi->mods_addr = (grub_uint32_t) modlist; - modlist += mbi->mods_count; - modlist->mod_start = (grub_uint32_t) module; - modlist->mod_end = (grub_uint32_t) module + size; - modlist->cmdline = (grub_uint32_t) cmdline; - modlist->pad = 0; + modlist[mbi->mods_count].mod_start = moduledest; + modlist[mbi->mods_count].mod_end = moduledest + size; + modlist[mbi->mods_count].cmdline = cmdlinedest; + modlist[mbi->mods_count].pad = 0; mbi->mods_count++; } else { - struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list)); + modlist = grub_malloc (sizeof (struct grub_mod_list)); if (! modlist) goto fail; - modlist->mod_start = (grub_uint32_t) module; - modlist->mod_end = (grub_uint32_t) module + size; - modlist->cmdline = (grub_uint32_t) cmdline; + modlist->mod_start = moduledest; + modlist->mod_end = moduledest + size; + modlist->cmdline = cmdlinedest; modlist->pad = 0; mbi->mods_count = 1; - mbi->mods_addr = (grub_uint32_t) modlist; mbi->flags |= MULTIBOOT_INFO_MODS; } @@ -465,9 +524,4 @@ grub_module (int argc, char *argv[]) if (file) grub_file_close (file); - if (grub_errno != GRUB_ERR_NONE) - { - grub_free (module); - grub_free (cmdline); - } } Index: ChangeLog =================================================================== --- ChangeLog (revision 2023) +++ ChangeLog (working copy) @@ -1,3 +1,14 @@ +2009-03-10 Vladimir Serbinenko + + Put multiboot modules directly after the kernel + + * loader/i386/multiboot.c (grub_multiboot_relocated): new function + (grub_multiboot_memalign): likewise + (grub_multiboot_boot): finalise multiboot index and copy relocator + (grub_multiboot_unload): don't free pointers in playground + (grub_multiboot): defer copying relocator + (grub_module): use new allocator functions + 2009-03-09 Felix Zielcke * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove duplicated --------------050209050809010109000509--