Reenable XNU
This commit is contained in:
parent
669a1c01fb
commit
cb1b2ad7e0
6 changed files with 148 additions and 150 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
142
loader/xnu.c
142
loader/xnu.c
|
@ -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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, src,
|
||||
grub_xnu_heap_target_start
|
||||
+ grub_xnu_heap_size, size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
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
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue