Hi,
Here are a few headers for the DXE service table, firmware volume protocol
and legacy bios protocol (this one currently misses the
grub_efi_ia32_register_set structure).
I'm posting them here, so that if someone wants to play with these parts of
EFI, he/she does not have to duplicate the effort.
I'll repost them as a patch once I get a use of them, as I'm not sure if
100% EFI support is exactly one of grub's goals.
If someone wants to review them, the specs are available at
http://www.intel.com/technology/framework/download.htm
Also, enabling legacy bios protocol in Apple EFI depends on a few drivers
that need to be scheduled and dispatched using dxe table functions. On my
machine (mac pro 1.1), the GUIDs of these drivers are:
{0x6229630c, 0x32c3, 0x4638, {0x80, 0x91, 0x83, 0x8d, 0x98, 0x5d, 0xfa,
0x82}},
{0x5479662b, 0x6ae4, 0x49e8, {0xa6, 0xbd, 0x6d, 0xe4, 0xb6, 0x25, 0x81,
0x1f}},
{0xf122a15c, 0xc10b, 0x4d54, {0x8f, 0x48, 0x60, 0xf4, 0xf0, 0x6d, 0xd1,
0xad}},
{0xbc6d08dc, 0x865d, 0x4ffe, {0x8b, 0x7a, 0xfb, 0x5f, 0xb0, 0x4f, 0x12,
0xf1}},
{0xd3709bb4, 0xb194, 0x4b71, {0xb9, 0xc0, 0xdb, 0xd8, 0xd2, 0xda, 0x97,
0xad}},
{0x208117f2, 0x25f8, 0x479d, {0xb7, 0x26, 0x10, 0xc1, 0xb, 0xed, 0x6d,
0xc1}},
{0xef33c296, 0xf64c, 0x4146, {0xad, 0x4, 0x34, 0x78, 0x99, 0x70, 0x2c,
0x84}},
{0x1f36527e, 0xa97c, 0x45f8, {0xb2, 0x4a, 0x9d, 0x95, 0xb0, 0xa9, 0x40,
0xfe}},
{0x9f2a114a, 0x834b, 0x4916, {0x94, 0x5c, 0x1c, 0x9, 0xf4, 0x94, 0x48,
0x19}},
{0x29cf55f8, 0xb675, 0x4f5d, {0x8f, 0x2f, 0xb8, 0x7a, 0x3e, 0xcf, 0xd0,
0x63}}
Then, chainloading to a legacy bios bootloader should be as easy as calling
the legacy_boot function form the legacy bios protocol. This is what I'll
try now ...
Regards,
Alex
/* dxe.h - definitions of the driver execution environment core interface */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007 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/>.
*/
/* The driver execution environment core interface is not a part of the EFI
spec, but defined in Intel's DXE CIS. */
#ifndef GRUB_EFI_DXE_HEADER
#define GRUB_EFI_DXE_HEADER 1
#define GRUB_EFI_DXE_SERVICES_SIGNATURE 0x565245535f455844
enum grub_efi_gcd_memory_type
{
GRUB_EFI_GCD_MEMORY_TYPE_NON_EXISTENT,
GRUB_EFI_GCD_MEMORY_TYPE_RESERVED,
GRUB_EFI_GCD_MEMORY_TYPE_SYSTEM_MEMORY,
GRUB_EFI_GCD_MEMORY_TYPE_MEMORY_MAPPED_IO,
GRUB_EFI_GCD_MEMORY_TYPE_MAXIMUM
};
typedef grub_efi_gcd_memory_type grub_efi_gcd_memory_type_t;
enum grub_efi_gcd_allocate_type
{
GRUB_EFI_GCD_ALLOCATE_ANY_SEARCH_BOTTOM_UP,
GRUB_EFI_GCD_ALLOCATE_MAX_ADDRESS_SEARCH_BOTTOM_UP,
GRUB_EFI_GCD_ALLOCATE_ADDRESS,
GRUB_EFI_GCD_ALLOCATE_ANY_SEARCH_TOP_DOWN,
GRUB_EFI_GCD_ALLOCATE_MAX_ADDRESS_SEARCH_TOP_DOWN,
GRUB_EFI_GCD_MAX_ALLOCATE_TYPE
};
typedef grub_efi_gcd_allocate_type grub_efi_gcd_allocate_type_t;
struct grub_efi_gcd_memory_space_descriptor
{
grub_efi_physical_address_t base_address;
grub_efi_uint64_t length;
grub_efi_uint64_t capabilities;
grub_efi_gcd_memory_type_t gcd_memory_type;
grub_efi_handle_t image_handle;
grub_efi_handle_t device_hande;
}
typedef grub_efi_gcd_memory_space_descriptor grub_efi_gcd_memory_space_descriptor_t;
enum grub_efi_gcd_io_type
{
GRUB_EFI_GCD_IO_TYPE_NON_EXISTENT,
GRUB_EFI_GCD_IO_TYPE_RESERVED,
GRUB_EFI_GCD_IO_TYPE_IO,
GRUB_EFI_GCD_IO_TYPE_MAXIMUM
};
typedef grub_efi_gcd_io_type grub_efi_gcd_io_type_t;
struct grub_efi_gcd_io_space_descriptor
{
grub_efi_physical_address_t base_address;
grub_efi_uint64_t length;
grub_efi_gcd_io_type_t gcd_io_type;
grub_efi_handle_t image_handle;
grub_efi_handle_t device_hande;
}
typedef grub_efi_gcd_io_space_descriptor grub_efi_gcd_io_space_descriptor_t;
struct grub_efi_dxe_services
{
grub_efi_table_header_t hdr;
grub_efi_status_t
(*add_memory_space) (grub_efi_gcd_memory_type_t gcd_memory_type,
grub_efi_physical_address_t base_address,
grub_efi_uint64_t length,
grub_efi_uint64_t capabilities);
grub_efi_status_t
(*allocate_memory_space) (grub_efi_gcd_allocate_type_t gcd_allocate_type,
grub_efi_gcd_memory_type_t gcd_memory_type,
grub_efi_uintn_t alignment,
grub_efi_uint64_t length,
grub_efi_physical_address_t *base_address,
grub_efi_handle_t image_handle,
grub_efi_handle_t device_handle);
grub_efi_status_t
(*free_memory_space) (grub_efi_physical_address_t base_address,
grub_efi_uint64_t length);
grub_efi_status_t
(*remove_memory_space) (grub_efi_physical_address_t base_address,
grub_efi_uint64_t length);
grub_efi_status_t
(*get_memory_space_descriptor) (grub_efi_physical_address_t base_address,
grub_efi_gcd_memory_space_descriptor_t *descriptor);
grub_efi_status_t
(*set_memory_space_attributes) (grub_efi_physical_address_t base_address,
grub_efi_uint64_t length,
grub_efi_uint64_t attributes);
grub_efi_status_t
(*get_memory_space_map) (grub_efi_uintn_t *number_of_descriptors,
grub_efi_gcd_memory_space_descriptor_t **memory_space_map);
grub_efi_status_t
(*add_io_space) (grub_efi_gcd_io_type_t gcd_io_type,
grub_efi_physical_address_t base_address,
grub_efi_uint64_t length);
grub_efi_status_t
(*allocate_io_space) (grub_efi_gcd_allocate_type_t gcd_allocate_type,
grub_efi_gcd_io_type_t gcd_io_type,
grub_efi_uintn_t alignment,
grub_efi_uint64_t length,
grub_efi_physical_address_t *base_address,
grub_efi_handle_t image_handle,
grub_efi_handle_t device_handle);
grub_efi_status_t
(*free_io_space) (grub_efi_physical_address_t base_address,
grub_efi_uint64_t length);
grub_efi_status_t
(*remove io_space) (grub_efi_physical_address_t base_address,
grub_efi_uint64_t length);
grub_efi_status_t
(*get_io_space_descriptor) (grub_efi_physical_address_t base_address,
grub_efi_gcd_io_space_descriptor_t *descriptor);
grub_efi_status_t
(*get_io_space_map) (grub_efi_uintn_t *number_of_descriptors,
grub_efi_gcd_io_space_descriptor_t **io_space_map);
grub_efi_status_t
(*dispatch) ();
grub_efi_status_t
(*schedule) (grub_efi_handle_t firmware_volume_handle,
grub_efi_guid_t *filename);
grub_efi_status_t
(*trust) (grub_efi_handle_t firmware_volume_handle,
grub_efi_guid_t *filename);
grub_efi_status_t
(*process_firmware_volume) (void *firmware_volume_header,
grub_efi_uintn_t size,
grub_efi_handle_t *firmware_volume_handle);
};
typedef struct grub_efi_dxe_services grub_efi_dxe_services_t;
#endif /* ! GRUB_EFI_DXE_HEADER */
/* firmware_volume.h - definitions of the firmware volume protocol */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007 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/>.
*/
/* The firmware volume bios protocol is not a part of the EFI spec,
but defined in Intel's Firmware Volume Specification. */
#ifndef GRUB_EFI_FIRMWARE_VOLUME_HEADER
#define GRUB_EFI_FIRMWARE_VOLUME_HEADER 1
#define GRUB_EFI_FIRMWARE_VOLUME_GUID \
{ 0x389f751f, 0x1838, 0x4388, \
{ 0x83, 0x90, 0xcd, 0x81, 0x54, 0xbd, 0x27, 0xf8 } \
}
#define GRUB_EFI_FV_FILETYPE_ALL 0
#define GRUB_EFI_FV_FILETYPE_RAW 1
#define GRUB_EFI_FV_FILETYPE_FREEFORM 2
#define GRUB_EFI_FV_FILETYPE_SECURITY_CORE 3
#define GRUB_EFI_FV_FILETYPE_PEI_CORE 4
#define GRUB_EFI_FV_FILETYPE_DXE_CORE 5
#define GRUB_EFI_FV_FILETYPE_PEIM 6
#define GRUB_EFI_FV_FILETYPE_DRIVER 7
#define GRUB_EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 8
#define GRUB_EFI_FV_FILETYPE_APPLICATION 9
#define GRUB_EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 11
typedef grub_uint64_t grub_efi_fv_attributes_t;
typedef grub_uint8_t grub_efi_fv_filetype_t;
typedef grub_uint32_t grub_efi_fv_file_attributes_t;
typedef grub_uint8_t grub_efi_section_type_t;
typedef grub_uint32_t grub_efi_fv_write_policy_t;
struct grub_efi_fv_write_file_data
{
grub_efi_guid_t *name_guid;
grub_efi_fv_filetype_t type;
grub_efi_fv_file_attributes_t file_attributes;
void *buffer;
grub_efi_uint32_t buffer_size;
};
typedef struct grub_efi_fv_write_file_data grub_efi_fv_write_file_data_t;
struct grub_efi_firmware_volume_protocol
{
grub_efi_status_t
(*get_volume_attributes) (struct grub_efi_firmware_volume_protocol *this,
grub_efi_fv_attributes_t *fvattributes);
grub_efi_status_t
(*set_volume_attributes) (struct grub_efi_firmware_volume_protocol *this,
grub_efi_fv_attributes_t *fvattributes);
grub_efi_status_t
(*read_file) (struct grub_efi_firmware_volume_protocol *this,
grub_efi_guid_t *name_guid,
void **buffer,
grub_efi_uintn_t *buffer_size,
grub_efi_fv_filetype_t *found_type,
grub_efi_fv_file_attributes_t *file_attributes,
grub_efi_uint32_t *authentication_status);
grub_efi_status_t
(*read_section) (struct grub_efi_firmware_volume_protocol *this,
grub_efi_guid_t *name_guid,
grub_efi_section_type_t section_type,
grub_efi_uintn_t section_instance,
void **buffer,
grub_efi_uintn_t *buffer_size,
grub_efi_uint32_t *authentication_status);
grub_efi_status_t
(*write_file) (struct grub_efi_firmware_volume_protocol *this,
grub_efi_uint32_t number_of_files,
grub_efi_fv_write_policy_t write_policy,
grub_efi_fv_write_file_data_t *file_data);
grub_efi_status_t
(*get_next_file) (struct grub_efi_firmware_volume_protocol *this,
void *key,
grub_efi_fv_filetype_t *file_type,
grub_efi_guid_t *name_guid,
grub_efi_fv_file_attributes_t *file_attributes,
grub_efi_uintn_t *size);
grub_efi_uint32_t key_size;
grub_efi_handle_t parent_handle;
};
typedef struct grub_efi_firmware_volume_protocol grub_efi_firmware_volume_protocol_t;
#endif /* ! GRUB_EFI_FIRMWARE_VOLUME_HEADER */
/* legacy_bios.h - definitions of the legacy bios protocol */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007 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/>.
*/
/* The legacy bios protocol is not a part of the EFI spec,
but defined in Intel's Compatibility Support Module Specification. */
#ifndef GRUB_EFI_LEGACY_BIOS_HEADER
#define GRUB_EFI_LEGACY_BIOS_HEADER 1
#define GRUB_EFI_LEGACY_BIOS_GUID \
{ 0xdb9a1e3d, 0x45cb, 0x4abb, \
{ 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \
}
#define GRUB_EFI_BBS_FLOPPY 0x1
#define GRUB_EFI_BBS_HARDDISK 0x2
#define GRUB_EFI_BBS_CDROM 0x3
#define GRUB_EFI_BBS_PCMCIA 0x4
#define GRUB_EFI_BBS_USB 0x5
#define GRUB_EFI_BBS_EMBED_NETWORK 0x6
#define GRUB_EFI_BBS_BEV_DEVICE 0x80
struct grub_efi_ia32_register_set
{
void *regs; /* FIXME: must define this structure following specification */
};
typedef struct grub_efi_ia32_register_set grub_efi_ia32_register_set_t;
struct grub_efi_atapi_identify
{
grub_uint16_t raw[256];
};
typedef struct grub_efi_atapi_identify grub_efi_atapi_identify_t;
struct grub_efi_hdd_info
{
grub_uint16_t status;
grub_uint32_t bus;
grub_uint32_t device;
grub_uint32_t function;
grub_uint16_t command_base_address;
grub_uint16_t control_base_address;
grub_uint16_t bus_master_address;
grub_uint8_t hdd_irq;
grub_efi_atapi_identify_t identify_drive[2];
};
typedef struct grub_efi_hdd_info grub_efi_hdd_info_t;
struct grub_efi_bbs_status_flags
{
grub_uint16_t old_position:4;
grub_uint16_t reserved1:4;
grub_uint16_t enabled:1;
grub_uint16_t failed:1;
grub_uint16_t media_present:2;
grub_uint16_t reserved2:4;
};
typedef struct grub_efi_bbs_status_flags grub_efi_bbs_status_flags_t;
struct grub_efi_bbs_table
{
grub_uint16_t boot_priority;
grub_uint32_t bus;
grub_uint32_t device;
grub_uint32_t function;
grub_uint8_t class;
grub_uint8_t sub_class;
grub_uint16_t mfg_string_offset;
grub_uint16_t mfg_string_segment;
grub_uint16_t device_type;
grub_efi_bbs_status_flags_t status_flags;
grub_uint16_t boot_handler_offset;
grub_uint16_t boot_handler_segment;
grub_uint16_t desc_string_offset;
grub_uint16_t desc_string_segment;
grub_uint32_t init_per_reserved;
grub_uint32_t additional_irq13_handler;
grub_uint32_t additional_irq18_handler;
grub_uint32_t additional_irq19_handler;
grub_uint32_t additional_irq40_handler;
grub_uint8_t assigned_drive_number;
grub_uint32_t additional_irq41_handler;
grub_uint32_t additional_irq46_handler;
grub_uint32_t ibv1;
grub_uint32_t ibv2;
};
typedef struct grub_efi_bbs_table grub_efi_bbs_table_t;
struct grub_efi_udc_attributes
{
grub_efi_uint8_t directory_service_validity:1;
grub_efi_uint8_t rabca_used_flag:1;
grub_efi_uint8_t execute_hdd_diagnostics_flag:1;
grub_efi_uint8_t reserved:5;
};
typedef struct grub_efi_udc_attributes grub_efi_udc_attributes_t;
struct grub_efi_legacy_bios_protocol
{
grub_efi_boolean_t
(*int86) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uint8_t bios_int,
grub_efi_ia32_register_set_t *regs);
grub_efi_boolean_t
(*far_call86) (struct grub_efi_legacy_bios_protocol *this,
grub_uint16_t segment,
grub_uint16_t offset,
grub_efi_ia32_register_set_t *regs,
void *stack,
grub_efi_uintn_t stack_size);
grub_efi_status_t
(*check_pci_rom) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_handle_t pci_handle,
void **rom_image,
grub_efi_uintn_t *rom_size,
grub_efi_uintn_t *flags);
grub_efi_status_t
(*install_pci_rom) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_handle_t pci_handle,
void **rom_image,
grub_efi_uintn_t *flags,
grub_efi_uint8_t *disk_start,
grub_efi_uint8_t *disk_end,
void **rom_shadow_address,
grub_efi_uint32_t *shadowed_rom_size);
grub_efi_status_t
(*legacy_boot) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_bios_device_path_t *boot_option,
grub_efi_uint32_t load_options_size,
void *load_options);
grub_efi_status_t
(*update_keyboard_led_status) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uint8_t leds);
grub_efi_status_t
(*get_bbs_info) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uint16_t *hdd_count,
grub_efi_hdd_info_t **hdd_info,
grub_efi_uint16_t *bbs_count,
grub_efi_bbs_table_t **bbs_table);
grub_efi_status_t
(*shadow_all_legacy_oproms) (struct grub_efi_legacy_bios_protocol *this);
grub_efi_status_t
(*prepare_to_boot_efi) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uint16_t *bbs_count,
grub_efi_bbs_table_t **bbs_table);
grub_efi_status_t
(*get_legacy_region) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uintn_t legacy_memory_size,
grub_efi_uintn_t region,
grub_efi_uintn_t alignment,
void **legacy_memory_address);
grub_efi_status_t
(*copy_legacy_region) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_uintn_t legacy_memory_size,
void *legacy_memory_address,
void *legacy_memory_source_address);
grub_efi_status_t
(*boot_unconventional_device) (struct grub_efi_legacy_bios_protocol *this,
grub_efi_udc_attributes_t attributes,
grub_efi_uintn_t bbs_entry,
void *beer_data,
void *service_area_data);
};
typedef struct grub_efi_legacy_bios_protocol grub_efi_legacy_bios_protocol_t;
#endif /* ! GRUB_EFI_LEGACY_BIOS_HEADER */
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel