From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SYepY-0007N3-HM for mharc-grub-devel@gnu.org; Sun, 27 May 2012 10:52:28 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47069) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SYepV-0007Me-5n for grub-devel@gnu.org; Sun, 27 May 2012 10:52:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SYepS-0001Ue-1q for grub-devel@gnu.org; Sun, 27 May 2012 10:52:24 -0400 Received: from mail-wi0-f171.google.com ([209.85.212.171]:47294) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SYepR-0001UG-Lk for grub-devel@gnu.org; Sun, 27 May 2012 10:52:21 -0400 Received: by wibhm14 with SMTP id hm14so750563wib.12 for ; Sun, 27 May 2012 07:52:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type; bh=fYcghr4ZCYCjzVRHDYfY1qH1AkLL4lFWJ2PXCDe6uXQ=; b=PgFnW7bLsA8zW3lQp8fi4ScTXX+0AMpgjANdNM8yyeHqPeGiqr2ANuppcq9EENeK8X HJUjeWoh8AJYnZlnHaImxEhVFajscs//3uM6/FPimjO+b/Jlmm/pkdtP721EDC04fVFJ +7XC9MtmXeWpY/BsH7dpu57JOrs8tv3nIEW0tu1IimH+AbdNCb3XE+1Ot/otgFm3B0vV 1BWpQPEybUWwZiXy5R0YSRCFdDK6jKH5OO2pl8sTQBcAZ4ltGSZ0+s7c14KvwZhCARni JRTFNSRtJYu4OpxhIdPN0seoSKsqxVBjzFXvDTseXTxgqiQffAFIjQNLvZ7mpujWE3Yd BkuQ== Received: by 10.180.74.193 with SMTP id w1mr9385062wiv.4.1338130339125; Sun, 27 May 2012 07:52:19 -0700 (PDT) Received: from debian.x201.phnet (141-174.79-83.cust.bluewin.ch. [83.79.174.141]) by mx.google.com with ESMTPS id e20sm14032325wiv.7.2012.05.27.07.52.14 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 27 May 2012 07:52:16 -0700 (PDT) Message-ID: <4FC23F9C.50000@gmail.com> Date: Sun, 27 May 2012 16:52:12 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.4) Gecko/20120510 Icedove/10.0.4 MIME-Version: 1.0 To: The development of GNU GRUB Subject: Re: [bug #36532] boot in EFI mode (x86_64) fails on some systems References: <959D45574D89AF41A9DADF6F446A2E9A2AE52B06DA@AUSX7MCPS310.AMER.DELL.COM> In-Reply-To: <959D45574D89AF41A9DADF6F446A2E9A2AE52B06DA@AUSX7MCPS310.AMER.DELL.COM> X-Enigmail-Version: 1.4.1 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig4A22CE6791F5EC5B7B85D35A" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.212.171 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 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, 27 May 2012 14:52:27 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig4A22CE6791F5EC5B7B85D35A Content-Type: multipart/mixed; boundary="------------000603060800080401050000" This is a multi-part message in MIME format. --------------000603060800080401050000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 24.05.2012 19:27, Stuart_Hayes@Dell.com wrote: > Hello=E2=80=A6 >=20 > =20 >=20 > I just submitted a grub2 bug, along with a patch, at > . Could you test the attached patch on top of HEAD? --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------000603060800080401050000 Content-Type: text/x-diff; name="efi.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="efi.diff" =3D=3D=3D modified file 'grub-core/loader/efi/chainloader.c' --- grub-core/loader/efi/chainloader.c 2012-03-10 19:41:28 +0000 +++ grub-core/loader/efi/chainloader.c 2012-05-27 14:29:35 +0000 @@ -111,14 +111,16 @@ =20 fp->header.type =3D GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; fp->header.subtype =3D GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; - size =3D len * sizeof (grub_efi_char16_t) + sizeof (*fp); + + size =3D grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_U= TF8, + (const grub_uint8_t *) str, len, 0); + for (p =3D fp->path_name; p < fp->path_name + size; p++) + if (*p =3D=3D '/') + *p =3D '\\'; + + size =3D size * sizeof (grub_efi_char16_t) + sizeof (*fp); fp->header.length[0] =3D (grub_efi_uint8_t) (size & 0xff); fp->header.length[1] =3D (grub_efi_uint8_t) (size >> 8); - for (p =3D fp->path_name; len > 0; len--, p++, str++) - { - /* FIXME: this assumes that the path is in ASCII. */ - *p =3D (grub_efi_char16_t) (*str =3D=3D '/' ? '\\' : *str); - } } =20 static grub_efi_device_path_t * @@ -154,6 +156,7 @@ =20 file_path =3D grub_malloc (size + ((grub_strlen (dir_start) + 1) + * GRUB_MAX_UTF16_PER_UTF8 * sizeof (grub_efi_char16_t)) + sizeof (grub_efi_file_path_device_path_t) * 2); if (! file_path) =3D=3D=3D modified file 'grub-core/loader/i386/linux.c' --- grub-core/loader/i386/linux.c 2012-04-17 11:00:06 +0000 +++ grub-core/loader/i386/linux.c 2012-05-27 14:44:23 +0000 @@ -59,14 +59,10 @@ #define ACCEPTS_PURE_TEXT 1 #endif =20 -#define GRUB_LINUX_CL_OFFSET 0x1000 - static grub_dl_t my_mod; =20 static grub_size_t linux_mem_size; static int loaded; -static void *real_mode_mem; -static grub_addr_t real_mode_target; static void *prot_mode_mem; static grub_addr_t prot_mode_target; static void *initrd_mem; @@ -78,6 +74,8 @@ static struct grub_relocator *relocator =3D NULL; static void *efi_mmap_buf; static grub_size_t maximal_cmdline_size; +static struct linux_kernel_params linux_params; +static char *linux_cmdline; #ifdef GRUB_MACHINE_EFI static grub_efi_uintn_t efi_mmap_size; #else @@ -183,8 +181,8 @@ { grub_relocator_unload (relocator); relocator =3D NULL; - real_mode_mem =3D prot_mode_mem =3D initrd_mem =3D 0; - real_mode_target =3D prot_mode_target =3D initrd_mem_target =3D 0; + prot_mode_mem =3D initrd_mem =3D 0; + prot_mode_target =3D initrd_mem_target =3D 0; } =20 /* Allocate pages for the real mode code and the protected mode code @@ -194,31 +192,13 @@ grub_size_t min_align, int relocatable, grub_uint64_t prefered_address) { - grub_size_t real_size, mmap_size; grub_err_t err; - - /* Make sure that each size is aligned to a page boundary. */ - real_size =3D GRUB_LINUX_CL_OFFSET + maximal_cmdline_size; - prot_size =3D page_align (prot_size); - mmap_size =3D find_mmap_size (); - -#ifdef GRUB_MACHINE_EFI - efi_mmap_size =3D find_efi_mmap_size (); - if (efi_mmap_size =3D=3D 0) - return grub_errno; -#endif - - grub_dprintf ("linux", "real_size =3D %x, prot_size =3D %x, mmap_size = =3D %x\n", - (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size); - - /* Calculate the number of pages; Combine the real mode code with - the memory map buffer for simplicity. */ - real_mode_pages =3D ((real_size + mmap_size + efi_mmap_size) >> 12); prot_mode_pages =3D (prot_size >> 12); =20 /* Initialize the memory pointers with NULL for convenience. */ free_pages (); =20 + prot_size =3D page_align (prot_size); relocator =3D grub_relocator_new (); if (!relocator) { @@ -229,59 +209,6 @@ /* FIXME: Should request low memory from the heap when this feature is= implemented. */ =20 - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, - grub_memory_type_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type) - { - /* We must put real mode code in the traditional space. */ - - if (type =3D=3D GRUB_MEMORY_AVAILABLE - && addr <=3D 0x90000) - { - if (addr < 0x10000) - { - size +=3D addr - 0x10000; - addr =3D 0x10000; - } - - if (addr + size > 0x90000) - size =3D 0x90000 - addr; - - if (real_size + mmap_size + efi_mmap_size > size) - return 0; - - real_mode_target =3D ((addr + size) - (real_size + mmap_size + efi_mm= ap_size)); - return 1; - } - - return 0; - } -#ifdef GRUB_MACHINE_EFI - grub_efi_mmap_iterate (hook, 1); - if (! real_mode_target) - grub_efi_mmap_iterate (hook, 0); -#else - grub_mmap_iterate (hook); -#endif - if (! real_mode_target) - { - err =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real = mode pages"); - goto fail; - } - - { - grub_relocator_chunk_t ch; - err =3D grub_relocator_alloc_chunk_addr (relocator, &ch, - real_mode_target, - (real_size + mmap_size=20 - + efi_mmap_size)); - if (err) - goto fail; - real_mode_mem =3D get_virtual_current_address (ch); - } - efi_mmap_buf =3D (grub_uint8_t *) real_mode_mem + real_size + mmap_siz= e; - { grub_relocator_chunk_t ch; if (relocatable) @@ -315,9 +242,6 @@ prot_mode_target =3D get_physical_target_address (ch); } =20 - grub_dprintf ("linux", "real_mode_mem =3D %lx, real_mode_target =3D %l= x, real_mode_pages =3D %x\n", - (unsigned long) real_mode_mem, (unsigned long) real_mode= _target, - (unsigned) real_mode_pages); grub_dprintf ("linux", "prot_mode_mem =3D %lx, prot_mode_target =3D %l= x, prot_mode_pages =3D %x\n", (unsigned long) prot_mode_mem, (unsigned long) prot_mode= _target, (unsigned) prot_mode_pages); @@ -335,12 +259,6 @@ { int n =3D *e820_num; =20 - if (n >=3D GRUB_E820_MAX_ENTRY) - { - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Too many e820 memory map entries"); - } - if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size =3D=3D sta= rt) && (e820_map[n - 1].type =3D=3D type)) e820_map[n - 1].size +=3D size; @@ -462,9 +380,89 @@ const char *modevar; char *tmp; struct grub_relocator32_state state; + void *real_mode_mem; + grub_addr_t real_mode_target; + grub_size_t real_size, mmap_size; + grub_size_t cl_offset; + + mmap_size =3D find_mmap_size (); + /* Make sure that each size is aligned to a page boundary. */ + cl_offset =3D ALIGN_UP (mmap_size + sizeof (*params), 4096); + real_size =3D cl_offset + maximal_cmdline_size; + +#ifdef GRUB_MACHINE_EFI + efi_mmap_size =3D find_efi_mmap_size (); + if (efi_mmap_size =3D=3D 0) + return grub_errno; +#endif + + grub_dprintf ("linux", "real_size =3D %x, mmap_size =3D %x\n", + (unsigned) real_size, (unsigned) mmap_size); + + /* Calculate the number of pages; Combine the real mode code with + the memory map buffer for simplicity. */ + real_mode_pages =3D ((real_size + efi_mmap_size) >> 12); + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) + { + /* We must put real mode code in the traditional space. */ + + if (type =3D=3D GRUB_MEMORY_AVAILABLE + && addr <=3D 0x90000) + { + if (addr < 0x10000) + { + size +=3D addr - 0x10000; + addr =3D 0x10000; + } + + if (addr + size > 0x90000) + size =3D 0x90000 - addr; + + if (real_size + efi_mmap_size > size) + return 0; + + real_mode_target =3D ((addr + size) - (real_size + efi_mmap_size)); + return 1; + } + + return 0; + } +#ifdef GRUB_MACHINE_EFI + grub_efi_mmap_iterate (hook, 1); + if (! real_mode_target) + grub_efi_mmap_iterate (hook, 0); +#else + grub_mmap_iterate (hook); +#endif + if (! real_mode_target) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mod= e pages"); + + { + grub_relocator_chunk_t ch; + err =3D grub_relocator_alloc_chunk_addr (relocator, &ch, + real_mode_target, + (real_size + efi_mmap_size)); + if (err) + return err; + real_mode_mem =3D get_virtual_current_address (ch); + } + efi_mmap_buf =3D (grub_uint8_t *) real_mode_mem + real_size; + + grub_dprintf ("linux", "real_mode_mem =3D %lx, real_mode_target =3D %l= x, real_mode_pages =3D %x\n", + (unsigned long) real_mode_mem, (unsigned long) real_mode= _target, + (unsigned) real_mode_pages); =20 params =3D real_mode_mem; =20 + *params =3D linux_params; + params->cmd_line_ptr =3D real_mode_target + cl_offset; + grub_memcpy ((char *) params + cl_offset, linux_cmdline, + maximal_cmdline_size); + #ifdef GRUB_MACHINE_IEEE1275 { const char *bootpath; @@ -482,10 +480,10 @@ grub_dprintf ("linux", "code32_start =3D %x\n", (unsigned) params->code32_start); =20 - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + auto int NESTED_FUNC_ATTR hook_fill (grub_uint64_t, grub_uint64_t, grub_memory_type_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,=20 - grub_memory_type_t type) + int NESTED_FUNC_ATTR hook_fill (grub_uint64_t addr, grub_uint64_t size= ,=20 + grub_memory_type_t type) { grub_uint32_t e820_type; switch (type) @@ -517,7 +515,7 @@ } =20 e820_num =3D 0; - if (grub_mmap_iterate (hook)) + if (grub_mmap_iterate (hook_fill)) return grub_errno; params->mmap_size =3D e820_num; =20 @@ -652,6 +650,8 @@ { grub_dl_unref (my_mod); loaded =3D 0; + grub_free (linux_cmdline); + linux_cmdline =3D 0; return GRUB_ERR_NONE; } =20 @@ -781,16 +781,16 @@ preffered_address)) goto fail; =20 - params =3D (struct linux_kernel_params *) real_mode_mem; - grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); + params =3D (struct linux_kernel_params *) &linux_params; + grub_memset (params, 0, sizeof (*params)); grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F= 1); =20 params->code32_start =3D prot_mode_target + lh.code32_start - GRUB_LIN= UX_BZIMAGE_ADDR; params->kernel_alignment =3D (1 << align); params->ps_mouse =3D params->padding10 =3D 0; =20 - len =3D 0x400 - sizeof (lh); - if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != =3D len) + len =3D sizeof (*params) - sizeof (lh); + if (grub_file_read (file, (char *) params + sizeof (lh), len) !=3D len= ) { if (!grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), @@ -805,7 +805,6 @@ params->cl_magic =3D GRUB_LINUX_CL_MAGIC; params->cl_offset =3D 0x1000; =20 - params->cmd_line_ptr =3D real_mode_target + 0x1000; params->ramdisk_image =3D 0; params->ramdisk_size =3D 0; =20 @@ -978,10 +977,12 @@ } =20 /* Create kernel command line. */ - grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE= , - sizeof (LINUX_IMAGE)); + linux_cmdline =3D grub_malloc (maximal_cmdline_size); + if (!linux_cmdline) + goto fail; + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); grub_create_loader_cmdline (argc, argv, - (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET + linux_cmdline + sizeof (LINUX_IMAGE) - 1, maximal_cmdline_size - (sizeof (LINUX_IMAGE) - 1)); @@ -1054,7 +1055,7 @@ =20 initrd_pages =3D (page_align (size) >> 12); =20 - lh =3D (struct linux_kernel_header *) real_mode_mem; + lh =3D (struct linux_kernel_header *) &linux_params; =20 /* Get the highest address available for the initrd. */ if (grub_le_to_cpu16 (lh->version) >=3D 0x0203) =3D=3D=3D modified file 'include/grub/i386/linux.h' --- include/grub/i386/linux.h 2012-03-04 11:13:05 +0000 +++ include/grub/i386/linux.h 2012-05-27 14:34:29 +0000 @@ -69,8 +69,6 @@ #define GRUB_E820_NVS 4 #define GRUB_E820_BADRAM 5 =20 -#define GRUB_E820_MAX_ENTRY 128 - struct grub_e820_mmap { grub_uint64_t addr; @@ -298,7 +296,7 @@ grub_uint32_t payload_length; grub_uint64_t setup_data; grub_uint8_t pad2[120]; /* 258 */ - struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY]; /* 2d0 */ + struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */ =20 } __attribute__ ((packed)); #endif /* ! ASM_FILE */ --------------000603060800080401050000-- --------------enig4A22CE6791F5EC5B7B85D35A 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.12 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iF4EAREKAAYFAk/CP5wACgkQNak7dOguQgl2uAD/d8UwH/mGpvRQ4ngJRO+9hezT l0BSN4pTEnMG1uOqdxgBALIfM3gh7phNWTXDXZHD3/ERRn11/ANbQkKn8QNb/iyx =ZbUd -----END PGP SIGNATURE----- --------------enig4A22CE6791F5EC5B7B85D35A--