[Top][All Lists]

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

[PATCH 2/2] ieee1275: set real-base in the PowerPC IEEE1275 Note to 32MB

From: Daniel Axtens
Subject: [PATCH 2/2] ieee1275: set real-base in the PowerPC IEEE1275 Note to 32MB
Date: Tue, 16 Nov 2021 14:42:05 +1100


Figuring out how to lay out memory in powerpc OpenFirmware is a bit
of a complicate dance.

Firstly, firmware needs to reserve a little bit of space for things
like interrupt vectors that live at a fixed address. This is usually
0x4000 bytes. PFW calls this "stage 1" (of the firmware, not the

As discussed in the previous patch, the ELF image is loaded at
'load-base' before it's unpacked. load-base is, by default, set at the
end of stage 1. From there, the ELF loader unpacks the binary to
wherever the program headers say and the program is executed.

Next in memory, we need space for the rest of firmware. (PFW calls
this "stage 2" of firmware.) The starting address begins at
'real-base'.* We need to not run past real-base when loading our ELF

load-base and real-base have defaults from firmware, and may be
configurable in various ways.


 - real-base defaults to 12MB (0xc00000)

 - real-base is configurable with the IEEE1275 ELF note.

 - a proprietary OS bootloader configures real-base to
   0x2000000 (32MB).


 - real-base is set dynamically towards the end of accessible memory.

 - real-base is not configurable.

On 32-bit, I'm not sure quite what the story is. I don't have any
32-bit Apple hardware to test with. However, with this change, grub
still loads and runs, including when I hack up the tests to install
the note by default.

* I'm assuming here that the firmware doesn't do virtual mode. This is
true on Power for both PFW and SLOF; Apple OF implementations may do
things differently.

Moving real-base

To account for growing grub binary sizes, we want to try to expand the
amount of memory that we have to work with. We have the following
constraints and inputs:

 - A good practical limit for the size of the grub binary is 8MB, as
   that's about the size of the PReP partition on a number of distro
   setups. (See previous patch.)

 - We also want things to work if people forget to include the
   note. Even if distros build it in to signed images, people
   running grub-install will probably forget to set it and we don't
   want to break their systems. (Helpfully, if you're running
   grub-install manually there's a decent chance you're not building
   in a bunch of modules so things are likely to be smaller anyway.)

 - We want to avoid doing anything too novel with enterprise software.

So when the note is included, set real-base to 32MB.


This means that:

 - The ELF file will be loaded at 0x4000 and have just short of 8MB to
   fit into. (This is entirely the work of the previous patch - the
   8MB limitation is because we now load at 8MB instead of 2MB.)

 - Nothing changes on SLOF, because SLOF ignores the note. We have
   oodles of space in SLOF.

 - On PFW when the note is not installed, we have about 4MB of space
   for ELF loader to put the program into (the gap between 8MB and the
   default real-base of 12MB). This is well more than any current grub
   image uses.

 - On PFW when the note _is_ installed, we will have about 24MB of
   space to put the program bits into. This is well more than we're
   likely to use unless people start putting very large arrays in BSS,
   but it means we're aligned with a proprietary bootloader and
   therefore we can be assured that some testing has been done.

Signed-off-by: Daniel Axtens <>
 util/grub-mkimagexx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index d78fa3e53308..2ac40b82a22d 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -467,7 +467,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct 
       note_ptr->header.n_type = grub_host_to_target32 
       strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME);
       note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff);
-      note_ptr->descriptor.real_base = grub_host_to_target32 (0x00c00000);
+      note_ptr->descriptor.real_base = grub_host_to_target32 (0x02000000);
       note_ptr->descriptor.real_size = grub_host_to_target32 (0xffffffff);
       note_ptr->descriptor.virt_base = grub_host_to_target32 (0xffffffff);
       note_ptr->descriptor.virt_size = grub_host_to_target32 (0xffffffff);

reply via email to

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