diff --git a/ChangeLog b/ChangeLog index d7f219b..95ca160 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2009-08-02 Vladimir Serbinenko + + Multiboot support on i386-efi. + + * conf/i386-efi.rmk (pkglib_MODULES): Add multiboot.mod. + (multiboot_mod_SOURCES): New variable. + (multiboot_mod_CFLAGS): Likewise. + (multiboot_mod_LDFLAGS): Likewise. + (multiboot_mod_ASFLAGS): Likewise. + * include/grub/i386/multiboot.h (grub_multiboot_real_boot): Explicitly + declare as regparm (3). + (grub_multiboot2_real_boot): Likewise. + (grub_multiboot_boot): Finish boot services. + (grub_fill_multiboot_mmap): Explicitly parse memory map types. + (grub_multiboot): Declare as noreturn to avoid finishing console. + * loader/multiboot_loader.c (grub_cmd_multiboot_loader): Enable + multiboot1 on i386-efi and disable multiboot2 on this platform. + (grub_cmd_module_loader): Likewise. + 2009-08-01 Vladimir Serbinenko * util/hostfs.c (grub_hostfs_dir): Don't use DT_DIR: It doesn't work diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 9177b9d..248ad87 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -83,7 +83,15 @@ 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/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/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/loader/i386/multiboot.c b/loader/i386/multiboot.c index 87ffcae..f51a38d 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -30,8 +30,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -49,6 +51,13 @@ #include #endif +#include +#include + +#ifdef GRUB_MACHINE_EFI +#include +#endif + extern grub_dl_t my_mod; static struct grub_multiboot_info *mbi, *mbi_dest; static grub_addr_t entry; @@ -59,6 +68,11 @@ static grub_size_t code_size; static grub_err_t grub_multiboot_boot (void) { +#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. */ @@ -114,14 +128,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++; @@ -371,7 +395,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/multiboot_loader.c b/loader/multiboot_loader.c index 986ee0b..7701ce0 100644 --- a/loader/multiboot_loader.c +++ b/loader/multiboot_loader.c @@ -140,7 +140,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_COREBOOT) || \ - defined(GRUB_MACHINE_QEMU) + defined(GRUB_MACHINE_QEMU) || (defined(GRUB_MACHINE_EFI) && !defined (__x86_64__)) if (header_multi_ver_found == 1) { grub_dprintf ("multiboot_loader", @@ -149,6 +149,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), module_version_status = 1; } #endif +#if !defined(GRUB_MACHINE_EFI) if (header_multi_ver_found == 0 || header_multi_ver_found == 2) { grub_dprintf ("multiboot_loader", @@ -156,6 +157,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), grub_multiboot2 (argc, argv); module_version_status = 2; } +#endif return grub_errno; @@ -174,7 +176,7 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)), { #if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \ - defined(GRUB_MACHINE_QEMU) + defined(GRUB_MACHINE_QEMU) || (defined(GRUB_MACHINE_EFI) && !defined (__x86_64__)) if (module_version_status == 1) { grub_dprintf("multiboot_loader", @@ -182,13 +184,14 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)), grub_module (argc, argv); } #endif +#if !defined(GRUB_MACHINE_EFI) if (module_version_status == 2) { grub_dprintf("multiboot_loader", "Launching multiboot 2 grub_module2() function\n"); grub_module2 (argc, argv); } - +#endif return grub_errno; }