Skip to contentSkip to conversation

enable multiboot2 loader on i386-ieee1275

PATCH In review Robert Millan 2 participants 9 messages Jan 21, 2008 – Jan 23, 2008 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 enable multiboot2 loader on i386-ieee1275

This makes multiboot2 work on i386-ieee1275. Tested both with elf32 and elf64 images.

In case of elf32 OFW images, they won't work because EAX is used for multiboot information and can't hold the needed pointer to OFW callback interface. See the comment I added to the draft:

http://grub.enbug.org/MultibootDraft#head-84d7c3521d0235f08f7fffaf35e2d06ced2f0a68

Signature · 5 lines
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)

* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add machine/loader.h' and machine/memory.h'.
(pkglib_MODULES): Add multiboot.mod' and _multiboot.mod'. (_multiboot_mod_SOURCES): New variable. (_multiboot_mod_CFLAGS): Likewise. (_multiboot_mod_LDFLAGS): Likewise. (multiboot_mod_SOURCES): Likewise. (multiboot_mod_CFLAGS): Likewise. (multiboot_mod_LDFLAGS): Likewise.

* include/grub/i386/ieee1275/loader.h: New file.

* include/grub/i386/ieee1275/machine.h: Likewise.

* include/grub/i386/ieee1275/memory.h: Likewise.

* include/grub/i386/pc/init.h (grub_os_area_addr): Remove (redundant) variable declaration.
(grub_os_area_size): Likewise.

* kern/i386/ieee1275/init.c (grub_os_area_addr, grub_os_area_size) (grub_lower_mem, grub_upper_mem): New variables. (grub_stop_floppy): New function (just to make grub_multiboot2_real_boot() happy).

* kern/i386/ieee1275/startup.S: Include <grub/machine/memory.h>', <grub/cpu/linux.h>', <multiboot.h>' and <multiboot2.h>'. (grub_stop): New function.
Include "../realmode.S"' and "../loader.S"'.

* loader/multiboot_loader.c: Include <grub/machine/machine.h>'. Replace __i386__' #ifdefs with `GRUB_MACHINE_PCBIOS'.

* loader/powerpc/ieee1275/multiboot2.c (grub_mb2_arch_boot): On i386, rely on grub_multiboot2_real_boot() for final boot.

conf/i386-ieee1275.rmk +15 -2
diff -x '*.mk' -Nurp grub2/conf/i386-ieee1275.rmk mb/conf/i386-ieee1275.rmk
@@ -22,7 +22,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/
 kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
-	ieee1275/ieee1275.h machine/kernel.h
+	ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h
 kernel_elf_CFLAGS = $(COMMON_CFLAGS)
 kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
 
@@ -96,7 +96,8 @@ grub_emu_SOURCES = commands/boot.c comma
 grub_emu_LDFLAGS = $(LIBCURSES)
 
 # Modules.
-pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod cpuid.mod
+pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod cpuid.mod	\
+	multiboot.mod _multiboot.mod
 
 # For normal.mod.
 normal_mod_DEPENDENCIES = grub_script.tab.c grub_script.tab.h
@@ -109,6 +110,18 @@ normal_mod_CFLAGS = $(COMMON_CFLAGS)
 normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For _multiboot.mod.
+_multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot2.c \
+			 loader/multiboot2.c \
+			 loader/multiboot_loader.c
+_multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/multiboot_loader_normal.c 
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For suspend.mod
 suspend_mod_SOURCES = commands/ieee1275/suspend.c
 suspend_mod_CFLAGS = $(COMMON_CFLAGS)
include/grub/i386/ieee1275/loader.h +1 -0
diff -x '*.mk' -Nurp grub2/include/grub/i386/ieee1275/loader.h mb/include/grub/i386/ieee1275/loader.h
@@ -0,0 +1 @@
+#include <grub/cpu/loader.h>
include/grub/i386/ieee1275/machine.h +24 -0
diff -x '*.mk' -Nurp grub2/include/grub/i386/ieee1275/machine.h mb/include/grub/i386/ieee1275/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_IEEE1275	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
include/grub/i386/ieee1275/memory.h +1 -0
diff -x '*.mk' -Nurp grub2/include/grub/i386/ieee1275/memory.h mb/include/grub/i386/ieee1275/memory.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/memory.h>
include/grub/i386/pc/init.h +0 -3
diff -x '*.mk' -Nurp grub2/include/grub/i386/pc/init.h mb/include/grub/i386/pc/init.h
@@ -22,9 +22,6 @@
 #include <grub/types.h>
 #include <grub/symbol.h>
 
-extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
-extern grub_size_t EXPORT_VAR(grub_os_area_size);
-
 /* Get the memory size in KB. If EXTENDED is zero, return conventional
    memory, otherwise return extended memory.  */
 grub_uint16_t grub_get_memsize (int extended);
kern/i386/ieee1275/init.c +9 -0
diff -x '*.mk' -Nurp grub2/kern/i386/ieee1275/init.c mb/kern/i386/ieee1275/init.c
@@ -19,6 +19,15 @@
 
 #include <grub/types.h>
 
+grub_addr_t grub_os_area_addr;
+grub_size_t grub_os_area_size;
+grub_size_t grub_lower_mem, grub_upper_mem;
+
+void
+grub_stop_floppy (void)
+{
+}
+
 void 
 grub_arch_sync_caches (void *address __attribute__ ((unused)),
 		       grub_size_t len __attribute__ ((unused)))
kern/i386/ieee1275/startup.S +23 -0
diff -x '*.mk' -Nurp grub2/kern/i386/ieee1275/startup.S mb/kern/i386/ieee1275/startup.S
@@ -19,6 +19,10 @@
 #define ASM_FILE	1
 
 #include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/linux.h>
+#include <multiboot.h>
+#include <multiboot2.h>
 
 /*
  * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
@@ -36,3 +40,22 @@ start:
 _start:
 	movl %eax, EXT_C(grub_ieee1275_entry_fn)
 	jmp EXT_C(cmain)
+
+/*
+ *  This call is special...  it never returns...  in fact it should simply
+ *  hang at this point!
+ */
+FUNCTION(grub_stop)
+	hlt
+	jmp EXT_C(grub_stop)
+
+/*
+ *  prot_to_real and associated structures (but NOT real_to_prot, that is
+ *  only needed for BIOS gates).
+ */
+#include "../realmode.S"
+
+/*
+ *  Routines needed by Linux and Multiboot loaders.
+ */
+#include "../loader.S"
loader/multiboot_loader.c +3 -2
diff -x '*.mk' -Nurp grub2/loader/multiboot_loader.c mb/loader/multiboot_loader.c
@@ -18,6 +18,7 @@
  */
 
 #include <multiboot2.h>
+#include <grub/machine/machine.h>
 #include <grub/multiboot_loader.h>
 #include <grub/multiboot.h>
 #include <grub/multiboot2.h>
@@ -113,7 +114,7 @@ grub_rescue_cmd_multiboot_loader (int ar
 
    /* XXX Find a better way to identify this. 
       This is for i386-pc */
-#ifdef __i386__
+#ifdef GRUB_MACHINE_PCBIOS
   if (header_multi_ver_found == 1)
     {
       grub_dprintf ("multiboot_loader",
@@ -143,7 +144,7 @@ void
 grub_rescue_cmd_module_loader (int argc, char *argv[])
 {
 
-#ifdef __i386__
+#ifdef GRUB_MACHINE_PCBIOS
   if (module_version_status == 1)
     {
       grub_dprintf("multiboot_loader",
loader/powerpc/ieee1275/multiboot2.c +6 -0
diff -x '*.mk' -Nurp grub2/loader/powerpc/ieee1275/multiboot2.c mb/loader/powerpc/ieee1275/multiboot2.c
@@ -115,5 +115,11 @@ void
 grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags)
 {
   kernel_entry_t entry = (kernel_entry_t) entry_addr;
+#if defined(__powerpc__)
   entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0);
+#elif defined(__i386__)
+  grub_multiboot2_real_boot (entry, tags);
+#else
+#error
+#endif
 }

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 5 lines · Torsten Duwe
Quoted 4 lines · Robert Millan

This makes multiboot2 work on i386-ieee1275. Tested both with elf32 and elf64 images.

grub2/loader/powerpc/ieee1275

Quoted 8 lines
               ^^^^^^
Quoted 1 line

#elif defined(__i386__)

NAK.

Please do not commit that. It's a nice hack I can try, but the real solution needs cleanup! Once you start serious Open Firmware support for x86, ieee1275 must not reside beneath PPC any longer. BTW sparc has OFW, too.

This file needs to move. There's nothing powerpc-specific about it, really, other than this line. Writing new files or duplicating code when there's no reason to, leads to bitrot. This happened to the sparc64 port, and I want to avoid it.

What I had in mind is getting the i386-ieee1275 port fully functional, and then move the files that are in powerpc/ directories to their corresponding ieee1275/ ones.

Signature · 5 lines
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
#3 lore raw
In reply to Robert Millan
Quoted 2 lines · Robert Millan

This makes multiboot2 work on i386-ieee1275. Tested both with elf32 and elf64 images.

It looks ok to me.

Quoted 5 lines

In case of elf32 OFW images, they won't work because EAX is used for multiboot information and can't hold the needed pointer to OFW callback interface. See the comment I added to the draft:

http://grub.enbug.org/MultibootDraft#head-84d7c3521d0235f08f7fffaf35e2d06ced2f0a68

Can't you use a tag for the pointer?

--
Marco

#4 lore raw
Quoted 6 lines · Marco Gerards
Quoted 2 lines · Robert Millan

This makes multiboot2 work on i386-ieee1275. Tested both with elf32 and elf64 images.

It looks ok to me.

Ok, committed.

Quoted 7 lines
Quoted 5 lines

In case of elf32 OFW images, they won't work because EAX is used for multiboot information and can't hold the needed pointer to OFW callback interface. See the comment I added to the draft:

http://grub.enbug.org/MultibootDraft#head-84d7c3521d0235f08f7fffaf35e2d06ced2f0a68

Can't you use a tag for the pointer?

We can, but that's not useful. If we can't make them compatible, I find it more feasible to write a separate loader for OFW images.

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Signature · 5 lines
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
#5 lore raw
Quoted 4 lines · Robert Millan
Quoted 1 line

Can't you use a tag for the pointer?

We can, but that's not useful. If we can't make them compatible, I find it more feasible to write a separate loader for OFW images.

Why not?

Quoted 4 lines

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Do you suggest to change the interface for x86?

--
Marco

#6 lore raw
Quoted 8 lines · Marco Gerards
Quoted 4 lines · Robert Millan
Quoted 1 line

Can't you use a tag for the pointer?

We can, but that's not useful. If we can't make them compatible, I find it more feasible to write a separate loader for OFW images.

Why not?

Because right now you can turn an existing ELF program into Multiboot-compliance with only adding three lines:

	.long   0xe85250d6
	.long   0
	.long   -0xe85250d6

this will allow you to boot it with GRUB. OTOH, if you have to add support for tag processing, and change the way it initialises its callback pointer, that makes it less worthwile.

Quoted 6 lines
Quoted 4 lines

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Do you suggest to change the interface for x86?

Yes. Multiboot2 is still a draft and not widely used (not even in comparison to Multiboot1). I don't think it's a big problem to change this.

Signature · 5 lines
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
#7 lore raw
Quoted 13 lines · Robert Millan
Quoted 8 lines · Marco Gerards
Quoted 4 lines · Robert Millan
Quoted 1 line

Can't you use a tag for the pointer?

We can, but that's not useful. If we can't make them compatible, I find it more feasible to write a separate loader for OFW images.

Why not?

Because right now you can turn an existing ELF program into Multiboot-compliance with only adding three lines:

Quoted 7 lines
	.long   0xe85250d6
	.long   0
	.long   -0xe85250d6

this will allow you to boot it with GRUB. OTOH, if you have to add support for tag processing, and change the way it initialises its callback pointer, that makes it less worthwile.

True.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Do you suggest to change the interface for x86?

Yes. Multiboot2 is still a draft and not widely used (not even in comparison to Multiboot1). I don't think it's a big problem to change this.

We could use ebx or so. Or will this cause new problems?

--
Marco

#8 lore raw
Quoted 11 lines · Marco Gerards
Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Do you suggest to change the interface for x86?

Yes. Multiboot2 is still a draft and not widely used (not even in comparison to Multiboot1). I don't think it's a big problem to change this.

We could use ebx or so. Or will this cause new problems?

Well, EBX itself is being used for the MBI, so not a good choice ;-)

About using a free register (I think ECX and EDX aren't used), this might cause the inconvenience that you might need to reestructure startup code, in case it is laid out in a way that already makes use of that register.

I don't think this is the case for the average OFW application that is written in C and just has a few lines of asm in _start.

Signature · 5 lines
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
#9 lore raw
Quoted 11 lines · Robert Millan
Quoted 10 lines · Marco Gerards
Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

Though I don't see why not do it. The boot abi is already compatible on PowerPC:

http://grub.enbug.org/MultibootDraft#head-198f9346038a3782a8263de281dd9cf2eb2759a8

Do you suggest to change the interface for x86?

Yes. Multiboot2 is still a draft and not widely used (not even in comparison to Multiboot1). I don't think it's a big problem to change this.

Quoted 7 lines
Quoted 1 line

We could use ebx or so. Or will this cause new problems?

Well, EBX itself is being used for the MBI, so not a good choice ;-)

About using a free register (I think ECX and EDX aren't used), this might cause the inconvenience that you might need to reestructure startup code, in case it is laid out in a way that already makes use of that register.

You can move it to EAX in case you do not care about OFW. In that case you get the old situation back. In case of OFW the old situation never worked :-)

Quoted 2 lines

I don't think this is the case for the average OFW application that is written in C and just has a few lines of asm in _start.

Right. And like I said, other kernels can just move ECX to EAX and the old code can be used.

--
Marco