Check memory map when choosing address
This commit is contained in:
parent
5490ddc18b
commit
ba2f141cb5
1 changed files with 40 additions and 6 deletions
|
@ -21,6 +21,7 @@
|
||||||
#include <grub/mm_private.h>
|
#include <grub/mm_private.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/cache.h>
|
#include <grub/cache.h>
|
||||||
|
#include <grub/memory.h>
|
||||||
|
|
||||||
struct grub_relocator
|
struct grub_relocator
|
||||||
{
|
{
|
||||||
|
@ -63,6 +64,7 @@ struct grub_relocator_extra_block
|
||||||
grub_addr_t end;
|
grub_addr_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
struct grub_relocator_fw_leftover
|
struct grub_relocator_fw_leftover
|
||||||
{
|
{
|
||||||
struct grub_relocator_fw_leftover *next;
|
struct grub_relocator_fw_leftover *next;
|
||||||
|
@ -72,6 +74,8 @@ struct grub_relocator_fw_leftover
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_relocator_fw_leftover *leftovers;
|
struct grub_relocator_fw_leftover *leftovers;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct grub_relocator_extra_block *extra_blocks;
|
struct grub_relocator_extra_block *extra_blocks;
|
||||||
|
|
||||||
struct grub_relocator *
|
struct grub_relocator *
|
||||||
|
@ -220,6 +224,7 @@ allocate_inreg (grub_addr_t addr, grub_size_t size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
static void
|
static void
|
||||||
check_leftover (struct grub_relocator_fw_leftover *lo)
|
check_leftover (struct grub_relocator_fw_leftover *lo)
|
||||||
{
|
{
|
||||||
|
@ -233,6 +238,7 @@ check_leftover (struct grub_relocator_fw_leftover *lo)
|
||||||
if (lo->next)
|
if (lo->next)
|
||||||
lo->next->prev = lo->prev;
|
lo->next->prev = lo->prev;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_subchunk (const struct grub_relocator_subchunk *subchu)
|
free_subchunk (const struct grub_relocator_subchunk *subchu)
|
||||||
|
@ -923,7 +929,10 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
curschu->size = alloc_end - alloc_start;
|
curschu->size = alloc_end - alloc_start;
|
||||||
if (typepre == CHUNK_TYPE_REGION_START)
|
if (typepre == CHUNK_TYPE_REGION_START)
|
||||||
if (!oom && (typepre == CHUNK_TYPE_REGION_START
|
if (!oom && (typepre == CHUNK_TYPE_REGION_START
|
||||||
|| typepre == CHUNK_TYPE_FIRMWARE))
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
|
|| typepre == CHUNK_TYPE_FIRMWARE
|
||||||
|
#endif
|
||||||
|
))
|
||||||
{
|
{
|
||||||
struct grub_relocator_extra_block *ne;
|
struct grub_relocator_extra_block *ne;
|
||||||
ne = grub_malloc (sizeof (*ne));
|
ne = grub_malloc (sizeof (*ne));
|
||||||
|
@ -1282,11 +1291,36 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
||||||
}
|
}
|
||||||
while (0);
|
while (0);
|
||||||
|
|
||||||
/* FIXME: check memory map. */
|
{
|
||||||
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
|
int found = 0;
|
||||||
chunk->target = ALIGN_DOWN (max_addr, align);
|
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||||
else
|
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz, grub_uint32_t type)
|
||||||
chunk->target = ALIGN_UP (min_addr, align);
|
{
|
||||||
|
grub_uint64_t candidate;
|
||||||
|
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||||
|
return 0;
|
||||||
|
candidate = ALIGN_UP (addr, align);
|
||||||
|
if (candidate < min_addr)
|
||||||
|
candidate = min_addr;
|
||||||
|
if (candidate + size >= addr + sz
|
||||||
|
|| candidate > ALIGN_DOWN (max_addr, align))
|
||||||
|
return 0;
|
||||||
|
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
|
||||||
|
candidate = ALIGN_DOWN (addr + sz - size, align);
|
||||||
|
if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH
|
||||||
|
&& candidate > chunk->target))
|
||||||
|
chunk->target = candidate;
|
||||||
|
if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_LOW
|
||||||
|
&& candidate < chunk->target))
|
||||||
|
chunk->target = candidate;
|
||||||
|
found = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_machine_mmap_iterate (hook);
|
||||||
|
if (!found)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target");
|
||||||
|
}
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
struct grub_relocator_chunk *chunk2;
|
struct grub_relocator_chunk *chunk2;
|
||||||
|
|
Loading…
Reference in a new issue