Possibility to prefer higher or lower chunks in relocator
This commit is contained in:
parent
611f8f0eb9
commit
49a716be3b
8 changed files with 41 additions and 17 deletions
|
@ -34,7 +34,12 @@ grub_err_t
|
|||
grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
||||
grub_addr_t *target,
|
||||
grub_addr_t min_addr, grub_addr_t max_addr,
|
||||
grub_size_t size, grub_size_t align);
|
||||
grub_size_t size, grub_size_t align,
|
||||
int preference);
|
||||
|
||||
#define GRUB_RELOCATOR_PREFERENCE_NONE 0
|
||||
#define GRUB_RELOCATOR_PREFERENCE_LOW 1
|
||||
#define GRUB_RELOCATOR_PREFERENCE_HIGH 2
|
||||
|
||||
void
|
||||
grub_relocator_unload (struct grub_relocator *rel);
|
||||
|
|
|
@ -129,7 +129,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
|
|||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
|
||||
(0xffffffff - RELOCATOR_SIZEOF (32))
|
||||
+ 1, RELOCATOR_SIZEOF (32), 16);
|
||||
+ 1, RELOCATOR_SIZEOF (32), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -166,7 +167,8 @@ grub_relocator64_boot (struct grub_relocator *rel,
|
|||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &src, &target, min_addr,
|
||||
max_addr - RELOCATOR_SIZEOF (64),
|
||||
RELOCATOR_SIZEOF (64), 16);
|
||||
RELOCATOR_SIZEOF (64), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -446,7 +446,8 @@ grub_err_t
|
|||
grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
||||
grub_addr_t *target,
|
||||
grub_addr_t min_addr, grub_addr_t max_addr,
|
||||
grub_size_t size, grub_size_t align)
|
||||
grub_size_t size, grub_size_t align,
|
||||
int preference)
|
||||
{
|
||||
grub_addr_t min_addr2 = 0, max_addr2;
|
||||
struct grub_relocator_chunk *chunk;
|
||||
|
@ -455,6 +456,11 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
if (max_addr > ~size)
|
||||
max_addr = ~size;
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
if (min_addr < 0x1000)
|
||||
min_addr = 0x1000;
|
||||
#endif
|
||||
|
||||
grub_dprintf ("relocator", "chunks = %p\n", rel->chunks);
|
||||
|
||||
chunk = grub_malloc (sizeof (struct grub_relocator_chunk));
|
||||
|
@ -462,7 +468,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
return grub_errno;
|
||||
|
||||
if (malloc_in_range (rel, min_addr, max_addr, align,
|
||||
size, &start, 1, 1))
|
||||
size, &start,
|
||||
preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1))
|
||||
{
|
||||
grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n",
|
||||
(unsigned long long) start, (unsigned long long) start);
|
||||
|
@ -500,6 +507,9 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
while (0);
|
||||
|
||||
/* FIXME: check memory map. */
|
||||
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
|
||||
chunk->target = ALIGN_DOWN (max_addr, align);
|
||||
else
|
||||
chunk->target = ALIGN_UP (min_addr, align);
|
||||
while (1)
|
||||
{
|
||||
|
@ -514,6 +524,9 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
|| (chunk->target <= chunk2->target + chunk2->size
|
||||
&& chunk2->target + chunk2->size < chunk->target + size))
|
||||
{
|
||||
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
|
||||
chunk->target = ALIGN_DOWN (chunk2->target, align);
|
||||
else
|
||||
chunk->target = ALIGN_UP (chunk2->target + chunk2->size, align);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -550,7 +550,8 @@ grub_freebsd_boot (void)
|
|||
&stack_target,
|
||||
0x10000, 0x90000,
|
||||
3 * sizeof (grub_uint32_t)
|
||||
+ sizeof (bi), 4);
|
||||
+ sizeof (bi), 4,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -575,7 +576,8 @@ grub_freebsd_boot (void)
|
|||
&stack_target,
|
||||
0x10000, 0x90000,
|
||||
9 * sizeof (grub_uint32_t)
|
||||
+ sizeof (bi), 4);
|
||||
+ sizeof (bi), 4,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
grub_memcpy (&stack[8], &bi, sizeof (bi));
|
||||
|
@ -798,7 +800,8 @@ grub_netbsd_boot (void)
|
|||
|
||||
err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
|
||||
&stack_target, 0x10000, 0x90000,
|
||||
7 * sizeof (grub_uint32_t), 4);
|
||||
7 * sizeof (grub_uint32_t), 4,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -943,9 +943,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
addr_min = (grub_addr_t) prot_mode_target + ((prot_mode_pages * 3) << 12)
|
||||
+ page_align (size);
|
||||
|
||||
if (addr_max > grub_os_area_addr + grub_os_area_size)
|
||||
addr_max = grub_os_area_addr + grub_os_area_size;
|
||||
|
||||
/* Put the initrd as high as possible, 4KiB aligned. */
|
||||
addr = (addr_max - size) & ~0xFFF;
|
||||
|
||||
|
@ -957,7 +954,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
|
||||
err = grub_relocator_alloc_chunk_align (relocator, &initrd_mem,
|
||||
&initrd_mem_target,
|
||||
addr_min, addr, size, 0x1000);
|
||||
addr_min, addr, size, 0x1000,
|
||||
GRUB_RELOCATOR_PREFERENCE_HIGH);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -259,7 +259,8 @@ grub_module (int argc, char *argv[])
|
|||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &module,
|
||||
&target,
|
||||
0, (0xffffffff - size) + 1,
|
||||
size, MULTIBOOT_MOD_ALIGN);
|
||||
size, MULTIBOOT_MOD_ALIGN,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -125,7 +125,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||
(void **) &ptrorig, &ptrdest,
|
||||
0, 0xffffffff - bufsize,
|
||||
bufsize, 4);
|
||||
bufsize, 4,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -115,7 +115,8 @@ grub_xnu_resume (char *imagename)
|
|||
&target_image, 0,
|
||||
(0xffffffff - hibhead.image_size) + 1,
|
||||
hibhead.image_size,
|
||||
GRUB_XNU_PAGESIZE);
|
||||
GRUB_XNU_PAGESIZE,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
{
|
||||
grub_file_close (file);
|
||||
|
|
Loading…
Reference in a new issue