Second part of p2v support

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-04-21 19:13:45 +02:00
parent 368c17f85d
commit 4b2ec20b41
15 changed files with 361 additions and 212 deletions

View File

@ -21,19 +21,29 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/memory.h>
struct grub_relocator;
struct grub_relocator_chunk;
typedef const struct grub_relocator_chunk *grub_relocator_chunk_t;
struct grub_relocator *grub_relocator_new (void);
grub_err_t
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
grub_addr_t target, grub_size_t size);
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
grub_relocator_chunk_t *out,
grub_phys_addr_t target, grub_size_t size);
void *
get_virtual_current_address (grub_relocator_chunk_t in);
grub_phys_addr_t
get_physical_target_address (grub_relocator_chunk_t in);
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_relocator_alloc_chunk_align (struct grub_relocator *rel,
grub_relocator_chunk_t *out,
grub_phys_addr_t min_addr,
grub_phys_addr_t max_addr,
grub_size_t size, grub_size_t align,
int preference);

View File

@ -32,7 +32,7 @@ void
grub_cpu_relocator_init (void);
grub_err_t
grub_relocator_prepare_relocs (struct grub_relocator *rel,
void *addr,
grub_addr_t addr,
void **relstart, grub_size_t *relsize);
void grub_cpu_relocator_forward (void *rels, void *src, void *tgt,
grub_size_t size);

View File

@ -84,12 +84,6 @@ grub_size_t grub_relocator_jumper_size = 12;
grub_size_t grub_relocator_jumper_size = 7;
#endif
static inline void *
ptov (grub_addr_t a)
{
return (void *) a;
}
void
grub_cpu_relocator_init (void)
{
@ -154,12 +148,11 @@ grub_err_t
grub_relocator32_boot (struct grub_relocator *rel,
struct grub_relocator32_state state)
{
grub_phys_addr_t target;
void *src;
grub_err_t err;
void *relst;
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
(0xffffffff - RELOCATOR_SIZEOF (32))
+ 1, RELOCATOR_SIZEOF (32), 16,
GRUB_RELOCATOR_PREFERENCE_NONE);
@ -174,9 +167,11 @@ grub_relocator32_boot (struct grub_relocator *rel,
grub_relocator32_esp = state.esp;
grub_relocator32_esi = state.esi;
grub_memmove (src, &grub_relocator32_start, RELOCATOR_SIZEOF (32));
grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start,
RELOCATOR_SIZEOF (32));
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
&relst, NULL);
if (err)
return err;
@ -191,12 +186,11 @@ grub_err_t
grub_relocator16_boot (struct grub_relocator *rel,
struct grub_relocator16_state state)
{
grub_phys_addr_t target;
void *src;
grub_err_t err;
void *relst;
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
0xa0000 - RELOCATOR_SIZEOF (16),
RELOCATOR_SIZEOF (16), 16,
GRUB_RELOCATOR_PREFERENCE_NONE);
@ -216,12 +210,16 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator16_edx = state.edx;
grub_memmove (src, &grub_relocator16_start, RELOCATOR_SIZEOF (16));
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
RELOCATOR_SIZEOF (16));
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
&relst, NULL);
if (err)
return err;
grub_printf ("%p\n", relst);
asm volatile ("cli");
((void (*) (void)) relst) ();
@ -234,12 +232,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
struct grub_relocator64_state state,
grub_addr_t min_addr, grub_addr_t max_addr)
{
grub_phys_addr_t target;
void *src;
grub_err_t err;
void *relst;
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (rel, &src, &target, min_addr,
err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
max_addr - RELOCATOR_SIZEOF (64),
RELOCATOR_SIZEOF (64), 16,
GRUB_RELOCATOR_PREFERENCE_NONE);
@ -255,9 +252,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
grub_relocator64_rsi = state.rsi;
grub_relocator64_cr3 = state.cr3;
grub_memmove (src, &grub_relocator64_start, RELOCATOR_SIZEOF (64));
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_start,
RELOCATOR_SIZEOF (64));
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
&relst, NULL);
if (err)
return err;

View File

@ -81,6 +81,18 @@ struct grub_relocator_fw_leftover *leftovers;
struct grub_relocator_extra_block *extra_blocks;
void *
get_virtual_current_address (grub_relocator_chunk_t in)
{
return in->srcv;
}
grub_phys_addr_t
get_physical_target_address (grub_relocator_chunk_t in)
{
return in->target;
}
struct grub_relocator *
grub_relocator_new (void)
{
@ -1126,7 +1138,8 @@ adjust_limits (struct grub_relocator *rel,
}
grub_err_t
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
grub_relocator_chunk_t *out,
grub_phys_addr_t target, grub_size_t size)
{
struct grub_relocator_chunk *chunk;
@ -1221,13 +1234,14 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
rel->chunks->next);
*src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*out = chunk;
return GRUB_ERR_NONE;
}
grub_err_t
grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
grub_phys_addr_t *target,
grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
grub_relocator_chunk_t *out,
grub_phys_addr_t min_addr,
grub_phys_addr_t max_addr,
grub_size_t size, grub_size_t align,
@ -1262,8 +1276,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
chunk->size = size;
chunk->next = rel->chunks;
rel->chunks = chunk;
*src = (void *) chunk->src;
*target = chunk->target;
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*out = chunk;
return GRUB_ERR_NONE;
}
@ -1300,12 +1314,12 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
return 0;
candidate = ALIGN_UP (addr, align);
if (candidate < min_addr)
candidate = min_addr;
if (candidate + size >= addr + sz
candidate = ALIGN_UP (min_addr, align);
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);
candidate = ALIGN_DOWN (min (addr + sz - size, max_addr), align);
if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH
&& candidate > chunk->target))
chunk->target = candidate;
@ -1353,8 +1367,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
rel->chunks = chunk;
grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
rel->chunks->next);
*src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*target = chunk->target;
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*out = chunk;
return GRUB_ERR_NONE;
}
@ -1378,7 +1392,7 @@ grub_relocator_unload (struct grub_relocator *rel)
}
grub_err_t
grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
void **relstart, grub_size_t *relsize)
{
grub_uint8_t *rels;
@ -1395,12 +1409,12 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
grub_relocator_align,
rel->relocators_size, &movers_chunk, 1, 1))
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
rels = rels0 = movers_chunk.srcv;
rels = rels0 = grub_map_memory (movers_chunk.src, movers_chunk.size);
if (relsize)
*relsize = rel->relocators_size;
grub_dprintf ("relocator", "Relocs allocated\n");
grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv);
{
unsigned i;

View File

@ -606,10 +606,14 @@ grub_freebsd_boot (void)
if (is_64bit)
p_size += 4096 * 3;
err = grub_relocator_alloc_chunk_addr (relocator, (void **) &p,
kern_end, p_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
kern_end, p_size);
if (err)
return err;
p = get_virtual_current_address (ch);
}
p_target = kern_end;
p0 = p;
kern_end += p_size;
@ -682,14 +686,18 @@ grub_freebsd_boot (void)
grub_uint32_t *stack;
grub_addr_t stack_target;
err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
&stack_target,
0x10000, 0x90000,
3 * sizeof (grub_uint32_t)
+ sizeof (bi), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch,
0x10000, 0x90000,
3 * sizeof (grub_uint32_t)
+ sizeof (bi), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
stack = get_virtual_current_address (ch);
stack_target = get_physical_target_address (ch);
}
#ifdef GRUB_MACHINE_EFI
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@ -714,14 +722,19 @@ grub_freebsd_boot (void)
struct grub_relocator32_state state;
grub_uint32_t *stack;
grub_addr_t stack_target;
err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
&stack_target,
0x10000, 0x90000,
9 * sizeof (grub_uint32_t)
+ sizeof (bi), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch,
0x10000, 0x90000,
9 * sizeof (grub_uint32_t)
+ sizeof (bi), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
stack = get_virtual_current_address (ch);
stack_target = get_physical_target_address (ch);
}
#ifdef GRUB_MACHINE_EFI
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@ -772,12 +785,16 @@ grub_openbsd_boot (void)
}
buf_target = GRUB_BSD_TEMP_BUFFER - 9 * sizeof (grub_uint32_t);
err = grub_relocator_alloc_chunk_addr (relocator, &buf0,
buf_target, tag_buf_len
+ sizeof (struct grub_openbsd_bootargs)
+ 9 * sizeof (grub_uint32_t));
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch, buf_target,
tag_buf_len
+ sizeof (struct grub_openbsd_bootargs)
+ 9 * sizeof (grub_uint32_t));
if (err)
return err;
buf0 = get_virtual_current_address (ch);
}
stack = (grub_uint32_t *) buf0;
arg0 = curarg = stack + 9;
@ -976,12 +993,16 @@ grub_netbsd_boot (void)
}
arg_target = kern_end;
err = grub_relocator_alloc_chunk_addr (relocator, &curarg,
arg_target, tag_buf_len
+ sizeof (struct grub_netbsd_bootinfo)
+ tag_count * sizeof (grub_uint32_t));
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
arg_target, tag_buf_len
+ sizeof (struct grub_netbsd_bootinfo)
+ tag_count * sizeof (grub_uint32_t));
if (err)
return err;
curarg = get_virtual_current_address (ch);
}
arg0 = curarg;
bootinfo = (void *) ((grub_uint8_t *) arg0 + tag_buf_len);
@ -1004,12 +1025,16 @@ grub_netbsd_boot (void)
}
}
err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
&stack_target, 0x10000, 0x90000,
7 * sizeof (grub_uint32_t), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000,
7 * sizeof (grub_uint32_t), 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
stack = get_virtual_current_address (ch);
stack_target = get_physical_target_address (ch);
}
#ifdef GRUB_MACHINE_EFI
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@ -1107,10 +1132,15 @@ grub_bsd_load_aout (grub_file_t file)
if (!relocator)
return grub_errno;
err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
kern_start, kern_end - kern_start);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
kern_start, kern_end - kern_start);
if (err)
return err;
kern_chunk_src = get_virtual_current_address (ch);
}
return grub_aout_load (file, ofs, kern_chunk_src,
ah.aout32.a_text + ah.aout32.a_data,
@ -1210,15 +1240,19 @@ grub_bsd_load_elf (grub_elf_t elf)
if (grub_elf_is_elf32 (elf))
{
grub_relocator_chunk_t ch;
entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
err = grub_elf32_phdr_iterate (elf, grub_bsd_elf32_size_hook, NULL);
if (err)
return err;
err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
kern_start, kern_end - kern_start);
if (err)
return err;
kern_chunk_src = get_virtual_current_address (ch);
return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
}
else if (grub_elf_is_elf64 (elf))
@ -1246,10 +1280,15 @@ grub_bsd_load_elf (grub_elf_t elf)
grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n",
(unsigned long) kern_start, (unsigned long) kern_end);
err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
kern_start, kern_end - kern_start);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start,
kern_end - kern_start);
if (err)
return err;
kern_chunk_src = get_virtual_current_address (ch);
}
return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
}
@ -1682,10 +1721,15 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
if ((!file) || (!file->size))
goto fail;
err = grub_relocator_alloc_chunk_addr (relocator, &src, kern_end,
file->size);
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end,
file->size);
if (err)
goto fail;
src = get_virtual_current_address (ch);
}
grub_file_read (file, src, file->size);
if (grub_errno)
@ -1728,10 +1772,15 @@ grub_netbsd_module_load (char *filename, grub_uint32_t type)
if ((!file) || (!file->size))
goto fail;
err = grub_relocator_alloc_chunk_addr (relocator, &src, kern_end,
file->size);
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end,
file->size);
if (err)
goto fail;
src = get_virtual_current_address (ch);
}
grub_file_read (file, src, file->size);
if (grub_errno)

