[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
multiboot on EFI
From: |
phcoder |
Subject: |
multiboot on EFI |
Date: |
Mon, 23 Mar 2009 13:29:55 +0100 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090318) |
Hello. Here is an initial version of patch for booting multiboot kernels
on i386-efi. No Changelog yet because it's not for inclusion yet.
--
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/conf/common.rmk b/conf/common.rmk
index 100fae7..e64a1a4 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -507,3 +507,10 @@ gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
bufio_mod_SOURCES = io/bufio.c
bufio_mod_CFLAGS = $(COMMON_CFLAGS)
bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += lsmmap.mod
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index 6f4e8f3..1304eb3 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -102,8 +102,7 @@ pkglib_MODULES = _linux.mod linux.mod normal.mod \
_multiboot.mod multiboot.mod aout.mod \
play.mod serial.mod ata.mod \
memdisk.mod pci.mod lspci.mod reboot.mod \
- halt.mod datetime.mod date.mod datehook.mod \
- lsmmap.mod
+ halt.mod datetime.mod date.mod datehook.mod
# For _linux.mod.
_linux_mod_SOURCES = loader/i386/linux.c
@@ -211,10 +210,5 @@ datehook_mod_SOURCES = hook/datehook.c
datehook_mod_CFLAGS = $(COMMON_CFLAGS)
datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index a2454d9..4303b1c 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -80,7 +80,20 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
# Modules.
pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \
_linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \
- datetime.mod date.mod datehook.mod
+ datetime.mod date.mod datehook.mod _multiboot.mod multiboot.mod
+
+# For _multiboot.mod.
+_multiboot_mod_SOURCES = loader/i386/multiboot.c \
+ loader/i386/multiboot_helper.S \
+ loader/multiboot_loader.c
+_multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+_multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/multiboot_loader_normal.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For kernel.mod.
kernel_mod_EXPORTS = no
@@ -90,14 +103,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c
kern/device.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
- kern/time.c kern/list.c kern/handler.c \
+ kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
kernel_mod_HEADERS = arg.h boot.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 \
- efi/efi.h efi/time.h efi/disk.h list.h handler.h
+ efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 305b31d..460dfdd 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -102,7 +102,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in
pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod \
multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \
_linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \
- date.mod datehook.mod lsmmap.mod
+ date.mod datehook.mod
#
# Only arch dependant part of normal.mod will be here. Common part for
@@ -209,10 +209,5 @@ datehook_mod_SOURCES = hook/datehook.c
datehook_mod_CFLAGS = $(COMMON_CFLAGS)
datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index e1ed9aa..0be2729 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -178,8 +178,8 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod
linux.mod normal.mod \
_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
- aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
- datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
+ pxe.mod pxecmd.mod datetime.mod date.mod \
+ datehook.mod ata_pthru.mod hdparm.mod \
usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
efiemu.mod efiemu_acpi.mod efiemu_pnvram.mod
@@ -318,21 +318,6 @@ lspci_mod_SOURCES = commands/lspci.c
lspci_mod_CFLAGS = $(COMMON_CFLAGS)
lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For aout.mod
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For _bsd.mod
-_bsd_mod_SOURCES = loader/i386/bsd.c
-_bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd_normal.c
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
# For usb.mod
usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
usb_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -388,11 +373,6 @@ datehook_mod_SOURCES = hook/datehook.c
datehook_mod_CFLAGS = $(COMMON_CFLAGS)
datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
# For ata_pthru.mod.
ata_pthru_mod_SOURCES = disk/ata_pthru.c
ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/conf/i386.rmk b/conf/i386.rmk
index 4e86ed8..5338457 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -19,3 +19,21 @@ pkglib_MODULES += uppermem.mod
uppermem_mod_SOURCES = lib/i386/uppermem.c
uppermem_mod_CFLAGS = $(COMMON_CFLAGS)
uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += aout.mod _bsd.mod bsd.mod
+# For aout.mod
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _bsd.mod
+_bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd_helper.S
+_bsd_mod_CFLAGS = $(COMMON_CFLAGS) -Werror
+_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+_bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd_normal.c
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 66d1d58..c9e185a 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -112,8 +112,7 @@ pkglib_MODULES = halt.mod \
suspend.mod \
_multiboot.mod \
multiboot.mod \
- memdisk.mod \
- lsmmap.mod
+ memdisk.mod
# For _linux.mod.
_linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -178,10 +177,5 @@ memdisk_mod_SOURCES = disk/memdisk.c
memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
include $(srcdir)/conf/common.mk
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 8c277c0..137a437 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -54,6 +54,8 @@ char *EXPORT_FUNC(grub_efi_get_filename)
(grub_efi_device_path_t *dp);
grub_efi_device_path_t *
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+int EXPORT_FUNC(grub_efi_finish_boot_services) (void);
+
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h
new file mode 100644
index 0000000..9000642
--- /dev/null
+++ b/include/grub/efi/memory.h
@@ -0,0 +1,15 @@
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER 1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE 1
+#define GRUB_MACHINE_MEMORY_RESERVED 2
+#define GRUB_MACHINE_MEMORY_ACPI 3
+#define GRUB_MACHINE_MEMORY_NVS 4
+#define GRUB_MACHINE_MEMORY_CODE 5
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h
index 00296c9..e8bed00 100644
--- a/include/grub/i386/bsd.h
+++ b/include/grub/i386/bsd.h
@@ -148,6 +148,8 @@ struct grub_openbsd_bios_mmap
{
grub_uint64_t addr;
grub_uint64_t len;
+#define OPENBSD_MMAP_AVAILABLE 1
+#define OPENBSD_MMAP_RESERVED 2
grub_uint32_t type;
};
@@ -229,4 +231,7 @@ void grub_rescue_cmd_netbsd (int argc, char *argv[]);
void grub_rescue_cmd_freebsd_loadenv (int argc, char *argv[]);
void grub_rescue_cmd_freebsd_module (int argc, char *argv[]);
+void grub_unix_real_boot (grub_addr_t entry, ...)
+ __attribute__ ((cdecl,noreturn));
+
#endif /* ! GRUB_BSD_CPU_HEADER */
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/i386/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h
index f858c0a..cb2f918 100644
--- a/include/grub/i386/loader.h
+++ b/include/grub/i386/loader.h
@@ -32,9 +32,6 @@ extern grub_size_t EXPORT_VAR(grub_os_area_size);
grub_err_t EXPORT_FUNC(grub_linux_boot) (void);
-void EXPORT_FUNC(grub_unix_real_boot) (grub_addr_t entry, ...)
- __attribute__ ((cdecl,noreturn));
-
/* It is necessary to export these functions, because normal mode commands
reuse rescue mode commands. */
void grub_rescue_cmd_linux (int argc, char *argv[]);
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
index ea68640..85405dc 100644
--- a/include/grub/i386/multiboot.h
+++ b/include/grub/i386/multiboot.h
@@ -22,7 +22,7 @@
/* The asm part of the multiboot loader. */
void grub_multiboot_real_boot (grub_addr_t entry,
struct grub_multiboot_info *mbi)
- __attribute__ ((noreturn));
+ __attribute__ ((noreturn,regparm (3)));
void grub_multiboot2_real_boot (grub_addr_t entry,
struct grub_multiboot_info *mbi)
__attribute__ ((noreturn));
diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h
index 08e92a9..e69ff77 100644
--- a/include/grub/i386/pc/memory.h
+++ b/include/grub/i386/pc/memory.h
@@ -92,6 +92,8 @@ struct grub_machine_mmap_entry
grub_uint64_t len;
#define GRUB_MACHINE_MEMORY_AVAILABLE 1
#define GRUB_MACHINE_MEMORY_RESERVED 2
+#define GRUB_MACHINE_MEMORY_ACPI 3
+#define GRUB_MACHINE_MEMORY_NVS 4
grub_uint32_t type;
} __attribute__((packed));
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/x86_64/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/kern/efi/efi.c b/kern/efi/efi.c
index 9c9a400..754f82c 100644
--- a/kern/efi/efi.c
+++ b/kern/efi/efi.c
@@ -187,6 +187,28 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
return status == GRUB_EFI_SUCCESS;
}
+int
+grub_efi_finish_boot_services (void)
+{
+ grub_efi_uintn_t mmap_size = 0;
+ grub_efi_uintn_t map_key;
+ grub_efi_uintn_t desc_size;
+ grub_efi_uint32_t desc_version;
+ void *mmap_buf;
+
+ if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+ &desc_size, &desc_version) < 0)
+ return 0;
+
+ mmap_buf = grub_malloc (mmap_size);
+
+ if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+ &desc_size, &desc_version) <= 0)
+ return 0;
+
+ return grub_efi_exit_boot_services (map_key);
+}
+
grub_uint32_t
grub_get_rtc (void)
{
diff --git a/kern/efi/mm.c b/kern/efi/mm.c
index 35b12ab..4635776 100644
--- a/kern/efi/mm.c
+++ b/kern/efi/mm.c
@@ -47,7 +47,7 @@ static struct allocated_page *allocated_pages = 0;
/* The minimum and maximum heap size for GRUB itself. */
#define MIN_HEAP_SIZE 0x100000
-#define MAX_HEAP_SIZE (16 * 0x100000)
+#define MAX_HEAP_SIZE (1600 * 0x100000)
/* Allocate pages. Return the pointer to the first of allocated pages. */
diff --git a/kern/efi/mmap.c b/kern/efi/mmap.c
new file mode 100644
index 0000000..11fbc72
--- /dev/null
+++ b/kern/efi/mmap.c
@@ -0,0 +1,158 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/err.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+struct region
+{
+ grub_uint64_t start;
+ grub_uint64_t len;
+ grub_uint32_t type;
+};
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t, grub_uint32_t))
+{
+ grub_efi_uintn_t mmap_size = 0;
+ grub_efi_memory_descriptor_t *map_buf;
+ grub_efi_uintn_t map_key = 0;
+ grub_efi_uintn_t desc_size = 0;
+ grub_efi_uint32_t desc_version = 0;
+ grub_uint64_t curstart, curend;
+ grub_uint32_t curtype;
+ grub_efi_memory_descriptor_t *desc;
+ struct region *regions;
+ struct region t;
+ int i, count, done = 1;
+
+ if (grub_efi_get_memory_map (&mmap_size, map_buf,
+ &map_key, &desc_size,
+ &desc_version) < 0)
+ return grub_errno;
+
+ map_buf = grub_malloc (mmap_size);
+ if (!map_buf)
+ return grub_errno;
+
+ if (grub_efi_get_memory_map (&mmap_size, map_buf,
+ &map_key, &desc_size,
+ &desc_version) <= 0)
+ {
+ grub_free (map_buf);
+ return grub_errno;
+ }
+
+ count = mmap_size / desc_size;
+ if (! count)
+ {
+ grub_free (map_buf);
+ return grub_error (GRUB_ERR_IO, "couldn't get EFI memory map");
+ }
+ regions = (struct region *) grub_malloc (count * sizeof (struct region));
+
+ for (desc = map_buf, i = 0;
+ desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size);
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
+ {
+ grub_dprintf ("efi_mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
+ desc->physical_start, desc->physical_start
+ + desc->num_pages * 4096, desc->type);
+ switch (desc->type)
+ {
+ case GRUB_EFI_RUNTIME_SERVICES_CODE:
+ regions[i].start = desc->physical_start;
+ regions[i].len = desc->num_pages * 4096;
+ regions[i].type = GRUB_MACHINE_MEMORY_CODE;
+ break;
+
+ case GRUB_EFI_RESERVED_MEMORY_TYPE:
+ case GRUB_EFI_RUNTIME_SERVICES_DATA:
+ case GRUB_EFI_UNUSABLE_MEMORY:
+ case GRUB_EFI_MEMORY_MAPPED_IO:
+ case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ case GRUB_EFI_PAL_CODE:
+ case GRUB_EFI_MAX_MEMORY_TYPE:
+ regions[i].start = desc->physical_start;
+ regions[i].len = desc->num_pages * 4096;
+ regions[i].type = GRUB_MACHINE_MEMORY_RESERVED;
+ break;
+
+ case GRUB_EFI_LOADER_CODE:
+ case GRUB_EFI_LOADER_DATA:
+ case GRUB_EFI_BOOT_SERVICES_CODE:
+ case GRUB_EFI_BOOT_SERVICES_DATA:
+ case GRUB_EFI_CONVENTIONAL_MEMORY:
+ regions[i].start = desc->physical_start;
+ regions[i].len = desc->num_pages * 4096;
+ regions[i].type = GRUB_MACHINE_MEMORY_AVAILABLE;
+ break;
+
+ case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+ regions[i].start = desc->physical_start;
+ regions[i].len = desc->num_pages * 4096;
+ regions[i].type = GRUB_MACHINE_MEMORY_ACPI;
+ break;
+
+ case GRUB_EFI_ACPI_MEMORY_NVS:
+ regions[i].start = desc->physical_start;
+ regions[i].len = desc->num_pages * 4096;
+ regions[i].type = GRUB_MACHINE_MEMORY_NVS;
+ break;
+ }
+ }
+
+ /* Bubble-sort the memory map */
+ while (done)
+ {
+ done = 0;
+ for (i = 0; i < count - 1; i++)
+ if (regions[i].start > regions[i + 1].start)
+ {
+ done = 1;
+ t = regions[i];
+ regions[i] = regions[i + 1];
+ regions[i + 1] = t;
+ }
+ }
+
+ curstart = regions[0].start;
+ curend = regions[0].start + regions[0].len;
+ curtype = regions[0].type;
+ for (i = 1; i < count; i++)
+ {
+ if (curend != regions[i].start || curtype != regions[i].type)
+ {
+ hook (curstart, curend - curstart, curtype);
+ curstart = regions[i].start;
+ curtype = regions[i].type;
+ }
+ curend = regions[i].start + regions[i].len;
+ }
+
+ hook (curstart, curend - curstart, curtype);
+
+ return GRUB_ERR_NONE;
+}
diff --git a/kern/i386/loader.S b/kern/i386/loader.S
index fc27b86..f1b6c18 100644
--- a/kern/i386/loader.S
+++ b/kern/i386/loader.S
@@ -117,27 +117,3 @@ bzimage:
linux_setup_seg:
.word 0
.code32
-
-/*
- * Use cdecl calling convention for *BSD kernels.
- */
-
-FUNCTION(grub_unix_real_boot)
-
- call EXT_C(grub_dl_unload_all)
- call EXT_C(grub_stop_floppy)
-
- /* Interrupts should be disabled. */
- cli
-
- /* Discard `grub_unix_real_boot' return address. */
- popl %eax
-
- /* Fetch `entry' address ... */
- popl %eax
-
- /*
- * ... and put our return address in its place. The kernel will
- * ignore it, but it expects %esp to point to it.
- */
- call *%eax
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
index 25d0f59..712b013 100644
--- a/loader/i386/bsd.c
+++ b/loader/i386/bsd.c
@@ -19,8 +19,8 @@
#include <grub/loader.h>
#include <grub/cpu/loader.h>
#include <grub/cpu/bsd.h>
-#include <grub/machine/init.h>
#include <grub/machine/memory.h>
+#include <grub/machine/machine.h>
#include <grub/file.h>
#include <grub/err.h>
#include <grub/rescue.h>
@@ -31,6 +31,11 @@
#include <grub/misc.h>
#include <grub/gzio.h>
#include <grub/aout.h>
+#include <grub/i386/uppermem.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
#define ALIGN_DWORD(a) ALIGN_UP (a, 4)
#define ALIGN_PAGE(a) ALIGN_UP (a, 4096)
@@ -302,6 +307,15 @@ grub_freebsd_boot (void)
bi.bi_kernend = kern_end;
+#ifdef GRUB_MACHINE_PCBIOS
+ grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+ if (! grub_efi_finish_boot_services ())
+ grub_fatal ("cannot exit boot services");
+#endif
+
grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
0, 0, 0, &bi, bi.bi_modulep, kern_end);
@@ -313,30 +327,39 @@ static grub_err_t
grub_openbsd_boot (void)
{
char *buf = (char *) GRUB_BSD_TEMP_BUFFER;
- struct grub_machine_mmap_entry mmap;
struct grub_openbsd_bios_mmap *pm;
struct grub_openbsd_bootargs *pa;
- grub_uint32_t bootdev, biosdev, unit, slice, part, cont;
+ grub_uint32_t bootdev, biosdev, unit, slice, part;
+ grub_uint64_t lower, upper;
+ grub_err_t err;
+
+ auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+ int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
+ {
+ pm->addr = addr;
+ pm->len = size;
+
+ switch (type)
+ {
+ case GRUB_MACHINE_MEMORY_AVAILABLE:
+ pm->type = OPENBSD_MMAP_AVAILABLE;
+ break;
+
+ default:
+ pm->type = OPENBSD_MMAP_RESERVED;
+ break;
+ }
+ pm++;
+
+ return 0;
+ }
pa = (struct grub_openbsd_bootargs *) buf;
pa->ba_type = OPENBSD_BOOTARG_MMAP;
pm = (struct grub_openbsd_bios_mmap *) (pa + 1);
- cont = grub_get_mmap_entry (&mmap, 0);
- if (mmap.size)
- do
- {
- pm->addr = mmap.addr;
- pm->len = mmap.len;
- pm->type = mmap.type;
- pm++;
-
- if (!cont)
- break;
- cont = grub_get_mmap_entry (&mmap, cont);
- }
- while (mmap.size);
+ grub_machine_mmap_iterate (hook);
pa->ba_size = (char *) pm - (char *) pa;
pa->ba_next = (struct grub_openbsd_bootargs *) pm;
@@ -348,8 +371,20 @@ grub_openbsd_boot (void)
bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
(part << OPENBSD_B_PARTSHIFT));
+ if ((err = grub_get_lower_upper_memory (&lower, &upper)))
+ return err;
+
+#ifdef GRUB_MACHINE_PCBIOS
+ grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+ if (! grub_efi_finish_boot_services ())
+ grub_fatal ("cannot exit boot services");
+#endif
+
grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER,
- 0, grub_upper_mem >> 10, grub_lower_mem >> 10,
+ 0, upper >> 10, lower >> 10,
(char *) pa - buf, buf);
/* Not reached. */
@@ -362,6 +397,8 @@ grub_netbsd_boot (void)
struct grub_netbsd_btinfo_rootdevice *rootdev;
struct grub_netbsd_bootinfo *bootinfo;
grub_uint32_t biosdev, unit, slice, part;
+ grub_uint64_t lower, upper;
+ grub_err_t err;
grub_bsd_get_device (&biosdev, &unit, &slice, &part);
@@ -376,8 +413,20 @@ grub_netbsd_boot (void)
bootinfo->bi_count = 1;
bootinfo->bi_data[0] = rootdev;
+ if ((err = grub_get_lower_upper_memory (&lower, &upper)))
+ return err;
+
+#ifdef GRUB_MACHINE_PCBIOS
+ grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+ if (! grub_efi_finish_boot_services ())
+ grub_fatal ("cannot exit boot services");
+#endif
+
grub_unix_real_boot (entry, bootflags, 0, bootinfo,
- 0, grub_upper_mem >> 10, grub_lower_mem >> 10);
+ 0, upper >> 10, lower >> 10);
/* Not reached. */
return GRUB_ERR_NONE;
@@ -461,10 +510,10 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t *
addr)
phdr->p_paddr &= 0xFFFFFF;
paddr = phdr->p_paddr;
- if ((paddr < grub_os_area_addr)
+ /* if ((paddr < grub_os_area_addr)
|| (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
- paddr);
+ paddr);*/
if ((!kern_start) || (paddr < kern_start))
kern_start = paddr;
@@ -577,7 +626,7 @@ grub_rescue_cmd_freebsd (int argc, char *argv[])
(grub_freebsd_add_meta_module (1, argc, argv, kern_start,
kern_end - kern_start)))
return;
- grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+ grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
}
}
@@ -589,7 +638,7 @@ grub_rescue_cmd_openbsd (int argc, char *argv[])
grub_bsd_parse_flags (argv[1], openbsd_opts, openbsd_flags));
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
- grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1);
+ grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 0);
}
void
@@ -600,7 +649,7 @@ grub_rescue_cmd_netbsd (int argc, char *argv[])
grub_bsd_parse_flags (argv[1], netbsd_opts, netbsd_flags));
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
- grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+ grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0);
}
void
@@ -718,11 +767,11 @@ grub_rescue_cmd_freebsd_module (int argc, char *argv[])
if ((!file) || (!file->size))
goto fail;
- if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+ /* if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module");
goto fail;
- }
+ }*/
grub_file_read (file, (char *) kern_end, file->size);
if ((!grub_errno) &&
diff --git a/loader/i386/bsd_helper.S b/loader/i386/bsd_helper.S
new file mode 100644
index 0000000..9cdea0c
--- /dev/null
+++ b/loader/i386/bsd_helper.S
@@ -0,0 +1,65 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 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/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ * Be careful of that you must not modify some registers. Quote
+ * from gcc-2.95.2/gcc/config/i386/i386.h:
+
+ 1 for registers not available across function calls.
+ These must include the FIXED_REGISTERS and also any
+ registers that can be used without being saved.
+ The latter must include the registers where values are returned
+ and the register where structure-value addresses are passed.
+ Aside from that, you can include as many other registers as you like.
+
+ ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ * So the first three arguments are passed in %eax, %edx, and %ecx,
+ * respectively, and if a function has a fixed number of arguments
+ * and the number if greater than three, the function must return
+ * with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+#include <grub/symbol.h>
+
+/*
+ * Use cdecl calling convention for *BSD kernels.
+ */
+
+FUNCTION(grub_unix_real_boot)
+
+ /* Interrupts should be disabled. */
+ cli
+
+ /* Discard `grub_unix_real_boot' return address. */
+ popl %eax
+
+ /* Fetch `entry' address ... */
+ popl %eax
+
+ /*
+ * ... and put our return address in its place. The kernel will
+ * ignore it, but it expects %esp to point to it.
+ */
+ call *%eax
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index ff758d1..055b1cf 100644
--- a/loader/i386/multiboot.c
+++ b/loader/i386/multiboot.c
@@ -30,7 +30,7 @@
#include <grub/loader.h>
#include <grub/machine/loader.h>
#include <grub/multiboot.h>
-#include <grub/machine/init.h>
+#include <grub/machine/machine.h>
#include <grub/machine/memory.h>
#include <grub/cpu/multiboot.h>
#include <grub/elf.h>
@@ -43,6 +43,13 @@
#include <grub/misc.h>
#include <grub/gzio.h>
#include <grub/env.h>
+#include <grub/cpu/loader.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/i386/uppermem.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
extern grub_dl_t my_mod;
static struct grub_multiboot_info *mbi, *mbi_dest;
@@ -54,7 +61,12 @@ static grub_size_t code_size;
static grub_err_t
grub_multiboot_boot (void)
{
- grub_stop_floppy ();
+ grub_printf ("Boot\n");
+
+#ifdef GRUB_MACHINE_EFI
+ if (! grub_efi_finish_boot_services ())
+ grub_fatal ("cannot exit boot services");
+#endif
grub_multiboot_real_boot (entry, mbi_dest);
@@ -111,14 +123,24 @@ grub_get_multiboot_mmap_len (void)
static void
grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
{
- struct grub_multiboot_mmap_entry *mmap_entry = (struct
grub_multiboot_mmap_entry *) first_entry;
+ struct grub_multiboot_mmap_entry *mmap_entry
+ = (struct grub_multiboot_mmap_entry *) first_entry;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
{
mmap_entry->addr = addr;
mmap_entry->len = size;
- mmap_entry->type = type;
+ switch (type)
+ {
+ case GRUB_MACHINE_MEMORY_AVAILABLE:
+ mmap_entry->type = GRUB_MULTIBOOT_MEMORY_AVAILABLE;
+ break;
+
+ default:
+ mmap_entry->type = GRUB_MULTIBOOT_MEMORY_RESERVED;
+ break;
+ }
mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof
(mmap_entry->size);
mmap_entry++;
@@ -201,6 +223,7 @@ grub_multiboot (int argc, char *argv[])
struct grub_multiboot_header *header;
grub_ssize_t len, cmdline_length, boot_loader_name_length;
grub_uint32_t mmap_length;
+ grub_uint64_t lower, upper;
int i;
grub_loader_unset ();
@@ -288,7 +311,9 @@ grub_multiboot (int argc, char *argv[])
grub_multiboot_payload_dest = header->load_addr;
grub_multiboot_payload_size += code_size;
- playground = grub_malloc (RELOCATOR_SIZEOF(forward) +
grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+ playground = grub_malloc (RELOCATOR_SIZEOF(forward)
+ + grub_multiboot_payload_size
+ + RELOCATOR_SIZEOF(backward));
if (! playground)
goto fail;
@@ -343,9 +368,12 @@ grub_multiboot (int argc, char *argv[])
grub_multiboot_payload_size,
grub_multiboot_payload_entry_offset);
+ if (grub_get_lower_upper_memory (&lower, &upper))
+ goto fail;
+
/* Convert from bytes to kilobytes. */
- mbi->mem_lower = grub_lower_mem / 1024;
- mbi->mem_upper = grub_upper_mem / 1024;
+ mbi->mem_lower = lower / 1024;
+ mbi->mem_upper = upper / 1024;
mbi->flags |= MULTIBOOT_INFO_MEMORY;
cmdline = p = cmdline_addr (grub_multiboot_payload_orig);
@@ -372,7 +400,7 @@ grub_multiboot (int argc, char *argv[])
if (grub_multiboot_get_bootdev (&mbi->boot_device))
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
- grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
+ grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
fail:
if (file)
diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S
index 1e71120..cd07246 100644
--- a/loader/i386/multiboot_helper.S
+++ b/loader/i386/multiboot_helper.S
@@ -52,7 +52,7 @@ VARIABLE(grub_multiboot_forward_relocator)
cld
rep
movsb
-
+
jmp *%edx
VARIABLE(grub_multiboot_forward_relocator_end)
@@ -91,7 +91,7 @@ FUNCTION(grub_multiboot_real_boot)
/* Move the magic value into eax. */
movl $MULTIBOOT_MAGIC2, %eax
-
+
/* Jump to the relocator. */
popl %ebp
jmp *%ebp
diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S
index 901be68..a83bd9a 100644
--- a/loader/i386/xnu_helper.S
+++ b/loader/i386/xnu_helper.S
@@ -15,6 +15,9 @@ FUNCTION(grub_xnu_launch)
jmp cont1
cont1:
lgdt gdtdesc
+
+ jmp cont2
+cont2:
.code32
@@ -28,8 +31,8 @@ cont1:
and $0xffffffef, %eax
wrmsr
- jmp cont2
-cont2:
+ jmp cont3
+cont3:
#endif
.code32
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
index abcad9b..8abce88 100644
--- a/loader/multiboot_loader.c
+++ b/loader/multiboot_loader.c
@@ -140,7 +140,7 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
/* XXX Find a better way to identify this.
This is for i386-pc */
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) || defined
(GRUB_MACHINE_EFI)
if (header_multi_ver_found == 1)
{
grub_dprintf ("multiboot_loader",
@@ -153,7 +153,9 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
{
grub_dprintf ("multiboot_loader",
"Launching multiboot 2 grub_multiboot2() function\n");
+#ifndef GRUB_MACHINE_EFI
grub_multiboot2 (argc, argv);
+#endif
module_version_status = 2;
}
@@ -170,7 +172,7 @@ void
grub_rescue_cmd_module_loader (int argc, char *argv[])
{
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) ||
defined(GRUB_MACHINE_EFI)
if (module_version_status == 1)
{
grub_dprintf("multiboot_loader",
@@ -182,7 +184,9 @@ grub_rescue_cmd_module_loader (int argc, char *argv[])
{
grub_dprintf("multiboot_loader",
"Launching multiboot 2 grub_module2() function\n");
+#ifndef GRUB_MACHINE_EFI
grub_module2 (argc, argv);
+#endif
}
}
diff --git a/conf/i386.rmk b/conf/i386.rmk
index 93f84ce..5338457 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -14,3 +14,8 @@ pkglib_MODULES += vga_text.mod
vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += uppermem.mod
+uppermem_mod_SOURCES = lib/i386/uppermem.c
+uppermem_mod_CFLAGS = $(COMMON_CFLAGS)
+uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/lib/i386/uppermem.c b/lib/i386/uppermem.c
new file mode 100644
index 0000000..623535f
--- /dev/null
+++ b/lib/i386/uppermem.c
@@ -0,0 +1,127 @@
+/* Compute amount of lower and upper memory till the first hole */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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 EFIEMU
+#include <grub/machine/memory.h>
+#include <grub/i386/uppermem.h>
+#endif
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+struct region
+{
+ grub_uint64_t start;
+ grub_uint64_t end;
+};
+
+#ifdef EFIEMU
+grub_err_t
+grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper)
+#else
+grub_err_t
+grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper)
+#endif
+{
+ grub_size_t count = 0;
+ struct region *regions = 0;
+ int done = 1;
+ unsigned i;
+ struct region t;
+ grub_uint64_t last_addr;
+
+ auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+ int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+ grub_uint32_t type)
+ {
+#ifdef EFIEMU
+ if (type != GRUB_EFIEMU_MEMORY_AVAILABLE)
+#else
+ if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+#endif
+ return 0;
+ regions = (struct region *)
+ grub_realloc (regions, (count + 1) * sizeof (struct region));
+ regions[count].start = addr;
+ regions[count].end = addr + size;
+ count++;
+ return 0;
+ }
+
+#ifdef EFIEMU
+ grub_efiemu_mmap_iterate (hook);
+#else
+ grub_machine_mmap_iterate (hook);
+#endif
+
+ /* Bubble-sort the memory map */
+ while (done)
+ {
+ done = 0;
+ for (i = 0; i < count - 1; i++)
+ if (regions[i].start > regions[i + 1].start)
+ {
+ done = 1;
+ t = regions[i];
+ regions[i] = regions[i + 1];
+ regions[i + 1] = t;
+ }
+ }
+
+ /* Set mem_upper and mem_lower */
+ last_addr = 0;
+ for (i = 0; i < count; i++)
+ {
+ grub_uint64_t end = regions[i].end;
+ /* Don't use memory after 0xa0000*/
+ if (end > 0xa0000)
+ end = 0xa0000;
+
+ /* low memory is finished */
+ if (regions[i].start > end)
+ break;
+
+ /* A hole */
+ if (regions[i].start > last_addr)
+ break;
+
+ last_addr = end;
+ }
+
+ *lower = last_addr;
+
+ /* Skip low memory */
+ for (i = 0; i < count && regions[i].end <= 0x100000;
+ i++);
+
+ last_addr = 0x100000;
+ for (; i < count; i++)
+ {
+ /* A hole */
+ if (regions[i].start > last_addr)
+ break;
+
+ last_addr = regions[i].end;
+ }
+
+ *upper = (last_addr - 0x100000);
+ grub_free (regions);
+
+ return GRUB_ERR_NONE;
+}
- multiboot on EFI,
phcoder <=
- Re: multiboot on EFI, uzer cheg, 2009/03/23
- Re: multiboot on EFI, phcoder, 2009/03/23
- Re: multiboot on EFI, phcoder, 2009/03/23
- Re: multiboot on EFI, uzer cheg, 2009/03/24
- Re: multiboot on EFI, phcoder, 2009/03/24
- Re: multiboot on EFI, uzer cheg, 2009/03/24
- Re: multiboot on EFI, Vladimir Serbinenko, 2009/03/26
Re: multiboot on EFI, Robert Millan, 2009/03/28