Reenable XNU

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-11 13:43:44 +01:00
parent 669a1c01fb
commit cb1b2ad7e0
6 changed files with 148 additions and 150 deletions

View file

@ -179,7 +179,7 @@ linux_mod_SOURCES = loader/i386/linux.c
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
#pkglib_MODULES += xnu.mod
pkglib_MODULES += xnu.mod
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
xnu_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -117,5 +117,4 @@ grub_err_t grub_xnu_boot (void);
grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
grub_err_t
grub_cpu_xnu_fill_devicetree (void);
extern grub_uint32_t grub_xnu_heap_will_be_at;
#endif

View file

@ -87,7 +87,7 @@ extern struct grub_xnu_devtree_key *grub_xnu_devtree_root;
void grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur);
grub_err_t grub_xnu_writetree_toheap (void **start, grub_size_t *size);
grub_err_t grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size);
struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key **parent,
char *name);
@ -102,11 +102,12 @@ grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
int maxrecursion);
grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
int maxrecursion);
void *grub_xnu_heap_malloc (int size);
grub_err_t grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target);
grub_err_t grub_xnu_fill_devicetree (void);
extern grub_uint32_t grub_xnu_heap_real_start;
extern struct grub_relocator *grub_xnu_relocator;
extern grub_size_t grub_xnu_heap_size;
extern void *grub_xnu_heap_start;
extern struct grub_video_bitmap *grub_xnu_bitmap;
extern int grub_xnu_is_64bit;
extern grub_addr_t grub_xnu_heap_target_start;
#endif

View file

@ -35,7 +35,6 @@
#include <grub/i18n.h>
char grub_xnu_cmdline[1024];
grub_uint32_t grub_xnu_heap_will_be_at;
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
/* Aliases set for some tables. */
@ -832,26 +831,25 @@ grub_xnu_boot_resume (void)
state.eip = grub_xnu_entry_point;
state.eax = grub_xnu_arg1;
return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
state);
return grub_relocator32_boot (grub_xnu_relocator, state);
}
/* Boot xnu. */
grub_err_t
grub_xnu_boot (void)
{
struct grub_xnu_boot_params *bootparams_relloc;
grub_off_t bootparams_relloc_off;
grub_off_t mmap_relloc_off;
struct grub_xnu_boot_params *bootparams;
grub_addr_t bootparams_target;
grub_err_t err;
grub_efi_uintn_t memory_map_size = 0;
grub_efi_memory_descriptor_t *memory_map;
grub_addr_t memory_map_target;
grub_efi_uintn_t map_key = 0;
grub_efi_uintn_t descriptor_size = 0;
grub_efi_uint32_t descriptor_version = 0;
grub_uint64_t firstruntimepage, lastruntimepage;
grub_uint64_t curruntimepage;
void *devtree;
grub_addr_t devtree_target;
grub_size_t devtreelen;
int i;
struct grub_relocator32_state state;
@ -895,26 +893,25 @@ grub_xnu_boot (void)
}
/* Relocate the boot parameters to heap. */
bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
if (! bootparams_relloc)
return grub_errno;
bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
- (grub_uint8_t *) grub_xnu_heap_start;
err = grub_xnu_heap_malloc (sizeof (*bootparams),
(void **) &bootparams, &bootparams_target);
if (err)
return err;
/* Set video. */
err = grub_xnu_set_video (bootparams_relloc);
err = grub_xnu_set_video (bootparams);
if (err != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_printf ("Booting in blind mode\n");
bootparams_relloc->lfb_mode = 0;
bootparams_relloc->lfb_width = 0;
bootparams_relloc->lfb_height = 0;
bootparams_relloc->lfb_depth = 0;
bootparams_relloc->lfb_line_len = 0;
bootparams_relloc->lfb_base = 0;
bootparams->lfb_mode = 0;
bootparams->lfb_width = 0;
bootparams->lfb_height = 0;
bootparams->lfb_depth = 0;
bootparams->lfb_line_len = 0;
bootparams->lfb_base = 0;
}
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
@ -925,38 +922,29 @@ grub_xnu_boot (void)
/* We will do few allocations later. Reserve some space for possible
memory map growth. */
memory_map_size += 20 * descriptor_size;
memory_map = grub_xnu_heap_malloc (memory_map_size);
if (! memory_map)
return grub_errno;
mmap_relloc_off = (grub_uint8_t *) memory_map
- (grub_uint8_t *) grub_xnu_heap_start;
err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
err = grub_xnu_heap_malloc (memory_map_size,
(void **) &memory_map, &memory_map_target);
if (err)
return err;
bootparams_relloc = (struct grub_xnu_boot_params *)
(bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
sizeof (bootparams_relloc->cmdline));
err = grub_xnu_writetree_toheap (&devtree_target, &devtreelen);
if (err)
return err;
bootparams_relloc->devtree
= ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
bootparams_relloc->devtreelen = devtreelen;
grub_memcpy (bootparams->cmdline, grub_xnu_cmdline,
sizeof (bootparams->cmdline));
memory_map = (grub_efi_memory_descriptor_t *)
((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off);
bootparams->devtree = devtree_target;
bootparams->devtreelen = devtreelen;
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
&map_key, &descriptor_size,
&descriptor_version) <= 0)
return grub_errno;
bootparams_relloc->efi_system_table
= PTR_TO_UINT32 (grub_autoefi_system_table);
bootparams->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table);
firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at
firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start
+ grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
/ GRUB_XNU_PAGESIZE) + 20;
curruntimepage = firstruntimepage;
@ -977,7 +965,7 @@ grub_xnu_boot (void)
<= PTR_TO_UINT64 (grub_autoefi_system_table)
&& curdesc->physical_start + (curdesc->num_pages << 12)
> PTR_TO_UINT64 (grub_autoefi_system_table))
bootparams_relloc->efi_system_table
bootparams->efi_system_table
= PTR_TO_UINT64 (grub_autoefi_system_table)
- curdesc->physical_start + curdesc->virtual_start;
if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
@ -987,25 +975,25 @@ grub_xnu_boot (void)
lastruntimepage = curruntimepage;
bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
bootparams_relloc->efi_mmap_size = memory_map_size;
bootparams_relloc->efi_mem_desc_size = descriptor_size;
bootparams_relloc->efi_mem_desc_version = descriptor_version;
bootparams->efi_mmap = memory_map_target;
bootparams->efi_mmap_size = memory_map_size;
bootparams->efi_mem_desc_size = descriptor_size;
bootparams->efi_mem_desc_version = descriptor_version;
bootparams_relloc->heap_start = grub_xnu_heap_will_be_at;
bootparams_relloc->heap_size = grub_xnu_heap_size;
bootparams_relloc->efi_runtime_first_page = firstruntimepage;
bootparams->heap_start = grub_xnu_heap_target_start;
bootparams->heap_size = grub_xnu_heap_size;
bootparams->efi_runtime_first_page = firstruntimepage;
bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage;
bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
bootparams->efi_runtime_npages = lastruntimepage - firstruntimepage;
bootparams->efi_uintnbits = SIZEOF_OF_UINTN * 8;
bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
bootparams->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
bootparams->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
/* Parameters for asm helper. */
grub_xnu_stack = bootparams_relloc->heap_start
+ bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
grub_xnu_stack = bootparams->heap_start
+ bootparams->heap_size + GRUB_XNU_PAGESIZE;
grub_xnu_arg1 = bootparams_target;
if (! grub_autoefi_exit_boot_services (map_key))
return grub_error (GRUB_ERR_IO, "can't exit boot services");
@ -1016,8 +1004,7 @@ grub_xnu_boot (void)
state.eip = grub_xnu_entry_point;
state.eax = grub_xnu_arg1;
state.esp = grub_xnu_stack;
return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
state);
return grub_relocator32_boot (grub_xnu_relocator, state);
}
static grub_command_t cmd_devprop_load;

View file

@ -39,45 +39,28 @@ static int driverspackagenum = 0;
static int driversnum = 0;
int grub_xnu_is_64bit = 0;
void *grub_xnu_heap_start = 0;
grub_addr_t grub_xnu_heap_target_start = 0;
grub_size_t grub_xnu_heap_size = 0;
/* Allocate heap by 32MB-blocks. */
#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
struct grub_relocator *grub_xnu_relocator;
static grub_err_t
grub_xnu_register_memory (char *prefix, int *suffix,
void *addr, grub_size_t size);
void *
grub_xnu_heap_malloc (int size)
grub_addr_t addr, grub_size_t size);
grub_err_t
grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
{
void *val;
int oldblknum, newblknum;
grub_err_t err;
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, src,
grub_xnu_heap_target_start
+ grub_xnu_heap_size, size);
if (err)
return err;
/* The page after the heap is used for stack. Ensure it's usable. */
if (grub_xnu_heap_size)
oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
else
oldblknum = 0;
newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
if (oldblknum != newblknum)
{
/* FIXME: instruct realloc to allocate at 1MB if possible once
advanced mm is ready. */
grub_xnu_heap_start
= XNU_RELOCATOR (realloc) (grub_xnu_heap_start,
newblknum
* GRUB_XNU_HEAP_ALLOC_BLOCK);
if (!grub_xnu_heap_start)
return NULL;
}
val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size;
*target = grub_xnu_heap_target_start + grub_xnu_heap_size;
grub_xnu_heap_size += size;
grub_dprintf ("xnu", "val=%p\n", val);
return val;
grub_dprintf ("xnu", "val=%p\n", *src);
return GRUB_ERR_NONE;
}
/* Make sure next block of the heap will be aligned.
@ -86,11 +69,9 @@ grub_xnu_heap_malloc (int size)
grub_err_t
grub_xnu_align_heap (int align)
{
int align_overhead = align - grub_xnu_heap_size % align;
if (align_overhead == align)
return GRUB_ERR_NONE;
if (! grub_xnu_heap_malloc (align_overhead))
return grub_errno;
grub_xnu_heap_size
= ALIGN_UP (grub_xnu_heap_target_start+ grub_xnu_heap_size, align)
- grub_xnu_heap_target_start;
return GRUB_ERR_NONE;
}
@ -206,13 +187,14 @@ grub_xnu_writetree_toheap_real (void *curptr,
}
grub_err_t
grub_xnu_writetree_toheap (void **start, grub_size_t *size)
grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size)
{
struct grub_xnu_devtree_key *chosen;
struct grub_xnu_devtree_key *memorymap;
struct grub_xnu_devtree_key *driverkey;
struct grub_xnu_extdesc *extdesc;
grub_err_t err;
void *src;
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
if (err)
@ -243,16 +225,17 @@ grub_xnu_writetree_toheap (void **start, grub_size_t *size)
/* Allocate the space based on the size with dummy value. */
*size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
*start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
- *size % GRUB_XNU_PAGESIZE);
err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE),
&src, target);
if (err)
return err;
/* Put real data in the dummy. */
extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start
+ grub_xnu_heap_will_be_at;
extdesc->addr = *target;
extdesc->size = (grub_uint32_t) *size;
/* Write the tree to heap. */
grub_xnu_writetree_toheap_real (*start, grub_xnu_devtree_root, "/");
grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/");
return GRUB_ERR_NONE;
}
@ -337,8 +320,9 @@ grub_xnu_unload (void)
/* Free loaded image. */
driversnum = 0;
driverspackagenum = 0;
grub_free (grub_xnu_heap_start);
grub_xnu_heap_start = 0;
grub_relocator_unload (grub_xnu_relocator);
grub_xnu_relocator = NULL;
grub_xnu_heap_target_start = 0;
grub_xnu_heap_size = 0;
grub_xnu_unlock ();
return GRUB_ERR_NONE;
@ -353,6 +337,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
grub_uint32_t startcode, endcode;
int i;
char *ptr, *loadaddr;
grub_addr_t loadaddr_target;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
@ -380,15 +365,18 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
(unsigned long) endcode, (unsigned long) startcode);
loadaddr = grub_xnu_heap_malloc (endcode - startcode);
grub_xnu_heap_will_be_at = startcode;
grub_xnu_relocator = grub_relocator_new ();
if (!grub_xnu_relocator)
return grub_errno;
grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
&loadaddr_target);
if (! loadaddr)
if (err)
{
grub_macho_close (macho);
grub_xnu_unload ();
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"not enough memory to load kernel");
return err;
}
/* Load kernel. */
@ -451,6 +439,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
grub_uint64_t startcode, endcode;
int i;
char *ptr, *loadaddr;
grub_addr_t loadaddr_target;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
@ -481,15 +470,18 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
(unsigned long) endcode, (unsigned long) startcode);
loadaddr = grub_xnu_heap_malloc (endcode - startcode);
grub_xnu_heap_will_be_at = startcode;
grub_xnu_relocator = grub_relocator_new ();
if (!grub_xnu_relocator)
return grub_errno;
grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
&loadaddr_target);
if (! loadaddr)
if (err)
{
grub_macho_close (macho);
grub_xnu_unload ();
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"not enough memory to load kernel");
return err;
}
/* Load kernel. */
@ -547,7 +539,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
and increment SUFFIX. */
static grub_err_t
grub_xnu_register_memory (char *prefix, int *suffix,
void *addr, grub_size_t size)
grub_addr_t addr, grub_size_t size)
{
struct grub_xnu_devtree_key *chosen;
struct grub_xnu_devtree_key *memorymap;
@ -585,8 +577,7 @@ grub_xnu_register_memory (char *prefix, int *suffix,
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
if (! driverkey->data)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
extdesc->addr = grub_xnu_heap_will_be_at +
((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
extdesc->addr = addr;
extdesc->size = (grub_uint32_t) size;
return GRUB_ERR_NONE;
}
@ -628,7 +619,8 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
grub_file_t infoplist;
struct grub_xnu_extheader *exthead;
int neededspace = sizeof (*exthead);
grub_uint8_t *buf;
grub_uint8_t *buf, *buf0;
grub_addr_t buf_target;
grub_size_t infoplistsize = 0, machosize = 0;
char *name, *nameend;
int namelen;
@ -683,7 +675,10 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
if (err)
return err;
buf = grub_xnu_heap_malloc (neededspace);
err = grub_xnu_heap_malloc (neededspace, (void **) &buf0, &buf_target);
if (err)
return err;
buf = buf0;
exthead = (struct grub_xnu_extheader *) buf;
grub_memset (exthead, 0, sizeof (*exthead));
@ -692,8 +687,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the binary. */
if (macho)
{
exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
exthead->binaryaddr = buf_target + (buf - buf0);
exthead->binarysize = machosize;
if (grub_xnu_is_64bit)
err = grub_macho_readfile64 (macho, buf);
@ -712,8 +706,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the plist. */
if (infoplist)
{
exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
exthead->infoplistaddr = buf_target + (buf - buf0);
exthead->infoplistsize = infoplistsize + 1;
if (grub_file_read (infoplist, buf, infoplistsize)
!= (grub_ssize_t) (infoplistsize))
@ -729,15 +722,14 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
}
grub_errno = GRUB_ERR_NONE;
exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
exthead->nameaddr = (buf - buf0) + buf_target;
exthead->namesize = namelen + 1;
grub_memcpy (buf, name, namelen);
buf[namelen] = 0;
buf += namelen + 1;
/* Announce to kernel */
return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
return grub_xnu_register_memory ("Driver-", &driversnum, buf_target,
neededspace);
}
@ -748,6 +740,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file;
void *loadto;
grub_addr_t loadto_target;
grub_err_t err;
grub_off_t readoff = 0;
grub_ssize_t readlen = -1;
@ -836,11 +829,11 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
return err;
}
loadto = grub_xnu_heap_malloc (readlen);
if (! loadto)
err = grub_xnu_heap_malloc (readlen, &loadto, &loadto_target);
if (err)
{
grub_file_close (file);
return grub_errno;
return err;
}
/* Read the file. */
@ -855,7 +848,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
/* Pass it to kernel. */
return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
loadto, readlen);
loadto_target, readlen);
}
static grub_err_t
@ -864,6 +857,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file;
void *loadto;
grub_addr_t loadto_target;
grub_err_t err;
grub_size_t size;
@ -884,9 +878,9 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
size = grub_file_size (file);
loadto = grub_xnu_heap_malloc (size);
if (! loadto)
return grub_errno;
err = grub_xnu_heap_malloc (size, &loadto, &loadto_target);
if (err)
return err;
if (grub_file_read (file, loadto, size)
!= (grub_ssize_t) (size))
{
@ -894,7 +888,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
}
return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
return grub_xnu_register_memory ("RAMDisk", 0, loadto_target, size);
}
/* Returns true if the kext should be loaded according to plist

View file

@ -45,10 +45,12 @@ grub_xnu_resume (char *imagename)
grub_file_t file;
grub_size_t total_header_size;
struct grub_xnu_hibernate_header hibhead;
grub_uint8_t *buf;
void *code;
void *image;
grub_uint32_t codedest;
grub_uint32_t codesize;
grub_addr_t target_image;
grub_err_t err;
file = grub_file_open (imagename);
if (! file)
@ -94,18 +96,35 @@ grub_xnu_resume (char *imagename)
/* Try to allocate necessary space.
FIXME: mm isn't good enough yet to handle huge allocations.
*/
grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size
+ codesize
+ GRUB_XNU_PAGESIZE);
if (! buf)
grub_xnu_relocator = grub_relocator_new ();
if (!grub_xnu_relocator)
{
grub_file_close (file);
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;
}
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &image,
&target_image, 0,
(0xffffffff - hibhead.image_size) + 1,
hibhead.image_size,
GRUB_XNU_PAGESIZE);
if (err)
{
grub_file_close (file);
return err;
}
/* Read code part. */
if (grub_file_seek (file, total_header_size) == (grub_off_t) -1
|| grub_file_read (file, buf, codesize)
|| grub_file_read (file, code, codesize)
!= (grub_ssize_t) codesize)
{
grub_file_close (file);
@ -114,8 +133,7 @@ grub_xnu_resume (char *imagename)
/* Read image. */
if (grub_file_seek (file, 0) == (grub_off_t) -1
|| grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE,
hibhead.image_size)
|| grub_file_read (file, image, hibhead.image_size)
!= (grub_ssize_t) hibhead.image_size)
{
grub_file_close (file);
@ -124,12 +142,11 @@ grub_xnu_resume (char *imagename)
grub_file_close (file);
/* Setup variables needed by asm helper. */
grub_xnu_heap_will_be_at = codedest;
grub_xnu_heap_start = buf;
grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size;
grub_xnu_heap_target_start = codedest;
grub_xnu_heap_size = target_image + hibhead.image_size - codedest;
grub_xnu_stack = (codedest + hibhead.stack);
grub_xnu_entry_point = (codedest + hibhead.entry_point);
grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE;
grub_xnu_arg1 = target_image;
grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point);
grub_dprintf ("xnu", "image at 0x%x\n",