View File

@ -103,10 +103,14 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
chunk_size += s->sh_size;
}
err = grub_relocator_alloc_chunk_addr (relocator, &chunk_src,
module, chunk_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
module, chunk_size);
if (err)
return err;
chunk_src = get_virtual_current_address (ch);
}
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+ e.e_shnum * e.e_shentsize);
@ -191,10 +195,16 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
chunk_size = s->sh_addr + s->sh_size;
}
err = grub_relocator_alloc_chunk_addr (relocator, &chunk_src,
module, chunk_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
module, chunk_size);
if (err)
return err;
chunk_src = get_virtual_current_address (ch);
}
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+ e.e_shnum * e.e_shentsize);
@ -300,10 +310,15 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
+ 2 * sizeof (grub_freebsd_addr_t);
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
err = grub_relocator_alloc_chunk_addr (relocator, &sym_chunk,
symtarget, chunk_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
symtarget, chunk_size);
if (err)
return err;
sym_chunk = get_virtual_current_address (ch);
}
symstart = symtarget;
symend = symstart + chunk_size;
@ -413,10 +428,14 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
+ sizeof (e) + e.e_shnum * e.e_shentsize;
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
err = grub_relocator_alloc_chunk_addr (relocator, &sym_chunk,
symtarget, chunk_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
symtarget, chunk_size);
if (err)
return err;
sym_chunk = get_virtual_current_address (ch);
}
symtab.nsyms = 1;
symtab.ssyms = symtarget;

View File

@ -412,20 +412,28 @@ allocate_pages (grub_size_t prot_size)
goto fail;
}
err = grub_relocator_alloc_chunk_addr (relocator, &real_mode_mem,
real_mode_target,
(real_size + mmap_size
+ efi_mmap_size));
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
real_mode_target,
(real_size + mmap_size
+ efi_mmap_size));
if (err)
goto fail;
real_mode_mem = get_virtual_current_address (ch);
}
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
err = grub_relocator_alloc_chunk_addr (relocator, &prot_mode_mem,
prot_mode_target, prot_size);
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
prot_mode_target, prot_size);
if (err)
goto fail;
prot_mode_mem = get_virtual_current_address (ch);
}
grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
"prot_mode_mem = %lx, prot_mode_pages = %x\n",
@ -1111,12 +1119,16 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
err = grub_relocator_alloc_chunk_align (relocator, &initrd_mem,
&initrd_mem_target,
addr_min, addr, size, 0x1000,
GRUB_RELOCATOR_PREFERENCE_HIGH);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch,
addr_min, addr, size, 0x1000,
GRUB_RELOCATOR_PREFERENCE_HIGH);
if (err)
return err;
initrd_mem = get_virtual_current_address (ch);
initrd_mem_target = get_physical_target_address (ch);
}
if (grub_file_read (file, initrd_mem, size) != size)
{

View File

@ -108,6 +108,7 @@ grub_multiboot_load (grub_file_t file)
header->load_end_addr - header->load_addr);
grub_size_t code_size;
void *source;
grub_relocator_chunk_t ch;
if (header->bss_end_addr)
code_size = (header->bss_end_addr - header->load_addr);
@ -115,7 +116,7 @@ grub_multiboot_load (grub_file_t file)
code_size = load_size;
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&source, header->load_addr,
&ch, header->load_addr,
code_size);
if (err)
{
@ -123,6 +124,7 @@ grub_multiboot_load (grub_file_t file)
grub_free (buffer);
return err;
}
source = get_virtual_current_address (ch);
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
{
@ -322,16 +324,18 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
grub_err_t err;
grub_size_t bufsize;
grub_relocator_chunk_t ch;
bufsize = grub_multiboot_get_mbi_size ();
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
(void **) &ptrorig, &ptrdest,
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
0, 0xffffffff - bufsize,
bufsize, 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
ptrorig = get_virtual_current_address (ch);
ptrdest = (grub_addr_t) get_virtual_current_address (ch);
*target = ptrdest;

View File

@ -255,12 +255,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
}
}
err = grub_relocator_alloc_chunk_addr (relocator, (void **)
&grub_linux_real_chunk,
grub_linux_real_target,
GRUB_LINUX_SETUP_MOVE_SIZE);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
grub_linux_real_target,
GRUB_LINUX_SETUP_MOVE_SIZE);
if (err)
return err;
grub_linux_real_chunk = get_virtual_current_address (ch);
}
/* Put the real mode code at the temporary address. */
grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh));
@ -301,12 +304,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
else
grub_linux_prot_target = GRUB_LINUX_ZIMAGE_ADDR;
err = grub_relocator_alloc_chunk_addr (relocator,
(void **) &grub_linux_prot_chunk,
grub_linux_prot_target,
grub_linux16_prot_size);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
grub_linux_prot_target,
grub_linux16_prot_size);
if (err)
return err;
grub_linux_prot_chunk = get_virtual_current_address (ch);
}
len = grub_linux16_prot_size;
if (grub_file_read (file, grub_linux_prot_chunk, grub_linux16_prot_size)
@ -398,13 +404,17 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
size = grub_file_size (file);
err = grub_relocator_alloc_chunk_align (relocator, (void **) &initrd_chunk,
&initrd_addr,
addr_min, addr_max - size,
size, 0x1000,
GRUB_RELOCATOR_PREFERENCE_HIGH);
if (err)
return err;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch,
addr_min, addr_max - size,
size, 0x1000,
GRUB_RELOCATOR_PREFERENCE_HIGH);
if (err)
return err;
initrd_chunk = get_virtual_current_address (ch);
initrd_addr = get_physical_target_address (ch);
}
if (grub_file_read (file, initrd_chunk, size) != size)
{

View File

@ -90,10 +90,14 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
if (! file)
goto fail;
err = grub_relocator_alloc_chunk_addr (rel, &bs, 0x7C00,
GRUB_DISK_SECTOR_SIZE);
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
GRUB_DISK_SECTOR_SIZE);
if (err)
goto fail;
bs = get_virtual_current_address (ch);
}
edx = grub_get_root_biosnumber ();
dev = grub_device_open (0);
@ -112,10 +116,14 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
grub_device_close (dev);
ntldrsize = grub_file_size (file);
err = grub_relocator_alloc_chunk_addr (rel, &ntldr, GRUB_NTLDR_SEGMENT << 4,
ntldrsize);
if (err)
goto fail;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
ntldrsize);
if (err)
goto fail;
ntldr = get_virtual_current_address (ch);
}
if (grub_file_read (file, ntldr, ntldrsize)
!= (grub_ssize_t) ntldrsize)

View File

@ -284,16 +284,20 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
size = grub_file_size (file);
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &module,
&target,
0, (0xffffffff - size) + 1,
size, MULTIBOOT_MOD_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_file_close (file);
return err;
}
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
0, (0xffffffff - size) + 1,
size, MULTIBOOT_MOD_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_file_close (file);
return err;
}
module = get_virtual_current_address (ch);
target = (grub_addr_t) get_virtual_current_address (ch);
}
err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
if (err)

View File

@ -92,14 +92,18 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&source, phdr(i)->p_paddr,
phdr(i)->p_memsz);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
return err;
}
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&ch, phdr(i)->p_paddr,
phdr(i)->p_memsz);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
return err;
}
source = get_virtual_current_address (ch);
}
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
== (grub_off_t) -1)
@ -163,18 +167,22 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
if (sh->sh_size == 0)
continue;
err
= grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
&src, &target, 0,
(0xffffffff - sh->sh_size) + 1,
sh->sh_size,
sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
return err;
}
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
&ch, 0,
(0xffffffff - sh->sh_size)
+ 1, sh->sh_size,
sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
return err;
}
src = get_virtual_current_address (ch);
target = get_physical_target_address (ch);
}
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
return grub_error (GRUB_ERR_BAD_OS,

View File

@ -191,6 +191,7 @@ grub_multiboot_load (grub_file_t file)
addr_tag->load_end_addr - addr_tag->load_addr);
grub_size_t code_size;
void *source;
grub_relocator_chunk_t ch;
if (addr_tag->bss_end_addr)
code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
@ -198,7 +199,7 @@ grub_multiboot_load (grub_file_t file)
code_size = load_size;
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&source, addr_tag->load_addr,
&ch, addr_tag->load_addr,
code_size);
if (err)
{
@ -206,6 +207,7 @@ grub_multiboot_load (grub_file_t file)
grub_free (buffer);
return err;
}
source = get_virtual_current_address (ch);
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
{
@ -460,19 +462,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
grub_uint8_t *mbistart;
grub_err_t err;
grub_size_t bufsize;
grub_addr_t ptrdest;
grub_relocator_chunk_t ch;
bufsize = grub_multiboot_get_mbi_size ();
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
(void **) &ptrorig, &ptrdest,
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
0, 0xffffffff - bufsize,
bufsize, 4,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
*target = ptrdest;
ptrorig = get_virtual_current_address (ch);
*target = get_physical_target_address (ch);
mbistart = ptrorig;
ptrorig += 2 * sizeof (grub_uint32_t);

View File

@ -51,13 +51,15 @@ grub_err_t
grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
{
grub_err_t err;
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, src,
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
grub_xnu_heap_target_start
+ grub_xnu_heap_size, size);
if (err)
return err;
*src = get_virtual_current_address (ch);
*target = grub_xnu_heap_target_start + grub_xnu_heap_size;
grub_xnu_heap_size += size;
grub_dprintf ("xnu", "val=%p\n", *src);

View File

@ -103,25 +103,33 @@ grub_xnu_resume (char *imagename)
return grub_errno;
}
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &code,
codedest, codesize + GRUB_XNU_PAGESIZE);
if (err)
{
grub_file_close (file);
return err;
}
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, codedest,
codesize + GRUB_XNU_PAGESIZE);
if (err)
{
grub_file_close (file);
return err;
}
code = get_virtual_current_address (ch);
}
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &image,
&target_image, 0,
(0xffffffff - hibhead.image_size) + 1,
hibhead.image_size,
GRUB_XNU_PAGESIZE,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_file_close (file);
return err;
}
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
(0xffffffff - hibhead.image_size) + 1,
hibhead.image_size,
GRUB_XNU_PAGESIZE,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
{
grub_file_close (file);
return err;
}
image = get_virtual_current_address (ch);
target_image = get_physical_target_address (ch);
}
/* Read code part. */
if (grub_file_seek (file, total_header_size) == (grub_off_t) -1