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;