grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [patch] rough Mac OS X loader


From: Marco Gerards
Subject: Re: [patch] rough Mac OS X loader
Date: Mon, 02 Jan 2006 18:29:34 +0100
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Hollis Blanchard <address@hidden> writes:

Hi Hollis,

> I've been working on a Mac OS X loader for GRUB. During the usual OS X
> boot process, the firmware loads the BootX bootloader (which is a
> hybrid CHRP script and XCOFF binary), which has a Mach-O loader and
> loads the OS X Mach kernel.

This is really great news!  Thanks a lot for doing this great job. :-)

> Rather than trying to load and run the Mach kernel directly, I chose
> to focus on the BootX bootloader, since it seems to do a fair amount
> of setup work that I would rather not duplicate in GRUB. Also
> important: if OS X is ever updated (for example, the parameter-passing
> mechanism between BootX and the kernel), we would need to track those
> changes, which is a lot more long-term maintenance.

Agreed.

> Unfortunately, BootX attempts to claim all memory from 0 to 96MiB,
> which conflicts with GRUB running in this area. To get around that
> problem, I install a trampoline just above 96MiB which releases all of
> GRUB's memory and jumps into BootX. It's a bit of a hack, and for
> example if the code being copied exceeds some fixed size (currently
> 0x200 bytes) things will fail mysteriously. I'm open to suggestions on
> that problem.
>
> I'm afraid I don't know if this code works yet. Because the current
> HFS+ driver doesn't support the HFS wrapper found on all Apple
> filesystems, I can't boot from an HFS+ installation. I've copied BootX
> to a plain HFS partition, and that works somewhat (I expect it fails
> when it cannot find /mach_kernel). I'm relatively optimistic, and I'm
> working on the HFS wrapper support now.

Cool.  If you need any help let me know.  I will look into this as
well, I assume we can discuss things in detail on IRC.

> There are a few rough edges still, but if there are no comments I will
> be checking this patch in largely unchanged some day.

Can you provide a changelog entry? :-)

There are some comments below, I hope some of them even make sense. ;)

>  include $(srcdir)/conf/common.mk
> Index: include/grub/xcoff.h
> ===================================================================

Is it possible to use the grub_ namespace in this file?  In elf.h this
is not done because it should be possible to update it from glibc,
AFAIK.

> Index: include/grub/powerpc/ieee1275/kernel.h
> ===================================================================
> RCS file: /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/kernel.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 kernel.h
> --- include/grub/powerpc/ieee1275/kernel.h    3 Aug 2005 22:53:50 -0000       
> 1.3
> +++ include/grub/powerpc/ieee1275/kernel.h    2 Jan 2006 00:34:11 -0000
> @@ -26,6 +26,9 @@ void EXPORT_FUNC (abort) (void);
>  void EXPORT_FUNC (grub_reboot) (void);
>  void EXPORT_FUNC (grub_halt) (void);
>  
> +void EXPORT_FUNC (grub_jump) (unsigned long text, unsigned long stack,
> +                           unsigned long arg1, unsigned long arg2);

Shouldn't a pointer be used here?

> +/* BootX, the Mac OS X bootloader, is an XCOFF executable with a CHRP script
> + * prepended to it.  We skip the script and load the XCOFF file.  */

What is in this script?  Are you completely sure it can be skipped?

Can you please remove the `*' on the second line so the comment
matches the style of the other sourcecode?


> +static grub_err_t
> +grub_macosx_release_mem (void)
> +{
> +  /* XXX write me */

I assume you encountered a bug in the firmware while writing this
function? :-)

> +  /* Load all section headers.  */
> +  scnhdr_bytes = filehdr->f_nscns * sizeof (struct xcoff_scnhdr);
> +  scnhdrs = grub_malloc (scnhdr_bytes);
> +  if (! scnhdrs)
> +    return grub_errno;
> +
> +  if (grub_file_read (file, (void *)scnhdrs, scnhdr_bytes) != scnhdr_bytes)
> +    return grub_error (GRUB_ERR_READ_ERROR,
> +                    "could not read XCOFF section headers");

You don't free scnhdrs here, is that intentional?

> +/* Find NULL-terminated `needle' in non-terminated `haystack'.  */
> +static void *
> +grub_memstr (void *haystack, int len, char *needle)

Perhaps it is better to move this to kern/misc.c?

> +/* grub_chain_trampoline is copied somewhere other than its link address
> + * and executes after all other code has been blown away. In order to call
> + * other functions from here, they must have been copied into a safe place 
> and
> + * their addresses passed as parameters. */

Same as above.

> +typedef void (*kernel_entry_t) (unsigned long, unsigned long, int (void *));
> +typedef int (*release_t) (grub_addr_t addr, grub_size_t size);
> +static void
> +grub_chain_trampoline (kernel_entry_t entry, release_t release)
> +{
> +  release (0x00003000, 0x06000000 - 0x3000);
> +  entry (0, 0, grub_ieee1275_entry_fn);
> +}
> +
> +static int
> +grub_macosx_install_trampoline (void)
> +{
> +  int rc;
> +
> +  /* XXX don't use magic numbers here */
> +  rc = grub_claimmap (GRUB_MACOSX_CHAIN_AREA, 0x200);
> +  rc |= grub_claimmap (GRUB_MACOSX_RELEASE_AREA, 0x200);
> +  rc |= grub_claimmap (GRUB_MACOSX_STACK_AREA, 0x200);
> +  if (rc)
> +    return rc;
> +
> +  grub_memcpy ((void *) GRUB_MACOSX_CHAIN_AREA, grub_chain_trampoline, 
> 0x200);
> +  grub_arch_sync_caches ((void *) GRUB_MACOSX_CHAIN_AREA, 0x200);
> +  grub_memcpy ((void *) GRUB_MACOSX_RELEASE_AREA, grub_ieee1275_release, 
> 0x200);
> +  grub_arch_sync_caches ((void *) GRUB_MACOSX_RELEASE_AREA, 0x200);

What is 0x200?  The maximum size of grub_chain_trampoline?  Perhaps
you can do something like: `grub_macosx_release_area -
grub_chain_trampoline', or do you think that is too unpredictable and
too ugly?

Thanks,
Marco





reply via email to

[Prev in Thread] Current Thread [Next in Thread]