From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1NU279-0000Hd-St for mharc-grub-devel@gnu.org; Sun, 10 Jan 2010 13:02:11 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NU278-0000HB-6e for grub-devel@gnu.org; Sun, 10 Jan 2010 13:02:10 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NU273-0000Gu-Mw for grub-devel@gnu.org; Sun, 10 Jan 2010 13:02:09 -0500 Received: from [199.232.76.173] (port=48339 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NU273-0000Gq-Jg for grub-devel@gnu.org; Sun, 10 Jan 2010 13:02:05 -0500 Received: from mail-bw0-f215.google.com ([209.85.218.215]:61773) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NU272-0006UY-5q for grub-devel@gnu.org; Sun, 10 Jan 2010 13:02:05 -0500 Received: by bwz7 with SMTP id 7so14343563bwz.26 for ; Sun, 10 Jan 2010 10:01:59 -0800 (PST) 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:x-enigmail-version:content-type; bh=dtfmJZMOd1gefa7Fo3tg7HU5GPTN0dVDntgJDkFN+cw=; b=YNdC2fBMn0ZoD1J59VlB7h27S1XKCTC+m5HFcfV0P6OI85lJHy2vTYzpZ5573u+sK6 Gs/Sst2kGXjU0Frp8cV7r0F10aL9xb+IhwTDISEx1DKCq6bmhSLafGm0ElndmKhGfoOA yAha+5HMMTHnc3rKL69Z0ruBk0AHHBSiVUMOI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :x-enigmail-version:content-type; b=YJxl0YgzP9zp+BZy1CQUbmFfeHkGsMceaPgXNwsCASNUCn3glNESGsSjmuC3ea1hl5 qtoacdyOHv3LFdZ8g6VEp8xiN16jE38P/vo/pycnE6O15ufvPc7z1czlEy/x2mtBCIzF tYeaqXMs1avmNryE4wfuLAp8jGxAtkFivT1uY= Received: by 10.204.6.5 with SMTP id 5mr1912340bkx.167.1263146518942; Sun, 10 Jan 2010 10:01:58 -0800 (PST) Received: from debian.bg45.phnet (155-68.2-85.cust.bluewin.ch [85.2.68.155]) by mx.google.com with ESMTPS id 16sm8481459bwz.7.2010.01.10.10.01.55 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 10 Jan 2010 10:01:56 -0800 (PST) Message-ID: <4B4A160B.6010908@gmail.com> Date: Sun, 10 Jan 2010 19:01:47 +0100 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20091109) MIME-Version: 1.0 To: The development of GRUB 2 X-Enigmail-Version: 0.95.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig267AAA1C4BDCA6918A7D025E" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] Manipulate mbi in abstract way X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 18:02:10 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig267AAA1C4BDCA6918A7D025E Content-Type: multipart/mixed; boundary="------------070502020404080300010200" This is a multi-part message in MIME format. --------------070502020404080300010200 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable It cleans up some mess in grub_multiboot and allows easier code sharing with upcomming tagged mbi --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------070502020404080300010200 Content-Type: text/x-diff; name="abstractmbi.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="abstractmbi.diff" =3D=3D=3D added file 'ChangeLog.abstractmbi' --- ChangeLog.abstractmbi 1970-01-01 00:00:00 +0000 +++ ChangeLog.abstractmbi 2010-01-10 16:11:01 +0000 @@ -0,0 +1,25 @@ +2010-01-10 Vladimir Serbinenko + + * conf/i386-coreboot.rmk (multiboot_mod_SOURCES): + Add loader/i386/multiboot_mbi.c. + (multiboot2_mod_SOURCES): Likewise. + * conf/i386-pc.rmk (multiboot_mod_SOURCES): Likewise. + (multiboot2_mod_SOURCES): Likewise. + * include/grub/multiboot.h (grub_multiboot_get_mbi_size): New proto. + (grub_multiboot_make_mbi): Likewise. + (grub_multiboot_free_mbi): Likewise. + (grub_multiboot_init_mbi): Likewise. + (grub_multiboot_add_module): Likewise. + (grub_multiboot_set_bootdev): Likewise. + * loader/i386/multiboot.c (mbi): Removed. + (mbi_dest): Likewise. + (alloc_mbi): New variable. + (grub_multiboot_payload_size): Removed. All users updated. + (grub_multiboot_pure_size): New variable. + (grub_multiboot_boot): Use grub_multiboot_make_mbi. + (grub_multiboot_unload): Use grub_multiboot_free_mbi. + (grub_get_multiboot_mmap_len): Moved to loader/i386/multiboot_mbi.c. + (grub_fill_multiboot_mmap): Likewise. + (grub_multiboot_get_bootdev): Likewise. + (grub_multiboot): Use multiboot_mbi functions. + * loader/i386/multiboot_mbi.c: New file. =3D=3D=3D modified file 'conf/i386-coreboot.rmk' --- conf/i386-coreboot.rmk 2010-01-09 22:22:48 +0000 +++ conf/i386-coreboot.rmk 2010-01-10 15:39:05 +0000 @@ -142,14 +142,16 @@ =20 pkglib_MODULES +=3D multiboot.mod multiboot_mod_SOURCES =3D loader/i386/multiboot.c \ - loader/multiboot_loader.c + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c multiboot_mod_CFLAGS =3D $(COMMON_CFLAGS) multiboot_mod_LDFLAGS =3D $(COMMON_LDFLAGS) multiboot_mod_ASFLAGS =3D $(COMMON_ASFLAGS) =20 pkglib_MODULES +=3D multiboot2.mod multiboot2_mod_SOURCES =3D loader/i386/multiboot.c \ - loader/multiboot_loader.c + loader/multiboot_loader.c \ + loader/i386/multiboot_mbi.c multiboot2_mod_CFLAGS =3D $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS =3D $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS =3D $(COMMON_ASFLAGS) =3D=3D=3D modified file 'conf/i386-pc.rmk' --- conf/i386-pc.rmk 2010-01-09 22:22:48 +0000 +++ conf/i386-pc.rmk 2010-01-10 15:39:05 +0000 @@ -203,6 +203,7 @@ =20 pkglib_MODULES +=3D multiboot.mod multiboot_mod_SOURCES =3D loader/i386/multiboot.c \ + loader/i386/multiboot_mbi.c \ loader/multiboot_loader.c multiboot_mod_CFLAGS =3D $(COMMON_CFLAGS) multiboot_mod_LDFLAGS =3D $(COMMON_LDFLAGS) @@ -210,7 +211,8 @@ =20 pkglib_MODULES +=3D multiboot2.mod multiboot2_mod_SOURCES =3D loader/i386/multiboot.c \ - loader/multiboot_loader.c + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c multiboot2_mod_CFLAGS =3D $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS =3D $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS =3D $(COMMON_ASFLAGS) =3D=3D=3D modified file 'include/grub/multiboot.h' --- include/grub/multiboot.h 2010-01-07 21:05:25 +0000 +++ include/grub/multiboot.h 2010-01-10 15:50:59 +0000 @@ -29,7 +29,20 @@ #include #endif =20 +#include +#include + void grub_multiboot (int argc, char *argv[]); void grub_module (int argc, char *argv[]); =20 +grub_size_t grub_multiboot_get_mbi_size (void); +grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, + grub_off_t buf_off, grub_size_t bufsize); +void grub_multiboot_free_mbi (void); +grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]); +grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t siz= e, + int argc, char *argv[]); +void grub_multiboot_set_bootdev (void); + + #endif /* ! GRUB_MULTIBOOT_HEADER */ =3D=3D=3D modified file 'loader/i386/multiboot.c' --- loader/i386/multiboot.c 2010-01-07 19:55:16 +0000 +++ loader/i386/multiboot.c 2010-01-10 16:09:27 +0000 @@ -45,31 +45,24 @@ #include #include #include -#ifdef GRUB_MACHINE_PCBIOS -#include -#include -#include -#include -#endif #include =20 extern grub_dl_t my_mod; -static struct multiboot_info *mbi, *mbi_dest; - -static grub_size_t code_size; +static grub_size_t code_size, alloc_mbi; =20 char *grub_multiboot_payload_orig; grub_addr_t grub_multiboot_payload_dest; -grub_size_t grub_multiboot_payload_size; +grub_size_t grub_multiboot_pure_size; grub_uint32_t grub_multiboot_payload_eip; =20 static grub_err_t grub_multiboot_boot (void) { + grub_size_t mbi_size; + grub_err_t err; struct grub_relocator32_state state =3D { .eax =3D MULTIBOOT_BOOTLOADER_MAGIC, - .ebx =3D PTR_TO_UINT32 (mbi_dest), .ecx =3D 0, .edx =3D 0, .eip =3D grub_multiboot_payload_eip, @@ -78,6 +71,24 @@ .esp =3D 0x7ff00 }; =20 + mbi_size =3D grub_multiboot_get_mbi_size (); + if (alloc_mbi < mbi_size) + { + grub_multiboot_payload_orig + =3D grub_relocator32_realloc (grub_multiboot_payload_orig, + grub_multiboot_pure_size + mbi_size); + if (!grub_multiboot_payload_orig) + return grub_errno; + alloc_mbi =3D mbi_size; + } + + state.ebx =3D grub_multiboot_payload_dest + grub_multiboot_pure_size; + err =3D grub_multiboot_make_mbi (grub_multiboot_payload_orig, + grub_multiboot_payload_dest, + grub_multiboot_pure_size, mbi_size); + if (err) + return err; + grub_relocator32_boot (grub_multiboot_payload_orig, grub_multiboot_payload_dest, state); @@ -89,69 +100,18 @@ static grub_err_t grub_multiboot_unload (void) { - if (mbi) - { - unsigned int i; - for (i =3D 0; i < mbi->mods_count; i++) - { - grub_free ((void *) - ((struct multiboot_mod_list *) mbi->mods_addr)[i].mod_start); - grub_free ((void *) - ((struct multiboot_mod_list *) mbi->mods_addr)[i].cmdline); - } - grub_free ((void *) mbi->mods_addr); - } + grub_multiboot_free_mbi (); + grub_relocator32_free (grub_multiboot_payload_orig); =20 - mbi =3D NULL; + alloc_mbi =3D 0; + grub_multiboot_payload_orig =3D NULL; grub_dl_unref (my_mod); =20 return GRUB_ERR_NONE; } =20 -/* Return the length of the Multiboot mmap that will be needed to alloca= te - our platform's map. */ -static grub_uint32_t -grub_get_multiboot_mmap_len (void) -{ - grub_size_t count =3D 0; - - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uin= t32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused))= , - grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) - { - count++; - return 0; - } - - grub_mmap_iterate (hook); - - return count * sizeof (struct multiboot_mmap_entry); -} - -/* Fill previously allocated Multiboot mmap. */ -static void -grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) -{ - struct multiboot_mmap_entry *mmap_entry =3D (struct multiboot_mmap_ent= ry *) first_entry; - - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uin= t32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, gru= b_uint32_t type) - { - mmap_entry->addr =3D addr; - mmap_entry->len =3D size; - mmap_entry->type =3D type; - mmap_entry->size =3D sizeof (struct multiboot_mmap_entry) - sizeof= (mmap_entry->size); - mmap_entry++; - - return 0; - } - - grub_mmap_iterate (hook); -} - #define MULTIBOOT_LOAD_ELF64 #include "multiboot_elfxx.c" #undef MULTIBOOT_LOAD_ELF64 @@ -172,58 +132,13 @@ return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); } =20 -static int -grub_multiboot_get_bootdev (grub_uint32_t *bootdev) -{ -#ifdef GRUB_MACHINE_PCBIOS - char *p; - grub_uint32_t biosdev, slice =3D ~0, part =3D ~0; - grub_device_t dev; - - biosdev =3D grub_get_root_biosnumber (); - - dev =3D grub_device_open (0); - if (dev && dev->disk && dev->disk->partition) - { - - p =3D dev->disk->partition->partmap->get_name (dev->disk->partitio= n); - if (p) - { - if ((p[0] >=3D '0') && (p[0] <=3D '9')) - { - slice =3D grub_strtoul (p, &p, 0) - 1; - - if ((p) && (p[0] =3D=3D ',')) - p++; - } - - if ((p[0] >=3D 'a') && (p[0] <=3D 'z')) - part =3D p[0] - 'a'; - } - } - if (dev) - grub_device_close (dev); - - *bootdev =3D ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) - | ((part & 0xff) << 8) | 0xff; - return (biosdev !=3D ~0UL); -#else - *bootdev =3D 0xffffffff; - return 0; -#endif -} - void grub_multiboot (int argc, char *argv[]) { grub_file_t file =3D 0; - char buffer[MULTIBOOT_SEARCH], *cmdline =3D 0, *p; + char buffer[MULTIBOOT_SEARCH]; struct multiboot_header *header; - grub_ssize_t len, cmdline_length, boot_loader_name_length; - grub_uint32_t mmap_length; - int i; - int cmdline_argc; - char **cmdline_argv; + grub_ssize_t len; =20 grub_loader_unset (); =20 @@ -274,31 +189,8 @@ grub_relocator32_free (grub_multiboot_payload_orig); grub_multiboot_payload_orig =3D NULL; =20 - mmap_length =3D grub_get_multiboot_mmap_len (); - - /* Figure out cmdline length. */ /* Skip filename. */ - cmdline_argc =3D argc - 1; - cmdline_argv =3D argv + 1; - - for (i =3D 0, cmdline_length =3D 0; i < cmdline_argc; i++) - cmdline_length +=3D grub_strlen (cmdline_argv[i]) + 1; - - if (cmdline_length =3D=3D 0) - cmdline_length =3D 1; - - boot_loader_name_length =3D sizeof(PACKAGE_STRING); - -#define cmdline_addr(x) ((void *) ((x) + code_size)) -#define boot_loader_name_addr(x) \ - ((void *) ((x) + code_size + cmdline_length)) -#define mbi_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_= loader_name_length)) -#define mmap_addr(x) ((void *) ((x) + code_size + cmdline_length + boot= _loader_name_length + sizeof (struct multiboot_info))) - - grub_multiboot_payload_size =3D cmdline_length - /* boot_loader_name_length might need to grow for mbi,etc to be alig= ned (see below) */ - + boot_loader_name_length + 3 - + sizeof (struct multiboot_info) + mmap_length; + grub_multiboot_init_mbi (argc - 1, argv + 1); =20 if (header->flags & MULTIBOOT_AOUT_KLUDGE) { @@ -313,10 +205,12 @@ code_size =3D load_size; grub_multiboot_payload_dest =3D header->load_addr; =20 - grub_multiboot_payload_size +=3D code_size; + grub_multiboot_pure_size +=3D code_size; =20 + /* Allocate a bit more to avoid relocations in most cases. */ + alloc_mbi =3D grub_multiboot_get_mbi_size () + 65536; grub_multiboot_payload_orig - =3D grub_relocator32_alloc (grub_multiboot_payload_size); + =3D grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi); =20 if (! grub_multiboot_payload_orig) goto fail; @@ -338,53 +232,35 @@ else if (grub_multiboot_load_elf (file, buffer) !=3D GRUB_ERR_NONE) goto fail; =20 - /* This provides alignment for the MBI, the memory map and the backwar= d relocator. */ - boot_loader_name_length +=3D (0x04 - ((unsigned long) mbi_addr (grub_m= ultiboot_payload_dest) & 0x03)); - - mbi =3D mbi_addr (grub_multiboot_payload_orig); - mbi_dest =3D mbi_addr (grub_multiboot_payload_dest); - grub_memset (mbi, 0, sizeof (struct multiboot_info)); - mbi->mmap_length =3D mmap_length; - - grub_fill_multiboot_mmap (mmap_addr (grub_multiboot_payload_orig)); - - /* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is m= andated - by the spec. Is there something we can do about it? */ - mbi->mmap_addr =3D (grub_uint32_t) mmap_addr (grub_multiboot_payload_d= est); - mbi->flags |=3D MULTIBOOT_INFO_MEM_MAP; - - /* Convert from bytes to kilobytes. */ - mbi->mem_lower =3D grub_mmap_get_lower () / 1024; - mbi->mem_upper =3D grub_mmap_get_upper () / 1024; - mbi->flags |=3D MULTIBOOT_INFO_MEMORY; - - cmdline =3D p =3D cmdline_addr (grub_multiboot_payload_orig); - if (! cmdline) - goto fail; - - for (i =3D 0; i < cmdline_argc; i++) + if (header->flags & MULTIBOOT_VIDEO_MODE) { - p =3D grub_stpcpy (p, cmdline_argv[i]); - *(p++) =3D ' '; + switch (header->mode_type) + { + case 1: + grub_env_set ("gfxpayload", "text"); + break; + + case 0: + { + char buf[sizeof ("XXXXXXXXXXxXXXXXXXXXXxXXXXXXXXXX,XXXXXXXXXXxXXXXX= XXXXX,auto")]; + if (header->depth && header->width && header->height) + grub_sprintf (buf, "%dx%dx%d,%dx%d,auto", header->width, + header->height, header->depth, header->width, + header->height); + else if (header->width && header->height) + grub_sprintf (buf, "%dx%d,auto", header->width, header->height); + else + grub_sprintf (buf, "auto"); + + grub_env_set ("gfxpayload", buf); + break; + } + } } =20 - /* Remove the space after the last word. */ - if (p !=3D cmdline) - p--; - *p =3D 0; - - mbi->flags |=3D MULTIBOOT_INFO_CMDLINE; - mbi->cmdline =3D (grub_uint32_t) cmdline_addr (grub_multiboot_payload_= dest); - - - grub_strcpy (boot_loader_name_addr (grub_multiboot_payload_orig), PACK= AGE_STRING); - mbi->flags |=3D MULTIBOOT_INFO_BOOT_LOADER_NAME; - mbi->boot_loader_name =3D (grub_uint32_t) boot_loader_name_addr (grub_= multiboot_payload_dest); - - if (grub_multiboot_get_bootdev (&mbi->boot_device)) - mbi->flags |=3D MULTIBOOT_INFO_BOOTDEV; - - grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); + grub_multiboot_set_bootdev (); + + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); =20 fail: if (file) @@ -392,22 +268,18 @@ =20 if (grub_errno !=3D GRUB_ERR_NONE) { - grub_free (cmdline); - grub_free (mbi); + grub_relocator32_free (grub_multiboot_payload_orig); grub_dl_unref (my_mod); } } =20 - void grub_module (int argc, char *argv[]) { grub_file_t file =3D 0; - grub_ssize_t size, len =3D 0; - char *module =3D 0, *cmdline =3D 0, *p; - int i; - int cmdline_argc; - char **cmdline_argv; + grub_ssize_t size; + char *module =3D 0; + grub_err_t err; =20 if (argc =3D=3D 0) { @@ -415,7 +287,7 @@ goto fail; } =20 - if (!mbi) + if (!grub_multiboot_payload_orig) { grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the multiboot kernel first"); @@ -431,73 +303,19 @@ if (! module) goto fail; =20 + err =3D grub_multiboot_add_module ((grub_addr_t) module, size, + argc - 1, argv + 1); + if (err) + goto fail; + if (grub_file_read (file, module, size) !=3D size) { grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } =20 - /* Skip module name. */ - cmdline_argc =3D argc - 1; - cmdline_argv =3D argv + 1; - - for (i =3D 0; i < cmdline_argc; i++) - len +=3D grub_strlen (cmdline_argv[i]) + 1; - - if (len =3D=3D 0) - len =3D 1; - - cmdline =3D p =3D grub_malloc (len); - if (! cmdline) - goto fail; - - for (i =3D 0; i < cmdline_argc; i++) - { - p =3D grub_stpcpy (p, cmdline_argv[i]); - *(p++) =3D ' '; - } - - /* Remove the space after the last word. */ - if (p !=3D cmdline) - p--; - *p =3D '\0'; - - if (mbi->flags & MULTIBOOT_INFO_MODS) - { - struct multiboot_mod_list *modlist =3D (struct multiboot_mod_list = *) mbi->mods_addr; - - modlist =3D grub_realloc (modlist, (mbi->mods_count + 1) - * sizeof (struct multiboot_mod_list)); - if (! modlist) - goto fail; - mbi->mods_addr =3D (grub_uint32_t) modlist; - modlist +=3D mbi->mods_count; - modlist->mod_start =3D (grub_uint32_t) module; - modlist->mod_end =3D (grub_uint32_t) module + size; - modlist->cmdline =3D (grub_uint32_t) cmdline; - modlist->pad =3D 0; - mbi->mods_count++; - } - else - { - struct multiboot_mod_list *modlist =3D grub_zalloc (sizeof (struct= multiboot_mod_list)); - if (! modlist) - goto fail; - modlist->mod_start =3D (grub_uint32_t) module; - modlist->mod_end =3D (grub_uint32_t) module + size; - modlist->cmdline =3D (grub_uint32_t) cmdline; - mbi->mods_count =3D 1; - mbi->mods_addr =3D (grub_uint32_t) modlist; - mbi->flags |=3D MULTIBOOT_INFO_MODS; - } - fail: if (file) grub_file_close (file); - - if (grub_errno !=3D GRUB_ERR_NONE) - { - grub_free (module); - grub_free (cmdline); - } } + =3D=3D=3D modified file 'loader/i386/multiboot_elfxx.c' --- loader/i386/multiboot_elfxx.c 2009-12-13 18:29:15 +0000 +++ loader/i386/multiboot_elfxx.c 2010-01-10 15:39:05 +0000 @@ -100,10 +100,11 @@ code_size =3D (phdr(highest_segment)->p_paddr + phdr(highest_segment)-= >p_memsz) - phdr(lowest_segment)->p_paddr; grub_multiboot_payload_dest =3D phdr(lowest_segment)->p_paddr; =20 - grub_multiboot_payload_size +=3D code_size; + grub_multiboot_pure_size +=3D code_size; =20 + alloc_mbi =3D grub_multiboot_get_mbi_size (); grub_multiboot_payload_orig - =3D grub_relocator32_alloc (grub_multiboot_payload_size); + =3D grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi); =20 if (!grub_multiboot_payload_orig) return grub_errno; =3D=3D=3D added file 'loader/i386/multiboot_mbi.c' --- loader/i386/multiboot_mbi.c 1970-01-01 00:00:00 +0000 +++ loader/i386/multiboot_mbi.c 2010-01-10 17:00:27 +0000 @@ -0,0 +1,336 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Fre= e Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by= + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +struct module +{ + struct module *next; + grub_addr_t start; + grub_size_t size; + char *cmdline; + int cmdline_size; +}; + +struct module *modules, *modules_last; +static grub_size_t cmdline_size; +static grub_size_t total_modcmd; +static unsigned modcnt; +static char *cmdline =3D NULL; +static grub_uint32_t bootdev; +static int bootdev_set; + +/* Return the length of the Multiboot mmap that will be needed to alloca= te + our platform's map. */ +static grub_uint32_t +grub_get_multiboot_mmap_len (void) +{ + grub_size_t count =3D 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uin= t32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused))= , + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + grub_mmap_iterate (hook); + + return count * sizeof (struct multiboot_mmap_entry); +} + +grub_size_t +grub_multiboot_get_mbi_size (void) +{ + return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len= (); +} + +/* Fill previously allocated Multiboot mmap. */ +static void +grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) +{ + struct multiboot_mmap_entry *mmap_entry =3D (struct multiboot_mmap_ent= ry *) first_entry; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uin= t32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, gru= b_uint32_t type) + { + mmap_entry->addr =3D addr; + mmap_entry->len =3D size; + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + mmap_entry->type =3D MULTIBOOT_MEMORY_AVAILABLE; + break; + =20 + default: + mmap_entry->type =3D MULTIBOOT_MEMORY_RESERVED; + break; + } + mmap_entry->size =3D sizeof (struct multiboot_mmap_entry) - sizeof= (mmap_entry->size); + mmap_entry++; + + return 0; + } + + grub_mmap_iterate (hook); +} + +grub_err_t +grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_= off, + grub_size_t bufsize) +{ + grub_uint8_t *ptrorig =3D (grub_uint8_t *) orig + buf_off; + grub_uint32_t ptrdest =3D dest + buf_off; + struct multiboot_info *mbi; + struct multiboot_mod_list *modlist; + unsigned i; + struct module *cur; + grub_size_t mmap_size; + + if (bufsize < grub_multiboot_get_mbi_size ()) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"= ); + + mbi =3D (struct multiboot_info *) ptrorig; + ptrorig +=3D sizeof (*mbi); + ptrdest +=3D sizeof (*mbi); + grub_memset (mbi, 0, sizeof (*mbi)); + + grub_memcpy (ptrorig, cmdline, cmdline_size); + mbi->flags |=3D MULTIBOOT_INFO_CMDLINE; + mbi->cmdline =3D ptrdest; + ptrorig +=3D ALIGN_UP (cmdline_size, 4); + ptrdest +=3D ALIGN_UP (cmdline_size, 4); + + grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING)); + mbi->flags |=3D MULTIBOOT_INFO_BOOT_LOADER_NAME; + mbi->boot_loader_name =3D ptrdest; + ptrorig +=3D ALIGN_UP (sizeof(PACKAGE_STRING), 4); + ptrdest +=3D ALIGN_UP (sizeof(PACKAGE_STRING), 4); + + if (modcnt) + { + mbi->flags |=3D MULTIBOOT_INFO_MODS; + mbi->mods_addr =3D ptrdest; + mbi->mods_count =3D modcnt; + modlist =3D (struct multiboot_mod_list *) ptrorig; + ptrorig +=3D modcnt * sizeof (struct multiboot_mod_list); + ptrdest +=3D modcnt * sizeof (struct multiboot_mod_list); + + for (i =3D 0, cur =3D modules; i < modcnt; i++, cur =3D cur->next)= + { + modlist[i].mod_start =3D cur->start; + modlist[i].mod_end =3D modlist[i].mod_start + cur->size; + modlist[i].cmdline =3D ptrdest; + grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size); + ptrorig +=3D ALIGN_UP (cur->cmdline_size, 4); + ptrdest +=3D ALIGN_UP (cur->cmdline_size, 4); + } + } + else + { + mbi->mods_addr =3D 0; + mbi->mods_count =3D 0; + } + + mmap_size =3D grub_get_multiboot_mmap_len ();=20 + grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig); + mbi->mmap_length =3D mmap_size; + mbi->mmap_addr =3D ptrdest; + mbi->flags |=3D MULTIBOOT_INFO_MEM_MAP; + ptrorig +=3D mmap_size; + ptrdest +=3D mmap_size; + + /* Convert from bytes to kilobytes. */ + mbi->mem_lower =3D grub_mmap_get_lower () / 1024; + mbi->mem_upper =3D grub_mmap_get_upper () / 1024; + mbi->flags |=3D MULTIBOOT_INFO_MEMORY; + + if (bootdev_set) + { + mbi->boot_device =3D bootdev; + mbi->flags |=3D MULTIBOOT_INFO_BOOTDEV; + } + + return GRUB_ERR_NONE; +} + +void +grub_multiboot_free_mbi (void) +{ + struct module *cur, *next; + + cmdline_size =3D 0; + total_modcmd =3D 0; + modcnt =3D 0; + grub_free (cmdline); + cmdline =3D NULL; + bootdev_set =3D 0; + + for (cur =3D modules; cur; cur =3D next) + { + next =3D cur->next; + grub_free (cur->cmdline); + grub_free (cur); + } + modules =3D NULL; + modules_last =3D NULL; +} + +grub_err_t +grub_multiboot_init_mbi (int argc, char *argv[]) +{ + grub_ssize_t len =3D 0; + char *p; + int i; + + grub_multiboot_free_mbi (); + + for (i =3D 0; i < argc; i++) + len +=3D grub_strlen (argv[i]) + 1; + if (len =3D=3D 0) + len =3D 1; + + cmdline =3D p =3D grub_malloc (len); + if (! cmdline) + return grub_errno; + cmdline_size =3D len; + + for (i =3D 0; i < argc; i++) + { + p =3D grub_stpcpy (p, argv[i]); + *(p++) =3D ' '; + } + + /* Remove the space after the last word. */ + if (p !=3D cmdline) + p--; + *p =3D '\0'; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_multiboot_add_module (grub_addr_t start, grub_size_t size, + int argc, char *argv[]) +{ + struct module *newmod; + char *p; + grub_ssize_t len =3D 0; + int i; + + newmod =3D grub_malloc (sizeof (*newmod)); + if (!newmod) + return grub_errno; + newmod->start =3D start; + newmod->size =3D size; + + for (i =3D 0; i < argc; i++) + len +=3D grub_strlen (argv[i]) + 1; + + if (len =3D=3D 0) + len =3D 1; + + newmod->cmdline =3D p =3D grub_malloc (len); + if (! newmod->cmdline) + { + grub_free (newmod); + return grub_errno; + } + newmod->cmdline_size =3D len; + total_modcmd +=3D ALIGN_UP (len, 4); + + for (i =3D 0; i < argc; i++) + { + p =3D grub_stpcpy (p, argv[i]); + *(p++) =3D ' '; + } + + /* Remove the space after the last word. */ + if (p !=3D newmod->cmdline) + p--; + *p =3D '\0'; + + if (modules_last) + modules_last->next =3D newmod; + else + { + modules =3D newmod; + modules_last->next =3D NULL; + } + modules_last =3D newmod; + + modcnt++; + + return GRUB_ERR_NONE; +} + +void +grub_multiboot_set_bootdev (void) +{ + char *p; + grub_uint32_t biosdev, slice =3D ~0, part =3D ~0; + grub_device_t dev; + +#ifdef GRUB_MACHINE_PCBIOS + biosdev =3D grub_get_root_biosnumber (); +#else + biosdev =3D 0xffffffff; +#endif + + dev =3D grub_device_open (0); + if (dev && dev->disk && dev->disk->partition) + { + + p =3D dev->disk->partition->partmap->get_name (dev->disk->partitio= n); + if (p) + { + if ((p[0] >=3D '0') && (p[0] <=3D '9')) + { + slice =3D grub_strtoul (p, &p, 0) - 1; + + if ((p) && (p[0] =3D=3D ',')) + p++; + } + + if ((p[0] >=3D 'a') && (p[0] <=3D 'z')) + part =3D p[0] - 'a'; + } + } + if (dev) + grub_device_close (dev); + + bootdev =3D ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16)=20 + | ((part & 0xff) << 8) | 0xff; + bootdev_set =3D 1; +} --------------070502020404080300010200-- --------------enig267AAA1C4BDCA6918A7D025E Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iF4EAREKAAYFAktKFhIACgkQNak7dOguQgmYUwD+NSVe5ervFqDdDwFOpSdsTRmA o+5vBMVmn7ufZHpFlJ8BAKpXEJR03Aul+dQrAB1iyr9Zs7Ck7vuhoWVZQ6dhH8kT =WXRU -----END PGP SIGNATURE----- --------------enig267AAA1C4BDCA6918A7D025E--