Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:wenbowang
grub
grub-0.97-relocatable-kernel-on-x86_64-uefi.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File grub-0.97-relocatable-kernel-on-x86_64-uefi.patch of Package grub
This patch fixes the problem that UEFI boot fains on systems that have the memory region starting at 1MB in use. The strategy is as follows: - Loading temporarily vmlinuz image to the address which AllocatePages() function returned. - After calling ExitBootServices() function, copy its reagion to the address which params->hdr.code32_start points to. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- Index: grub-0.97/efi/efimm.c =================================================================== --- grub-0.97.orig/efi/efimm.c +++ grub-0.97/efi/efimm.c @@ -78,6 +78,45 @@ grub_efi_free_pool (void *buffer) Call_Service_1(b->free_pool, buffer); } +void * +grub_efi_allocate_anypages(grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_physical_address_t address; + + b = grub_efi_system_table->boot_services; + status = Call_Service_4 (b->allocate_pages, + GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_LOADER_DATA, + pages, + &address); + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (allocated_pages) + { + unsigned i; + + for (i = 0; i < MAX_ALLOCATED_PAGES; i++) + if (allocated_pages[i].addr == 0) + { + allocated_pages[i].addr = address; + allocated_pages[i].num_pages = pages; + break; + } + + if (i == MAX_ALLOCATED_PAGES) + { + grub_printf ("too many page allocations"); + return NULL; + } + } + + return (void *) ((grub_addr_t) address); + +} + /* Allocate pages. Return the pointer to the first of allocated pages. */ void * grub_efi_allocate_pages (grub_efi_physical_address_t address, Index: grub-0.97/efi/grub/efi/efi.h =================================================================== --- grub-0.97.orig/efi/grub/efi/efi.h +++ grub-0.97/efi/grub/efi/efi.h @@ -45,6 +45,7 @@ int grub_efi_set_text_mode (int on); void grub_efi_stall (grub_efi_uintn_t microseconds); void *grub_efi_allocate_pool (grub_efi_uintn_t size); void grub_efi_free_pool (void *buffer); +void *grub_efi_allocate_anypages (grub_efi_uintn_t pages); void *grub_efi_allocate_pages (grub_efi_physical_address_t address, grub_efi_uintn_t pages); void Index: grub-0.97/efi/x86_64/loader/linux.c =================================================================== --- grub-0.97.orig/efi/x86_64/loader/linux.c +++ grub-0.97/efi/x86_64/loader/linux.c @@ -40,6 +40,8 @@ static unsigned long linux_mem_size; static int loaded; static void *real_mode_mem; +static void *prot_mode_mem; +static grub_size_t prot_kernel_size; static void *initrd_mem; static void *mmap_buf; static grub_efi_uintn_t real_mode_pages; @@ -143,6 +145,7 @@ allocate_pages (grub_size_t real_size, g /* Initialize the memory pointers with NULL for convenience. */ real_mode_mem = 0; + prot_mode_mem = 0; mmap_buf = 0; /* Read the memory map temporarily, to find free space. */ @@ -205,6 +208,13 @@ allocate_pages (grub_size_t real_size, g goto fail; } + grub_printf("Trying to allocate %u pages for VMLINUZ\n", + (unsigned) prot_mode_pages); + prot_mode_mem = grub_efi_allocate_anypages(prot_mode_pages); + + if (!prot_mode_mem) + grub_fatal("Cannot allocate pages for VMLINUZ"); + mmap_buf = grub_efi_allocate_pages (0, mmap_pages); if (! mmap_buf) { @@ -259,6 +269,11 @@ big_linux_boot (void) grub_fatal ("cannot exit boot services"); /* Note that no boot services are available from here. */ + + /* copy vmlinuz image to hdr.code32_start */ + memcpy ((char *)(unsigned long)(params->hdr.code32_start), (char *)prot_mode_mem, + prot_kernel_size); + /* copy switch image */ memcpy ((void *) 0x700, switch_image, switch_size); lh = ¶ms->hdr; @@ -370,6 +385,7 @@ grub_load_linux (char *kernel, char *arg real_size = 0x1000 + grub_strlen(arg); prot_size = grub_file_size () - (setup_sects << SECTOR_BITS) - SECTOR_SIZE; + prot_kernel_size = prot_size; if (! allocate_pages (real_size, prot_size)) goto fail; @@ -501,7 +517,7 @@ grub_load_linux (char *kernel, char *arg grub_seek ((setup_sects << SECTOR_BITS) + SECTOR_SIZE); len = prot_size; - if (grub_read ((char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) + if (grub_read ((char *)prot_mode_mem, len) != len) grub_printf ("Couldn't read file"); if (errnum == ERR_NONE)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor