[PATCH] grub2 should not unzip Linux initramfs
Hi, the initramfs protocol (see [1]) supports multiple concatenated archives. Because of grub2's implicit unzipping of gz-compressed multiboot modules, a valid initramfs-file (e.g. in my case containing of two concatenated gz-files) may be rendered unbootable. I have attached the trivial patch adding --nounzip to the the appropriate module-directive when generating XEN boot entries. As this resembles the behavior when booting without XEN (using the grub2 commands linux and initrd) more closely I don't expect any problems. I have reported this to the Debian bugtracker before [2] with no response, but I suppose this is the correct point to report this issue. Thank you Lukas [1] https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt [2] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=700197 diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 4cf93d2..f12f059 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -135,7 +135,7 @@ EOF message="$(gettext_printf "Loading initial ramdisk ...")" sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' - module ${rel_dirname}/${initrd} + module --nounzip ${rel_dirname}/${initrd} EOF fi sed "s/^/$submenu_indentation/" << EOF signature.asc Description: OpenPGP digital signature ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
Re: [PATCH] grub2 should not unzip Linux initramfs
Committed, thanks. On 12.11.2013 11:25, Lukas Schwaighofer wrote: > Hi, > > the initramfs protocol (see [1]) supports multiple concatenated archives. > > Because of grub2's implicit unzipping of gz-compressed multiboot > modules, a valid initramfs-file (e.g. in my case containing of two > concatenated gz-files) may be rendered unbootable. > > I have attached the trivial patch adding --nounzip to the the > appropriate module-directive when generating XEN boot entries. As this > resembles the behavior when booting without XEN (using the grub2 > commands linux and initrd) more closely I don't expect any problems. > > I have reported this to the Debian bugtracker before [2] with no > response, but I suppose this is the correct point to report this issue. > > Thank you > Lukas > > > [1] > https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt > [2] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=700197 > > > > ___ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > signature.asc Description: OpenPGP digital signature ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
Feature Request: add a command to get/set (U)EFI firmware variables
Greetings everyone: I want to request a feature for GRUB that will improve on its usability on the (U)EFI platform. Specifically, a command to get/set (U)EFI firmware variables using (U)EFI system calls. Let me take a moment to explain why it is necessary and what it could be used for. For those who don't know, (U)EFI is a new firmware specification to replace BIOS. Unlike BIOS, however, it includes a small firmware environment similar to those found in MS/DOS or other small operating systems. I am the developer of Mac Linux USB Loader and Enterprise, a combination of tools to allow Linux distributions without (U)EFI support to boot from USB on Intel-based Apple Macintosh computers. While some distributions like Ubuntu and Fedora are making progress, generally speaking their solutions don't work well on Macs due to various quirks and inconsistencies in Apple's implementation of (U)EFI. Currently, to boot USB drives, I am using a pre-compiled image of GRUB 2 for (U)EFI to boot a Linux distribution from an ISO file using GRUB's loop back and iso9660 file system support. Sadly, the image was downloaded from the web, was likely modified, is incompatible with many distributions of GNU/Linux and, unfortunately, appears to use a modified copy of GRUB without providing source code. For these reasons I am developing my own solution, Enterprise, to fix these problems. In my current build of Enterprise, I have compiled GRUB to use the provided distribution's loopback.cfg file to boot. Sadly, this has not been a pleasant experience as all distributions have these files set up differently, and some do not include them at all. So, what I have currently is a (U)EFI executable that guides the user through figuring out which Linux kernel options would assist them in booting Linux on their Macs (more info can be found here on my blog at: http://bit.ly/1j2COHX ). My trouble is getting the information from Enterprise and my compiled GRUB image. So, I intend to set the boot options using (U)EFI firmware variables created using (U)EFI's RT->SetVariable and RT->GetVariable calls. Now I just need the equivalent functionality in GRUB, accessible from GRUB "functions" that are callable from GRUB's normal module and configuration (grub.cfg) files. The results would be saved to variables. This would not only be useful for me. Others could use this, for instance, to detect what (U)EFI firmware version that they have and boot different GNU/Linux distributions, or check for other things. For example, you could do something like: set firmware_version=getuefivar 'LoaderFirmwareVendor' export firmware_version ... if [ ${firmware_version} == 'Apple' ]; then linux ... initrd ... else linux ... initrd ... fi I'm fluent in C, am somewhat knowledgeable of the (U)EFI system, and am not afraid to modify GRUB's source code. What do you guys think of this idea? Sorry for this long-winded post. :) -- SevenBits ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[RFT] Use pair of shifts instead of and in ARM code
1ff and 3fff can't be easily loaded on ARM. This patch replaces load+and with pair of shift to keep only wanted bits. diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S index 0c16b10..454bad3 100644 --- a/grub-core/kern/arm/cache_armv7.S +++ b/grub-core/kern/arm/cache_armv7.S @@ -58,11 +64,17 @@ clean_invalidate_dcache: @ read current cache information mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR lsr r3, r8, #13 @ Number of sets -1 - ldr r9, =0x3fff - and r3, r3, r9 + + @ Keep only 14 bits of r3 + lsl r3, r3, #18 + lsr r3, r3, #18 + lsr r4, r8, #3 @ Number of ways -1 - ldr r9, =0x1ff - and r4, r4, r9 + + @ Keep only 9 bits of r4 + lsl r4, r4, #23 + lsr r4, r4, #23 + and r7, r8, #7 @ log2(line size in words) - 2 add r7, r7, #2 @ adjust mov r8, #1 signature.asc Description: OpenPGP digital signature ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 3/4] efi: Support GRUB_MMAP_MALLOC_LOW in the EFI firmware allocator
EFI supports allocating memory below a specified address; use that to implement GRUB_MMAP_MALLOC_LOW by requesting memory below 1M. --- ChangeLog entry: 2013-11-13 Josh Triplett * include/grub/efi/memory.h (GRUB_MMAP_MALLOC_LOW): Define. * grub-core/mmap/efi/mmap.c (grub_mmap_malign_and_register): Add support for GRUB_MMAP_MALLOC_LOW, to allocate memory below 1M via the EFI firmware. grub-core/mmap/efi/mmap.c | 15 ++- include/grub/efi/memory.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index e6cd185..64ad05c 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -239,9 +239,9 @@ void * grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), grub_uint64_t size, int *handle, int type, - int flags __attribute__ ((unused))) + int flags) { - grub_efi_physical_address_t address; + grub_efi_physical_address_t address, max_address; grub_efi_boot_services_t *b; grub_efi_uintn_t pages; grub_efi_status_t status; @@ -254,13 +254,18 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), b = grub_efi_system_table->boot_services; - address = 0x; + if (flags & GRUB_MMAP_MALLOC_LOW) + max_address = 0xf; + else + max_address = 0x; + address = max_address; #if GRUB_TARGET_SIZEOF_VOID_P < 8 /* Limit the memory access to less than 4GB for 32-bit platforms. */ atype = GRUB_EFI_ALLOCATE_MAX_ADDRESS; #else - atype = GRUB_EFI_ALLOCATE_ANY_PAGES; + atype = (flags & GRUB_MMAP_MALLOC_LOW) ? GRUB_EFI_ALLOCATE_MAX_ADDRESS + : GRUB_EFI_ALLOCATE_ANY_PAGES; #endif pages = (size + 0xfff) >> 12; @@ -276,7 +281,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), { /* Uggh, the address 0 was allocated... This is too annoying, so reallocate another one. */ - address = 0x; + address = max_address; status = efi_call_4 (b->allocate_pages, atype, make_efi_memtype (type), pages, &address); grub_efi_free_pages (0, pages); diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h index 20526b1..b4940af 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -24,6 +24,8 @@ #define GRUB_MMAP_REGISTER_BY_FIRMWARE 1 +#define GRUB_MMAP_MALLOC_LOW 1 + grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size, int type, int handle); grub_err_t grub_machine_mmap_unregister (int handle); -- 1.8.4.3 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 0/4] i386-efi and x86_64-efi fixes
The first three patches improve the EFI firmware allocator, fixing some bugs in the process. The last patch fixes many compilation-specific and firmware-specific crashes. To avoid unnecessary patch conflicts, I've included appropriately formatted ChangeLog entries for each patch separately in each mail, below the commit messages and above the diffstats. Josh Triplett (4): efi: Fix firmware memory allocation to round to 4k pages, not 1k efi: Fix requests to allocate GRUB_MEMORY_AVAILABLE efi: Support GRUB_MMAP_MALLOC_LOW in the EFI firmware allocator efi: On x86-64, align the stack to a 16-byte boundary as required by ABI grub-core/kern/x86_64/efi/startup.S | 6 +- grub-core/mmap/efi/mmap.c | 23 ++- include/grub/efi/memory.h | 2 ++ 3 files changed, 21 insertions(+), 10 deletions(-) -- 1.8.4.3 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 2/4] efi: Fix requests to allocate GRUB_MEMORY_AVAILABLE
EFI firmware refuses to allocate memory of type GRUB_EFI_CONVENTIONAL_MEMORY, because that indicates a block of available memory that other allocations (or the OS) would then step on. Map GRUB_MEMORY_AVAILABLE to GRUB_EFI_LOADER_CODE instead. --- ChangeLog entry: 2013-11-13 Josh Triplett * grub-core/mmap/efi/mmap.c (make_efi_memtype): Map GRUB_MEMORY_AVAILABLE to GRUB_EFI_LOADER_CODE rather than GRUB_EFI_CONVENTIONAL_MEMORY. EFI firmware refuses to allocate memory of type GRUB_EFI_CONVENTIONAL_MEMORY, because that indicates a block of available memory that other allocations (or the OS) would then step on. grub-core/mmap/efi/mmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index a77efe8..e6cd185 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -146,7 +146,7 @@ make_efi_memtype (int type) return GRUB_EFI_UNUSABLE_MEMORY; case GRUB_MEMORY_AVAILABLE: - return GRUB_EFI_CONVENTIONAL_MEMORY; + return GRUB_EFI_LOADER_CODE; case GRUB_MEMORY_ACPI: return GRUB_EFI_ACPI_RECLAIM_MEMORY; -- 1.8.4.3 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/4] efi: Fix firmware memory allocation to round to 4k pages, not 1k
EFI memory allocation operates in 4k pages, but the firmware memory allocator used 0x3ff in several places rather than 0xfff. --- ChangeLog entry: 2013-11-13 Josh Triplett * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to 4k page boundaries as expected by firmware rather than 1k boundaries. (grub_mmap_malign_and_register): Likewise. grub-core/mmap/efi/mmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 4f17c8b..a77efe8 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -184,8 +184,8 @@ grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type) return 0; b = grub_efi_system_table->boot_services; - address = start & (~0x3ffULL); - pages = (end - address + 0x3ff) >> 12; + address = start & (~0xfffULL); + pages = (end - address + 0xfff) >> 12; status = efi_call_2 (b->free_pages, address, pages); if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND) { @@ -263,7 +263,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), atype = GRUB_EFI_ALLOCATE_ANY_PAGES; #endif - pages = (size + 0x3ff) >> 12; + pages = (size + 0xfff) >> 12; status = efi_call_4 (b->allocate_pages, atype, make_efi_memtype (type), pages, &address); if (status != GRUB_EFI_SUCCESS) -- 1.8.4.3 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 4/4] efi: On x86-64, align the stack to a 16-byte boundary as required by ABI
The x86-64 ABI specification requires a 16-byte-aligned stack. In some cases, GCC emits code that assumes this alignment, which crashes if not aligned. The EFI firmware is also entitled to assume that stack alignment without checking, and some firmware does make that assumption. --- ChangeLog entry: 2013-11-13 Josh Triplett * grub-core/kern/x86_64/efi/startup.S (_start): Align the stack to a 16-byte boundary, as required by the x86-64 ABI, before calling grub_main. In some cases, GCC emits code that assumes this alignment, which crashes if not aligned. The EFI firmware is also entitled to assume that stack alignment without checking. grub-core/kern/x86_64/efi/startup.S | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index f86f019..94bd6ae 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -29,7 +29,11 @@ start: _start: movq%rcx, EXT_C(grub_efi_image_handle)(%rip) movq%rdx, EXT_C(grub_efi_system_table)(%rip) - + mov %rsp, %rax + subq$8, %rsp + and $~0xf, %rsp + mov %rax, (%rsp) callEXT_C(grub_main) + mov (%rsp), %rsp ret -- 1.8.4.3 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
Re: [PATCH 3/4] efi: Support GRUB_MMAP_MALLOC_LOW in the EFI firmware allocator
В Tue, 12 Nov 2013 18:26:39 -0800 Josh Triplett пишет: > EFI supports allocating memory below a specified address; use that to > implement GRUB_MMAP_MALLOC_LOW by requesting memory below 1M. Out of curiosity - why would you need it on EFI? Your patch does not add any consumer of GRUB_MMAP_MALLOC_LOW and on EFI notion of low memory should not exist? > --- > > ChangeLog entry: > > 2013-11-13 Josh Triplett > > * include/grub/efi/memory.h (GRUB_MMAP_MALLOC_LOW): Define. > * grub-core/mmap/efi/mmap.c (grub_mmap_malign_and_register): Add > support for GRUB_MMAP_MALLOC_LOW, to allocate memory below 1M via the > EFI firmware. > > grub-core/mmap/efi/mmap.c | 15 ++- > include/grub/efi/memory.h | 2 ++ > 2 files changed, 12 insertions(+), 5 deletions(-) > > diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c > index e6cd185..64ad05c 100644 > --- a/grub-core/mmap/efi/mmap.c > +++ b/grub-core/mmap/efi/mmap.c > @@ -239,9 +239,9 @@ void * > grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), > grub_uint64_t size, > int *handle, int type, > -int flags __attribute__ ((unused))) > +int flags) > { > - grub_efi_physical_address_t address; > + grub_efi_physical_address_t address, max_address; >grub_efi_boot_services_t *b; >grub_efi_uintn_t pages; >grub_efi_status_t status; > @@ -254,13 +254,18 @@ grub_mmap_malign_and_register (grub_uint64_t align > __attribute__ ((unused)), > >b = grub_efi_system_table->boot_services; > > - address = 0x; > + if (flags & GRUB_MMAP_MALLOC_LOW) > + max_address = 0xf; > + else > + max_address = 0x; > + address = max_address; > > #if GRUB_TARGET_SIZEOF_VOID_P < 8 >/* Limit the memory access to less than 4GB for 32-bit platforms. */ >atype = GRUB_EFI_ALLOCATE_MAX_ADDRESS; > #else > - atype = GRUB_EFI_ALLOCATE_ANY_PAGES; > + atype = (flags & GRUB_MMAP_MALLOC_LOW) ? GRUB_EFI_ALLOCATE_MAX_ADDRESS > + : GRUB_EFI_ALLOCATE_ANY_PAGES; > #endif > >pages = (size + 0xfff) >> 12; > @@ -276,7 +281,7 @@ grub_mmap_malign_and_register (grub_uint64_t align > __attribute__ ((unused)), > { >/* Uggh, the address 0 was allocated... This is too annoying, >so reallocate another one. */ > - address = 0x; > + address = max_address; >status = efi_call_4 (b->allocate_pages, atype, > make_efi_memtype (type), pages, &address); >grub_efi_free_pages (0, pages); > diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h > index 20526b1..b4940af 100644 > --- a/include/grub/efi/memory.h > +++ b/include/grub/efi/memory.h > @@ -24,6 +24,8 @@ > > #define GRUB_MMAP_REGISTER_BY_FIRMWARE 1 > > +#define GRUB_MMAP_MALLOC_LOW 1 > + > grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t > size, > int type, int handle); > grub_err_t grub_machine_mmap_unregister (int handle); ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel