grub-devel
[Top][All Lists]
Advanced

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

Re: [ppc patch] grub-mkimage and module loading


From: Hollis Blanchard
Subject: Re: [ppc patch] grub-mkimage and module loading
Date: Sat, 1 Jan 2005 16:42:26 -0600

On Dec 2, 2004, at 11:36 PM, Hollis Blanchard wrote:

I'm firmly convinced that grub_load_modules(), currently in kern/main.c,
will need to be changed to a more generic interface. For example, each
arch could provide its own grub_module_start() and grub_module_end()
functions. It is no longer a valid assumption that the modules begin
immediately after grub_end_addr in memory. But for now I will leave that
to someone (Marco?) doing the real module loading; grub-mkimage just
needs to get it into memory (which I've verified it does).

On PPC, it is difficult to inform runtime grub of its modules that were added post-compile. There are two pieces of module information we need at runtime: the address and the length of the modules.

x86 grub uses a binary format so grub_total_module_size can be placed at a known location at compile time, to be overwritten at install time. The address is known because the modules are appended directly after the executable.

PPC grub is an ELF executable. That makes it very difficult to overwrite a variable at install time, as the variable lives in a section at some offset inside the file. We can use a constant location for the module base address, but we still need to communicate the module size somehow. Here are some options:

1) create a very small special-purpose section (e.g. ".moduleinfo") to hold the address and size of the post-compile modules. Cons: would require more ELF header parsing in grub-mkimage; wouldn't work if we need to go XCOFF or binary on Old World Macintosh (we might need to, due to firmware limitations). 1.5) a variation of 1), embed the information inside a normal section like .text. That might be easier to work with when using non-ELF formats. 2) Store the number of modules in memory just before the first grub_module_header. This is very simple, and I have implemented a working example already: 3) Run the object through ld several times (used in Linux to get the ramdisk location). This would require running ld at install time though, and I believe we don't want to require users have a toolchain present.

#define MODULE_BASE 0x00300000 /* where grub-mkimage puts them */
void
grub_load_modules (void)
{
  struct grub_modules {
    int num_modules;
    struct grub_module_header first_header;
  } *module_base = (struct grub_modules *) MODULE_BASE;
  struct grub_module_header *header = &module_base->first_header;
  int i;

  for (i = 0; i < module_base->num_modules; i++)
    {
      if (! grub_dl_load_core ((char *) header + header->offset,
                               (header->size - header->offset)))
        grub_fatal ("%s", grub_errmsg);
header = (struct grub_module_header *) ((char *) header + header->size);
    }
}

I am in favor of option 2. This approach could also be used for the i386 port, but I guess there are other reasons we need to overwrite fixed-location variables there, so maybe it wouldn't simplify much. (I'm looking at the VARIABLE() macros in kern/i386/pc/startup.S) So it would also be easy to move the existing grub_load_modules() into arch-specific code, and use something like the above function for the PPC port.

Comments?

-Hollis





reply via email to

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