diff --git a/conf/common.rmk b/conf/common.rmk
index 2335d8f..b96db4c 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -546,3 +546,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 f000328..8ab3a3c 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -105,7 +105,7 @@ pkglib_MODULES = linux.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 mmap.mod
+ mmap.mod
# For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
@@ -188,10 +188,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 c698d3e..1b55bd5 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -83,7 +83,17 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
linux.mod halt.mod reboot.mod pci.mod lspci.mod \
datetime.mod date.mod datehook.mod loadbios.mod \
- fixvideo.mod mmap.mod acpi.mod
+ fixvideo.mod mmap.mod acpi.mod multiboot.mod
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+ loader/i386/multiboot_helper.S \
+ loader/multiboot2.c \
+ loader/efi/multiboot2.c \
+ loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For kernel.mod.
kernel_mod_EXPORTS = no
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 804676b..2244b46 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -105,7 +105,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in
pkglib_MODULES = halt.mod reboot.mod suspend.mod \
multiboot.mod aout.mod serial.mod linux.mod \
nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \
- date.mod datehook.mod lsmmap.mod mmap.mod
+ date.mod datehook.mod mmap.mod
# For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
@@ -187,10 +187,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 6c9100f..b9e8f47 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -307,17 +307,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 loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
# For usb.mod
usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
usb_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -373,11 +362,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 93f84ce..5c972f9 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -14,3 +14,16 @@ 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 += aout.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 loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS) -Werror
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 911adc6..3425742 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -113,8 +113,7 @@ pkglib_MODULES = halt.mod \
reboot.mod \
suspend.mod \
multiboot.mod \
- memdisk.mod \
- lsmmap.mod
+ memdisk.mod
# For linux.mod.
linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -148,10 +147,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/i386/loader.h b/include/grub/i386/loader.h
index 72a44d0..9344fc3 100644
--- a/include/grub/i386/loader.h
+++ b/include/grub/i386/loader.h
@@ -27,8 +27,6 @@ extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
extern char *EXPORT_VAR(grub_linux_tmp_addr);
extern char *EXPORT_VAR(grub_linux_real_addr);
extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
-extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
-extern grub_size_t EXPORT_VAR(grub_os_area_size);
grub_err_t EXPORT_FUNC(grub_linux16_boot) (void);
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
index 2dd7ec0..a6da360 100644
--- a/include/grub/i386/multiboot.h
+++ b/include/grub/i386/multiboot.h
@@ -22,10 +22,10 @@
/* 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));
+ __attribute__ ((noreturn,regparm (3)));
extern grub_addr_t grub_multiboot_payload_orig;
extern grub_addr_t grub_multiboot_payload_dest;
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index 751055f..1c2aeec 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -172,7 +172,6 @@ int EXPORT_FUNC(grub_children_iterate) (char *devpath,
int (*hook) (struct grub_ieee1275_devalias *alias));
grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
diff --git a/include/grub/loader.h b/include/grub/loader.h
index 319f3c5..41d255b 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -63,4 +63,8 @@ void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret),
/* Unregister given preboot hook. */
void grub_loader_unregister_preboot_hook (void *hnd);
+int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
+
+void EXPORT_FUNC(grub_declaimmap) (grub_addr_t addr, grub_size_t size);
+
#endif /* ! GRUB_LOADER_HEADER */
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
index bfbffcc..1e6701e 100644
--- a/include/grub/multiboot2.h
+++ b/include/grub/multiboot2.h
@@ -39,12 +39,6 @@ void
grub_mb2_arch_unload (struct multiboot_tag_header *tags);
grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr);
-
-grub_err_t
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr);
-
-grub_err_t
grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr);
grub_err_t
diff --git a/kern/efi/mm.c b/kern/efi/mm.c
index 4635776..3c9b51e 100644
--- a/kern/efi/mm.c
+++ b/kern/efi/mm.c
@@ -427,3 +427,21 @@ grub_efi_mm_fini (void)
BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
}
}
+
+/* XXX: Manage subpage allocations */
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+ void *ret;
+ ret = grub_efi_allocate_pages (addr & (~0xfff),
+ (size + (addr & 0xfff) + 0xfff) >> 12);
+ return (! ret) ? -1 : 0;
+}
+
+/* XXX: Manage subpage allocations */
+void
+grub_declaimmap (grub_addr_t addr, grub_size_t size)
+{
+ grub_efi_free_pages (addr & (~0xfff),
+ (size + (addr & 0xfff) + 0xfff) >> 12);
+}
diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
index c12af2c..d0423b7 100644
--- a/kern/i386/coreboot/init.c
+++ b/kern/i386/coreboot/init.c
@@ -147,3 +147,18 @@ grub_arch_modules_addr (void)
{
return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
}
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+ if ((addr < grub_os_area_addr)
+ || (addr + size > grub_os_area_addr + grub_os_area_size))
+ return -1;
+ return 0;
+}
+
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
+ grub_size_t size __attribute__ ((unused)))
+{
+}
diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
index c64497e..84b6ba7 100644
--- a/kern/i386/pc/init.c
+++ b/kern/i386/pc/init.c
@@ -43,8 +43,8 @@ struct mem_region
static struct mem_region mem_regions[MAX_REGIONS];
static int num_regions;
-grub_addr_t grub_os_area_addr;
-grub_size_t grub_os_area_size;
+static grub_addr_t grub_os_area_addr;
+static grub_size_t grub_os_area_size;
void
grub_arch_sync_caches (void *address __attribute__ ((unused)),
@@ -232,3 +232,18 @@ grub_arch_modules_addr (void)
return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
+ (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
}
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+ if ((addr < grub_os_area_addr)
+ || (addr + size > grub_os_area_addr + grub_os_area_size))
+ return -1;
+ return 0;
+}
+
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
+ grub_size_t size __attribute__ ((unused)))
+{
+}
diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c
index 7d65023..b1498da 100644
--- a/kern/ieee1275/openfw.c
+++ b/kern/ieee1275/openfw.c
@@ -247,6 +247,13 @@ grub_claimmap (grub_addr_t addr, grub_size_t size)
return 0;
}
+/* XXX Could someone with better OFW knowledge that me fill this? */
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
+ grub_size_t size __attribute__ ((unused)))
+{
+}
+
/* Get the device arguments of the Open Firmware node name `path'. */
static char *
grub_ieee1275_get_devargs (const char *path)
diff --git a/loader/efi/multiboot2.c b/loader/efi/multiboot2.c
new file mode 100644
index 0000000..44bb542
--- /dev/null
+++ b/loader/efi/multiboot2.c
@@ -0,0 +1,75 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007,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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+ grub_addr_t modaddr;
+
+ modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
+ if (! modaddr)
+ return grub_errno;
+
+ *addr = modaddr;
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
+{
+ grub_free((void *) addr);
+ return GRUB_ERR_NONE;
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry, void *tags)
+{
+ grub_multiboot2_real_boot (entry, tags);
+}
+
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+ struct multiboot_tag_header *tag;
+
+ /* Free all module memory in the tag list. */
+ for_each_tag (tag, tags)
+ {
+ if (tag->key == MULTIBOOT2_TAG_MODULE)
+ {
+ struct multiboot_tag_module *module =
+ (struct multiboot_tag_module *) tag;
+ grub_free((void *) module->addr);
+ }
+ }
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+ /* XXX Create system table et al. */
+ return GRUB_ERR_NONE;
+}
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
index db76399..e491774 100644
--- a/loader/i386/bsd.c
+++ b/loader/i386/bsd.c
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -34,6 +33,10 @@
#include
#include
+#ifdef GRUB_MACHINE_EFI
+#include
+#endif
+
#define ALIGN_DWORD(a) ALIGN_UP (a, 4)
#define ALIGN_QWORD(a) ALIGN_UP (a, 8)
#define ALIGN_VAR(a) ((is_64bit) ? (ALIGN_QWORD(a)) : (ALIGN_DWORD(a)))
@@ -516,14 +519,25 @@ grub_freebsd_boot (void)
grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
&grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start);
+#ifdef GRUB_MACHINE_EFI
+ if (! grub_efi_finish_boot_services ())
+ grub_fatal ("cannot exit boot services");
+#endif
+
/* Launch trampoline. */
launch_trampoline (entry, entry_hi, pagetable, bi.bi_modulep,
kern_end);
}
else
- grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
- 0, 0, 0, &bi, bi.bi_modulep, kern_end);
+ {
+#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);
+ }
/* Not reached. */
return GRUB_ERR_NONE;
}
@@ -573,6 +587,11 @@ grub_openbsd_boot (void)
bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
(part << OPENBSD_B_PARTSHIFT));
+#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_mmap_get_upper () >> 10,
grub_mmap_get_lower () >> 10,
@@ -688,8 +707,7 @@ 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)
- || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+ if (grub_claimmap (paddr, phdr->p_memsz) < 0)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
paddr);
@@ -711,8 +729,7 @@ grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr)
paddr = phdr->p_paddr & 0xffffff;
- if ((paddr < grub_os_area_addr)
- || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+ if (grub_claimmap (paddr, phdr->p_memsz) < 0)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
paddr);
@@ -835,7 +852,7 @@ grub_cmd_freebsd (grub_command_t cmd __attribute__ ((unused)),
(grub_freebsd_add_meta_module (1, argc, argv, kern_start,
kern_end - kern_start)))
return grub_errno;
- grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+ grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
}
return grub_errno;
@@ -850,7 +867,7 @@ grub_cmd_openbsd (grub_command_t cmd __attribute__ ((unused)),
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);
return grub_errno;
}
@@ -864,7 +881,7 @@ grub_cmd_netbsd (grub_command_t cmd __attribute__ ((unused)),
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);
return grub_errno;
}
@@ -982,7 +999,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
if ((!file) || (!file->size))
goto fail;
- if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+ if (grub_claimmap (kern_end, file->size) < 0)
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module");
goto fail;
diff --git a/loader/i386/bsd_pagetable.c b/loader/i386/bsd_pagetable.c
index 754f6f0..522a19c 100644
--- a/loader/i386/bsd_pagetable.c
+++ b/loader/i386/bsd_pagetable.c
@@ -1,24 +1,3 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (c) 1998 Michael Smith
- * 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 .
- */
-
-/* Based on the code from FreeBSD originally distributed under the
- following terms: */
/*-
* Copyright (c) 1998 Michael Smith
@@ -47,6 +26,23 @@
*
* $FreeBSD$
*/
+/*
+ * 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 .
+ */
static void
diff --git a/loader/i386/bsd_trampoline.S b/loader/i386/bsd_trampoline.S
index f6bfe2c..b283a87 100644
--- a/loader/i386/bsd_trampoline.S
+++ b/loader/i386/bsd_trampoline.S
@@ -1,27 +1,7 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (c) 2003 Peter Wemm
- * 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 .
- */
-
-/* Based on the code from FreeBSD originally distributed under the
- following terms: */
/*-
* Copyright (c) 2003 Peter Wemm
+ * Copyright (C) 2009 Free Software Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,6 +27,23 @@
*
* $FreeBSD$
*/
+/*
+ * 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 .
+ */
#define MSR_EFER 0xc0000080
diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c
index 9be88aa..81e2036 100644
--- a/loader/i386/efi/linux.c
+++ b/loader/i386/efi/linux.c
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#include
#include
@@ -47,9 +48,10 @@ static int loaded;
static void *real_mode_mem;
static void *prot_mode_mem;
static void *initrd_mem;
-static grub_efi_uintn_t real_mode_pages;
-static grub_efi_uintn_t prot_mode_pages;
-static grub_efi_uintn_t initrd_pages;
+static grub_size_t real_size;
+static grub_size_t mmap_size;
+static grub_size_t prot_size;
+static grub_size_t initrd_size;
static void *mmap_buf;
static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
@@ -96,26 +98,26 @@ page_align (grub_size_t size)
/* Find the optimal number of pages for the memory map. Is it better to
move this code to efi/mm.c? */
-static grub_efi_uintn_t
+static grub_size_t
find_mmap_size (void)
{
- static grub_efi_uintn_t mmap_size = 0;
+ static grub_efi_uintn_t cache_mmap_size = 0;
- if (mmap_size != 0)
- return mmap_size;
+ if (cache_mmap_size != 0)
+ return cache_mmap_size;
- mmap_size = (1 << 12);
+ cache_mmap_size = (1 << 12);
while (1)
{
int ret;
grub_efi_memory_descriptor_t *mmap;
grub_efi_uintn_t desc_size;
- mmap = grub_malloc (mmap_size);
+ mmap = grub_malloc (cache_mmap_size);
if (! mmap)
return 0;
- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+ ret = grub_efi_get_memory_map (&cache_mmap_size, mmap, 0, &desc_size, 0);
grub_free (mmap);
if (ret < 0)
@@ -123,14 +125,14 @@ find_mmap_size (void)
else if (ret > 0)
break;
- mmap_size += (1 << 12);
+ cache_mmap_size += (1 << 12);
}
/* Increase the size a bit for safety, because GRUB allocates more on
later, and EFI itself may allocate more. */
- mmap_size += (1 << 12);
+ cache_mmap_size += (1 << 12);
- return page_align (mmap_size);
+ return page_align (cache_mmap_size);
}
static void
@@ -138,19 +140,19 @@ free_pages (void)
{
if (real_mode_mem)
{
- grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
+ grub_declaimmap ((grub_addr_t) real_mode_mem, real_size + mmap_size);
real_mode_mem = 0;
}
if (prot_mode_mem)
{
- grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
+ grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
prot_mode_mem = 0;
}
if (initrd_mem)
{
- grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+ grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
initrd_mem = 0;
}
}
@@ -162,9 +164,8 @@ allocate_pages (grub_size_t prot_size)
{
grub_efi_uintn_t desc_size;
grub_efi_memory_descriptor_t *mmap, *mmap_end;
- grub_efi_uintn_t mmap_size, tmp_mmap_size;
+ grub_efi_uintn_t tmp_mmap_size;
grub_efi_memory_descriptor_t *desc;
- grub_size_t real_size;
/* Make sure that each size is aligned to a page boundary. */
real_size = GRUB_LINUX_CL_END_OFFSET;
@@ -174,11 +175,6 @@ allocate_pages (grub_size_t prot_size)
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
- /* Calculate the number of pages; Combine the real mode code with
- the memory map buffer for simplicity. */
- real_mode_pages = ((real_size + mmap_size) >> 12);
- prot_mode_pages = (prot_size >> 12);
-
/* Initialize the memory pointers with NULL for convenience. */
real_mode_mem = 0;
prot_mode_mem = 0;
@@ -193,44 +189,40 @@ allocate_pages (grub_size_t prot_size)
grub_fatal ("cannot get memory map");
mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
-
- /* First, find free pages for the real mode code
- and the memory map buffer. */
- for (desc = mmap;
- desc < mmap_end;
- desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+
+ /* FIXME: Should request low memory from the heap when this feature is
+ implemented. */
+
+ 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)
{
- /* Probably it is better to put the real mode code in the traditional
- space for safety. */
- if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
- && desc->physical_start <= 0x90000
- && desc->num_pages >= real_mode_pages)
+ /* We must put real mode code in the traditional space. */
+
+ if (type == GRUB_MACHINE_MEMORY_AVAILABLE
+ && addr <= 0x90000)
{
- grub_efi_physical_address_t physical_end;
- grub_efi_physical_address_t addr;
-
- physical_end = desc->physical_start + (desc->num_pages << 12);
- if (physical_end > 0x90000)
- physical_end = 0x90000;
-
- grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
- (unsigned) desc->physical_start,
- (unsigned) physical_end);
- addr = physical_end - real_size - mmap_size;
if (addr < 0x10000)
- continue;
+ {
+ size += addr - 0x10000;
+ addr = 0x10000;
+ }
- grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
- (unsigned) real_mode_pages, (unsigned long) addr);
- real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
- if (! real_mode_mem)
- grub_fatal ("cannot allocate pages");
-
- desc->num_pages -= real_mode_pages;
- break;
+ if (addr + size > 0x90000)
+ size = 0x90000 - addr;
+
+ if (real_size + mmap_size > size)
+ return 0;
+
+ real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size));
+ if (grub_claimmap ((grub_addr_t) real_mode_mem,
+ real_size + mmap_size) < 0)
+ return 0;
+ return 1;
}
- }
+ return 0;
+ }
+ grub_mmap_iterate (hook);
if (! real_mode_mem)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
@@ -239,20 +231,20 @@ allocate_pages (grub_size_t prot_size)
mmap_buf = (void *) ((char *) real_mode_mem + real_size);
+ prot_mode_mem = (void *) 0x100000;
/* Next, find free pages for the protected mode code. */
/* XXX what happens if anything is using this address? */
- prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages);
- if (! prot_mode_mem)
+ if (grub_claimmap (0x100000, prot_size) < 0)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY,
"cannot allocate protected mode pages");
goto fail;
}
- grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
- "prot_mode_mem = %lx, prot_mode_pages = %x\n",
- (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
- (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+ grub_dprintf ("linux", "real_mode_mem = %lx, real_size = %x, "
+ "prot_mode_mem = %lx, prot_size = %x\n",
+ (unsigned long) real_mode_mem, (unsigned) real_size,
+ (unsigned long) prot_mode_mem, (unsigned) prot_size);
grub_free (mmap);
return 1;
@@ -602,7 +594,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
struct linux_kernel_header lh;
struct linux_kernel_params *params;
grub_uint8_t setup_sects;
- grub_size_t real_size, prot_size;
grub_ssize_t len;
int i;
char *dest;
@@ -885,9 +876,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
grub_ssize_t size;
grub_addr_t addr_min, addr_max;
grub_addr_t addr;
- grub_efi_uintn_t mmap_size;
- grub_efi_memory_descriptor_t *desc;
- grub_efi_uintn_t desc_size;
struct linux_kernel_header *lh;
if (argc == 0)
@@ -907,11 +895,24 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
size = grub_file_size (file);
- initrd_pages = (page_align (size) >> 12);
+ initrd_size = page_align (size);
lh = (struct linux_kernel_header *) real_mode_mem;
+
+ /* Get the highest address available for the initrd. */
+ if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+ {
+ addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+ /* XXX in reality, Linux specifies a bogus value, so
+ it is necessary to make sure that ADDR_MAX does not exceed
+ 0x3fffffff. */
+ if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+ addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+ }
+ else
+ addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
- addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
if (linux_mem_size != 0 && linux_mem_size < addr_max)
addr_max = linux_mem_size;
@@ -922,49 +923,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
addr_max -= 0x10000;
/* Usually, the compression ratio is about 50%. */
- addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
- + page_align (size);
+ addr_min = (grub_addr_t) prot_mode_mem + prot_size * 3
+ + page_align (size);
- /* Find the highest address to put the initrd. */
- mmap_size = find_mmap_size ();
- if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
- grub_fatal ("cannot get memory map");
-
- addr = 0;
- for (desc = mmap_buf;
- desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
- desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
- {
- if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
- && desc->num_pages >= initrd_pages)
- {
- grub_efi_physical_address_t physical_end;
-
- physical_end = desc->physical_start + (desc->num_pages << 12);
- if (physical_end > addr_max)
- physical_end = addr_max;
-
- if (physical_end < page_align (size))
- continue;
-
- physical_end -= page_align (size);
-
- if ((physical_end >= addr_min) &&
- (physical_end >= desc->physical_start) &&
- (physical_end > addr))
- addr = physical_end;
- }
- }
+ /* Put the initrd as high as possible, 4KiB aligned. */
+ addr = (addr_max - size) & ~0xFFF;
+ while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
+ addr -= 0x1000;
- if (addr == 0)
+ if (addr < addr_min)
{
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
goto fail;
}
- initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
- if (! initrd_mem)
- grub_fatal ("cannot allocate pages");
+ initrd_mem = (void *) addr;
if (grub_file_read (file, initrd_mem, size) != size)
{
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
index 02bade5..3ac2afd 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -46,9 +46,10 @@ static int loaded;
static void *real_mode_mem;
static void *prot_mode_mem;
static void *initrd_mem;
-static grub_uint32_t real_mode_pages;
-static grub_uint32_t prot_mode_pages;
-static grub_uint32_t initrd_pages;
+static grub_size_t real_size;
+static grub_size_t mmap_size;
+static grub_size_t prot_size;
+static grub_size_t initrd_size;
static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
{
@@ -158,7 +159,7 @@ page_align (grub_size_t size)
static grub_size_t
find_mmap_size (void)
{
- grub_size_t count = 0, mmap_size;
+ grub_size_t count = 0, mmap_size_local;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
@@ -171,40 +172,50 @@ find_mmap_size (void)
grub_mmap_iterate (hook);
- mmap_size = count * sizeof (struct grub_e820_mmap);
+ mmap_size_local = count * sizeof (struct grub_e820_mmap);
/* Increase the size a bit for safety, because GRUB allocates more on
later. */
- mmap_size += (1 << 12);
+ mmap_size_local += (1 << 12);
- return page_align (mmap_size);
+ return page_align (mmap_size_local);
}
static void
free_pages (void)
{
- real_mode_mem = prot_mode_mem = initrd_mem = 0;
+ if (real_mode_mem)
+ {
+ grub_declaimmap ((grub_addr_t) real_mode_mem, real_size
+ + mmap_size);
+ real_mode_mem = 0;
+ }
+
+ if (prot_mode_mem)
+ {
+ grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
+ prot_mode_mem = 0;
+ }
+
+ if (initrd_mem)
+ {
+ grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
+ initrd_mem = 0;
+ }
}
/* Allocate pages for the real mode code and the protected mode code
for linux as well as a memory map buffer. */
static int
-allocate_pages (grub_size_t prot_size)
+allocate_pages (grub_size_t prot_size_arg)
{
- grub_size_t real_size, mmap_size;
-
/* Make sure that each size is aligned to a page boundary. */
real_size = GRUB_LINUX_CL_END_OFFSET;
- prot_size = page_align (prot_size);
+ prot_size_arg = page_align (prot_size_arg);
mmap_size = find_mmap_size ();
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
- (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
-
- /* Calculate the number of pages; Combine the real mode code with
- the memory map buffer for simplicity. */
- real_mode_pages = ((real_size + mmap_size) >> 12);
- prot_mode_pages = (prot_size >> 12);
+ (unsigned) real_size, (unsigned) prot_size_arg, (unsigned) mmap_size);
/* Initialize the memory pointers with NULL for convenience. */
free_pages ();
@@ -232,7 +243,9 @@ allocate_pages (grub_size_t prot_size)
if (real_size + mmap_size > size)
return 0;
- real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size));
+ real_mode_mem = UINT_TO_PTR((addr + size) - (real_size + mmap_size));
+ if (grub_claimmap (real_mode_mem, real_size + mmap_size) < 0)
+ return 0;
return 1;
}
@@ -246,11 +259,19 @@ allocate_pages (grub_size_t prot_size)
}
prot_mode_mem = (void *) 0x100000;
+ /* Next, find free pages for the protected mode code. */
+ /* XXX what happens if anything is using this address? */
+ if (grub_claimmap (0x100000, prot_size_arg) < 0)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "cannot allocate protected mode pages");
+ goto fail;
+ }
- grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
- "prot_mode_mem = %lx, prot_mode_pages = %x\n",
- (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
- (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+ grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_size = %x, "
+ "prot_mode_mem = %lx, prot_mode_size = %x\n",
+ (unsigned long) real_mode_mem, (unsigned) real_size,
+ (unsigned long) prot_mode_mem, (unsigned) prot_size);
return 1;
@@ -480,7 +501,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
struct linux_kernel_header lh;
struct linux_kernel_params *params;
grub_uint8_t setup_sects;
- grub_size_t real_size, prot_size;
grub_ssize_t len;
int i;
char *dest;
@@ -724,7 +744,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
size = grub_file_size (file);
- initrd_pages = (page_align (size) >> 12);
+ initrd_size = page_align (size);
lh = (struct linux_kernel_header *) real_mode_mem;
@@ -752,14 +772,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
addr_max -= 0x10000;
/* Usually, the compression ratio is about 50%. */
- addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+ addr_min = (grub_addr_t) prot_mode_mem + ((prot_size * 3))
+ page_align (size);
- if (addr_max > grub_os_area_addr + grub_os_area_size)
- addr_max = grub_os_area_addr + grub_os_area_size;
-
/* Put the initrd as high as possible, 4KiB aligned. */
addr = (addr_max - size) & ~0xFFF;
+ while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
+ addr -= 0x1000;
if (addr < addr_min)
{
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index 73dee43..99da51f 100644
--- a/loader/i386/multiboot.c
+++ b/loader/i386/multiboot.c
@@ -30,8 +30,9 @@
#include
#include
#include
-#include
+#include
#include
+#include
#include
#include
#include
@@ -42,6 +43,12 @@
#include
#include
#include
+#include
+#include
+
+#ifdef GRUB_MACHINE_EFI
+#include
+#endif
extern grub_dl_t my_mod;
static struct grub_multiboot_info *mbi, *mbi_dest;
@@ -53,6 +60,13 @@ static grub_size_t code_size;
static grub_err_t
grub_multiboot_boot (void)
{
+ 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);
/* Not reached. */
@@ -108,14 +122,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++;
@@ -198,6 +222,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 ();
@@ -285,7 +310,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;
@@ -369,7 +396,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/pc/linux.c b/loader/i386/pc/linux.c
index 34a4ebc..358de0b 100644
--- a/loader/i386/pc/linux.c
+++ b/loader/i386/pc/linux.c
@@ -71,11 +71,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (! file)
goto fail;
- if ((grub_size_t) grub_file_size (file) > grub_os_area_size)
+ if (grub_claimmap (GRUB_LINUX_BZIMAGE_ADDR, grub_file_size (file)) < 0)
{
- grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
- (grub_size_t) grub_file_size (file),
- grub_os_area_size);
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x)",
+ (grub_size_t) grub_file_size (file));
goto fail;
}
@@ -341,9 +340,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
addr_max -= 0x10000;
- if (addr_max > grub_os_area_addr + grub_os_area_size)
- addr_max = grub_os_area_addr + grub_os_area_size;
-
addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
file = grub_file_open (argv[0]);
@@ -354,6 +350,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
/* Put the initrd as high as possible, 4KiB aligned. */
addr = (addr_max - size) & ~0xFFF;
+ while (addr >= addr_min && grub_claimmap (addr, size) < 0)
+ addr -= 0x1000;
if (addr < addr_min)
{
diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c
index d5fe8e3..b065fa7 100644
--- a/loader/i386/pc/multiboot2.c
+++ b/loader/i386/pc/multiboot2.c
@@ -25,32 +25,6 @@
#include
grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
- Elf32_Addr paddr = phdr->p_paddr;
-
- 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);
-
- return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
- Elf64_Addr paddr = phdr->p_paddr;
-
- 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);
-
- return GRUB_ERR_NONE;
-}
-
-grub_err_t
grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
{
grub_addr_t modaddr;
@@ -73,6 +47,7 @@ grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
void
grub_mb2_arch_boot (grub_addr_t entry, void *tags)
{
+ grub_stop_floppy ();
grub_multiboot2_real_boot (entry, tags);
}
diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c
index c253fc9..462135b 100644
--- a/loader/ieee1275/multiboot2.c
+++ b/loader/ieee1275/multiboot2.c
@@ -31,41 +31,6 @@
typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
unsigned long, unsigned long);
-/* Claim the memory occupied by the multiboot kernel. */
-grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
- int rc;
-
- rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
- if (rc)
- return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
- phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
-
- grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
- phdr->p_paddr + phdr->p_memsz);
-
- return GRUB_ERR_NONE;
-}
-
-/* Claim the memory occupied by the multiboot kernel. */
-grub_err_t
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
- int rc;
-
- rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
- if (rc)
- return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
- phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
-
- grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
- (unsigned long) phdr->p_paddr,
- (unsigned long) (phdr->p_paddr + phdr->p_memsz));
-
- return GRUB_ERR_NONE;
-}
-
grub_err_t
grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
{
diff --git a/loader/multiboot2.c b/loader/multiboot2.c
index fd82828..53e27be 100644
--- a/loader/multiboot2.c
+++ b/loader/multiboot2.c
@@ -37,6 +37,42 @@ static char *grub_mb2_tags_pos;
static grub_size_t grub_mb2_tags_len;
static int grub_mb2_tags_count;
+/* Claim the memory occupied by the multiboot kernel. */
+static grub_err_t
+grub_mb2_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+ int rc;
+
+ rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+ if (rc)
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
+ phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+ grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
+ phdr->p_paddr + phdr->p_memsz);
+
+ return GRUB_ERR_NONE;
+}
+
+/* Claim the memory occupied by the multiboot kernel. */
+static grub_err_t
+grub_mb2_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+ int rc;
+
+ rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+ if (rc)
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
+ phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+ grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
+ (unsigned long) phdr->p_paddr,
+ (unsigned long) (phdr->p_paddr + phdr->p_memsz));
+
+ return GRUB_ERR_NONE;
+}
+
+
static void
grub_mb2_tags_free (void)
{
@@ -278,13 +314,13 @@ grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[])
if (grub_elf_is_elf32 (elf))
{
entry = elf->ehdr.ehdr32.e_entry;
- err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base,
+ err = grub_elf32_load (elf, grub_mb2_elf32_hook, &kern_base,
&kern_size);
}
else if (grub_elf_is_elf64 (elf))
{
entry = elf->ehdr.ehdr64.e_entry;
- err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base,
+ err = grub_elf64_load (elf, grub_mb2_elf64_hook, &kern_base,
&kern_size);
}
else
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
index 11ba666..8088766 100644
--- a/loader/multiboot_loader.c
+++ b/loader/multiboot_loader.c
@@ -139,7 +139,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
/* XXX Find a better way to identify this.
This is for i386-pc */
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(__i386__)
if (header_multi_ver_found == 1)
{
grub_dprintf ("multiboot_loader",
@@ -172,7 +172,7 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(__i386__)
if (module_version_status == 1)
{
grub_dprintf("multiboot_loader",
@@ -184,7 +184,9 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
{
grub_dprintf("multiboot_loader",
"Launching multiboot 2 grub_module2() function\n");
+#ifndef GRUB_MACHINE_EFI
grub_module2 (argc, argv);
+#endif
}
return grub_errno;