boot services avoid code based on the patch by Matthew Garrett
This commit is contained in:
parent
86e5ab4b81
commit
9be4c45dbe
18 changed files with 136 additions and 37 deletions
|
@ -38,7 +38,8 @@ grub_reboot (void)
|
||||||
while (1);
|
while (1);
|
||||||
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000,
|
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000,
|
||||||
grub_reboot_end - grub_reboot_start,
|
grub_reboot_end - grub_reboot_start,
|
||||||
16, GRUB_RELOCATOR_PREFERENCE_NONE);
|
16, GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
while (1);
|
while (1);
|
||||||
buf = get_virtual_current_address (ch);
|
buf = get_virtual_current_address (ch);
|
||||||
|
|
|
@ -155,7 +155,8 @@ grub_cpu_relocator_forward (void *ptr, void *src, void *dest,
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_relocator32_boot (struct grub_relocator *rel,
|
grub_relocator32_boot (struct grub_relocator *rel,
|
||||||
struct grub_relocator32_state state)
|
struct grub_relocator32_state state,
|
||||||
|
int avoid_efi_bootservices)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
void *relst;
|
void *relst;
|
||||||
|
@ -164,7 +165,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
|
||||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
(0xffffffff - RELOCATOR_SIZEOF (32))
|
(0xffffffff - RELOCATOR_SIZEOF (32))
|
||||||
+ 1, RELOCATOR_SIZEOF (32), 16,
|
+ 1, RELOCATOR_SIZEOF (32), 16,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
avoid_efi_bootservices);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -207,7 +209,8 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
||||||
- GRUB_RELOCATOR16_STACK_SIZE,
|
- GRUB_RELOCATOR16_STACK_SIZE,
|
||||||
RELOCATOR_SIZEOF (16)
|
RELOCATOR_SIZEOF (16)
|
||||||
+ GRUB_RELOCATOR16_STACK_SIZE, 16,
|
+ GRUB_RELOCATOR16_STACK_SIZE, 16,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -261,7 +264,8 @@ grub_relocator64_boot (struct grub_relocator *rel,
|
||||||
err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
|
err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
|
||||||
max_addr - RELOCATOR_SIZEOF (64),
|
max_addr - RELOCATOR_SIZEOF (64),
|
||||||
RELOCATOR_SIZEOF (64), 16,
|
RELOCATOR_SIZEOF (64), 16,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -1319,7 +1319,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
||||||
grub_phys_addr_t min_addr,
|
grub_phys_addr_t min_addr,
|
||||||
grub_phys_addr_t max_addr,
|
grub_phys_addr_t max_addr,
|
||||||
grub_size_t size, grub_size_t align,
|
grub_size_t size, grub_size_t align,
|
||||||
int preference)
|
int preference,
|
||||||
|
int avoid_efi_boot_services)
|
||||||
{
|
{
|
||||||
grub_addr_t min_addr2 = 0, max_addr2;
|
grub_addr_t min_addr2 = 0, max_addr2;
|
||||||
struct grub_relocator_chunk *chunk;
|
struct grub_relocator_chunk *chunk;
|
||||||
|
@ -1406,7 +1407,12 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_machine_mmap_iterate (hook);
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
grub_efi_mmap_iterate (hook, avoid_efi_boot_services);
|
||||||
|
#else
|
||||||
|
(void) avoid_efi_boot_services;
|
||||||
|
grub_mmap_iterate (hook);
|
||||||
|
#endif
|
||||||
if (!found)
|
if (!found)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target");
|
return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target");
|
||||||
}
|
}
|
||||||
|
|
|
@ -723,7 +723,8 @@ grub_freebsd_boot (void)
|
||||||
0x10000, 0x90000,
|
0x10000, 0x90000,
|
||||||
3 * sizeof (grub_uint32_t)
|
3 * sizeof (grub_uint32_t)
|
||||||
+ sizeof (bi), 4,
|
+ sizeof (bi), 4,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
stack = get_virtual_current_address (ch);
|
stack = get_virtual_current_address (ch);
|
||||||
|
@ -760,7 +761,8 @@ grub_freebsd_boot (void)
|
||||||
0x10000, 0x90000,
|
0x10000, 0x90000,
|
||||||
9 * sizeof (grub_uint32_t)
|
9 * sizeof (grub_uint32_t)
|
||||||
+ sizeof (bi), 4,
|
+ sizeof (bi), 4,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
stack = get_virtual_current_address (ch);
|
stack = get_virtual_current_address (ch);
|
||||||
|
@ -786,7 +788,7 @@ grub_freebsd_boot (void)
|
||||||
stack[6] = stack_target + 9 * sizeof (grub_uint32_t);
|
stack[6] = stack_target + 9 * sizeof (grub_uint32_t);
|
||||||
stack[7] = bi.tags;
|
stack[7] = bi.tags;
|
||||||
stack[8] = kern_end;
|
stack[8] = kern_end;
|
||||||
return grub_relocator32_boot (relocator, state);
|
return grub_relocator32_boot (relocator, state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not reached. */
|
/* Not reached. */
|
||||||
|
@ -873,7 +875,7 @@ grub_openbsd_boot (void)
|
||||||
stack[7] = (grub_uint8_t *) curarg - (grub_uint8_t *) arg0;
|
stack[7] = (grub_uint8_t *) curarg - (grub_uint8_t *) arg0;
|
||||||
stack[8] = ((grub_uint8_t *) arg0 - (grub_uint8_t *) buf0) + buf_target;
|
stack[8] = ((grub_uint8_t *) arg0 - (grub_uint8_t *) buf0) + buf_target;
|
||||||
|
|
||||||
return grub_relocator32_boot (relocator, state);
|
return grub_relocator32_boot (relocator, state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -1144,7 +1146,8 @@ grub_netbsd_boot (void)
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000,
|
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000,
|
||||||
7 * sizeof (grub_uint32_t), 4,
|
7 * sizeof (grub_uint32_t), 4,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||||
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
stack = get_virtual_current_address (ch);
|
stack = get_virtual_current_address (ch);
|
||||||
|
@ -1168,7 +1171,7 @@ grub_netbsd_boot (void)
|
||||||
stack[5] = grub_mmap_get_upper () >> 10;
|
stack[5] = grub_mmap_get_upper () >> 10;
|
||||||
stack[6] = grub_mmap_get_lower () >> 10;
|
stack[6] = grub_mmap_get_lower () >> 10;
|
||||||
|
|
||||||
return grub_relocator32_boot (relocator, state);
|
return grub_relocator32_boot (relocator, state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
|
|
@ -43,7 +43,7 @@ grub_chain_boot (void)
|
||||||
grub_video_set_mode ("text", 0, 0);
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
state.eip = entry;
|
state.eip = entry;
|
||||||
return grub_relocator32_boot (relocator, state);
|
return grub_relocator32_boot (relocator, state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
|
|
@ -189,7 +189,9 @@ free_pages (void)
|
||||||
/* Allocate pages for the real mode code and the protected mode code
|
/* Allocate pages for the real mode code and the protected mode code
|
||||||
for linux as well as a memory map buffer. */
|
for linux as well as a memory map buffer. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
allocate_pages (grub_size_t prot_size)
|
allocate_pages (grub_size_t prot_size, grub_size_t *align,
|
||||||
|
grub_size_t min_align, int relocatable,
|
||||||
|
grub_uint64_t prefered_address)
|
||||||
{
|
{
|
||||||
grub_size_t real_size, mmap_size;
|
grub_size_t real_size, mmap_size;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -254,7 +256,11 @@ allocate_pages (grub_size_t prot_size)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
grub_efi_mmap_iterate (hook, 1);
|
||||||
|
#else
|
||||||
grub_mmap_iterate (hook);
|
grub_mmap_iterate (hook);
|
||||||
|
#endif
|
||||||
if (! real_mode_target)
|
if (! real_mode_target)
|
||||||
{
|
{
|
||||||
err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
||||||
|
@ -273,15 +279,36 @@ allocate_pages (grub_size_t prot_size)
|
||||||
}
|
}
|
||||||
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
|
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
|
||||||
|
|
||||||
prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
|
if (relocatable)
|
||||||
|
{
|
||||||
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
|
prefered_address,
|
||||||
|
prefered_address,
|
||||||
|
prot_size, 1,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_LOW,
|
||||||
|
1);
|
||||||
|
for (; err && *align >= min_align; (*align)--)
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
|
0x1000000, 0xffffffff,
|
||||||
|
prot_size, 1 << *align,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_LOW,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|