Possibility to prefer higher or lower chunks in relocator

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-12 22:14:26 +01:00
parent 611f8f0eb9
commit 49a716be3b
8 changed files with 41 additions and 17 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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,7 +507,10 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
while (0);
/* FIXME: check memory map. */
chunk->target = ALIGN_UP (min_addr, align);
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
chunk->target = ALIGN_DOWN (max_addr, align);
else
chunk->target = ALIGN_UP (min_addr, align);
while (1)
{
struct grub_relocator_chunk *chunk2;
@ -514,7 +524,10 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|| (chunk->target <= chunk2->target + chunk2->size
&& chunk2->target + chunk2->size < chunk->target + size))
{
chunk->target = ALIGN_UP (chunk2->target + chunk2->size, align);
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
chunk->target = ALIGN_DOWN (chunk2->target, align);
else
chunk->target = ALIGN_UP (chunk2->target + chunk2->size, align);
break;
}
if (!chunk2)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);