+2006-04-23 Yoshinori K. Okuji <okuji@enbug.org>
+
+ Use grub_abort instead of grub_stop, and grub_exit must be
+ define in each architecture now. Also, this change adds support
+ for EFI disks.
+
+ * util/i386/pc/grub-probefs.c: Include grub/term.h.
+ (grub_getkey): New function.
+ (grub_term_get_current): Likewise.
+
+ * util/i386/pc/grub-setup.c: Include grub/term.h.
+ (grub_getkey): New function.
+ (grub_term_get_current): Likewise.
+
+ * util/misc.c (grub_stop): Renamed to ...
+ (grub_exit): ... this.
+
+ * kern/powerpc/ieee1275/init.c (abort): Renamed to ...
+ (grub_exit): ... this.
+ (grub_machine_init): Use grub_abort instead of abort.
+ (grub_stop): Removed.
+
+ * kern/powerpc/ieee1275/cmain.c (cmain): Use grub_abort instead of
+ abort.
+
+ * kern/i386/pc/startup.S (grub_exit): New function.
+ (cold_reboot): New label.
+
+ * kern/efi/init.c: Include grub/efi/disk.h and grub/env.h.
+ (grub_efi_init): Call grub_efidisk_init.
+ (grub_efi_fini): Call grub_efidisk_fini.
+
+ * kern/efi/efi.c: Include grub/mm.h.
+ (grub_efi_console_control_guid): Renamed to ...
+ (console_control_guid): ... this.
+ (grub_efi_loaded_image_guid): Renamed to ...
+ (loaded_image_guid): ... this.
+ (grub_efi_locate_handle): New function.
+ (grub_efi_open_protocol): Likewise.
+ (grub_efi_set_text_mode): Use CONSOLE_CONTROL_GUID instead of
+ GRUB_EFI_CONSOLE_CONTROL_GUID.
+ (grub_efi_exit): Removed.
+ (grub_stop): Likewise.
+ (grub_efi_get_loaded_image): Use grub_efi_open_protocol.
+ (grub_exit): New function.
+ (grub_print_device_path): Likewise.
+
+ * kern/rescue.c (grub_rescue_cmd_exit): New function.
+ (grub_enter_rescue_mode): Register "exit".
+
+ * kern/misc.c (grub_real_dprintf): A cosmetic change.
+ (grub_abort): New function.
+
+ * kern/err.c (grub_fatal): Use grub_abort instead of grub_stop.
+
+ * include/grub/sparc64/ieee1275/kernel.h (abort): Removed.
+
+ * include/grub/powerpc/ieee1275/kernel.h (abort): Removed.
+
+ * include/grub/efi/efi.h (grub_efi_exit): Removed.
+ (grub_print_device_path): New prototype.
+ (grub_efi_locate_handle): Likewise.
+ (grub_efi_open_protocol): Likewise.
+
+ * include/grub/efi/disk.h (grub_efidisk_fini): New file.
+ * disk/efi/efidisk.c: Likewise.
+
+ * DISTLIST: Added disk/efi/efidisk.c and include/grub/efi/disk.h.
+
+ * include/grub/efi/console_control.h
+ (GRUB_EFI_CONSOLE_CONTROL_GUID): Use an array for the last 8 bytes.
+
+ * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): Specify the
+ last 8 bytes as an array.
+ (GRUB_EFI_DISK_IO_GUID): New macro.
+ (GRUB_EFI_BLOCK_IO_GUID): Likewise.
+ (GRUB_EFI_DEVICE_PATH_GUID): Likewise.
+ (grub_efi_ipv6_address_t): Change the type to grub_uint16_t from
+ grub_uint8_t.
+ (struct grub_efi_guid): Use an array to specify the last 8 bytes.
+ (struct grub_efi_device_path): Rename the member "sub_type" to
+ "subtype".
+ (GRUB_EFI_DEVICE_PATH_TYPE): New macro.
+ (GRUB_EFI_DEVICE_PATH_SUBTYPE): Likewise.
+ (GRUB_EFI_DEVICE_PATH_LENGTH): Likewise.
+ (GRUB_EFI_END_DEVICE_PATH_TYPE): Likewise.
+ (GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE): Likewise.
+ (GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE): Likewise.
+ (GRUB_EFI_END_ENTIRE_DEVICE_PATH): Likewise.
+ (GRUB_EFI_NEXT_DEVICE_PATH): Likewise.
+ (GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE): Likewise.
+ (GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE): Likewise.
+ (struct grub_efi_pci_device_path): New structure.
+ (grub_efi_pci_device_path_t): New type.
+ (GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_pccard_device_path): New structure.
+ (grub_efi_pccard_device_path_t): New type.
+ (GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_memory_mapped_device_path): New structure.
+ (grub_efi_memory_mapped_device_path_t): New type.
+ (GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_vendor_device_path): New structure.
+ (grub_efi_vendor_device_path_t): New type.
+ (GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_controller_device_path): New structure.
+ (grub_efi_controller_device_path_t): New type.
+ (GRUB_EFI_ACPI_DEVICE_PATH_TYPE): New macro.
+ (GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE): Likewise.
+ (struct grub_efi_acpi_device_path): New structure.
+ (grub_efi_acpi_device_path_t): New type.
+ (GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_expanded_acpi_device_path): New structure.
+ (grub_efi_expanded_acpi_device_path_t): New type.
+ (GRUB_EFI_EXPANDED_ACPI_HIDSTR): New macro.
+ (GRUB_EFI_EXPANDED_ACPI_UIDSTR): Likewise.
+ (GRUB_EFI_EXPANDED_ACPI_CIDSTR): Likewise.
+ (GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE): Likewise.
+ (GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE): Likewise.
+ (struct grub_efi_atapi_device_path): New structure.
+ (grub_efi_atapi_device_path_t): New type.
+ (GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_fibre_channel_device_path): New structure.
+ (grub_efi_fibre_channel_device_path_t): New type.
+ (GRUB_EFI_1394_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_1394_device_path): New structure.
+ (grub_efi_1394_device_path_t): New type.
+ (GRUB_EFI_USB_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_usb_device_path): New structure.
+ (grub_efi_usb_device_path_t): New type.
+ (GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_usb_class_device_path): New structure.
+ (grub_efi_usb_class_device_path_t): New type.
+ (GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_i2o_device_path): New structure.
+ (grub_efi_i2o_device_path_t): New type.
+ (GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_mac_address_device_path): New structure.
+ (grub_efi_mac_address_device_path_t): New type.
+ (GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_ipv4_device_path): New structure.
+ (grub_efi_ipv4_device_path_t): New type.
+ (GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_ipv6_device_path): New structure.
+ (grub_efi_ipv6_device_path_t): New type.
+ (GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_infiniband_device_path): New structure.
+ (grub_efi_infiniband_device_path_t): New type.
+ (GRUB_EFI_UART_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_uart_device_path): New structure.
+ (grub_efi_uart_device_path_t): New type.
+ (GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_vendor_messaging_device_path): New structure.
+ (grub_efi_vendor_messaging_device_path_t): New type.
+ (GRUB_EFI_MEDIA_DEVICE_PATH_TYPE): New macro.
+ (GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE): Likewise.
+ (struct grub_efi_hard_drive_device_path): New structure.
+ (grub_efi_hard_drive_device_path_t): New type.
+ (GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_cdrom_device_path): New structure.
+ (grub_efi_cdrom_device_path_t): New type.
+ (GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_vendor_media_device_path): New structure.
+ (grub_efi_vendor_media_device_path_t): New type.
+ (GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_file_path_device_path): New structure.
+ (grub_efi_file_path_device_path_t): New type.
+ (GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE): New macro.
+ (struct grub_efi_protocol_device_path): New structure.
+ (grub_efi_protocol_device_path_t): New type.
+ (GRUB_EFI_BIOS_DEVICE_PATH_TYPE): New macro.
+ (GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE): Likewise.
+ (struct grub_efi_bios_device_path): New structure.
+ (grub_efi_bios_device_path_t): New type.
+ (struct grub_efi_disk_io): New structure.
+ (grub_efi_disk_io_t): New type.
+ (struct grub_efi_block_io_media): New structure.
+ (grub_efi_block_io_media_t): New type.
+ (struct grub_efi_block_io): New structure.
+ (grub_efi_block_io_t): New type.
+
+ * include/grub/misc.h (grub_stop): Removed.
+ (grub_exit): New prototype.
+ (grub_abort): Likewise.
+
+ * include/grub/disk.h (enum grub_disk_dev_id): Added
+ GRUB_DISK_DEVICE_EFIDISK_ID.
+
+ * conf/i386-efi.rmk (kernel_mod_SOURCES): Added
+ disk/efi/efidisk.c.
+ (kernel_syms.lst): Remove the target if an error occurs.
+
2006-04-22 Yoshinori K. Okuji <okuji@enbug.org>
* kern/misc.c (grub_lltoa): Rewritten the decimal conversion part,
conf/sparc64-ieee1275.mk
conf/sparc64-ieee1275.rmk
disk/loopback.c
+disk/efi/efidisk.c
disk/i386/pc/biosdisk.c
disk/ieee1275/ofdisk.c
font/manager.c
include/grub/efi/api.h
include/grub/efi/console.h
include/grub/efi/console_control.h
+include/grub/efi/disk.h
include/grub/efi/efi.h
include/grub/efi/pe32.h
include/grub/efi/time.h
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.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
-CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o und-kernel.lst
+ term/efi/console.c disk/efi/efidisk.c
+CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o und-kernel.lst
ifneq ($(kernel_mod_EXPORTS),no)
CLEANFILES += def-kernel.lst
DEFSYMFILES += def-kernel.lst
endif
-MOSTLYCLEANFILES += kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_i386_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-term_efi_console.d
+MOSTLYCLEANFILES += kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_i386_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-term_efi_console.d kernel_mod-disk_efi_efidisk.d
UNDSYMFILES += und-kernel.lst
kernel.mod: pre-kernel.o mod-kernel.o
$(CC) $(kernel_mod_LDFLAGS) $(LDFLAGS) -Wl,-r,-d -o $@ $^
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
-pre-kernel.o: kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o
+pre-kernel.o: kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o
-rm -f $@
$(CC) $(kernel_mod_LDFLAGS) $(LDFLAGS) -Wl,-r,-d -o $@ $^
set -e; $(CC) -Iterm/efi -I$(srcdir)/term/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+kernel_mod-disk_efi_efidisk.o: disk/efi/efidisk.c
+ $(CC) -Idisk/efi -I$(srcdir)/disk/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
+
+kernel_mod-disk_efi_efidisk.d: disk/efi/efidisk.c
+ set -e; $(CC) -Idisk/efi -I$(srcdir)/disk/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -M $< | sed 's,efidisk\.o[ :]*,kernel_mod-disk_efi_efidisk.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
+
+-include kernel_mod-disk_efi_efidisk.d
+
+CLEANFILES += cmd-kernel_mod-disk_efi_efidisk.lst fs-kernel_mod-disk_efi_efidisk.lst
+COMMANDFILES += cmd-kernel_mod-disk_efi_efidisk.lst
+FSFILES += fs-kernel_mod-disk_efi_efidisk.lst
+
+cmd-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c gencmdlist.sh
+ set -e; $(CC) -Idisk/efi -I$(srcdir)/disk/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c genfslist.sh
+ set -e; $(CC) -Idisk/efi -I$(srcdir)/disk/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+
kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.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 types.h \
sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@
kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) genkernsyms.sh
- sh $(srcdir)/genkernsyms.sh $(filter %.h,$^) > $@
+ sh $(srcdir)/genkernsyms.sh $(filter %.h,$^) > $@ || rm -f $@
# For normal.mod.
normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.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
+ term/efi/console.c disk/efi/efidisk.c
kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.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 types.h \
sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@
kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) genkernsyms.sh
- sh $(srcdir)/genkernsyms.sh $(filter %.h,$^) > $@
+ sh $(srcdir)/genkernsyms.sh $(filter %.h,$^) > $@ || rm -f $@
# For normal.mod.
normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/term.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+
+struct grub_efidisk_data
+{
+ grub_efi_handle_t handle;
+ grub_efi_device_path_t *device_path;
+ grub_efi_device_path_t *last_device_path;
+ grub_efi_block_io_t *block_io;
+ grub_efi_disk_io_t *disk_io;
+ struct grub_efidisk_data *next;
+};
+
+/* GUIDs. */
+static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID;
+static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID;
+static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+
+static struct grub_efidisk_data *fd_devices;
+static struct grub_efidisk_data *hd_devices;
+static struct grub_efidisk_data *cd_devices;
+
+/* Duplicate a device path. */
+static grub_efi_device_path_t *
+duplicate_device_path (const grub_efi_device_path_t *dp)
+{
+ grub_efi_device_path_t *p;
+ grub_size_t total_size = 0;
+
+ for (p = (grub_efi_device_path_t *) dp;
+ ;
+ p = GRUB_EFI_NEXT_DEVICE_PATH (p))
+ {
+ total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
+ break;
+ }
+
+ p = grub_malloc (total_size);
+ if (! p)
+ return 0;
+
+ grub_memcpy (p, dp, total_size);
+ return p;
+}
+
+/* Return the device path node right before the end node. */
+static grub_efi_device_path_t *
+find_last_device_path (const grub_efi_device_path_t *dp)
+{
+ grub_efi_device_path_t *next, *p;
+
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+ return 0;
+
+ for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
+ ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
+ p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
+ ;
+
+ return p;
+}
+
+/* Compare device paths. */
+static int
+compare_device_paths (const grub_efi_device_path_t *dp1,
+ const grub_efi_device_path_t *dp2)
+{
+ if (! dp1 || ! dp2)
+ /* Return non-zero. */
+ return 1;
+
+ while (1)
+ {
+ grub_efi_uint8_t type1, type2;
+ grub_efi_uint8_t subtype1, subtype2;
+ grub_efi_uint16_t len1, len2;
+ int ret;
+
+ type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
+ type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+
+ if (type1 != type2)
+ return (int) type2 - (int) type1;
+
+ subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
+ subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+
+ if (subtype1 != subtype2)
+ return (int) subtype1 - (int) subtype2;
+
+ len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
+ len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+
+ if (len1 != len2)
+ return (int) len1 - (int) len2;
+
+ ret = grub_memcmp (dp1, dp2, len1);
+ if (ret != 0)
+ return ret;
+
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
+ break;
+
+ dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
+ dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+ }
+
+ return 0;
+}
+
+static struct grub_efidisk_data *
+make_devices (void)
+{
+ grub_efi_uintn_t num_handles;
+ grub_efi_handle_t *handles;
+ grub_efi_handle_t *handle;
+ struct grub_efidisk_data *devices = 0;
+
+ /* Find handles which support the disk io interface. */
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid,
+ 0, &num_handles);
+ if (! handles)
+ return 0;
+
+ /* Make a linked list of devices. */
+ for (handle = handles; num_handles--; handle++)
+ {
+ grub_efi_device_path_t *dp;
+ grub_efi_device_path_t *ldp;
+ struct grub_efidisk_data *d;
+ grub_efi_block_io_t *bio;
+ grub_efi_disk_io_t *dio;
+
+ dp = grub_efi_open_protocol (*handle, &device_path_guid,
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (! dp)
+ continue;
+
+ ldp = find_last_device_path (dp);
+ if (! ldp)
+ /* This is empty. Why? */
+ continue;
+
+ bio = grub_efi_open_protocol (*handle, &block_io_guid,
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ dio = grub_efi_open_protocol (*handle, &disk_io_guid,
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (! bio || ! dio)
+ /* This should not happen... Why? */
+ continue;
+
+ d = grub_malloc (sizeof (*d));
+ if (! d)
+ {
+ /* Uggh. */
+ grub_free (handles);
+ return 0;
+ }
+
+ d->handle = *handle;
+ d->device_path = dp;
+ d->last_device_path = ldp;
+ d->block_io = bio;
+ d->disk_io = dio;
+ d->next = devices;
+ devices = d;
+ }
+
+ grub_free (handles);
+
+ return devices;
+}
+
+/* Find the parent device. */
+static struct grub_efidisk_data *
+find_parent_device (struct grub_efidisk_data *devices,
+ struct grub_efidisk_data *d)
+{
+ grub_efi_device_path_t *dp, *ldp;
+ struct grub_efidisk_data *parent;
+
+ dp = duplicate_device_path (d->device_path);
+ if (! dp)
+ return 0;
+
+ ldp = find_last_device_path (dp);
+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ ldp->length[0] = sizeof (*ldp);
+ ldp->length[1] = 0;
+
+ for (parent = devices; parent; parent = parent->next)
+ {
+ /* Ignore itself. */
+ if (parent == d)
+ continue;
+
+ if (compare_device_paths (parent->device_path, dp) == 0)
+ {
+ /* Found. */
+ if (! parent->last_device_path)
+ parent = 0;
+
+ break;
+ }
+ }
+
+ grub_free (dp);
+ return parent;
+}
+
+/* Add a device into a list of devices in an ascending order. */
+static void
+add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
+{
+ struct grub_efidisk_data **p;
+ struct grub_efidisk_data *n;
+
+ for (p = devices; *p; p = &((*p)->next))
+ {
+ int ret;
+
+ ret = compare_device_paths ((*p)->device_path, d->device_path);
+ if (ret == 0)
+ return;
+ else if (ret > 0)
+ break;
+ }
+
+ n = grub_malloc (sizeof (*n));
+ if (! n)
+ return;
+
+ grub_memcpy (n, d, sizeof (*n));
+ n->next = (*p);
+ (*p) = n;
+}
+
+/* Name the devices. */
+static void
+name_devices (struct grub_efidisk_data *devices)
+{
+ struct grub_efidisk_data *d;
+
+ /* First, identify devices by media device paths. */
+ for (d = devices; d; d = d->next)
+ {
+ grub_efi_device_path_t *dp;
+
+ dp = d->last_device_path;
+ if (! dp)
+ continue;
+
+ if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+ {
+ int is_hard_drive = 0;
+
+ switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
+ {
+ case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+ is_hard_drive = 1;
+ /* Fall through by intention. */
+ case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+ {
+ struct grub_efidisk_data *parent;
+
+ parent = find_parent_device (devices, d);
+ if (parent)
+ {
+ if (is_hard_drive)
+ {
+#if 0
+ grub_printf ("adding a hard drive by a partition: ");
+ grub_print_device_path (parent->device_path);
+#endif
+ add_device (&hd_devices, parent);
+ }
+ else
+ {
+#if 0
+ grub_printf ("adding a cdrom by a partition: ");
+ grub_print_device_path (parent->device_path);
+#endif
+ add_device (&cd_devices, parent);
+ }
+
+ /* Mark the parent as used. */
+ parent->last_device_path = 0;
+ }
+ }
+ /* Mark itself as used. */
+ d->last_device_path = 0;
+ break;
+
+ default:
+ /* For now, ignore the others. */
+ break;
+ }
+ }
+ }
+
+ /* Let's see what can be added more. */
+ for (d = devices; d; d = d->next)
+ {
+ grub_efi_device_path_t *dp;
+ grub_efi_block_io_media_t *m;
+
+ dp = d->last_device_path;
+ if (! dp)
+ continue;
+
+ m = d->block_io->media;
+ if (m->logical_partition)
+ {
+ /* Only one partition in a non-media device. Assume that this
+ is a floppy drive. */
+#if 0
+ grub_printf ("adding a floppy by guessing: ");
+ grub_print_device_path (d->device_path);
+#endif
+ add_device (&fd_devices, d);
+ }
+ else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
+ {
+ /* This check is too heuristic, but assume that this is a
+ CDROM drive. */
+#if 0
+ grub_printf ("adding a cdrom by guessing: ");
+ grub_print_device_path (d->device_path);
+#endif
+ add_device (&cd_devices, d);
+ }
+ else
+ {
+ /* The default is a hard drive. */
+#if 0
+ grub_printf ("adding a hard drive by guessing: ");
+ grub_print_device_path (d->device_path);
+#endif
+ add_device (&hd_devices, d);
+ }
+ }
+}
+
+static void
+free_devices (struct grub_efidisk_data *devices)
+{
+ struct grub_efidisk_data *p, *q;
+
+ for (p = devices; p; p = q)
+ {
+ q = p->next;
+ grub_free (p);
+ }
+}
+
+/* Enumerate all disks to name devices. */
+static void
+enumerate_disks (void)
+{
+ struct grub_efidisk_data *devices;
+
+ devices = make_devices ();
+ if (! devices)
+ return;
+
+ name_devices (devices);
+ free_devices (devices);
+}
+
+static int
+grub_efidisk_iterate (int (*hook) (const char *name))
+{
+ struct grub_efidisk_data *d;
+ char buf[16];
+ int count;
+
+ for (d = fd_devices, count = 0; d; d = d->next, count++)
+ {
+ grub_sprintf (buf, "fd%d", count);
+ grub_dprintf ("efidisk", "iterating %s\n", buf);
+ if (hook (buf))
+ return 1;
+ }
+
+ for (d = hd_devices, count = 0; d; d = d->next, count++)
+ {
+ grub_sprintf (buf, "hd%d", count);
+ grub_dprintf ("efidisk", "iterating %s\n", buf);
+ if (hook (buf))
+ return 1;
+ }
+
+ for (d = cd_devices, count = 0; d; d = d->next, count++)
+ {
+ grub_sprintf (buf, "cd%d", count);
+ grub_dprintf ("efidisk", "iterating %s\n", buf);
+ if (hook (buf))
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+get_drive_number (const char *name)
+{
+ unsigned long drive;
+
+ if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd')
+ goto fail;
+
+ drive = grub_strtoul (name + 2, 0, 10);
+ if (grub_errno != GRUB_ERR_NONE)
+ goto fail;
+
+ return (int) drive ;
+
+ fail:
+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk");
+ return -1;
+}
+
+static struct grub_efidisk_data *
+get_device (struct grub_efidisk_data *devices, int num)
+{
+ struct grub_efidisk_data *d;
+
+ for (d = devices; d && num; d = d->next, num--)
+ ;
+
+ if (num == 0)
+ return d;
+
+ return 0;
+}
+
+static grub_err_t
+grub_efidisk_open (const char *name, struct grub_disk *disk)
+{
+ int num;
+ struct grub_efidisk_data *d = 0;
+ grub_efi_block_io_media_t *m;
+
+ grub_dprintf ("efidisk", "opening %s\n", name);
+
+ num = get_drive_number (name);
+ if (num < 0)
+ return grub_errno;
+
+ switch (name[0])
+ {
+ case 'f':
+ disk->has_partitions = 0;
+ d = get_device (fd_devices, num);
+ break;
+ case 'c':
+ /* FIXME: a CDROM should have partitions, but not implemented yet. */
+ disk->has_partitions = 0;
+ d = get_device (cd_devices, num);
+ break;
+ case 'h':
+ disk->has_partitions = 1;
+ d = get_device (hd_devices, num);
+ break;
+ default:
+ /* Never reach here. */
+ break;
+ }
+
+ if (! d)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");
+
+ disk->id = ((num << 8) | name[0]);
+ m = d->block_io->media;
+ /* FIXME: Probably it is better to store the block size in the disk,
+ and total sectors should be replaced with total blocks. */
+ grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
+ m, m->last_block, m->block_size);
+ disk->total_sectors = (m->last_block
+ * (m->block_size >> GRUB_DISK_SECTOR_BITS));
+ disk->data = d;
+
+ grub_dprintf ("efidisk", "opening %s succeeded\n", name);
+
+ return GRUB_ERR_NONE;
+}
+
+static void
+grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused)))
+{
+ /* EFI disks do not allocate extra memory, so nothing to do here. */
+ grub_dprintf ("efidisk", "closing %s", disk->name);
+}
+
+static grub_err_t
+grub_efidisk_read (struct grub_disk *disk, unsigned long sector,
+ unsigned long size, char *buf)
+{
+ /* For now, use the disk io interface rather than the block io's. */
+ struct grub_efidisk_data *d;
+ grub_efi_disk_io_t *dio;
+ grub_efi_block_io_t *bio;
+ grub_efi_status_t status;
+
+ d = disk->data;
+ dio = d->disk_io;
+ bio = d->block_io;
+
+ grub_dprintf ("efidisk", "reading 0x%lx sectors at the sector 0x%lx from %s\n",
+ size, sector, disk->name);
+
+ status = dio->read (dio, bio->media->media_id,
+ (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+ (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+ buf);
+ if (status != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error");
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efidisk_write (struct grub_disk *disk, unsigned long sector,
+ unsigned long size, const char *buf)
+{
+ /* For now, use the disk io interface rather than the block io's. */
+ struct grub_efidisk_data *d;
+ grub_efi_disk_io_t *dio;
+ grub_efi_block_io_t *bio;
+ grub_efi_status_t status;
+
+ d = disk->data;
+ dio = d->disk_io;
+ bio = d->block_io;
+
+ grub_dprintf ("efidisk", "writing 0x%lx sectors at the sector 0x%lx to %s\n",
+ size, sector, disk->name);
+
+ status = dio->write (dio, bio->media->media_id,
+ (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+ (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+ (void *) buf);
+ if (status != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error");
+
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_disk_dev grub_efidisk_dev =
+ {
+ .name = "efidisk",
+ .id = GRUB_DISK_DEVICE_EFIDISK_ID,
+ .iterate = grub_efidisk_iterate,
+ .open = grub_efidisk_open,
+ .close = grub_efidisk_close,
+ .read = grub_efidisk_read,
+ .write = grub_efidisk_write,
+ .next = 0
+ };
+
+void
+grub_efidisk_init (void)
+{
+ enumerate_disks ();
+ grub_disk_dev_register (&grub_efidisk_dev);
+}
+
+void
+grub_efidisk_fini (void)
+{
+ free_devices (fd_devices);
+ free_devices (hd_devices);
+ free_devices (cd_devices);
+ grub_disk_dev_unregister (&grub_efidisk_dev);
+}
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2004,2005,2006 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
{
GRUB_DISK_DEVICE_BIOSDISK_ID,
GRUB_DISK_DEVICE_OFDISK_ID,
- GRUB_DISK_DEVICE_LOOPBACK_ID
+ GRUB_DISK_DEVICE_LOOPBACK_ID,
+ GRUB_DISK_DEVICE_EFIDISK_ID
};
struct grub_disk;
#define GRUB_EFI_OPTIONAL_PTR 0x00000001
#define GRUB_EFI_LOADED_IMAGE_GUID \
- { 0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }
+ { 0x5b1b31a1, 0x9562, 0x11d2, \
+ { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_DISK_IO_GUID \
+ { 0xce345171, 0xba0b, 0x11d2, \
+ { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_BLOCK_IO_GUID \
+ { 0x964e5b21, 0x6459, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_DEVICE_PATH_GUID \
+ { 0x09576e91, 0x6d3f, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
/* Enumerations. */
enum grub_efi_timer_delay
typedef grub_efi_uintn_t grub_efi_tpl_t;
typedef grub_uint8_t grub_efi_mac_address_t[32];
typedef grub_uint8_t grub_efi_ipv4_address_t[4];
-typedef grub_uint8_t grub_efi_ipv6_address_t[8];
+typedef grub_uint16_t grub_efi_ipv6_address_t[8];
typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
typedef grub_efi_uint64_t grub_efi_physical_address_t;
typedef grub_efi_uint64_t grub_efi_virtual_address_t;
grub_uint32_t data1;
grub_uint16_t data2;
grub_uint16_t data3;
- grub_uint8_t data4;
- grub_uint8_t data5;
- grub_uint8_t data6;
- grub_uint8_t data7;
- grub_uint8_t data8;
- grub_uint8_t data9;
- grub_uint8_t data10;
- grub_uint8_t data11;
+ grub_uint8_t data4[8];
} __attribute__ ((aligned(8)));
typedef struct grub_efi_guid grub_efi_guid_t;
};
typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t;
+/* Device Path definitions. */
struct grub_efi_device_path
{
grub_efi_uint8_t type;
- grub_efi_uint8_t sub_type;
+ grub_efi_uint8_t subtype;
grub_efi_uint8_t length[2];
};
typedef struct grub_efi_device_path grub_efi_device_path_t;
It seems to be identical to EFI_DEVICE_PATH. */
typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
+#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
+#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
+#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) \
+ ((dp)->length[0] | ((grub_efi_uint16_t) ((dp)->length[1]) << 8))
+
+/* The End of Device Path nodes. */
+#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+
+#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
+ ((grub_efi_device_path_t *) ((char *) (dp) \
+ + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+
+/* Hardware Device Path. */
+#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
+
+#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_pci_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t function;
+ grub_efi_uint8_t device;
+};
+typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t;
+
+#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_pccard_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t function;
+};
+typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t;
+
+#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_memory_mapped_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_memory_type_t memory_type;
+ grub_efi_physical_address_t start_address;
+ grub_efi_physical_address_t end_address;
+};
+typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t;
+
+#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_vendor_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_guid_t vendor_guid;
+ grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
+
+#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_controller_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t controller_number;
+};
+typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t;
+
+/* ACPI Device Path. */
+#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2
+
+#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_acpi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t hid;
+ grub_efi_uint32_t uid;
+};
+typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_expanded_acpi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t hid;
+ grub_efi_uint32_t uid;
+ grub_efi_uint32_t cid;
+ char hidstr[1];
+};
+typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+ (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
+#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+ (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+ + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
+#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \
+ (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+ + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
+
+/* Messaging Device Path. */
+#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3
+
+#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_atapi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t primary_secondary;
+ grub_efi_uint8_t slave_master;
+ grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t;
+
+#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_scsi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t pun;
+ grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t;
+
+#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_fibre_channel_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t wwn;
+ grub_efi_uint64_t lun;
+};
+typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t;
+
+#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_1394_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t guid;
+};
+typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t;
+
+#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_usb_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t parent_port_number;
+ grub_efi_uint8_t interface;
+};
+typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t;
+
+#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15
+
+struct grub_efi_usb_class_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t vendor_id;
+ grub_efi_uint16_t product_id;
+ grub_efi_uint8_t device_class;
+ grub_efi_uint8_t device_subclass;
+ grub_efi_uint8_t device_protocol;
+};
+typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t;
+
+#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6
+
+struct grub_efi_i2o_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t tid;
+};
+typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t;
+
+#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11
+
+struct grub_efi_mac_address_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_mac_address_t mac_address;
+ grub_efi_uint8_t if_type;
+};
+typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t;
+
+#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12
+
+struct grub_efi_ipv4_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_ipv4_address_t local_ip_address;
+ grub_efi_ipv4_address_t remote_ip_address;
+ grub_efi_uint16_t local_port;
+ grub_efi_uint16_t remote_port;
+ grub_efi_uint16_t protocol;
+ grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
+
+#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13
+
+struct grub_efi_ipv6_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_ipv6_address_t local_ip_address;
+ grub_efi_ipv6_address_t remote_ip_address;
+ grub_efi_uint16_t local_port;
+ grub_efi_uint16_t remote_port;
+ grub_efi_uint16_t protocol;
+ grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
+
+#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9
+
+struct grub_efi_infiniband_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t resource_flags;
+ grub_efi_uint8_t port_gid[16];
+ grub_efi_uint64_t remote_id;
+ grub_efi_uint64_t target_port_id;
+ grub_efi_uint64_t device_id;
+};
+typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t;
+
+#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14
+
+struct grub_efi_uart_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t baud_rate;
+ grub_efi_uint8_t data_bits;
+ grub_efi_uint8_t parity;
+ grub_efi_uint8_t stop_bits;
+};
+typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
+
+#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
+
+struct grub_efi_vendor_messaging_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_guid_t vendor_guid;
+ grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t;
+
+/* Media Device Path. */
+#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4
+
+#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_hard_drive_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t partition_number;
+ grub_efi_lba_t partition_start;
+ grub_efi_lba_t partition_size;
+ grub_efi_uint8_t partition_signature[8];
+ grub_efi_uint8_t mbr_type;
+ grub_efi_uint8_t signature_type;
+};
+typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t;
+
+#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_cdrom_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t boot_entry;
+ grub_efi_lba_t partition_start;
+ grub_efi_lba_t partition_size;
+};
+typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
+
+#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_vendor_media_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_guid_t vendor_guid;
+ grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
+
+#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_file_path_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_char16_t path_name[0];
+};
+typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
+
+#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_protocol_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_guid_t guid;
+};
+typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
+
+/* BIOS Boot Specification Device Path. */
+#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5
+
+#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_bios_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t device_type;
+ grub_efi_uint16_t status_flags;
+ char description[0];
+};
+typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
+
struct grub_efi_open_protocol_information_entry
{
grub_efi_handle_t agent_handle;
};
typedef struct grub_efi_loaded_image grub_efi_loaded_image_t;
+struct grub_efi_disk_io
+{
+ grub_efi_uint64_t revision;
+ grub_efi_status_t (*read) (struct grub_efi_disk_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_uint64_t offset,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*write) (struct grub_efi_disk_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_uint64_t offset,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+};
+typedef struct grub_efi_disk_io grub_efi_disk_io_t;
+
+struct grub_efi_block_io_media
+{
+ grub_efi_uint32_t media_id;
+ grub_efi_boolean_t removable_media;
+ grub_efi_boolean_t media_present;
+ grub_efi_boolean_t logical_partition;
+ grub_efi_boolean_t read_only;
+ grub_efi_boolean_t write_caching;
+ grub_efi_uint8_t pad[3];
+ grub_efi_uint32_t block_size;
+ grub_efi_uint32_t io_align;
+ grub_efi_uint8_t pad2[4];
+ grub_efi_lba_t last_block;
+};
+typedef struct grub_efi_block_io_media grub_efi_block_io_media_t;
+
+struct grub_efi_block_io
+{
+ grub_efi_uint64_t revision;
+ grub_efi_block_io_media_t *media;
+ grub_efi_status_t (*reset) (struct grub_efi_block_io *this,
+ grub_efi_boolean_t extended_verification);
+ grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_lba_t lba,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_lba_t lba,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this);
+};
+typedef struct grub_efi_block_io grub_efi_block_io_t;
+
#endif /* ! GRUB_EFI_API_HEADER */
#define GRUB_EFI_CONSOLE_CONTROL_HEADER 1
#define GRUB_EFI_CONSOLE_CONTROL_GUID \
- { 0xf42f7782, 0x12e, 0x4c12, 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 }
+ { 0xf42f7782, 0x12e, 0x4c12, \
+ { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \
+ }
enum grub_efi_screen_mode
{
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_EFI_DISK_HEADER
+#define GRUB_EFI_DISK_HEADER 1
+
+void grub_efidisk_init (void);
+void grub_efidisk_fini (void);
+
+#endif /* ! GRUB_EFI_DISK_HEADER */
/* Functions. */
void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
void *registration);
+grub_efi_handle_t *
+EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type,
+ grub_efi_guid_t *protocol,
+ void *search_key,
+ grub_efi_uintn_t *num_handles);
+void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ grub_efi_uint32_t attributes);
int EXPORT_FUNC(grub_efi_set_text_mode) (int on);
-void EXPORT_FUNC(grub_efi_exit) (void) __attribute__((noreturn));
void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
-void *EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
- grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
-int EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
- grub_efi_memory_descriptor_t *memory_map,
- grub_efi_uintn_t *map_key,
- grub_efi_uintn_t *descriptor_size,
- grub_efi_uint32_t *descriptor_version);
+int
+EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version);
grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (void);
+void EXPORT_FUNC(grub_print_device_path) (grub_efi_device_path_t *dp);
void grub_efi_mm_init (void);
void grub_efi_mm_fini (void);
int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args);
-void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest,
grub_uint16_t *src,
grub_size_t size);
grub_abs (int x)
{
if (x < 0)
- return (unsigned int)(-x);
+ return (unsigned int) (-x);
else
- return (unsigned int)x;
+ return (unsigned int) x;
}
#endif /* ! GRUB_MISC_HEADER */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <grub/symbol.h>
-void EXPORT_FUNC (abort) (void);
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
#include <grub/symbol.h>
-void EXPORT_FUNC (abort) (void);
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
#include <grub/machine/time.h>
#include <grub/term.h>
#include <grub/kernel.h>
+#include <grub/mm.h>
/* The handle of GRUB itself. Filled in by the startup code. */
grub_efi_handle_t grub_efi_image_handle;
/* The pointer to a system table. Filled in by the startup code. */
grub_efi_system_table_t *grub_efi_system_table;
-static grub_efi_guid_t grub_efi_console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
-static grub_efi_guid_t grub_efi_loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
+static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
+static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
void *
grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
return interface;
}
+/* Return the array of handles which meet the requirement. If successful,
+ the number of handles is stored in NUM_HANDLES. The array is allocated
+ from the heap. */
+grub_efi_handle_t *
+grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
+ grub_efi_guid_t *protocol,
+ void *search_key,
+ grub_efi_uintn_t *num_handles)
+{
+ grub_efi_boot_services_t *b;
+ grub_efi_status_t status;
+ grub_efi_handle_t *buffer;
+ grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
+
+ buffer = grub_malloc (buffer_size);
+ if (! buffer)
+ return 0;
+
+ b = grub_efi_system_table->boot_services;
+ status = b->locate_handle (search_type, protocol, search_key,
+ &buffer_size, buffer);
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+ {
+ grub_free (buffer);
+ buffer = grub_malloc (buffer_size);
+ if (! buffer)
+ return 0;
+
+ status = b->locate_handle (search_type, protocol, search_key,
+ &buffer_size, buffer);
+ }
+
+ if (status != GRUB_EFI_SUCCESS)
+ {
+ grub_free (buffer);
+ return 0;
+ }
+
+ *num_handles = buffer_size / sizeof (grub_efi_handle_t);
+ return buffer;
+}
+
+void *
+grub_efi_open_protocol (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ grub_efi_uint32_t attributes)
+{
+ grub_efi_boot_services_t *b;
+ grub_efi_status_t status;
+ void *interface;
+
+ b = grub_efi_system_table->boot_services;
+ status = b->open_protocol (handle,
+ protocol,
+ &interface,
+ grub_efi_image_handle,
+ 0,
+ attributes);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+
+ return interface;
+}
+
int
grub_efi_set_text_mode (int on)
{
grub_efi_console_control_protocol_t *c;
grub_efi_screen_mode_t mode, new_mode;
- c = grub_efi_locate_protocol (&grub_efi_console_control_guid, 0);
+ c = grub_efi_locate_protocol (&console_control_guid, 0);
if (! c)
return 0;
return 1;
}
-void
-grub_efi_exit (void)
-{
- grub_efi_system_table->boot_services->exit (grub_efi_image_handle,
- GRUB_EFI_SUCCESS,
- 0, 0);
-}
-
void
grub_efi_stall (grub_efi_uintn_t microseconds)
{
grub_efi_loaded_image_t *
grub_efi_get_loaded_image (void)
{
- grub_efi_boot_services_t *b;
- void *interface;
- grub_efi_status_t status;
-
- b = grub_efi_system_table->boot_services;
- status = b->open_protocol (grub_efi_image_handle,
- &grub_efi_loaded_image_guid,
- &interface,
- grub_efi_image_handle,
- 0,
- GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (status != GRUB_EFI_SUCCESS)
- return 0;
-
- return interface;
+ return grub_efi_open_protocol (grub_efi_image_handle,
+ &loaded_image_guid,
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
}
void
-grub_stop (void)
+grub_exit (void)
{
- grub_printf ("\nPress any key to abort.\n");
- grub_getkey ();
-
- grub_efi_fini ();
- grub_efi_exit ();
+ grub_efi_system_table->boot_services->exit (grub_efi_image_handle,
+ GRUB_EFI_SUCCESS,
+ 0, 0);
}
grub_uint32_t
return (grub_addr_t) info;
}
+
+/* Print the chain of Device Path nodes. This is mainly for debugging. */
+void
+grub_print_device_path (grub_efi_device_path_t *dp)
+{
+ while (1)
+ {
+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+
+ switch (type)
+ {
+ case GRUB_EFI_END_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
+ /* grub_printf ("/EndEntire\n"); */
+ grub_putchar ('\n');
+ break;
+ case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
+ /* grub_printf ("/EndThis\n"); */
+ grub_putchar ('\n');
+ break;
+ default:
+ grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_pci_device_path_t pci;
+ grub_memcpy (&pci, dp, len);
+ grub_printf ("/PCI(%x,%x)",
+ (unsigned) pci.function, (unsigned) pci.device);
+ }
+ break;
+ case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_pccard_device_path_t pccard;
+ grub_memcpy (&pccard, dp, len);
+ grub_printf ("/PCCARD(%x)",
+ (unsigned) pccard.function);
+ }
+ break;
+ case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_memory_mapped_device_path_t mmapped;
+ grub_memcpy (&mmapped, dp, len);
+ grub_printf ("/MMap(%x,%llx,%llx)",
+ (unsigned) mmapped.memory_type,
+ mmapped.start_address,
+ mmapped.end_address);
+ }
+ break;
+ case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_vendor_device_path_t vendor;
+ grub_memcpy (&vendor, dp, sizeof (vendor));
+ grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+ (unsigned) vendor.vendor_guid.data1,
+ (unsigned) vendor.vendor_guid.data2,
+ (unsigned) vendor.vendor_guid.data3,
+ (unsigned) vendor.vendor_guid.data4[0],
+ (unsigned) vendor.vendor_guid.data4[1],
+ (unsigned) vendor.vendor_guid.data4[2],
+ (unsigned) vendor.vendor_guid.data4[3],
+ (unsigned) vendor.vendor_guid.data4[4],
+ (unsigned) vendor.vendor_guid.data4[5],
+ (unsigned) vendor.vendor_guid.data4[6],
+ (unsigned) vendor.vendor_guid.data4[7]);
+ }
+ break;
+ case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_controller_device_path_t controller;
+ grub_memcpy (&controller, dp, len);
+ grub_printf ("/Ctrl(%x)",
+ (unsigned) controller.controller_number);
+ }
+ break;
+ default:
+ grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_acpi_device_path_t acpi;
+ grub_memcpy (&acpi, dp, len);
+ grub_printf ("/ACPI(%x,%x)",
+ (unsigned) acpi.hid,
+ (unsigned) acpi.uid);
+ }
+ break;
+ case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_expanded_acpi_device_path_t eacpi;
+ grub_memcpy (&eacpi, dp, sizeof (eacpi));
+ grub_printf ("/ACPI(");
+
+ if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
+ grub_printf ("%x,", (unsigned) eacpi.hid);
+ else
+ grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
+
+ if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
+ grub_printf ("%x,", (unsigned) eacpi.uid);
+ else
+ grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
+
+ if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
+ grub_printf ("%x)", (unsigned) eacpi.cid);
+ else
+ grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
+ }
+ break;
+ default:
+ grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_atapi_device_path_t atapi;
+ grub_memcpy (&atapi, dp, len);
+ grub_printf ("/ATAPI(%x,%x,%x)",
+ (unsigned) atapi.primary_secondary,
+ (unsigned) atapi.slave_master,
+ (unsigned) atapi.lun);
+ }
+ break;
+ case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_scsi_device_path_t scsi;
+ grub_memcpy (&scsi, dp, len);
+ grub_printf ("/SCSI(%x,%x)",
+ (unsigned) scsi.pun,
+ (unsigned) scsi.lun);
+ }
+ break;
+ case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_fibre_channel_device_path_t fc;
+ grub_memcpy (&fc, dp, len);
+ grub_printf ("/FibreChannel(%llx,%llx)",
+ fc.wwn, fc.lun);
+ }
+ break;
+ case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_1394_device_path_t firewire;
+ grub_memcpy (&firewire, dp, len);
+ grub_printf ("/1394(%llx)", firewire.guid);
+ }
+ break;
+ case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_usb_device_path_t usb;
+ grub_memcpy (&usb, dp, len);
+ grub_printf ("/USB(%x,%x)",
+ (unsigned) usb.parent_port_number,
+ (unsigned) usb.interface);
+ }
+ break;
+ case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_usb_class_device_path_t usb_class;
+ grub_memcpy (&usb_class, dp, len);
+ grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
+ (unsigned) usb_class.vendor_id,
+ (unsigned) usb_class.product_id,
+ (unsigned) usb_class.device_class,
+ (unsigned) usb_class.device_subclass,
+ (unsigned) usb_class.device_protocol);
+ }
+ break;
+ case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_i2o_device_path_t i2o;
+ grub_memcpy (&i2o, dp, len);
+ grub_printf ("/I2O(%x)", (unsigned) i2o.tid);
+ }
+ break;
+ case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_mac_address_device_path_t mac;
+ grub_memcpy (&mac, dp, len);
+ grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
+ (unsigned) mac.mac_address[0],
+ (unsigned) mac.mac_address[1],
+ (unsigned) mac.mac_address[2],
+ (unsigned) mac.mac_address[3],
+ (unsigned) mac.mac_address[4],
+ (unsigned) mac.mac_address[5],
+ (unsigned) mac.if_type);
+ }
+ break;
+ case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_ipv4_device_path_t ipv4;
+ grub_memcpy (&ipv4, dp, len);
+ grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
+ (unsigned) ipv4.local_ip_address[0],
+ (unsigned) ipv4.local_ip_address[1],
+ (unsigned) ipv4.local_ip_address[2],
+ (unsigned) ipv4.local_ip_address[3],
+ (unsigned) ipv4.remote_ip_address[0],
+ (unsigned) ipv4.remote_ip_address[1],
+ (unsigned) ipv4.remote_ip_address[2],
+ (unsigned) ipv4.remote_ip_address[3],
+ (unsigned) ipv4.local_port,
+ (unsigned) ipv4.remote_port,
+ (unsigned) ipv4.protocol,
+ (unsigned) ipv4.static_ip_address);
+ }
+ break;
+ case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_ipv6_device_path_t ipv6;
+ grub_memcpy (&ipv6, dp, len);
+ grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
+ (unsigned) ipv6.local_ip_address[0],
+ (unsigned) ipv6.local_ip_address[1],
+ (unsigned) ipv6.local_ip_address[2],
+ (unsigned) ipv6.local_ip_address[3],
+ (unsigned) ipv6.local_ip_address[4],
+ (unsigned) ipv6.local_ip_address[5],
+ (unsigned) ipv6.local_ip_address[6],
+ (unsigned) ipv6.local_ip_address[7],
+ (unsigned) ipv6.remote_ip_address[0],
+ (unsigned) ipv6.remote_ip_address[1],
+ (unsigned) ipv6.remote_ip_address[2],
+ (unsigned) ipv6.remote_ip_address[3],
+ (unsigned) ipv6.remote_ip_address[4],
+ (unsigned) ipv6.remote_ip_address[5],
+ (unsigned) ipv6.remote_ip_address[6],
+ (unsigned) ipv6.remote_ip_address[7],
+ (unsigned) ipv6.local_port,
+ (unsigned) ipv6.remote_port,
+ (unsigned) ipv6.protocol,
+ (unsigned) ipv6.static_ip_address);
+ }
+ break;
+ case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_infiniband_device_path_t ib;
+ grub_memcpy (&ib, dp, len);
+ grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
+ (unsigned) ib.port_gid[0], /* XXX */
+ ib.remote_id,
+ ib.target_port_id,
+ ib.device_id);
+ }
+ break;
+ case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_uart_device_path_t uart;
+ grub_memcpy (&uart, dp, len);
+ grub_printf ("/UART(%llu,%u,%x,%x)",
+ uart.baud_rate,
+ uart.data_bits,
+ uart.parity,
+ uart.stop_bits);
+ }
+ break;
+ case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_vendor_messaging_device_path_t vendor;
+ grub_memcpy (&vendor, dp, sizeof (vendor));
+ grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+ (unsigned) vendor.vendor_guid.data1,
+ (unsigned) vendor.vendor_guid.data2,
+ (unsigned) vendor.vendor_guid.data3,
+ (unsigned) vendor.vendor_guid.data4[0],
+ (unsigned) vendor.vendor_guid.data4[1],
+ (unsigned) vendor.vendor_guid.data4[2],
+ (unsigned) vendor.vendor_guid.data4[3],
+ (unsigned) vendor.vendor_guid.data4[4],
+ (unsigned) vendor.vendor_guid.data4[5],
+ (unsigned) vendor.vendor_guid.data4[6],
+ (unsigned) vendor.vendor_guid.data4[7]);
+ }
+ break;
+ default:
+ grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_hard_drive_device_path_t hd;
+ grub_memcpy (&hd, dp, len);
+ grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
+ hd.partition_number,
+ hd.partition_start,
+ hd.partition_size,
+ (unsigned) hd.partition_signature[0],
+ (unsigned) hd.partition_signature[1],
+ (unsigned) hd.partition_signature[2],
+ (unsigned) hd.partition_signature[3],
+ (unsigned) hd.partition_signature[4],
+ (unsigned) hd.partition_signature[5],
+ (unsigned) hd.partition_signature[6],
+ (unsigned) hd.partition_signature[7],
+ (unsigned) hd.mbr_type,
+ (unsigned) hd.signature_type);
+ }
+ break;
+ case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_cdrom_device_path_t cd;
+ grub_memcpy (&cd, dp, len);
+ grub_printf ("/CD(%u,%llx,%llx)",
+ cd.boot_entry,
+ cd.partition_start,
+ cd.partition_size);
+ }
+ break;
+ case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_vendor_media_device_path_t vendor;
+ grub_memcpy (&vendor, dp, sizeof (vendor));
+ grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+ (unsigned) vendor.vendor_guid.data1,
+ (unsigned) vendor.vendor_guid.data2,
+ (unsigned) vendor.vendor_guid.data3,
+ (unsigned) vendor.vendor_guid.data4[0],
+ (unsigned) vendor.vendor_guid.data4[1],
+ (unsigned) vendor.vendor_guid.data4[2],
+ (unsigned) vendor.vendor_guid.data4[3],
+ (unsigned) vendor.vendor_guid.data4[4],
+ (unsigned) vendor.vendor_guid.data4[5],
+ (unsigned) vendor.vendor_guid.data4[6],
+ (unsigned) vendor.vendor_guid.data4[7]);
+ }
+ break;
+ case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_file_path_device_path_t *fp;
+ grub_uint8_t buf[(len - 4) * 4 + 1];
+ fp = (grub_efi_file_path_device_path_t *) dp;
+ *grub_utf16_to_utf8 (buf, fp->path_name, len - 4) = '\0';
+ grub_printf ("/File(%s)", buf);
+ }
+ break;
+ case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_protocol_device_path_t proto;
+ grub_memcpy (&proto, dp, sizeof (proto));
+ grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+ (unsigned) proto.guid.data1,
+ (unsigned) proto.guid.data2,
+ (unsigned) proto.guid.data3,
+ (unsigned) proto.guid.data4[0],
+ (unsigned) proto.guid.data4[1],
+ (unsigned) proto.guid.data4[2],
+ (unsigned) proto.guid.data4[3],
+ (unsigned) proto.guid.data4[4],
+ (unsigned) proto.guid.data4[5],
+ (unsigned) proto.guid.data4[6],
+ (unsigned) proto.guid.data4[7]);
+ }
+ break;
+ default:
+ grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
+ switch (subtype)
+ {
+ case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
+ {
+ grub_efi_bios_device_path_t bios;
+ grub_memcpy (&bios, dp, sizeof (bios));
+ grub_printf ("/BIOS(%x,%x,%s)",
+ (unsigned) bios.device_type,
+ (unsigned) bios.status_flags,
+ (char *) (dp + 1));
+ }
+ break;
+ default:
+ grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
+ break;
+ }
+ break;
+
+ default:
+ grub_printf ("/UnknownType(%x,%x)\n",
+ (unsigned) type,
+ (unsigned) subtype);
+ return;
+ break;
+ }
+
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+ break;
+
+ dp = (grub_efi_device_path_t *) ((char *) dp + len);
+ }
+}
#include <grub/efi/efi.h>
#include <grub/efi/console.h>
+#include <grub/efi/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
+#include <grub/env.h>
#include <grub/machine/kernel.h>
void
/* Initialize the memory management system. */
grub_efi_mm_init ();
+ grub_efidisk_init ();
+
/* FIXME: this must be set to something meaningful. */
grub_env_set ("prefix", grub_prefix);
}
void
grub_efi_fini (void)
{
+ grub_efidisk_fini ();
grub_efi_mm_fini ();
grub_console_fini ();
}
grub_vprintf (fmt, ap);
va_end (ap);
- grub_stop ();
+ grub_abort ();
}
void
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
outb %al, %dx
ret
+/*
+ * grub_exit()
+ *
+ * Exit the system.
+ */
+FUNCTION(grub_exit)
+ call prot_to_real
+ .code16
+ /* Tell the BIOS a boot failure. If this does not work, reboot. */
+ int $0x18
+ jmp cold_reboot
+
/*
* grub_reboot()
*
FUNCTION(grub_reboot)
call prot_to_real
.code16
+cold_reboot:
/* cold boot */
movw $0x0472, %di
movw %ax, (%di)
}
void
-grub_real_dprintf(const char *file, const int line, const char *condition,
- const char *fmt, ...)
+grub_real_dprintf (const char *file, const int line, const char *condition,
+ const char *fmt, ...)
{
va_list args;
const char *debug = grub_env_get ("debug");
+
if (! debug)
return;
+
if (grub_strword (debug, "all") || grub_strword (debug, condition))
{
- grub_printf ("%s,%d : ", file, line);
+ grub_printf ("%s:%d: ", file, line);
va_start (args, fmt);
grub_vprintf (fmt, args);
va_end (args);
return p - dest;
}
+
+/* Abort GRUB. This function does not return. */
+void
+grub_abort (void)
+{
+ if (grub_term_get_current ())
+ {
+ grub_printf ("Abort. Press any key to exit.");
+ grub_getkey ();
+ }
+
+ grub_exit ();
+}
/* cmain.c - Startup code for the PowerPC. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* Need to claim ourselves so we don't cannibalize our memory later. */
if (grub_ieee1275_claim ((grub_addr_t) &_start, (grub_addr_t) &_end
- (grub_addr_t) &_start, 0, 0))
- abort();
+ grub_abort ();
}
else
{
static grub_addr_t grub_heap_len;
void
-abort (void)
+grub_exit (void)
{
/* Trap to Open Firmware. */
asm ("trap");
{
grub_printf ("Failed to claim heap at 0x%x, len 0x%x\n", grub_heap_start,
grub_heap_len);
- abort ();
+ grub_abort ();
}
grub_mm_init_region ((void *) grub_heap_start, grub_heap_len);
grub_console_fini ();
}
-void
-grub_stop (void)
-{
- for (;;);
-}
-
grub_uint32_t
grub_get_rtc (void)
{
grub_env_unset (argv[0]);
}
+/* exit */
+static void
+grub_rescue_cmd_exit (int argc __attribute__ ((unused)),
+ char *argv[] __attribute__ ((unused)))
+{
+ grub_exit ();
+}
+
static void
attempt_normal_mode (void)
{
"set an environment variable");
grub_rescue_register_command ("unset", grub_rescue_cmd_unset,
"remove an environment variable");
+ grub_rescue_register_command ("exit", grub_rescue_cmd_exit,
+ "exit from GRUB");
while (1)
{
/* grub-probefs.c - probe a filesystem module for a given path */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 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
#include <grub/pc_partition.h>
#include <grub/machine/util/biosdisk.h>
#include <grub/util/getroot.h>
+#include <grub/term.h>
#include <stdio.h>
#include <unistd.h>
putchar (c);
}
+int
+grub_getkey (void)
+{
+ return -1;
+}
+
+grub_term_t
+grub_term_get_current (void)
+{
+ return 0;
+}
+
void
grub_refresh (void)
{
/* grub-setup.c - make GRUB usable */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006 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
#include <grub/machine/util/biosdisk.h>
#include <grub/machine/boot.h>
#include <grub/machine/kernel.h>
+#include <grub/term.h>
#include <stdio.h>
#include <unistd.h>
putchar (c);
}
+int
+grub_getkey (void)
+{
+ return -1;
+}
+
+grub_term_t
+grub_term_get_current (void)
+{
+ return 0;
+}
+
void
grub_refresh (void)
{
}
void
-grub_stop (void)
+grub_exit (void)
{
exit (1);
}