* multiboot on EFI @ 2009-03-23 12:29 phcoder 2009-03-23 21:16 ` uzer cheg 2009-03-28 13:13 ` Robert Millan 0 siblings, 2 replies; 15+ messages in thread From: phcoder @ 2009-03-23 12:29 UTC (permalink / raw) To: The development of GRUB 2 [-- Attachment #1: Type: text/plain, Size: 183 bytes --] Hello. Here is an initial version of patch for booting multiboot kernels on i386-efi. No Changelog yet because it's not for inclusion yet. -- Regards Vladimir 'phcoder' Serbinenko [-- Attachment #2: efiboot.diff --] [-- Type: text/x-diff, Size: 32540 bytes --] diff --git a/conf/common.rmk b/conf/common.rmk index 100fae7..e64a1a4 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -507,3 +507,10 @@ gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) bufio_mod_SOURCES = io/bufio.c bufio_mod_CFLAGS = $(COMMON_CFLAGS) bufio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += lsmmap.mod + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 6f4e8f3..1304eb3 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -102,8 +102,7 @@ pkglib_MODULES = _linux.mod linux.mod normal.mod \ _multiboot.mod multiboot.mod aout.mod \ play.mod serial.mod ata.mod \ memdisk.mod pci.mod lspci.mod reboot.mod \ - halt.mod datetime.mod date.mod datehook.mod \ - lsmmap.mod + halt.mod datetime.mod date.mod datehook.mod # For _linux.mod. _linux_mod_SOURCES = loader/i386/linux.c @@ -211,10 +210,5 @@ datehook_mod_SOURCES = hook/datehook.c datehook_mod_CFLAGS = $(COMMON_CFLAGS) datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index a2454d9..4303b1c 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -80,7 +80,20 @@ grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ _linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \ - datetime.mod date.mod datehook.mod + datetime.mod date.mod datehook.mod _multiboot.mod multiboot.mod + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/i386/multiboot.c \ + loader/i386/multiboot_helper.S \ + loader/multiboot_loader.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) +_multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) # For kernel.mod. kernel_mod_EXPORTS = no @@ -90,14 +103,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ term/efi/console.c disk/efi/efidisk.c \ - kern/time.c kern/list.c kern/handler.c \ + kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h list.h handler.h + efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h kernel_mod_CFLAGS = $(COMMON_CFLAGS) kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 305b31d..460dfdd 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -102,7 +102,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod \ multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \ _linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ - date.mod datehook.mod lsmmap.mod + date.mod datehook.mod # # Only arch dependant part of normal.mod will be here. Common part for @@ -209,10 +209,5 @@ datehook_mod_SOURCES = hook/datehook.c datehook_mod_CFLAGS = $(COMMON_CFLAGS) datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index e1ed9aa..0be2729 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -178,8 +178,8 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \ vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ ata.mod vga.mod memdisk.mod pci.mod lspci.mod \ - aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ - datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \ + pxe.mod pxecmd.mod datetime.mod date.mod \ + datehook.mod ata_pthru.mod hdparm.mod \ usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \ efiemu.mod efiemu_acpi.mod efiemu_pnvram.mod @@ -318,21 +318,6 @@ lspci_mod_SOURCES = commands/lspci.c lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For aout.mod -aout_mod_SOURCES = loader/aout.c -aout_mod_CFLAGS = $(COMMON_CFLAGS) -aout_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For _bsd.mod -_bsd_mod_SOURCES = loader/i386/bsd.c -_bsd_mod_CFLAGS = $(COMMON_CFLAGS) -_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For bsd.mod -bsd_mod_SOURCES = loader/i386/bsd_normal.c -bsd_mod_CFLAGS = $(COMMON_CFLAGS) -bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For usb.mod usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c usb_mod_CFLAGS = $(COMMON_CFLAGS) @@ -388,11 +373,6 @@ datehook_mod_SOURCES = hook/datehook.c datehook_mod_CFLAGS = $(COMMON_CFLAGS) datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ata_pthru.mod. ata_pthru_mod_SOURCES = disk/ata_pthru.c ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386.rmk b/conf/i386.rmk index 4e86ed8..5338457 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -19,3 +19,21 @@ pkglib_MODULES += uppermem.mod uppermem_mod_SOURCES = lib/i386/uppermem.c uppermem_mod_CFLAGS = $(COMMON_CFLAGS) uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += aout.mod _bsd.mod bsd.mod +# For aout.mod +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _bsd.mod +_bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd_helper.S +_bsd_mod_CFLAGS = $(COMMON_CFLAGS) -Werror +_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +_bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For bsd.mod +bsd_mod_SOURCES = loader/i386/bsd_normal.c +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 66d1d58..c9e185a 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -112,8 +112,7 @@ pkglib_MODULES = halt.mod \ suspend.mod \ _multiboot.mod \ multiboot.mod \ - memdisk.mod \ - lsmmap.mod + memdisk.mod # For _linux.mod. _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c @@ -178,10 +177,5 @@ memdisk_mod_SOURCES = disk/memdisk.c memdisk_mod_CFLAGS = $(COMMON_CFLAGS) memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 8c277c0..137a437 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -54,6 +54,8 @@ char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); grub_efi_device_path_t * EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); +int EXPORT_FUNC(grub_efi_finish_boot_services) (void); + void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h new file mode 100644 index 0000000..9000642 --- /dev/null +++ b/include/grub/efi/memory.h @@ -0,0 +1,15 @@ +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#include <grub/err.h> +#include <grub/types.h> + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_RESERVED 2 +#define GRUB_MACHINE_MEMORY_ACPI 3 +#define GRUB_MACHINE_MEMORY_NVS 4 +#define GRUB_MACHINE_MEMORY_CODE 5 + +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) +(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +#endif /* ! GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 00296c9..e8bed00 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -148,6 +148,8 @@ struct grub_openbsd_bios_mmap { grub_uint64_t addr; grub_uint64_t len; +#define OPENBSD_MMAP_AVAILABLE 1 +#define OPENBSD_MMAP_RESERVED 2 grub_uint32_t type; }; @@ -229,4 +231,7 @@ void grub_rescue_cmd_netbsd (int argc, char *argv[]); void grub_rescue_cmd_freebsd_loadenv (int argc, char *argv[]); void grub_rescue_cmd_freebsd_module (int argc, char *argv[]); +void grub_unix_real_boot (grub_addr_t entry, ...) + __attribute__ ((cdecl,noreturn)); + #endif /* ! GRUB_BSD_CPU_HEADER */ diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h new file mode 100644 index 0000000..c9a61bb --- /dev/null +++ b/include/grub/i386/efi/memory.h @@ -0,0 +1 @@ +#include <grub/efi/memory.h> diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h index f858c0a..cb2f918 100644 --- a/include/grub/i386/loader.h +++ b/include/grub/i386/loader.h @@ -32,9 +32,6 @@ extern grub_size_t EXPORT_VAR(grub_os_area_size); grub_err_t EXPORT_FUNC(grub_linux_boot) (void); -void EXPORT_FUNC(grub_unix_real_boot) (grub_addr_t entry, ...) - __attribute__ ((cdecl,noreturn)); - /* It is necessary to export these functions, because normal mode commands reuse rescue mode commands. */ void grub_rescue_cmd_linux (int argc, char *argv[]); diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index ea68640..85405dc 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -22,7 +22,7 @@ /* The asm part of the multiboot loader. */ void grub_multiboot_real_boot (grub_addr_t entry, struct grub_multiboot_info *mbi) - __attribute__ ((noreturn)); + __attribute__ ((noreturn,regparm (3))); void grub_multiboot2_real_boot (grub_addr_t entry, struct grub_multiboot_info *mbi) __attribute__ ((noreturn)); diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 08e92a9..e69ff77 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry grub_uint64_t len; #define GRUB_MACHINE_MEMORY_AVAILABLE 1 #define GRUB_MACHINE_MEMORY_RESERVED 2 +#define GRUB_MACHINE_MEMORY_ACPI 3 +#define GRUB_MACHINE_MEMORY_NVS 4 grub_uint32_t type; } __attribute__((packed)); diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h new file mode 100644 index 0000000..c9a61bb --- /dev/null +++ b/include/grub/x86_64/efi/memory.h @@ -0,0 +1 @@ +#include <grub/efi/memory.h> diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 9c9a400..754f82c 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -187,6 +187,28 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key) return status == GRUB_EFI_SUCCESS; } +int +grub_efi_finish_boot_services (void) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_uintn_t map_key; + grub_efi_uintn_t desc_size; + grub_efi_uint32_t desc_version; + void *mmap_buf; + + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) < 0) + return 0; + + mmap_buf = grub_malloc (mmap_size); + + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) <= 0) + return 0; + + return grub_efi_exit_boot_services (map_key); +} + grub_uint32_t grub_get_rtc (void) { diff --git a/kern/efi/mm.c b/kern/efi/mm.c index 35b12ab..4635776 100644 --- a/kern/efi/mm.c +++ b/kern/efi/mm.c @@ -47,7 +47,7 @@ static struct allocated_page *allocated_pages = 0; /* The minimum and maximum heap size for GRUB itself. */ #define MIN_HEAP_SIZE 0x100000 -#define MAX_HEAP_SIZE (16 * 0x100000) +#define MAX_HEAP_SIZE (1600 * 0x100000) /* Allocate pages. Return the pointer to the first of allocated pages. */ diff --git a/kern/efi/mmap.c b/kern/efi/mmap.c new file mode 100644 index 0000000..11fbc72 --- /dev/null +++ b/kern/efi/mmap.c @@ -0,0 +1,158 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/machine/memory.h> +#include <grub/err.h> +#include <grub/efi/api.h> +#include <grub/efi/efi.h> +#include <grub/mm.h> +#include <grub/misc.h> + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +struct region +{ + grub_uint64_t start; + grub_uint64_t len; + grub_uint32_t type; +}; + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_memory_descriptor_t *map_buf; + grub_efi_uintn_t map_key = 0; + grub_efi_uintn_t desc_size = 0; + grub_efi_uint32_t desc_version = 0; + grub_uint64_t curstart, curend; + grub_uint32_t curtype; + grub_efi_memory_descriptor_t *desc; + struct region *regions; + struct region t; + int i, count, done = 1; + + if (grub_efi_get_memory_map (&mmap_size, map_buf, + &map_key, &desc_size, + &desc_version) < 0) + return grub_errno; + + map_buf = grub_malloc (mmap_size); + if (!map_buf) + return grub_errno; + + if (grub_efi_get_memory_map (&mmap_size, map_buf, + &map_key, &desc_size, + &desc_version) <= 0) + { + grub_free (map_buf); + return grub_errno; + } + + count = mmap_size / desc_size; + if (! count) + { + grub_free (map_buf); + return grub_error (GRUB_ERR_IO, "couldn't get EFI memory map"); + } + regions = (struct region *) grub_malloc (count * sizeof (struct region)); + + for (desc = map_buf, i = 0; + desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++) + { + grub_dprintf ("efi_mmap", "EFI memory region 0x%llx-0x%llx: %d\n", + desc->physical_start, desc->physical_start + + desc->num_pages * 4096, desc->type); + switch (desc->type) + { + case GRUB_EFI_RUNTIME_SERVICES_CODE: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_CODE; + break; + + case GRUB_EFI_RESERVED_MEMORY_TYPE: + case GRUB_EFI_RUNTIME_SERVICES_DATA: + case GRUB_EFI_UNUSABLE_MEMORY: + case GRUB_EFI_MEMORY_MAPPED_IO: + case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: + case GRUB_EFI_PAL_CODE: + case GRUB_EFI_MAX_MEMORY_TYPE: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_RESERVED; + break; + + case GRUB_EFI_LOADER_CODE: + case GRUB_EFI_LOADER_DATA: + case GRUB_EFI_BOOT_SERVICES_CODE: + case GRUB_EFI_BOOT_SERVICES_DATA: + case GRUB_EFI_CONVENTIONAL_MEMORY: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_AVAILABLE; + break; + + case GRUB_EFI_ACPI_RECLAIM_MEMORY: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_ACPI; + break; + + case GRUB_EFI_ACPI_MEMORY_NVS: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_NVS; + break; + } + } + + /* Bubble-sort the memory map */ + while (done) + { + done = 0; + for (i = 0; i < count - 1; i++) + if (regions[i].start > regions[i + 1].start) + { + done = 1; + t = regions[i]; + regions[i] = regions[i + 1]; + regions[i + 1] = t; + } + } + + curstart = regions[0].start; + curend = regions[0].start + regions[0].len; + curtype = regions[0].type; + for (i = 1; i < count; i++) + { + if (curend != regions[i].start || curtype != regions[i].type) + { + hook (curstart, curend - curstart, curtype); + curstart = regions[i].start; + curtype = regions[i].type; + } + curend = regions[i].start + regions[i].len; + } + + hook (curstart, curend - curstart, curtype); + + return GRUB_ERR_NONE; +} diff --git a/kern/i386/loader.S b/kern/i386/loader.S index fc27b86..f1b6c18 100644 --- a/kern/i386/loader.S +++ b/kern/i386/loader.S @@ -117,27 +117,3 @@ bzimage: linux_setup_seg: .word 0 .code32 - -/* - * Use cdecl calling convention for *BSD kernels. - */ - -FUNCTION(grub_unix_real_boot) - - call EXT_C(grub_dl_unload_all) - call EXT_C(grub_stop_floppy) - - /* Interrupts should be disabled. */ - cli - - /* Discard `grub_unix_real_boot' return address. */ - popl %eax - - /* Fetch `entry' address ... */ - popl %eax - - /* - * ... and put our return address in its place. The kernel will - * ignore it, but it expects %esp to point to it. - */ - call *%eax diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 25d0f59..712b013 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -19,8 +19,8 @@ #include <grub/loader.h> #include <grub/cpu/loader.h> #include <grub/cpu/bsd.h> -#include <grub/machine/init.h> #include <grub/machine/memory.h> +#include <grub/machine/machine.h> #include <grub/file.h> #include <grub/err.h> #include <grub/rescue.h> @@ -31,6 +31,11 @@ #include <grub/misc.h> #include <grub/gzio.h> #include <grub/aout.h> +#include <grub/i386/uppermem.h> + +#ifdef GRUB_MACHINE_EFI +#include <grub/efi/efi.h> +#endif #define ALIGN_DWORD(a) ALIGN_UP (a, 4) #define ALIGN_PAGE(a) ALIGN_UP (a, 4096) @@ -302,6 +307,15 @@ grub_freebsd_boot (void) bi.bi_kernend = kern_end; +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev, 0, 0, 0, &bi, bi.bi_modulep, kern_end); @@ -313,30 +327,39 @@ static grub_err_t grub_openbsd_boot (void) { char *buf = (char *) GRUB_BSD_TEMP_BUFFER; - struct grub_machine_mmap_entry mmap; struct grub_openbsd_bios_mmap *pm; struct grub_openbsd_bootargs *pa; - grub_uint32_t bootdev, biosdev, unit, slice, part, cont; + grub_uint32_t bootdev, biosdev, unit, slice, part; + grub_uint64_t lower, upper; + grub_err_t err; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + pm->addr = addr; + pm->len = size; + + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + pm->type = OPENBSD_MMAP_AVAILABLE; + break; + + default: + pm->type = OPENBSD_MMAP_RESERVED; + break; + } + pm++; + + return 0; + } pa = (struct grub_openbsd_bootargs *) buf; pa->ba_type = OPENBSD_BOOTARG_MMAP; pm = (struct grub_openbsd_bios_mmap *) (pa + 1); - cont = grub_get_mmap_entry (&mmap, 0); - if (mmap.size) - do - { - pm->addr = mmap.addr; - pm->len = mmap.len; - pm->type = mmap.type; - pm++; - - if (!cont) - break; - cont = grub_get_mmap_entry (&mmap, cont); - } - while (mmap.size); + grub_machine_mmap_iterate (hook); pa->ba_size = (char *) pm - (char *) pa; pa->ba_next = (struct grub_openbsd_bootargs *) pm; @@ -348,8 +371,20 @@ grub_openbsd_boot (void) bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) + (part << OPENBSD_B_PARTSHIFT)); + if ((err = grub_get_lower_upper_memory (&lower, &upper))) + return err; + +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER, - 0, grub_upper_mem >> 10, grub_lower_mem >> 10, + 0, upper >> 10, lower >> 10, (char *) pa - buf, buf); /* Not reached. */ @@ -362,6 +397,8 @@ grub_netbsd_boot (void) struct grub_netbsd_btinfo_rootdevice *rootdev; struct grub_netbsd_bootinfo *bootinfo; grub_uint32_t biosdev, unit, slice, part; + grub_uint64_t lower, upper; + grub_err_t err; grub_bsd_get_device (&biosdev, &unit, &slice, &part); @@ -376,8 +413,20 @@ grub_netbsd_boot (void) bootinfo->bi_count = 1; bootinfo->bi_data[0] = rootdev; + if ((err = grub_get_lower_upper_memory (&lower, &upper))) + return err; + +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags, 0, bootinfo, - 0, grub_upper_mem >> 10, grub_lower_mem >> 10); + 0, upper >> 10, lower >> 10); /* Not reached. */ return GRUB_ERR_NONE; @@ -461,10 +510,10 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr) phdr->p_paddr &= 0xFFFFFF; paddr = phdr->p_paddr; - if ((paddr < grub_os_area_addr) + /* if ((paddr < grub_os_area_addr) || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", - paddr); + paddr);*/ if ((!kern_start) || (paddr < kern_start)) kern_start = paddr; @@ -577,7 +626,7 @@ grub_rescue_cmd_freebsd (int argc, char *argv[]) (grub_freebsd_add_meta_module (1, argc, argv, kern_start, kern_end - kern_start))) return; - grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1); + grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0); } } @@ -589,7 +638,7 @@ grub_rescue_cmd_openbsd (int argc, char *argv[]) grub_bsd_parse_flags (argv[1], openbsd_opts, openbsd_flags)); if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) - grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1); + grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 0); } void @@ -600,7 +649,7 @@ grub_rescue_cmd_netbsd (int argc, char *argv[]) grub_bsd_parse_flags (argv[1], netbsd_opts, netbsd_flags)); if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) - grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1); + grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0); } void @@ -718,11 +767,11 @@ grub_rescue_cmd_freebsd_module (int argc, char *argv[]) if ((!file) || (!file->size)) goto fail; - if (kern_end + file->size > grub_os_area_addr + grub_os_area_size) + /* if (kern_end + file->size > grub_os_area_addr + grub_os_area_size) { grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module"); goto fail; - } + }*/ grub_file_read (file, (char *) kern_end, file->size); if ((!grub_errno) && diff --git a/loader/i386/bsd_helper.S b/loader/i386/bsd_helper.S new file mode 100644 index 0000000..9cdea0c --- /dev/null +++ b/loader/i386/bsd_helper.S @@ -0,0 +1,65 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +#include <grub/symbol.h> + +/* + * Use cdecl calling convention for *BSD kernels. + */ + +FUNCTION(grub_unix_real_boot) + + /* Interrupts should be disabled. */ + cli + + /* Discard `grub_unix_real_boot' return address. */ + popl %eax + + /* Fetch `entry' address ... */ + popl %eax + + /* + * ... and put our return address in its place. The kernel will + * ignore it, but it expects %esp to point to it. + */ + call *%eax diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index ff758d1..055b1cf 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -30,7 +30,7 @@ #include <grub/loader.h> #include <grub/machine/loader.h> #include <grub/multiboot.h> -#include <grub/machine/init.h> +#include <grub/machine/machine.h> #include <grub/machine/memory.h> #include <grub/cpu/multiboot.h> #include <grub/elf.h> @@ -43,6 +43,13 @@ #include <grub/misc.h> #include <grub/gzio.h> #include <grub/env.h> +#include <grub/cpu/loader.h> +#include <grub/cpu/multiboot.h> +#include <grub/i386/uppermem.h> + +#ifdef GRUB_MACHINE_EFI +#include <grub/efi/efi.h> +#endif extern grub_dl_t my_mod; static struct grub_multiboot_info *mbi, *mbi_dest; @@ -54,7 +61,12 @@ static grub_size_t code_size; static grub_err_t grub_multiboot_boot (void) { - grub_stop_floppy (); + grub_printf ("Boot\n"); + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif grub_multiboot_real_boot (entry, mbi_dest); @@ -111,14 +123,24 @@ grub_get_multiboot_mmap_len (void) static void grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry) { - struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry; + struct grub_multiboot_mmap_entry *mmap_entry + = (struct grub_multiboot_mmap_entry *) first_entry; auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) { mmap_entry->addr = addr; mmap_entry->len = size; - mmap_entry->type = type; + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + mmap_entry->type = GRUB_MULTIBOOT_MEMORY_AVAILABLE; + break; + + default: + mmap_entry->type = GRUB_MULTIBOOT_MEMORY_RESERVED; + break; + } mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size); mmap_entry++; @@ -201,6 +223,7 @@ grub_multiboot (int argc, char *argv[]) struct grub_multiboot_header *header; grub_ssize_t len, cmdline_length, boot_loader_name_length; grub_uint32_t mmap_length; + grub_uint64_t lower, upper; int i; grub_loader_unset (); @@ -288,7 +311,9 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_dest = header->load_addr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); + playground = grub_malloc (RELOCATOR_SIZEOF(forward) + + grub_multiboot_payload_size + + RELOCATOR_SIZEOF(backward)); if (! playground) goto fail; @@ -343,9 +368,12 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_size, grub_multiboot_payload_entry_offset); + if (grub_get_lower_upper_memory (&lower, &upper)) + goto fail; + /* Convert from bytes to kilobytes. */ - mbi->mem_lower = grub_lower_mem / 1024; - mbi->mem_upper = grub_upper_mem / 1024; + mbi->mem_lower = lower / 1024; + mbi->mem_upper = upper / 1024; mbi->flags |= MULTIBOOT_INFO_MEMORY; cmdline = p = cmdline_addr (grub_multiboot_payload_orig); @@ -372,7 +400,7 @@ grub_multiboot (int argc, char *argv[]) if (grub_multiboot_get_bootdev (&mbi->boot_device)) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; - grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); fail: if (file) diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S index 1e71120..cd07246 100644 --- a/loader/i386/multiboot_helper.S +++ b/loader/i386/multiboot_helper.S @@ -52,7 +52,7 @@ VARIABLE(grub_multiboot_forward_relocator) cld rep movsb - + jmp *%edx VARIABLE(grub_multiboot_forward_relocator_end) @@ -91,7 +91,7 @@ FUNCTION(grub_multiboot_real_boot) /* Move the magic value into eax. */ movl $MULTIBOOT_MAGIC2, %eax - + /* Jump to the relocator. */ popl %ebp jmp *%ebp diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S index 901be68..a83bd9a 100644 --- a/loader/i386/xnu_helper.S +++ b/loader/i386/xnu_helper.S @@ -15,6 +15,9 @@ FUNCTION(grub_xnu_launch) jmp cont1 cont1: lgdt gdtdesc + + jmp cont2 +cont2: .code32 @@ -28,8 +31,8 @@ cont1: and $0xffffffef, %eax wrmsr - jmp cont2 -cont2: + jmp cont3 +cont3: #endif .code32 diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c index abcad9b..8abce88 100644 --- a/loader/multiboot_loader.c +++ b/loader/multiboot_loader.c @@ -140,7 +140,7 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[]) /* XXX Find a better way to identify this. This is for i386-pc */ -#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) +#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) || defined (GRUB_MACHINE_EFI) if (header_multi_ver_found == 1) { grub_dprintf ("multiboot_loader", @@ -153,7 +153,9 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[]) { grub_dprintf ("multiboot_loader", "Launching multiboot 2 grub_multiboot2() function\n"); +#ifndef GRUB_MACHINE_EFI grub_multiboot2 (argc, argv); +#endif module_version_status = 2; } @@ -170,7 +172,7 @@ void grub_rescue_cmd_module_loader (int argc, char *argv[]) { -#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) +#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) || defined(GRUB_MACHINE_EFI) if (module_version_status == 1) { grub_dprintf("multiboot_loader", @@ -182,7 +184,9 @@ grub_rescue_cmd_module_loader (int argc, char *argv[]) { grub_dprintf("multiboot_loader", "Launching multiboot 2 grub_module2() function\n"); +#ifndef GRUB_MACHINE_EFI grub_module2 (argc, argv); +#endif } } [-- Attachment #3: uppermem.diff --] [-- Type: text/x-diff, Size: 3753 bytes --] diff --git a/conf/i386.rmk b/conf/i386.rmk index 93f84ce..5338457 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -14,3 +14,8 @@ pkglib_MODULES += vga_text.mod vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += uppermem.mod +uppermem_mod_SOURCES = lib/i386/uppermem.c +uppermem_mod_CFLAGS = $(COMMON_CFLAGS) +uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/lib/i386/uppermem.c b/lib/i386/uppermem.c new file mode 100644 index 0000000..623535f --- /dev/null +++ b/lib/i386/uppermem.c @@ -0,0 +1,127 @@ +/* Compute amount of lower and upper memory till the first hole */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EFIEMU +#include <grub/machine/memory.h> +#include <grub/i386/uppermem.h> +#endif + +#include <grub/mm.h> +#include <grub/misc.h> + +struct region +{ + grub_uint64_t start; + grub_uint64_t end; +}; + +#ifdef EFIEMU +grub_err_t +grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper) +#else +grub_err_t +grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper) +#endif +{ + grub_size_t count = 0; + struct region *regions = 0; + int done = 1; + unsigned i; + struct region t; + grub_uint64_t last_addr; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_uint32_t type) + { +#ifdef EFIEMU + if (type != GRUB_EFIEMU_MEMORY_AVAILABLE) +#else + if (type != GRUB_MACHINE_MEMORY_AVAILABLE) +#endif + return 0; + regions = (struct region *) + grub_realloc (regions, (count + 1) * sizeof (struct region)); + regions[count].start = addr; + regions[count].end = addr + size; + count++; + return 0; + } + +#ifdef EFIEMU + grub_efiemu_mmap_iterate (hook); +#else + grub_machine_mmap_iterate (hook); +#endif + + /* Bubble-sort the memory map */ + while (done) + { + done = 0; + for (i = 0; i < count - 1; i++) + if (regions[i].start > regions[i + 1].start) + { + done = 1; + t = regions[i]; + regions[i] = regions[i + 1]; + regions[i + 1] = t; + } + } + + /* Set mem_upper and mem_lower */ + last_addr = 0; + for (i = 0; i < count; i++) + { + grub_uint64_t end = regions[i].end; + /* Don't use memory after 0xa0000*/ + if (end > 0xa0000) + end = 0xa0000; + + /* low memory is finished */ + if (regions[i].start > end) + break; + + /* A hole */ + if (regions[i].start > last_addr) + break; + + last_addr = end; + } + + *lower = last_addr; + + /* Skip low memory */ + for (i = 0; i < count && regions[i].end <= 0x100000; + i++); + + last_addr = 0x100000; + for (; i < count; i++) + { + /* A hole */ + if (regions[i].start > last_addr) + break; + + last_addr = regions[i].end; + } + + *upper = (last_addr - 0x100000); + grub_free (regions); + + return GRUB_ERR_NONE; +} ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-23 12:29 multiboot on EFI phcoder @ 2009-03-23 21:16 ` uzer cheg 2009-03-23 22:14 ` phcoder 2009-03-28 13:13 ` Robert Millan 1 sibling, 1 reply; 15+ messages in thread From: uzer cheg @ 2009-03-23 21:16 UTC (permalink / raw) To: The development of GRUB 2 Vladimir, First of all I'd like to say thank you for a quick feedback and development. I tried to apply your patches and test it on my Apple Xserve Intel 32 bit. I've done following; # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 # cd ./grub2 # patch -b -p1 < ./uppermem.diff patching file conf/i386.rmk patching file lib/i386/uppermem.c --- it's Ok --- Than # patch -b -p1 < ./efiboot.diff patching file conf/common.rmk Hunk #1 succeeded at 503 (offset -4 lines). patching file conf/i386-coreboot.rmk Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). Hunk #2 succeeded at 200 (offset -10 lines). patching file conf/i386-efi.rmk Hunk #1 FAILED at 80. Hunk #2 FAILED at 103. ... etc. I would like to ask you for what revision of grub2 this patches where done? Do I have to checkout any specific branch of grub2? Thank you in advance. 2009/3/23 phcoder <phcoder@gmail.com>: > Hello. Here is an initial version of patch for booting multiboot kernels on > i386-efi. No Changelog yet because it's not for inclusion yet. > -- > > Regards > Vladimir 'phcoder' Serbinenko > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-23 21:16 ` uzer cheg @ 2009-03-23 22:14 ` phcoder 2009-03-23 22:33 ` phcoder 2009-03-24 10:31 ` uzer cheg 0 siblings, 2 replies; 15+ messages in thread From: phcoder @ 2009-03-23 22:14 UTC (permalink / raw) To: The development of GRUB 2 Try with 2030. Actually it's diffed against 2030+some of my posted and unposted patches. If it still doesn't apply please report I'll update and rediff it against HEAD. I'm interested in behaviour of this code on real EFI however doesn't expect this version to be able to work completely. x86_64-efi isn't supported by this patch yet Also if xen uses any bios interrupts it will probably triple fault. On IRC we discussed a possibility of loading seabios and it's probably feasible but will take more time uzer cheg wrote: > Vladimir, > > First of all I'd like to say thank you for a quick feedback and development. > > I tried to apply your patches and test it on my Apple Xserve Intel 32 bit. > I've done following; > > # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 > # cd ./grub2 > # patch -b -p1 < ./uppermem.diff > patching file conf/i386.rmk > patching file lib/i386/uppermem.c > --- it's Ok > --- Than > # patch -b -p1 < ./efiboot.diff > patching file conf/common.rmk > Hunk #1 succeeded at 503 (offset -4 lines). > patching file conf/i386-coreboot.rmk > Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). > Hunk #2 succeeded at 200 (offset -10 lines). > patching file conf/i386-efi.rmk > Hunk #1 FAILED at 80. > Hunk #2 FAILED at 103. > ... > etc. > > > I would like to ask you for what revision of grub2 this patches where done? > Do I have to checkout any specific branch of grub2? > > Thank you in advance. > > 2009/3/23 phcoder <phcoder@gmail.com>: >> Hello. Here is an initial version of patch for booting multiboot kernels on >> i386-efi. No Changelog yet because it's not for inclusion yet. >> -- >> >> Regards >> Vladimir 'phcoder' Serbinenko >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> http://lists.gnu.org/mailman/listinfo/grub-devel >> >> > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel -- Regards Vladimir 'phcoder' Serbinenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-23 22:14 ` phcoder @ 2009-03-23 22:33 ` phcoder 2009-03-24 10:31 ` uzer cheg 1 sibling, 0 replies; 15+ messages in thread From: phcoder @ 2009-03-23 22:33 UTC (permalink / raw) To: The development of GRUB 2 You may also need my elf bugfix patch (was applied as rev 2037) phcoder wrote: > Try with 2030. Actually it's diffed against 2030+some of my posted and > unposted patches. If it still doesn't apply please report I'll update > and rediff it against HEAD. > I'm interested in behaviour of this code on real EFI however doesn't > expect this version to be able to work completely. > x86_64-efi isn't supported by this patch yet > Also if xen uses any bios interrupts it will probably triple fault. On > IRC we discussed a possibility of loading seabios and it's probably > feasible but will take more time > uzer cheg wrote: >> Vladimir, >> >> First of all I'd like to say thank you for a quick feedback and >> development. >> >> I tried to apply your patches and test it on my Apple Xserve Intel 32 >> bit. >> I've done following; >> >> # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 >> # cd ./grub2 >> # patch -b -p1 < ./uppermem.diff >> patching file conf/i386.rmk >> patching file lib/i386/uppermem.c >> --- it's Ok >> --- Than >> # patch -b -p1 < ./efiboot.diff >> patching file conf/common.rmk >> Hunk #1 succeeded at 503 (offset -4 lines). >> patching file conf/i386-coreboot.rmk >> Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). >> Hunk #2 succeeded at 200 (offset -10 lines). >> patching file conf/i386-efi.rmk >> Hunk #1 FAILED at 80. >> Hunk #2 FAILED at 103. >> ... >> etc. >> >> >> I would like to ask you for what revision of grub2 this patches where >> done? >> Do I have to checkout any specific branch of grub2? >> >> Thank you in advance. >> >> 2009/3/23 phcoder <phcoder@gmail.com>: >>> Hello. Here is an initial version of patch for booting multiboot >>> kernels on >>> i386-efi. No Changelog yet because it's not for inclusion yet. >>> -- >>> >>> Regards >>> Vladimir 'phcoder' Serbinenko >>> >>> _______________________________________________ >>> Grub-devel mailing list >>> Grub-devel@gnu.org >>> http://lists.gnu.org/mailman/listinfo/grub-devel >>> >>> >> >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> http://lists.gnu.org/mailman/listinfo/grub-devel > > -- Regards Vladimir 'phcoder' Serbinenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-23 22:14 ` phcoder 2009-03-23 22:33 ` phcoder @ 2009-03-24 10:31 ` uzer cheg 2009-03-24 10:54 ` phcoder 1 sibling, 1 reply; 15+ messages in thread From: uzer cheg @ 2009-03-24 10:31 UTC (permalink / raw) To: The development of GRUB 2 Dear Vladimir, I tried rev 2030 and 2037. And I also had few errors on patching stage. I think it is a good idea to commit your code to head branch. I will wait for it and try it asap. Thank you. On Tue, Mar 24, 2009 at 12:14 AM, phcoder <phcoder@gmail.com> wrote: > Try with 2030. Actually it's diffed against 2030+some of my posted and > unposted patches. If it still doesn't apply please report I'll update and > rediff it against HEAD. > I'm interested in behaviour of this code on real EFI however doesn't expect > this version to be able to work completely. > x86_64-efi isn't supported by this patch yet > Also if xen uses any bios interrupts it will probably triple fault. On IRC > we discussed a possibility of loading seabios and it's probably feasible but > will take more time > uzer cheg wrote: >> >> Vladimir, >> >> First of all I'd like to say thank you for a quick feedback and >> development. >> >> I tried to apply your patches and test it on my Apple Xserve Intel 32 >> bit. >> I've done following; >> >> # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 >> # cd ./grub2 >> # patch -b -p1 < ./uppermem.diff >> patching file conf/i386.rmk >> patching file lib/i386/uppermem.c >> --- it's Ok >> --- Than >> # patch -b -p1 < ./efiboot.diff >> patching file conf/common.rmk >> Hunk #1 succeeded at 503 (offset -4 lines). >> patching file conf/i386-coreboot.rmk >> Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). >> Hunk #2 succeeded at 200 (offset -10 lines). >> patching file conf/i386-efi.rmk >> Hunk #1 FAILED at 80. >> Hunk #2 FAILED at 103. >> ... >> etc. >> >> >> I would like to ask you for what revision of grub2 this patches where >> done? >> Do I have to checkout any specific branch of grub2? >> >> Thank you in advance. >> >> 2009/3/23 phcoder <phcoder@gmail.com>: >>> >>> Hello. Here is an initial version of patch for booting multiboot kernels >>> on >>> i386-efi. No Changelog yet because it's not for inclusion yet. >>> -- >>> >>> Regards >>> Vladimir 'phcoder' Serbinenko >>> >>> _______________________________________________ >>> Grub-devel mailing list >>> Grub-devel@gnu.org >>> http://lists.gnu.org/mailman/listinfo/grub-devel >>> >>> >> >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> http://lists.gnu.org/mailman/listinfo/grub-devel > > > -- > > Regards > Vladimir 'phcoder' Serbinenko > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-24 10:31 ` uzer cheg @ 2009-03-24 10:54 ` phcoder 2009-03-24 10:58 ` uzer cheg 0 siblings, 1 reply; 15+ messages in thread From: phcoder @ 2009-03-24 10:54 UTC (permalink / raw) To: The development of GRUB 2 Hello. I have to write rights to svn. And even if I had I would never commit a code in such stage (not reviewed, tested only on qemu, still in developement) However I'll rediff the code against HEAD when I'll have time uzer cheg wrote: > Dear Vladimir, > I tried rev 2030 and 2037. > And I also had few errors on patching stage. > > I think it is a good idea to commit your code to head branch. > I will wait for it and try it asap. > > Thank you. > > On Tue, Mar 24, 2009 at 12:14 AM, phcoder <phcoder@gmail.com> wrote: >> Try with 2030. Actually it's diffed against 2030+some of my posted and >> unposted patches. If it still doesn't apply please report I'll update and >> rediff it against HEAD. >> I'm interested in behaviour of this code on real EFI however doesn't expect >> this version to be able to work completely. >> x86_64-efi isn't supported by this patch yet >> Also if xen uses any bios interrupts it will probably triple fault. On IRC >> we discussed a possibility of loading seabios and it's probably feasible but >> will take more time >> uzer cheg wrote: >>> Vladimir, >>> >>> First of all I'd like to say thank you for a quick feedback and >>> development. >>> >>> I tried to apply your patches and test it on my Apple Xserve Intel 32 >>> bit. >>> I've done following; >>> >>> # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 >>> # cd ./grub2 >>> # patch -b -p1 < ./uppermem.diff >>> patching file conf/i386.rmk >>> patching file lib/i386/uppermem.c >>> --- it's Ok >>> --- Than >>> # patch -b -p1 < ./efiboot.diff >>> patching file conf/common.rmk >>> Hunk #1 succeeded at 503 (offset -4 lines). >>> patching file conf/i386-coreboot.rmk >>> Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). >>> Hunk #2 succeeded at 200 (offset -10 lines). >>> patching file conf/i386-efi.rmk >>> Hunk #1 FAILED at 80. >>> Hunk #2 FAILED at 103. >>> ... >>> etc. >>> >>> >>> I would like to ask you for what revision of grub2 this patches where >>> done? >>> Do I have to checkout any specific branch of grub2? >>> >>> Thank you in advance. >>> >>> 2009/3/23 phcoder <phcoder@gmail.com>: >>>> Hello. Here is an initial version of patch for booting multiboot kernels >>>> on >>>> i386-efi. No Changelog yet because it's not for inclusion yet. >>>> -- >>>> >>>> Regards >>>> Vladimir 'phcoder' Serbinenko >>>> >>>> _______________________________________________ >>>> Grub-devel mailing list >>>> Grub-devel@gnu.org >>>> http://lists.gnu.org/mailman/listinfo/grub-devel >>>> >>>> >>> >>> _______________________________________________ >>> Grub-devel mailing list >>> Grub-devel@gnu.org >>> http://lists.gnu.org/mailman/listinfo/grub-devel >> >> -- >> >> Regards >> Vladimir 'phcoder' Serbinenko >> >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> http://lists.gnu.org/mailman/listinfo/grub-devel >> > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel -- Regards Vladimir 'phcoder' Serbinenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-24 10:54 ` phcoder @ 2009-03-24 10:58 ` uzer cheg 2009-03-26 19:25 ` Vladimir Serbinenko 0 siblings, 1 reply; 15+ messages in thread From: uzer cheg @ 2009-03-24 10:58 UTC (permalink / raw) To: The development of GRUB 2 Ok. I see. So I will wait for rediffed patches and number of revision. Thank you in advance. On Tue, Mar 24, 2009 at 12:54 PM, phcoder <phcoder@gmail.com> wrote: > Hello. I have to write rights to svn. And even if I had I would never commit > a code in such stage (not reviewed, tested only on qemu, still in > developement) > However I'll rediff the code against HEAD when I'll have time > > uzer cheg wrote: >> >> Dear Vladimir, >> I tried rev 2030 and 2037. >> And I also had few errors on patching stage. >> >> I think it is a good idea to commit your code to head branch. >> I will wait for it and try it asap. >> >> Thank you. >> >> On Tue, Mar 24, 2009 at 12:14 AM, phcoder <phcoder@gmail.com> wrote: >>> >>> Try with 2030. Actually it's diffed against 2030+some of my posted and >>> unposted patches. If it still doesn't apply please report I'll update and >>> rediff it against HEAD. >>> I'm interested in behaviour of this code on real EFI however doesn't >>> expect >>> this version to be able to work completely. >>> x86_64-efi isn't supported by this patch yet >>> Also if xen uses any bios interrupts it will probably triple fault. On >>> IRC >>> we discussed a possibility of loading seabios and it's probably feasible >>> but >>> will take more time >>> uzer cheg wrote: >>>> >>>> Vladimir, >>>> >>>> First of all I'd like to say thank you for a quick feedback and >>>> development. >>>> >>>> I tried to apply your patches and test it on my Apple Xserve Intel 32 >>>> bit. >>>> I've done following; >>>> >>>> # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 >>>> # cd ./grub2 >>>> # patch -b -p1 < ./uppermem.diff >>>> patching file conf/i386.rmk >>>> patching file lib/i386/uppermem.c >>>> --- it's Ok >>>> --- Than >>>> # patch -b -p1 < ./efiboot.diff >>>> patching file conf/common.rmk >>>> Hunk #1 succeeded at 503 (offset -4 lines). >>>> patching file conf/i386-coreboot.rmk >>>> Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). >>>> Hunk #2 succeeded at 200 (offset -10 lines). >>>> patching file conf/i386-efi.rmk >>>> Hunk #1 FAILED at 80. >>>> Hunk #2 FAILED at 103. >>>> ... >>>> etc. >>>> >>>> >>>> I would like to ask you for what revision of grub2 this patches where >>>> done? >>>> Do I have to checkout any specific branch of grub2? >>>> >>>> Thank you in advance. >>>> >>>> 2009/3/23 phcoder <phcoder@gmail.com>: >>>>> >>>>> Hello. Here is an initial version of patch for booting multiboot >>>>> kernels >>>>> on >>>>> i386-efi. No Changelog yet because it's not for inclusion yet. >>>>> -- >>>>> >>>>> Regards >>>>> Vladimir 'phcoder' Serbinenko >>>>> >>>>> _______________________________________________ >>>>> Grub-devel mailing list >>>>> Grub-devel@gnu.org >>>>> http://lists.gnu.org/mailman/listinfo/grub-devel >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> Grub-devel mailing list >>>> Grub-devel@gnu.org >>>> http://lists.gnu.org/mailman/listinfo/grub-devel >>> >>> -- >>> >>> Regards >>> Vladimir 'phcoder' Serbinenko >>> >>> >>> _______________________________________________ >>> Grub-devel mailing list >>> Grub-devel@gnu.org >>> http://lists.gnu.org/mailman/listinfo/grub-devel >>> >> >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> http://lists.gnu.org/mailman/listinfo/grub-devel > > > -- > > Regards > Vladimir 'phcoder' Serbinenko > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-24 10:58 ` uzer cheg @ 2009-03-26 19:25 ` Vladimir Serbinenko 0 siblings, 0 replies; 15+ messages in thread From: Vladimir Serbinenko @ 2009-03-26 19:25 UTC (permalink / raw) To: The development of GRUB 2 [-- Attachment #1: Type: text/plain, Size: 4280 bytes --] Hello. Unfortunately my laptop broke down. I have a copy of all my data but no system suitable for developement. So I'll take a break (about a week probably) from grub2 developement. BTW I have also some initial work on i386/linux and i386/efi/linux unification. On Tue, Mar 24, 2009 at 11:58 AM, uzer cheg <usercheg@gmail.com> wrote: > Ok. I see. > > So I will wait for rediffed patches and number of revision. > > Thank you in advance. > > On Tue, Mar 24, 2009 at 12:54 PM, phcoder <phcoder@gmail.com> wrote: > > Hello. I have to write rights to svn. And even if I had I would never > commit > > a code in such stage (not reviewed, tested only on qemu, still in > > developement) > > However I'll rediff the code against HEAD when I'll have time > > > > uzer cheg wrote: > >> > >> Dear Vladimir, > >> I tried rev 2030 and 2037. > >> And I also had few errors on patching stage. > >> > >> I think it is a good idea to commit your code to head branch. > >> I will wait for it and try it asap. > >> > >> Thank you. > >> > >> On Tue, Mar 24, 2009 at 12:14 AM, phcoder <phcoder@gmail.com> wrote: > >>> > >>> Try with 2030. Actually it's diffed against 2030+some of my posted and > >>> unposted patches. If it still doesn't apply please report I'll update > and > >>> rediff it against HEAD. > >>> I'm interested in behaviour of this code on real EFI however doesn't > >>> expect > >>> this version to be able to work completely. > >>> x86_64-efi isn't supported by this patch yet > >>> Also if xen uses any bios interrupts it will probably triple fault. On > >>> IRC > >>> we discussed a possibility of loading seabios and it's probably > feasible > >>> but > >>> will take more time > >>> uzer cheg wrote: > >>>> > >>>> Vladimir, > >>>> > >>>> First of all I'd like to say thank you for a quick feedback and > >>>> development. > >>>> > >>>> I tried to apply your patches and test it on my Apple Xserve Intel 32 > >>>> bit. > >>>> I've done following; > >>>> > >>>> # svn co svn://svn.sv.gnu.org/grub/trunk/grub2 > >>>> # cd ./grub2 > >>>> # patch -b -p1 < ./uppermem.diff > >>>> patching file conf/i386.rmk > >>>> patching file lib/i386/uppermem.c > >>>> --- it's Ok > >>>> --- Than > >>>> # patch -b -p1 < ./efiboot.diff > >>>> patching file conf/common.rmk > >>>> Hunk #1 succeeded at 503 (offset -4 lines). > >>>> patching file conf/i386-coreboot.rmk > >>>> Hunk #1 succeeded at 99 with fuzz 2 (offset -3 lines). > >>>> Hunk #2 succeeded at 200 (offset -10 lines). > >>>> patching file conf/i386-efi.rmk > >>>> Hunk #1 FAILED at 80. > >>>> Hunk #2 FAILED at 103. > >>>> ... > >>>> etc. > >>>> > >>>> > >>>> I would like to ask you for what revision of grub2 this patches where > >>>> done? > >>>> Do I have to checkout any specific branch of grub2? > >>>> > >>>> Thank you in advance. > >>>> > >>>> 2009/3/23 phcoder <phcoder@gmail.com>: > >>>>> > >>>>> Hello. Here is an initial version of patch for booting multiboot > >>>>> kernels > >>>>> on > >>>>> i386-efi. No Changelog yet because it's not for inclusion yet. > >>>>> -- > >>>>> > >>>>> Regards > >>>>> Vladimir 'phcoder' Serbinenko > >>>>> > >>>>> _______________________________________________ > >>>>> Grub-devel mailing list > >>>>> Grub-devel@gnu.org > >>>>> http://lists.gnu.org/mailman/listinfo/grub-devel > >>>>> > >>>>> > >>>> > >>>> _______________________________________________ > >>>> Grub-devel mailing list > >>>> Grub-devel@gnu.org > >>>> http://lists.gnu.org/mailman/listinfo/grub-devel > >>> > >>> -- > >>> > >>> Regards > >>> Vladimir 'phcoder' Serbinenko > >>> > >>> > >>> _______________________________________________ > >>> Grub-devel mailing list > >>> Grub-devel@gnu.org > >>> http://lists.gnu.org/mailman/listinfo/grub-devel > >>> > >> > >> > >> _______________________________________________ > >> Grub-devel mailing list > >> Grub-devel@gnu.org > >> http://lists.gnu.org/mailman/listinfo/grub-devel > > > > > > -- > > > > Regards > > Vladimir 'phcoder' Serbinenko > > > > > > _______________________________________________ > > Grub-devel mailing list > > Grub-devel@gnu.org > > http://lists.gnu.org/mailman/listinfo/grub-devel > > > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > [-- Attachment #2: Type: text/html, Size: 7125 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-23 12:29 multiboot on EFI phcoder 2009-03-23 21:16 ` uzer cheg @ 2009-03-28 13:13 ` Robert Millan 2009-03-28 14:31 ` Yoshinori K. Okuji 2009-03-28 22:33 ` phcoder 1 sibling, 2 replies; 15+ messages in thread From: Robert Millan @ 2009-03-28 13:13 UTC (permalink / raw) To: The development of GRUB 2 On Mon, Mar 23, 2009 at 01:29:55PM +0100, phcoder wrote: > Hello. Here is an initial version of patch for booting multiboot kernels > on i386-efi. No Changelog yet because it's not for inclusion yet. Very nice! Would it be hard to split the patch and make it more granular? I see it implements base mmap / lsmmap support on efi, then ports the *BSD loaders and the Multiboot loader too, and the uppermem facility. > pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ > _linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \ > - datetime.mod date.mod datehook.mod > + datetime.mod date.mod datehook.mod _multiboot.mod multiboot.mod > + > +# For _multiboot.mod. > +_multiboot_mod_SOURCES = loader/i386/multiboot.c \ > + loader/i386/multiboot_helper.S \ > + loader/multiboot_loader.c > +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) > +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) > +_multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) If everybody's fine with it, I'd like to suggest adding stuff to pkglib_MODULES in the same place as its corresponding variables. I've done this already a few times, and I think it makes the build system a bit more maintainable. What do you all think about this? > diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h > index 08e92a9..e69ff77 100644 > --- a/include/grub/i386/pc/memory.h > +++ b/include/grub/i386/pc/memory.h > @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry > grub_uint64_t len; > #define GRUB_MACHINE_MEMORY_AVAILABLE 1 > #define GRUB_MACHINE_MEMORY_RESERVED 2 > +#define GRUB_MACHINE_MEMORY_ACPI 3 > +#define GRUB_MACHINE_MEMORY_NVS 4 > grub_uint32_t type; > } __attribute__((packed)); Do we need specific knowledge of these two on i386-pc ? > /* The minimum and maximum heap size for GRUB itself. */ > #define MIN_HEAP_SIZE 0x100000 > -#define MAX_HEAP_SIZE (16 * 0x100000) > +#define MAX_HEAP_SIZE (1600 * 0x100000) Is 1600 MB what we want, or to remove the limit? > + /* Bubble-sort the memory map */ > + while (done) > + { > + done = 0; > + for (i = 0; i < count - 1; i++) > + if (regions[i].start > regions[i + 1].start) > + { > + done = 1; > + t = regions[i]; > + regions[i] = regions[i + 1]; > + regions[i + 1] = t; > + } > + } Do we need the memory map to be sorted? AFAIK loadees can cope with unsorted maps fine; is there an exception? > +#ifdef GRUB_MACHINE_PCBIOS > + grub_stop_floppy (); > +#endif grub_stop_floppy() doesn't do any BIOS-specific stuff. Wouldn't __i386__ be more appropiate? -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all." ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-28 13:13 ` Robert Millan @ 2009-03-28 14:31 ` Yoshinori K. Okuji 2009-04-01 12:57 ` Robert Millan 2009-03-28 22:33 ` phcoder 1 sibling, 1 reply; 15+ messages in thread From: Yoshinori K. Okuji @ 2009-03-28 14:31 UTC (permalink / raw) To: The development of GRUB 2 On Saturday 28 March 2009 22:13:06 Robert Millan wrote: > Do we need the memory map to be sorted? AFAIK loadees can cope with > unsorted maps fine; is there an exception? As I wrote in the draft, a boot loader should sort the memory map. An OS image must deal with an unsorted memory map, because the wording is "should", but it is still user-friendly (especially for debugging). > > +#ifdef GRUB_MACHINE_PCBIOS > > + grub_stop_floppy (); > > +#endif > > grub_stop_floppy() doesn't do any BIOS-specific stuff. Wouldn't __i386__ > be more appropiate? This should be moved to an arch-specific finalization function. Honestly, I prefer that this is done by disk drivers automatically when unloading, but some people seem to like giving up unloading modules. Regards, Okuji ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-28 14:31 ` Yoshinori K. Okuji @ 2009-04-01 12:57 ` Robert Millan 2009-04-01 13:58 ` Yoshinori K. Okuji 0 siblings, 1 reply; 15+ messages in thread From: Robert Millan @ 2009-04-01 12:57 UTC (permalink / raw) To: The development of GRUB 2 On Sat, Mar 28, 2009 at 11:31:14PM +0900, Yoshinori K. Okuji wrote: > On Saturday 28 March 2009 22:13:06 Robert Millan wrote: > > Do we need the memory map to be sorted? AFAIK loadees can cope with > > unsorted maps fine; is there an exception? > > As I wrote in the draft, a boot loader should sort the memory map. An OS image > must deal with an unsorted memory map, because the wording is "should", but > it is still user-friendly (especially for debugging). You mean the multiboot 2 draft? Since this change is backward-compatible, is there any reason we want this in multiboot 2 but not in multiboot 1? I don't like that the two diverge so much, it makes the implementation so much harder to maintain. Right now the multiboot 2 loader is a complete bitrot. Can we merge this and similar backward-compatible changes into multiboot 1? -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all." ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-04-01 12:57 ` Robert Millan @ 2009-04-01 13:58 ` Yoshinori K. Okuji 0 siblings, 0 replies; 15+ messages in thread From: Yoshinori K. Okuji @ 2009-04-01 13:58 UTC (permalink / raw) To: The development of GRUB 2 On Wednesday 01 April 2009 21:57:55 Robert Millan wrote: > On Sat, Mar 28, 2009 at 11:31:14PM +0900, Yoshinori K. Okuji wrote: > > On Saturday 28 March 2009 22:13:06 Robert Millan wrote: > > > Do we need the memory map to be sorted? AFAIK loadees can cope with > > > unsorted maps fine; is there an exception? > > > > As I wrote in the draft, a boot loader should sort the memory map. An OS > > image must deal with an unsorted memory map, because the wording is > > "should", but it is still user-friendly (especially for debugging). > > You mean the multiboot 2 draft? Since this change is backward-compatible, > is there any reason we want this in multiboot 2 but not in multiboot 1? No. > I don't like that the two diverge so much, it makes the implementation so > much harder to maintain. Right now the multiboot 2 loader is a complete > bitrot. > > Can we merge this and similar backward-compatible changes into multiboot 1? I agree. Regards, Okuji ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-28 13:13 ` Robert Millan 2009-03-28 14:31 ` Yoshinori K. Okuji @ 2009-03-28 22:33 ` phcoder 2009-04-04 16:28 ` phcoder 1 sibling, 1 reply; 15+ messages in thread From: phcoder @ 2009-03-28 22:33 UTC (permalink / raw) To: The development of GRUB 2 Robert Millan wrote: > Would it be hard to split the patch and make it more granular? I see it > implements base mmap / lsmmap support on efi, then ports the *BSD loaders > and the Multiboot loader too, and the uppermem facility. The only reason why it's not splitted is that it's totally "preview". When it'll be more ready I'll split it > If everybody's fine with it, I'd like to suggest adding stuff to pkglib_MODULES > in the same place as its corresponding variables. I've done this already a few > times, and I think it makes the build system a bit more maintainable. What do > you all think about this? I also agree with this but I temporarily kept this in architecture-specific file because of some minor problems with multiboot2. I'll fix this too > >> diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h >> index 08e92a9..e69ff77 100644 >> --- a/include/grub/i386/pc/memory.h >> +++ b/include/grub/i386/pc/memory.h >> @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry >> grub_uint64_t len; >> #define GRUB_MACHINE_MEMORY_AVAILABLE 1 >> #define GRUB_MACHINE_MEMORY_RESERVED 2 >> +#define GRUB_MACHINE_MEMORY_ACPI 3 >> +#define GRUB_MACHINE_MEMORY_NVS 4 >> grub_uint32_t type; >> } __attribute__((packed)); > > Do we need specific knowledge of these two on i386-pc ? > This one is because some loaders just copy e820 map types and I don't want to modify what OS gets on i386-pc >> /* The minimum and maximum heap size for GRUB itself. */ >> #define MIN_HEAP_SIZE 0x100000 >> -#define MAX_HEAP_SIZE (16 * 0x100000) >> +#define MAX_HEAP_SIZE (1600 * 0x100000) > > Is 1600 MB what we want, or to remove the limit? > I would suggest to remove the limit altogether >> + /* Bubble-sort the memory map */ >> + while (done) >> + { >> + done = 0; >> + for (i = 0; i < count - 1; i++) >> + if (regions[i].start > regions[i + 1].start) >> + { >> + done = 1; >> + t = regions[i]; >> + regions[i] = regions[i + 1]; >> + regions[i + 1] = t; >> + } >> + } > > Do we need the memory map to be sorted? AFAIK loadees can cope with unsorted > maps fine; is there an exception? > I prefer to sort. Even as just a precaution. Actually even sorted EFI map may break a lot of OS because it usually has more entries (the runtime code isn't guaranteed to be contiguous and if it isn't it results in mmap having a lot of entries) and sometimes the first N kilobytes are defined as unusable (it's the case with qemu-tianocore) which under current definition means that low_memory=0 >> +#ifdef GRUB_MACHINE_PCBIOS >> + grub_stop_floppy (); >> +#endif > > grub_stop_floppy() doesn't do any BIOS-specific stuff. Wouldn't __i386__ > be more appropiate? > I've already moved it to machine_fini just because my computer died I couldn't send the new patch -- Regards Vladimir 'phcoder' Serbinenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-03-28 22:33 ` phcoder @ 2009-04-04 16:28 ` phcoder 2009-04-04 16:51 ` phcoder 0 siblings, 1 reply; 15+ messages in thread From: phcoder @ 2009-04-04 16:28 UTC (permalink / raw) To: The development of GRUB 2 [-- Attachment #1: Type: text/plain, Size: 3144 bytes --] For those interested in testing: here is a rediff and some updates. Soon I'll split it into components phcoder wrote: > Robert Millan wrote: >> Would it be hard to split the patch and make it more granular? I see it >> implements base mmap / lsmmap support on efi, then ports the *BSD loaders >> and the Multiboot loader too, and the uppermem facility. > The only reason why it's not splitted is that it's totally "preview". > When it'll be more ready I'll split it >> If everybody's fine with it, I'd like to suggest adding stuff to >> pkglib_MODULES >> in the same place as its corresponding variables. I've done this >> already a few >> times, and I think it makes the build system a bit more maintainable. >> What do >> you all think about this? > > I also agree with this but I temporarily kept this in > architecture-specific file because of some minor problems with > multiboot2. I'll fix this too > >> >>> diff --git a/include/grub/i386/pc/memory.h >>> b/include/grub/i386/pc/memory.h >>> index 08e92a9..e69ff77 100644 >>> --- a/include/grub/i386/pc/memory.h >>> +++ b/include/grub/i386/pc/memory.h >>> @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry >>> grub_uint64_t len; >>> #define GRUB_MACHINE_MEMORY_AVAILABLE 1 >>> #define GRUB_MACHINE_MEMORY_RESERVED 2 >>> +#define GRUB_MACHINE_MEMORY_ACPI 3 >>> +#define GRUB_MACHINE_MEMORY_NVS 4 >>> grub_uint32_t type; >>> } __attribute__((packed)); >> >> Do we need specific knowledge of these two on i386-pc ? >> > This one is because some loaders just copy e820 map types and I don't > want to modify what OS gets on i386-pc >>> /* The minimum and maximum heap size for GRUB itself. */ >>> #define MIN_HEAP_SIZE 0x100000 >>> -#define MAX_HEAP_SIZE (16 * 0x100000) >>> +#define MAX_HEAP_SIZE (1600 * 0x100000) >> >> Is 1600 MB what we want, or to remove the limit? >> > I would suggest to remove the limit altogether >>> + /* Bubble-sort the memory map */ >>> + while (done) >>> + { >>> + done = 0; >>> + for (i = 0; i < count - 1; i++) >>> + if (regions[i].start > regions[i + 1].start) >>> + { >>> + done = 1; >>> + t = regions[i]; >>> + regions[i] = regions[i + 1]; >>> + regions[i + 1] = t; >>> + } >>> + } >> >> Do we need the memory map to be sorted? AFAIK loadees can cope with >> unsorted >> maps fine; is there an exception? >> > I prefer to sort. Even as just a precaution. Actually even sorted EFI > map may break a lot of OS because it usually has more entries (the > runtime code isn't guaranteed to be contiguous and if it isn't it > results in mmap having a lot of entries) and sometimes the first N > kilobytes are defined as unusable (it's the case with qemu-tianocore) > which under current definition means that low_memory=0 >>> +#ifdef GRUB_MACHINE_PCBIOS >>> + grub_stop_floppy (); >>> +#endif >> >> grub_stop_floppy() doesn't do any BIOS-specific stuff. Wouldn't __i386__ >> be more appropiate? >> > I've already moved it to machine_fini just because my computer died I > couldn't send the new patch > -- Regards Vladimir 'phcoder' Serbinenko [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: efiboot.all.diff --] [-- Type: text/x-diff; name="efiboot.all.diff", Size: 0 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: multiboot on EFI 2009-04-04 16:28 ` phcoder @ 2009-04-04 16:51 ` phcoder 0 siblings, 0 replies; 15+ messages in thread From: phcoder @ 2009-04-04 16:51 UTC (permalink / raw) To: The development of GRUB 2 [-- Attachment #1: Type: text/plain, Size: 3279 bytes --] File was empty. Sorry phcoder wrote: > For those interested in testing: here is a rediff and some updates. Soon > I'll split it into components > phcoder wrote: >> Robert Millan wrote: >>> Would it be hard to split the patch and make it more granular? I see it >>> implements base mmap / lsmmap support on efi, then ports the *BSD >>> loaders >>> and the Multiboot loader too, and the uppermem facility. >> The only reason why it's not splitted is that it's totally "preview". >> When it'll be more ready I'll split it >>> If everybody's fine with it, I'd like to suggest adding stuff to >>> pkglib_MODULES >>> in the same place as its corresponding variables. I've done this >>> already a few >>> times, and I think it makes the build system a bit more >>> maintainable. What do >>> you all think about this? >> >> I also agree with this but I temporarily kept this in >> architecture-specific file because of some minor problems with >> multiboot2. I'll fix this too >> >>> >>>> diff --git a/include/grub/i386/pc/memory.h >>>> b/include/grub/i386/pc/memory.h >>>> index 08e92a9..e69ff77 100644 >>>> --- a/include/grub/i386/pc/memory.h >>>> +++ b/include/grub/i386/pc/memory.h >>>> @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry >>>> grub_uint64_t len; >>>> #define GRUB_MACHINE_MEMORY_AVAILABLE 1 >>>> #define GRUB_MACHINE_MEMORY_RESERVED 2 >>>> +#define GRUB_MACHINE_MEMORY_ACPI 3 >>>> +#define GRUB_MACHINE_MEMORY_NVS 4 >>>> grub_uint32_t type; >>>> } __attribute__((packed)); >>> >>> Do we need specific knowledge of these two on i386-pc ? >>> >> This one is because some loaders just copy e820 map types and I don't >> want to modify what OS gets on i386-pc >>>> /* The minimum and maximum heap size for GRUB itself. */ >>>> #define MIN_HEAP_SIZE 0x100000 >>>> -#define MAX_HEAP_SIZE (16 * 0x100000) >>>> +#define MAX_HEAP_SIZE (1600 * 0x100000) >>> >>> Is 1600 MB what we want, or to remove the limit? >>> >> I would suggest to remove the limit altogether >>>> + /* Bubble-sort the memory map */ >>>> + while (done) >>>> + { >>>> + done = 0; >>>> + for (i = 0; i < count - 1; i++) >>>> + if (regions[i].start > regions[i + 1].start) >>>> + { >>>> + done = 1; >>>> + t = regions[i]; >>>> + regions[i] = regions[i + 1]; >>>> + regions[i + 1] = t; >>>> + } >>>> + } >>> >>> Do we need the memory map to be sorted? AFAIK loadees can cope with >>> unsorted >>> maps fine; is there an exception? >>> >> I prefer to sort. Even as just a precaution. Actually even sorted EFI >> map may break a lot of OS because it usually has more entries (the >> runtime code isn't guaranteed to be contiguous and if it isn't it >> results in mmap having a lot of entries) and sometimes the first N >> kilobytes are defined as unusable (it's the case with qemu-tianocore) >> which under current definition means that low_memory=0 >>>> +#ifdef GRUB_MACHINE_PCBIOS >>>> + grub_stop_floppy (); >>>> +#endif >>> >>> grub_stop_floppy() doesn't do any BIOS-specific stuff. Wouldn't >>> __i386__ >>> be more appropiate? >>> >> I've already moved it to machine_fini just because my computer died I >> couldn't send the new patch >> > > -- Regards Vladimir 'phcoder' Serbinenko [-- Attachment #2: efiboot.all.diff --] [-- Type: text/x-diff, Size: 67518 bytes --] diff --git a/conf/common.rmk b/conf/common.rmk index 43bc683..b812d8b 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -503,3 +503,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 53595de..ab4dc4f 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -99,8 +99,7 @@ grub_install_SOURCES = util/i386/pc/grub-install.in pkglib_MODULES = linux.mod normal.mod multiboot.mod \ aout.mod play.mod serial.mod ata.mod \ memdisk.mod pci.mod lspci.mod reboot.mod \ - halt.mod datetime.mod date.mod datehook.mod \ - lsmmap.mod + halt.mod datetime.mod date.mod datehook.mod # For linux.mod. linux_mod_SOURCES = loader/i386/linux.c @@ -198,10 +197,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 18a99df..6de450e 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -79,7 +79,18 @@ grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. pkglib_MODULES = kernel.mod normal.mod chain.mod appleldr.mod \ linux.mod halt.mod reboot.mod pci.mod lspci.mod \ - datetime.mod date.mod datehook.mod + datetime.mod date.mod datehook.mod multiboot.mod + +# 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 @@ -89,14 +100,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ term/efi/console.c disk/efi/efidisk.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h list.h handler.h command.h + efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h command.h kernel_mod_CFLAGS = $(COMMON_CFLAGS) kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index a84b5aa..a06f97d 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -102,7 +102,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod \ multiboot.mod aout.mod serial.mod linux.mod \ nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ - date.mod datehook.mod lsmmap.mod + date.mod datehook.mod # # Only arch dependant part of normal.mod will be here. Common part for @@ -127,6 +127,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For multiboot.mod. multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ + loader/i386/multiboot.c \ loader/i386/multiboot_helper.S \ loader/multiboot2.c \ loader/multiboot_loader.c @@ -199,10 +200,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 7fa1975..405048f 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -287,16 +287,6 @@ lspci_mod_SOURCES = commands/lspci.c lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For aout.mod -aout_mod_SOURCES = loader/aout.c -aout_mod_CFLAGS = $(COMMON_CFLAGS) -aout_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For bsd.mod -bsd_mod_SOURCES = loader/i386/bsd.c -bsd_mod_CFLAGS = $(COMMON_CFLAGS) -bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For usb.mod usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c usb_mod_CFLAGS = $(COMMON_CFLAGS) @@ -352,11 +342,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..ddf7118 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -14,3 +14,21 @@ pkglib_MODULES += vga_text.mod vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += uppermem.mod +uppermem_mod_SOURCES = lib/i386/uppermem.c +uppermem_mod_CFLAGS = $(COMMON_CFLAGS) +uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS) + +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 +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 9ba2981..bcb2e76 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -110,8 +110,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 @@ -166,10 +165,5 @@ memdisk_mod_SOURCES = disk/memdisk.c memdisk_mod_CFLAGS = $(COMMON_CFLAGS) memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 8c277c0..137a437 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -54,6 +54,8 @@ char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); grub_efi_device_path_t * EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); +int EXPORT_FUNC(grub_efi_finish_boot_services) (void); + void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h new file mode 100644 index 0000000..9000642 --- /dev/null +++ b/include/grub/efi/memory.h @@ -0,0 +1,15 @@ +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#include <grub/err.h> +#include <grub/types.h> + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_RESERVED 2 +#define GRUB_MACHINE_MEMORY_ACPI 3 +#define GRUB_MACHINE_MEMORY_NVS 4 +#define GRUB_MACHINE_MEMORY_CODE 5 + +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) +(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +#endif /* ! GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index f50f18e..723dff5 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -148,6 +148,8 @@ struct grub_openbsd_bios_mmap { grub_uint64_t addr; grub_uint64_t len; +#define OPENBSD_MMAP_AVAILABLE 1 +#define OPENBSD_MMAP_RESERVED 2 grub_uint32_t type; }; @@ -222,4 +224,7 @@ struct grub_netbsd_btinfo_bootdisk int partition; }; +void grub_unix_real_boot (grub_addr_t entry, ...) + __attribute__ ((cdecl,noreturn)); + #endif /* ! GRUB_BSD_CPU_HEADER */ diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h new file mode 100644 index 0000000..c9a61bb --- /dev/null +++ b/include/grub/i386/efi/memory.h @@ -0,0 +1 @@ +#include <grub/efi/memory.h> diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h index afd3eb9..685c2e0 100644 --- a/include/grub/i386/loader.h +++ b/include/grub/i386/loader.h @@ -27,12 +27,14 @@ 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); -void EXPORT_FUNC(grub_unix_real_boot) (grub_addr_t entry, ...) - __attribute__ ((cdecl,noreturn)); +/* It is necessary to export these functions, because normal mode commands + reuse rescue mode commands. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +void EXPORT_FUNC(grub_stop_floppy) (void); #endif /* ! GRUB_LOADER_CPU_HEADER */ 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/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 08e92a9..e69ff77 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -92,6 +92,8 @@ struct grub_machine_mmap_entry grub_uint64_t len; #define GRUB_MACHINE_MEMORY_AVAILABLE 1 #define GRUB_MACHINE_MEMORY_RESERVED 2 +#define GRUB_MACHINE_MEMORY_ACPI 3 +#define GRUB_MACHINE_MEMORY_NVS 4 grub_uint32_t type; } __attribute__((packed)); diff --git a/include/grub/i386/uppermem.h b/include/grub/i386/uppermem.h new file mode 100644 index 0000000..bceed3e --- /dev/null +++ b/include/grub/i386/uppermem.h @@ -0,0 +1,7 @@ +#ifndef GRUB_UPPERMEM_HEADER +#define GRUB_UPPERMEM_HEADER + +grub_err_t +grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper); + +#endif diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 628d888..448fed5 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -169,7 +169,6 @@ grub_err_t 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 1ae5fdd..544b2f5 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -41,4 +41,8 @@ void EXPORT_FUNC(grub_loader_unset) (void); depending on the setting by grub_loader_set. */ grub_err_t EXPORT_FUNC(grub_loader_boot) (void); +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/include/grub/types.h b/include/grub/types.h index 8d51b66..faf2257 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -100,6 +100,16 @@ typedef grub_int32_t grub_ssize_t; # define LONG_MAX 2147483647UL #endif +#if GRUB_CPU_SIZEOF_VOID_P == 4 +#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x)) +#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x)) +#define PTR_TO_UINT32(x) ((grub_uint32_t)(x)) +#else +#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x)) +#define PTR_TO_UINT64(x) ((grub_uint64_t)(x)) +#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x)) +#endif + /* The type for representing a file offset. */ typedef grub_uint64_t grub_off_t; diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h new file mode 100644 index 0000000..c9a61bb --- /dev/null +++ b/include/grub/x86_64/efi/memory.h @@ -0,0 +1 @@ +#include <grub/efi/memory.h> diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 9c9a400..754f82c 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -187,6 +187,28 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key) return status == GRUB_EFI_SUCCESS; } +int +grub_efi_finish_boot_services (void) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_uintn_t map_key; + grub_efi_uintn_t desc_size; + grub_efi_uint32_t desc_version; + void *mmap_buf; + + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) < 0) + return 0; + + mmap_buf = grub_malloc (mmap_size); + + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) <= 0) + return 0; + + return grub_efi_exit_boot_services (map_key); +} + grub_uint32_t grub_get_rtc (void) { diff --git a/kern/efi/mm.c b/kern/efi/mm.c index 35b12ab..4635776 100644 --- a/kern/efi/mm.c +++ b/kern/efi/mm.c @@ -47,7 +47,7 @@ static struct allocated_page *allocated_pages = 0; /* The minimum and maximum heap size for GRUB itself. */ #define MIN_HEAP_SIZE 0x100000 -#define MAX_HEAP_SIZE (16 * 0x100000) +#define MAX_HEAP_SIZE (1600 * 0x100000) /* Allocate pages. Return the pointer to the first of allocated pages. */ diff --git a/kern/efi/mmap.c b/kern/efi/mmap.c new file mode 100644 index 0000000..3f795cb --- /dev/null +++ b/kern/efi/mmap.c @@ -0,0 +1,177 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/machine/memory.h> +#include <grub/err.h> +#include <grub/efi/api.h> +#include <grub/efi/efi.h> +#include <grub/mm.h> +#include <grub/misc.h> +#include <grub/loader.h> + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +struct region +{ + grub_uint64_t start; + grub_uint64_t len; + grub_uint32_t type; +}; + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_memory_descriptor_t *map_buf; + grub_efi_uintn_t map_key = 0; + grub_efi_uintn_t desc_size = 0; + grub_efi_uint32_t desc_version = 0; + grub_uint64_t curstart, curend; + grub_uint32_t curtype; + grub_efi_memory_descriptor_t *desc; + struct region *regions; + struct region t; + int i, count, done = 1; + + if (grub_efi_get_memory_map (&mmap_size, map_buf, + &map_key, &desc_size, + &desc_version) < 0) + return grub_errno; + + map_buf = grub_malloc (mmap_size); + if (!map_buf) + return grub_errno; + + if (grub_efi_get_memory_map (&mmap_size, map_buf, + &map_key, &desc_size, + &desc_version) <= 0) + { + grub_free (map_buf); + return grub_errno; + } + + count = mmap_size / desc_size; + if (! count) + { + grub_free (map_buf); + return grub_error (GRUB_ERR_IO, "couldn't get EFI memory map"); + } + regions = (struct region *) grub_malloc (count * sizeof (struct region)); + + for (desc = map_buf, i = 0; + desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++) + { + grub_dprintf ("efi_mmap", "EFI memory region 0x%llx-0x%llx: %d\n", + desc->physical_start, desc->physical_start + + desc->num_pages * 4096, desc->type); + switch (desc->type) + { + case GRUB_EFI_RUNTIME_SERVICES_CODE: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_CODE; + break; + + case GRUB_EFI_RESERVED_MEMORY_TYPE: + case GRUB_EFI_RUNTIME_SERVICES_DATA: + case GRUB_EFI_UNUSABLE_MEMORY: + case GRUB_EFI_MEMORY_MAPPED_IO: + case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: + case GRUB_EFI_PAL_CODE: + case GRUB_EFI_MAX_MEMORY_TYPE: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_RESERVED; + break; + + case GRUB_EFI_LOADER_CODE: + case GRUB_EFI_LOADER_DATA: + case GRUB_EFI_BOOT_SERVICES_CODE: + case GRUB_EFI_BOOT_SERVICES_DATA: + case GRUB_EFI_CONVENTIONAL_MEMORY: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_AVAILABLE; + break; + + case GRUB_EFI_ACPI_RECLAIM_MEMORY: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_ACPI; + break; + + case GRUB_EFI_ACPI_MEMORY_NVS: + regions[i].start = desc->physical_start; + regions[i].len = desc->num_pages * 4096; + regions[i].type = GRUB_MACHINE_MEMORY_NVS; + break; + } + } + + /* Bubble-sort the memory map */ + while (done) + { + done = 0; + for (i = 0; i < count - 1; i++) + if (regions[i].start > regions[i + 1].start) + { + done = 1; + t = regions[i]; + regions[i] = regions[i + 1]; + regions[i + 1] = t; + } + } + + curstart = regions[0].start; + curend = regions[0].start + regions[0].len; + curtype = regions[0].type; + for (i = 1; i < count; i++) + { + if (curend != regions[i].start || curtype != regions[i].type) + { + hook (curstart, curend - curstart, curtype); + curstart = regions[i].start; + curtype = regions[i].type; + } + curend = regions[i].start + regions[i].len; + } + + hook (curstart, curend - curstart, curtype); + + return GRUB_ERR_NONE; +} + +/* 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 1348488..9c1aee0 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -155,3 +155,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/loader.S b/kern/i386/loader.S index bbd2187..d9b37bf 100644 --- a/kern/i386/loader.S +++ b/kern/i386/loader.S @@ -117,26 +117,3 @@ bzimage: linux_setup_seg: .word 0 .code32 - -/* - * Use cdecl calling convention for *BSD kernels. - */ - -FUNCTION(grub_unix_real_boot) - - call EXT_C(grub_dl_unload_all) - - /* Interrupts should be disabled. */ - cli - - /* Discard `grub_unix_real_boot' return address. */ - popl %eax - - /* Fetch `entry' address ... */ - popl %eax - - /* - * ... and put our return address in its place. The kernel will - * ignore it, but it expects %esp to point to it. - */ - call *%eax diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index 6191412..17d5343 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; grub_size_t grub_lower_mem, grub_upper_mem; void @@ -233,3 +233,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 e88f3b3..27f8293 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -194,6 +194,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/lib/i386/uppermem.c b/lib/i386/uppermem.c new file mode 100644 index 0000000..623535f --- /dev/null +++ b/lib/i386/uppermem.c @@ -0,0 +1,127 @@ +/* Compute amount of lower and upper memory till the first hole */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EFIEMU +#include <grub/machine/memory.h> +#include <grub/i386/uppermem.h> +#endif + +#include <grub/mm.h> +#include <grub/misc.h> + +struct region +{ + grub_uint64_t start; + grub_uint64_t end; +}; + +#ifdef EFIEMU +grub_err_t +grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper) +#else +grub_err_t +grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper) +#endif +{ + grub_size_t count = 0; + struct region *regions = 0; + int done = 1; + unsigned i; + struct region t; + grub_uint64_t last_addr; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_uint32_t type) + { +#ifdef EFIEMU + if (type != GRUB_EFIEMU_MEMORY_AVAILABLE) +#else + if (type != GRUB_MACHINE_MEMORY_AVAILABLE) +#endif + return 0; + regions = (struct region *) + grub_realloc (regions, (count + 1) * sizeof (struct region)); + regions[count].start = addr; + regions[count].end = addr + size; + count++; + return 0; + } + +#ifdef EFIEMU + grub_efiemu_mmap_iterate (hook); +#else + grub_machine_mmap_iterate (hook); +#endif + + /* Bubble-sort the memory map */ + while (done) + { + done = 0; + for (i = 0; i < count - 1; i++) + if (regions[i].start > regions[i + 1].start) + { + done = 1; + t = regions[i]; + regions[i] = regions[i + 1]; + regions[i + 1] = t; + } + } + + /* Set mem_upper and mem_lower */ + last_addr = 0; + for (i = 0; i < count; i++) + { + grub_uint64_t end = regions[i].end; + /* Don't use memory after 0xa0000*/ + if (end > 0xa0000) + end = 0xa0000; + + /* low memory is finished */ + if (regions[i].start > end) + break; + + /* A hole */ + if (regions[i].start > last_addr) + break; + + last_addr = end; + } + + *lower = last_addr; + + /* Skip low memory */ + for (i = 0; i < count && regions[i].end <= 0x100000; + i++); + + last_addr = 0x100000; + for (; i < count; i++) + { + /* A hole */ + if (regions[i].start > last_addr) + break; + + last_addr = regions[i].end; + } + + *upper = (last_addr - 0x100000); + grub_free (regions); + + return GRUB_ERR_NONE; +} 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 <http://www.gnu.org/licenses/>. + */ + +#include <multiboot2.h> +#include <grub/multiboot2.h> +#include <grub/elf.h> +#include <grub/err.h> +#include <grub/machine/loader.h> +#include <grub/mm.h> + +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 355cb3f..4023566 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -19,8 +19,8 @@ #include <grub/loader.h> #include <grub/cpu/loader.h> #include <grub/cpu/bsd.h> -#include <grub/machine/init.h> #include <grub/machine/memory.h> +#include <grub/machine/machine.h> #include <grub/file.h> #include <grub/err.h> #include <grub/dl.h> @@ -30,8 +30,13 @@ #include <grub/misc.h> #include <grub/gzio.h> #include <grub/aout.h> +#include <grub/i386/uppermem.h> #include <grub/command.h> +#ifdef GRUB_MACHINE_EFI +#include <grub/efi/efi.h> +#endif + #define ALIGN_DWORD(a) ALIGN_UP (a, 4) #define ALIGN_PAGE(a) ALIGN_UP (a, 4096) @@ -302,6 +307,15 @@ grub_freebsd_boot (void) bi.bi_kernend = kern_end; +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev, 0, 0, 0, &bi, bi.bi_modulep, kern_end); @@ -313,30 +327,39 @@ static grub_err_t grub_openbsd_boot (void) { char *buf = (char *) GRUB_BSD_TEMP_BUFFER; - struct grub_machine_mmap_entry mmap; struct grub_openbsd_bios_mmap *pm; struct grub_openbsd_bootargs *pa; - grub_uint32_t bootdev, biosdev, unit, slice, part, cont; + grub_uint32_t bootdev, biosdev, unit, slice, part; + grub_uint64_t lower, upper; + grub_err_t err; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + pm->addr = addr; + pm->len = size; + + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + pm->type = OPENBSD_MMAP_AVAILABLE; + break; + + default: + pm->type = OPENBSD_MMAP_RESERVED; + break; + } + pm++; + + return 0; + } pa = (struct grub_openbsd_bootargs *) buf; pa->ba_type = OPENBSD_BOOTARG_MMAP; pm = (struct grub_openbsd_bios_mmap *) (pa + 1); - cont = grub_get_mmap_entry (&mmap, 0); - if (mmap.size) - do - { - pm->addr = mmap.addr; - pm->len = mmap.len; - pm->type = mmap.type; - pm++; - if (!cont) - break; - - cont = grub_get_mmap_entry (&mmap, cont); - } - while (mmap.size); + grub_machine_mmap_iterate (hook); pa->ba_size = (char *) pm - (char *) pa; pa->ba_next = (struct grub_openbsd_bootargs *) pm; @@ -348,8 +371,20 @@ grub_openbsd_boot (void) bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) + (part << OPENBSD_B_PARTSHIFT)); + if ((err = grub_get_lower_upper_memory (&lower, &upper))) + return err; + +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER, - 0, grub_upper_mem >> 10, grub_lower_mem >> 10, + 0, upper >> 10, lower >> 10, (char *) pa - buf, buf); /* Not reached. */ @@ -362,6 +397,8 @@ grub_netbsd_boot (void) struct grub_netbsd_btinfo_rootdevice *rootdev; struct grub_netbsd_bootinfo *bootinfo; grub_uint32_t biosdev, unit, slice, part; + grub_uint64_t lower, upper; + grub_err_t err; grub_bsd_get_device (&biosdev, &unit, &slice, &part); @@ -376,8 +413,20 @@ grub_netbsd_boot (void) bootinfo->bi_count = 1; bootinfo->bi_data[0] = rootdev; + if ((err = grub_get_lower_upper_memory (&lower, &upper))) + return err; + +#ifdef GRUB_MACHINE_PCBIOS + grub_stop_floppy (); +#endif + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_unix_real_boot (entry, bootflags, 0, bootinfo, - 0, grub_upper_mem >> 10, grub_lower_mem >> 10); + 0, upper >> 10, lower >> 10); /* Not reached. */ return GRUB_ERR_NONE; @@ -461,8 +510,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); @@ -578,7 +626,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; @@ -593,7 +641,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; } @@ -607,7 +655,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; } @@ -725,7 +773,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_helper.S b/loader/i386/bsd_helper.S new file mode 100644 index 0000000..9cdea0c --- /dev/null +++ b/loader/i386/bsd_helper.S @@ -0,0 +1,65 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +#include <grub/symbol.h> + +/* + * Use cdecl calling convention for *BSD kernels. + */ + +FUNCTION(grub_unix_real_boot) + + /* Interrupts should be disabled. */ + cli + + /* Discard `grub_unix_real_boot' return address. */ + popl %eax + + /* Fetch `entry' address ... */ + popl %eax + + /* + * ... and put our return address in its place. The kernel will + * ignore it, but it expects %esp to point to it. + */ + call *%eax diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index d8c6a67..7cc13d3 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -18,6 +18,7 @@ #include <grub/loader.h> #include <grub/machine/loader.h> +#include <grub/machine/memory.h> #include <grub/file.h> #include <grub/disk.h> #include <grub/err.h> @@ -45,9 +46,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))) = @@ -94,26 +96,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) @@ -121,14 +123,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 @@ -136,19 +138,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; } } @@ -160,9 +162,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; @@ -172,11 +173,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; @@ -191,44 +187,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_machine_mmap_iterate (hook); if (! real_mode_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); @@ -237,20 +229,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; @@ -350,7 +342,6 @@ grub_linux_boot (void) grub_efi_uintn_t map_key; grub_efi_uintn_t desc_size; grub_efi_uint32_t desc_version; - grub_efi_memory_descriptor_t *desc; int e820_num; fake_bios_data (); @@ -370,77 +361,46 @@ grub_linux_boot (void) &desc_size, &desc_version) <= 0) grub_fatal ("cannot get memory map"); - e820_num = 0; - for (desc = mmap_buf; - desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + 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) { - switch (desc->type) + switch (type) { - case GRUB_EFI_ACPI_RECLAIM_MEMORY: - grub_e820_add_region (params->e820_map, &e820_num, - desc->physical_start, - desc->num_pages << 12, - GRUB_E820_ACPI); - break; + case GRUB_MACHINE_MEMORY_AVAILABLE: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_RAM); + break; - case GRUB_EFI_ACPI_MEMORY_NVS: - grub_e820_add_region (params->e820_map, &e820_num, - desc->physical_start, - desc->num_pages << 12, - GRUB_E820_NVS); - break; +#ifdef GRUB_MACHINE_MEMORY_ACPI + case GRUB_MACHINE_MEMORY_ACPI: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_ACPI); + break; +#endif - case GRUB_EFI_RUNTIME_SERVICES_CODE: - grub_e820_add_region (params->e820_map, &e820_num, - desc->physical_start, - desc->num_pages << 12, - GRUB_E820_EXEC_CODE); - break; - - case GRUB_EFI_LOADER_CODE: - case GRUB_EFI_LOADER_DATA: - case GRUB_EFI_BOOT_SERVICES_CODE: - case GRUB_EFI_BOOT_SERVICES_DATA: - case GRUB_EFI_CONVENTIONAL_MEMORY: - { - grub_uint64_t start, size, end; - - start = desc->physical_start; - size = desc->num_pages << 12; - end = start + size; - - /* Skip A0000 - 100000 region. */ - if ((start < 0x100000ULL) && (end > 0xA0000ULL)) - { - if (start < 0xA0000ULL) - { - grub_e820_add_region (params->e820_map, &e820_num, - start, - 0xA0000ULL - start, - GRUB_E820_RAM); - } - - if (end <= 0x100000ULL) - continue; - - start = 0x100000ULL; - size = end - start; - } - - grub_e820_add_region (params->e820_map, &e820_num, - start, size, GRUB_E820_RAM); - break; - } +#ifdef GRUB_MACHINE_MEMORY_NVS + case GRUB_MACHINE_MEMORY_NVS: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_NVS); + break; +#endif + +#ifdef GRUB_MACHINE_MEMORY_CODE + case GRUB_MACHINE_MEMORY_CODE: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_EXEC_CODE); + break; +#endif default: grub_e820_add_region (params->e820_map, &e820_num, - desc->physical_start, - desc->num_pages << 12, - GRUB_E820_RESERVED); + addr, size, GRUB_E820_RESERVED); } + return 0; } + e820_num = 0; + grub_machine_mmap_iterate (hook); params->mmap_size = e820_num; if (! grub_efi_exit_boot_services (map_key)) @@ -617,7 +577,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; @@ -908,9 +867,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) @@ -930,11 +886,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; @@ -945,49 +914,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) + 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 a2fff83..daff376 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -45,9 +45,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))) = { @@ -182,7 +183,24 @@ find_mmap_size (void) 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 @@ -190,8 +208,6 @@ free_pages (void) static int allocate_pages (grub_size_t prot_size) { - 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); @@ -200,11 +216,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; @@ -233,6 +244,8 @@ allocate_pages (grub_size_t prot_size) return 0; real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size)); + if (grub_claimmap (real_mode_mem, real_size + mmap_size) < 0) + return 0; return 1; } @@ -246,6 +259,14 @@ 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) < 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", @@ -395,6 +416,27 @@ grub_linux_boot (void) addr, size, GRUB_E820_RAM); break; +#ifdef GRUB_MACHINE_MEMORY_ACPI + case GRUB_MACHINE_MEMORY_ACPI: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_ACPI); + break; +#endif + +#ifdef GRUB_MACHINE_MEMORY_NVS + case GRUB_MACHINE_MEMORY_NVS: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_NVS); + break; +#endif + +#ifdef GRUB_MACHINE_MEMORY_CODE + case GRUB_MACHINE_MEMORY_CODE: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_EXEC_CODE); + break; +#endif + default: grub_e820_add_region (params->e820_map, &e820_num, addr, size, GRUB_E820_RESERVED); @@ -457,7 +499,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; @@ -690,7 +731,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; @@ -721,11 +762,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12) + 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 27042a5..055b1cf 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -30,7 +30,7 @@ #include <grub/loader.h> #include <grub/machine/loader.h> #include <grub/multiboot.h> -#include <grub/machine/init.h> +#include <grub/machine/machine.h> #include <grub/machine/memory.h> #include <grub/cpu/multiboot.h> #include <grub/elf.h> @@ -43,6 +43,13 @@ #include <grub/misc.h> #include <grub/gzio.h> #include <grub/env.h> +#include <grub/cpu/loader.h> +#include <grub/cpu/multiboot.h> +#include <grub/i386/uppermem.h> + +#ifdef GRUB_MACHINE_EFI +#include <grub/efi/efi.h> +#endif extern grub_dl_t my_mod; static struct grub_multiboot_info *mbi, *mbi_dest; @@ -54,6 +61,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. */ @@ -109,14 +123,24 @@ grub_get_multiboot_mmap_len (void) static void grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry) { - struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry; + struct grub_multiboot_mmap_entry *mmap_entry + = (struct grub_multiboot_mmap_entry *) first_entry; auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) { mmap_entry->addr = addr; mmap_entry->len = size; - mmap_entry->type = type; + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + mmap_entry->type = GRUB_MULTIBOOT_MEMORY_AVAILABLE; + break; + + default: + mmap_entry->type = GRUB_MULTIBOOT_MEMORY_RESERVED; + break; + } mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size); mmap_entry++; @@ -199,6 +223,7 @@ grub_multiboot (int argc, char *argv[]) struct grub_multiboot_header *header; grub_ssize_t len, cmdline_length, boot_loader_name_length; grub_uint32_t mmap_length; + grub_uint64_t lower, upper; int i; grub_loader_unset (); @@ -286,7 +311,9 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_dest = header->load_addr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); + playground = grub_malloc (RELOCATOR_SIZEOF(forward) + + grub_multiboot_payload_size + + RELOCATOR_SIZEOF(backward)); if (! playground) goto fail; @@ -341,9 +368,12 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_size, grub_multiboot_payload_entry_offset); + if (grub_get_lower_upper_memory (&lower, &upper)) + goto fail; + /* Convert from bytes to kilobytes. */ - mbi->mem_lower = grub_lower_mem / 1024; - mbi->mem_upper = grub_upper_mem / 1024; + mbi->mem_lower = lower / 1024; + mbi->mem_upper = upper / 1024; mbi->flags |= MULTIBOOT_INFO_MEMORY; cmdline = p = cmdline_addr (grub_multiboot_payload_orig); @@ -370,7 +400,7 @@ grub_multiboot (int argc, char *argv[]) if (grub_multiboot_get_bootdev (&mbi->boot_device)) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; - grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); fail: if (file) diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c index 8ff97f4..4823ddc 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; } @@ -340,9 +339,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]); @@ -353,6 +349,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/mm.h> 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 2fb56bf..a6cee06 100644 --- a/loader/multiboot2.c +++ b/loader/multiboot2.c @@ -38,6 +38,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) { @@ -279,13 +315,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 f4a3933..6c30d5a 100644 --- a/loader/multiboot_loader.c +++ b/loader/multiboot_loader.c @@ -137,9 +137,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), /* Launch multi boot with header */ - /* 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", @@ -152,7 +150,9 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), { grub_dprintf ("multiboot_loader", "Launching multiboot 2 grub_multiboot2() function\n"); +#ifndef GRUB_MACHINE_EFI grub_multiboot2 (argc, argv); +#endif module_version_status = 2; } @@ -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; ^ permalink raw reply related [flat|nested] 15+ messages in thread
end of thread, other threads:[~2009-04-04 16:51 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-03-23 12:29 multiboot on EFI phcoder 2009-03-23 21:16 ` uzer cheg 2009-03-23 22:14 ` phcoder 2009-03-23 22:33 ` phcoder 2009-03-24 10:31 ` uzer cheg 2009-03-24 10:54 ` phcoder 2009-03-24 10:58 ` uzer cheg 2009-03-26 19:25 ` Vladimir Serbinenko 2009-03-28 13:13 ` Robert Millan 2009-03-28 14:31 ` Yoshinori K. Okuji 2009-04-01 12:57 ` Robert Millan 2009-04-01 13:58 ` Yoshinori K. Okuji 2009-03-28 22:33 ` phcoder 2009-04-04 16:28 ` phcoder 2009-04-04 16:51 ` phcoder
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.