diff --git a/GRUB2/grub-2.04/grub-core/kern/efi/efi.c b/GRUB2/grub-2.04/grub-core/kern/efi/efi.c new file mode 100644 index 00000000..dc811577 --- /dev/null +++ b/GRUB2/grub-2.04/grub-core/kern/efi/efi.c @@ -0,0 +1,966 @@ +/* efi.c - generic EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID; +static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; +static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; + +void * +grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration) +{ + void *interface; + grub_efi_status_t status; + + status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol, + protocol, registration, &interface); + if (status != GRUB_EFI_SUCCESS) + return 0; + + 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 = efi_call_5 (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 = efi_call_5 (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 = efi_call_6 (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 (&console_control_guid, 0); + if (! c) + /* No console control protocol instance available, assume it is + already in text mode. */ + return 1; + + if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS) + return 0; + + new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS; + if (mode != new_mode) + if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS) + return 0; + + return 1; +} + +void +grub_efi_stall (grub_efi_uintn_t microseconds) +{ + efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds); +} + +grub_efi_loaded_image_t * +grub_efi_get_loaded_image (grub_efi_handle_t image_handle) +{ + return grub_efi_open_protocol (image_handle, + &loaded_image_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +void +grub_reboot (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); + for (;;) ; +} + +void +grub_exit (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + efi_call_4 (grub_efi_system_table->boot_services->exit, + grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); + for (;;) ; +} + +grub_err_t +grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_efi_runtime_services_t *r; + grub_efi_status_t status; + + r = grub_efi_system_table->runtime_services; + status = efi_call_4 (r->set_virtual_address_map, memory_map_size, + descriptor_size, descriptor_version, virtual_map); + + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); +} + +grub_err_t +grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, + void *data, grub_size_t datasize) +{ + grub_efi_status_t status; + grub_efi_runtime_services_t *r; + grub_efi_char16_t *var16; + grub_size_t len, len16; + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; + var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + if (!var16) + return grub_errno; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); + var16[len16] = 0; + + r = grub_efi_system_table->runtime_services; + + status = efi_call_5 (r->set_variable, var16, guid, + (GRUB_EFI_VARIABLE_NON_VOLATILE + | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS + | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), + datasize, data); + grub_free (var16); + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); +} + +void * +grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, + grub_size_t *datasize_out) +{ + grub_efi_status_t status; + grub_efi_uintn_t datasize = 0; + grub_efi_runtime_services_t *r; + grub_efi_char16_t *var16; + void *data; + grub_size_t len, len16; + + *datasize_out = 0; + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; + var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + if (!var16) + return NULL; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); + var16[len16] = 0; + + r = grub_efi_system_table->runtime_services; + + status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL); + + if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize) + { + grub_free (var16); + return NULL; + } + + data = grub_malloc (datasize); + if (!data) + { + grub_free (var16); + return NULL; + } + + status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data); + grub_free (var16); + + if (status == GRUB_EFI_SUCCESS) + { + *datasize_out = datasize; + return data; + } + + grub_free (data); + return NULL; +} + +#pragma GCC diagnostic ignored "-Wcast-align" + +/* Search the mods section from the PE32/PE32+ image. This code uses + a PE32 header, but should work with PE32+ as well. */ +grub_addr_t +grub_efi_modules_addr (void) +{ + grub_efi_loaded_image_t *image; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *coff_header; + struct grub_pe32_section_table *sections; + struct grub_pe32_section_table *section; + struct grub_module_info *info; + grub_uint16_t i; + + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (! image) + return 0; + + header = image->image_base; + coff_header = &(header->coff_header); + sections + = (struct grub_pe32_section_table *) ((char *) coff_header + + sizeof (*coff_header) + + coff_header->optional_header_size); + + for (i = 0, section = sections; + i < coff_header->num_sections; + i++, section++) + { + if (grub_strcmp (section->name, "mods") == 0) + break; + } + + if (i == coff_header->num_sections) + return 0; + + info = (struct grub_module_info *) ((char *) image->image_base + + section->virtual_address); + if (info->magic != GRUB_MODULE_MAGIC) + return 0; + + return (grub_addr_t) info; +} + +#pragma GCC diagnostic error "-Wcast-align" + +char * +grub_efi_get_filename (grub_efi_device_path_t *dp0) +{ + char *name = 0, *p, *pi; + grub_size_t filesize = 0; + grub_efi_device_path_t *dp; + + if (!dp0) + return NULL; + + dp = dp0; + + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + + if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) + break; + if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) + { + grub_efi_uint16_t len; + len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) + / sizeof (grub_efi_char16_t)); + filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2; + } + + dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); + } + + if (!filesize) + return NULL; + + dp = dp0; + + p = name = grub_malloc (filesize); + if (!name) + return NULL; + + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + + if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) + break; + else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) + { + grub_efi_file_path_device_path_t *fp; + grub_efi_uint16_t len; + grub_efi_char16_t *dup_name; + + *p++ = '/'; + + len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) + / sizeof (grub_efi_char16_t)); + fp = (grub_efi_file_path_device_path_t *) dp; + /* According to EFI spec Path Name is NULL terminated */ + while (len > 0 && fp->path_name[len - 1] == 0) + len--; + + dup_name = grub_malloc (len * sizeof (*dup_name)); + if (!dup_name) + { + grub_free (name); + return NULL; + } + p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, + grub_memcpy (dup_name, fp->path_name, len * sizeof (*dup_name)), + len); + grub_free (dup_name); + } + + dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); + } + + *p = '\0'; + + for (pi = name, p = name; *pi;) + { + /* EFI breaks paths with backslashes. */ + if (*pi == '\\' || *pi == '/') + { + *p++ = '/'; + while (*pi == '\\' || *pi == '/') + pi++; + continue; + } + *p++ = *pi++; + } + *p = '\0'; + + return name; +} + +grub_efi_device_path_t * +grub_efi_get_device_path (grub_efi_handle_t handle) +{ + return grub_efi_open_protocol (handle, &device_path_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +/* Return the device path node right before the end node. */ +grub_efi_device_path_t * +grub_efi_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; +} + +/* Duplicate a device path. */ +grub_efi_device_path_t * +grub_efi_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; +} + +static void +dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) +{ + grub_uint32_t vendor_data_len = vendor->header.length - sizeof (*vendor); + grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ", + type, + (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], + vendor_data_len); + if (vendor->header.length > sizeof (*vendor)) + { + grub_uint32_t i; + for (i = 0; i < vendor_data_len; i++) + grub_printf ("%02x ", vendor->vendor_defined_data[i]); + } + grub_printf ("]"); +} + + +/* Print the chain of Device Path nodes. This is mainly for debugging. */ +void +grub_efi_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_efi_pci_device_path_t *) dp; + 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_efi_pccard_device_path_t *) dp; + 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_efi_memory_mapped_device_path_t *) dp; + grub_printf ("/MMap(%x,%llx,%llx)", + (unsigned) mmapped->memory_type, + (unsigned long long) mmapped->start_address, + (unsigned long long) mmapped->end_address); + } + break; + case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Hardware", + (grub_efi_vendor_device_path_t *) dp); + break; + case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE: + { + grub_efi_controller_device_path_t *controller + = (grub_efi_controller_device_path_t *) dp; + 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_efi_acpi_device_path_t *) dp; + 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_efi_expanded_acpi_device_path_t *) dp; + 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_efi_atapi_device_path_t *) dp; + 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_efi_scsi_device_path_t *) dp; + 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_efi_fibre_channel_device_path_t *) dp; + grub_printf ("/FibreChannel(%llx,%llx)", + (unsigned long long) fc->wwn, + (unsigned long long) fc->lun); + } + break; + case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE: + { + grub_efi_1394_device_path_t *firewire + = (grub_efi_1394_device_path_t *) dp; + grub_printf ("/1394(%llx)", + (unsigned long long) firewire->guid); + } + break; + case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_device_path_t *usb + = (grub_efi_usb_device_path_t *) dp; + grub_printf ("/USB(%x,%x)", + (unsigned) usb->parent_port_number, + (unsigned) usb->usb_interface); + } + break; + case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_class_device_path_t *usb_class + = (grub_efi_usb_class_device_path_t *) dp; + 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_efi_i2o_device_path_t *) dp; + 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_efi_mac_address_device_path_t *) dp; + 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_efi_ipv4_device_path_t *) dp; + 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_efi_ipv6_device_path_t *) dp; + 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_efi_infiniband_device_path_t *) dp; + grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)", + (unsigned) ib->port_gid[0], /* XXX */ + (unsigned long long) ib->remote_id, + (unsigned long long) ib->target_port_id, + (unsigned long long) ib->device_id); + } + break; + case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE: + { + grub_efi_uart_device_path_t *uart + = (grub_efi_uart_device_path_t *) dp; + grub_printf ("/UART(%llu,%u,%x,%x)", + (unsigned long long) uart->baud_rate, + uart->data_bits, + uart->parity, + uart->stop_bits); + } + break; + case GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE: + { + grub_efi_sata_device_path_t *sata; + sata = (grub_efi_sata_device_path_t *) dp; + grub_printf ("/Sata(%x,%x,%x)", + sata->hba_port, + sata->multiplier_port, + sata->lun); + } + break; + + case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Messaging", + (grub_efi_vendor_device_path_t *) dp); + 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_efi_hard_drive_device_path_t *) dp; + grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)", + hd->partition_number, + (unsigned long long) hd->partition_start, + (unsigned long long) 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->partmap_type, + (unsigned) hd->signature_type); + } + break; + case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: + { + grub_efi_cdrom_device_path_t *cd + = (grub_efi_cdrom_device_path_t *) dp; + grub_printf ("/CD(%u,%llx,%llx)", + cd->boot_entry, + (unsigned long long) cd->partition_start, + (unsigned long long) cd->partition_size); + } + break; + case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Media", + (grub_efi_vendor_device_path_t *) dp); + break; + case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE: + { + grub_efi_file_path_device_path_t *fp; + grub_uint8_t *buf; + fp = (grub_efi_file_path_device_path_t *) dp; + buf = grub_malloc ((len - 4) * 2 + 1); + if (buf) + { + grub_efi_char16_t *dup_name = grub_malloc (len - 4); + if (!dup_name) + { + grub_errno = GRUB_ERR_NONE; + grub_printf ("/File((null))"); + grub_free (buf); + break; + } + *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, fp->path_name, len - 4), + (len - 4) / sizeof (grub_efi_char16_t)) + = '\0'; + grub_free (dup_name); + } + else + grub_errno = GRUB_ERR_NONE; + grub_printf ("/File(%s)", buf); + grub_free (buf); + } + break; + case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE: + { + grub_efi_protocol_device_path_t *proto + = (grub_efi_protocol_device_path_t *) dp; + 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_efi_bios_device_path_t *) dp; + 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); + } +} + +/* Compare device paths. */ +int +grub_efi_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; +} + +void * grub_efi_allocate_iso_buf(grub_uint64_t size) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + return NULL; + } + + return (void *)(unsigned long)address; +} diff --git a/GRUB2/grub-2.04/include/grub/efi/efi.h b/GRUB2/grub-2.04/include/grub/efi/efi.h new file mode 100644 index 00000000..263359db --- /dev/null +++ b/GRUB2/grub-2.04/include/grub/efi/efi.h @@ -0,0 +1,124 @@ +/* efi.h - declare variables and functions for EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 . + */ + +#ifndef GRUB_EFI_EFI_HEADER +#define GRUB_EFI_EFI_HEADER 1 + +#include +#include +#include + +/* 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_stall) (grub_efi_uintn_t microseconds); +void * +EXPORT_FUNC(grub_efi_allocate_pages_real) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype); +void * +EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +void * +EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); +void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); +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); +void grub_efi_memory_fini (void); +grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); +void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); +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); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp); +grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *efi_desc_size, + grub_efi_uint32_t *efi_desc_version); +grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); +void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable, + const grub_efi_guid_t *guid, + grub_size_t *datasize_out); +grub_err_t +EXPORT_FUNC (grub_efi_set_variable) (const char *var, + const grub_efi_guid_t *guid, + void *data, + grub_size_t datasize); +int +EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2); + +void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size); + + +extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, + char **device, + char **path); + +#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) +void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); +grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); +#include +grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); +grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, + char *args); +#endif + +grub_addr_t grub_efi_modules_addr (void); + +void grub_efi_mm_init (void); +void grub_efi_mm_fini (void); +void grub_efi_init (void); +void grub_efi_fini (void); +void grub_efi_set_prefix (void); + +/* Variables. */ +extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); +extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); + +extern int EXPORT_VAR(grub_efi_is_finished); + +struct grub_net_card; + +grub_efi_handle_t +grub_efinet_get_device_handle (struct grub_net_card *card); + +#endif /* ! GRUB_EFI_EFI_HEADER */ diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh index 997e8360..05b9487b 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh @@ -19,38 +19,69 @@ . $VTOY_PATH/hook/ventoy-os-lib.sh -DISTRO='default' - -if [ -d /KNOPPIX ]; then - DISTRO='knoppix' -elif [ -e /etc/initrd-release ]; then - if $EGREP -q "ID=.*antix|ID=.*mx" /etc/initrd-release; then - DISTRO='antix' - fi -fi - -if [ -e /init ]; then - if $GREP -q PUPPYSFS /init; then - if $GREP -q VEKETSFS /init; then - DISTRO='veket' - else - DISTRO='puppy' +ventoy_get_debian_distro() { + if [ -d /KNOPPIX ]; then + echo 'knoppix'; return + elif [ -e /etc/initrd-release ]; then + if $EGREP -q "ID=.*antix|ID=.*mx" /etc/initrd-release; then + echo 'antix'; return + fi + fi + + if [ -e /init ]; then + if $GREP -q PUPPYSFS /init; then + if $GREP -q VEKETSFS /init; then + echo 'veket'; return + else + echo 'puppy'; return + fi fi fi -fi -if [ -e /etc/os-release ]; then - if $GREP -q 'Tails' /etc/os-release; then - DISTRO='tails' + if [ -e /etc/os-release ]; then + if $GREP -q 'Tails' /etc/os-release; then + echo 'tails'; return + fi fi -fi -if [ "$DISTRO"="default" ]; then if $GREP -q 'slax/' /proc/cmdline; then - DISTRO='slax' + echo 'slax'; return + fi + + if $GREP -q 'PVE ' /proc/version; then + echo 'pve'; return + fi + + if $GREP -q '[Dd]eepin' /proc/version; then + echo 'deepin'; return fi -fi + + if $GREP -q '[Uu][Oo][Ss] ' /proc/version; then + echo 'deepin'; return + fi + + if [ -d /porteus ]; then + echo 'porteus'; return + fi + + if $GREP -q 'porteus' /proc/version; then + echo 'porteus'; return + fi + + echo 'default' +} +DISTRO=$(ventoy_get_debian_distro) echo "##### distribution = $DISTRO ######" >> $VTLOG . $VTOY_PATH/hook/debian/${DISTRO}-hook.sh + + + + + + + + + + diff --git a/IMG/cpio/ventoy/init b/IMG/cpio/ventoy/init index fa3f6843..d1c331fb 100644 --- a/IMG/cpio/ventoy/init +++ b/IMG/cpio/ventoy/init @@ -67,6 +67,12 @@ ventoy_unpack_initramfs() { vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4 echo "=====ventoy_unpack_initramfs: #$*#" >> $VTLOG + #special process + #if [ "${vtmagic:0:4}" = '5678' ]; then + # echo -en '\x1F\x8B' | dd status=none of=$vtfile bs=1 count=2 conv=notrunc + # vtmagic='1F8B' + #fi + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then echo "vtx=$vtx" >> $VTLOG @@ -100,12 +106,19 @@ export EXTRACT_UNSAFE_SYMLINKS=1 # special process need_xzminidec() { - testmagic=$(hexdump -n 2 -e '2/1 "%02X"' /initrd001) + if [ -e /initrd001 ]; then + testmagic=$(hexdump -n 2 -e '2/1 "%02X"' /initrd001) + else + testmagic='xxxx' + fi + if [ "FD37" = "${testmagic:0:4}" ]; then if echo $vtkerver | grep -q 'kaspersky'; then true elif echo $vtkerver | grep -q 'kiosk.*Gentoo'; then true + elif echo $vtkerver | grep -q 'porteus '; then + true else false fi diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy.sh index 6da1e7d0..727102a2 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy.sh @@ -148,6 +148,13 @@ ventoy_get_os_type() { fi fi + if $EGREP -q 'ALT ' /proc/version; then + echo 'alt'; return + fi + + if $EGREP -q 'porteus' /proc/version; then + echo 'debian'; return + fi echo "default" } diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 92657044..3c939c26 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -74,6 +74,9 @@ function distro_specify_initrd_file { vt_linux_specify_initrd_file /pmagic/initrd.img elif [ -e (loop)/boot/initrd.xz ]; then vt_linux_specify_initrd_file /boot/initrd.xz + elif [ -f (loop)/boot/initrd ]; then + vt_linux_specify_initrd_file /boot/initrd + fi } @@ -127,6 +130,11 @@ function uefi_linux_menu_func { vt_linux_parse_initrd_grub dir (loop)/boot/grub/ fi + if [ -e (loop)/syslinux/alt0/full.cz ]; then + set LoadIsoEfiDriver=on + set FirstTryBootFile='@EFI@BOOT@grubx64.efi' + fi + distro_specify_initrd_file locate_initrd @@ -136,7 +144,7 @@ function uefi_linux_menu_func { if [ -n "$vtoy_chain_mem_addr" ]; then terminal_output console - chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else echo "chain empty failed" @@ -209,7 +217,6 @@ function uefi_iso_memdisk { - function legacy_windows_menu_func { vt_windows_reset @@ -348,7 +355,7 @@ function legacy_iso_memdisk { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.05" +set VENTOY_VERSION="1.0.06" #disable timeout unset timeout diff --git a/INSTALL/ventoy/ipxe.krn b/INSTALL/ventoy/ipxe.krn index 4b0514d7..b55f455c 100644 Binary files a/INSTALL/ventoy/ipxe.krn and b/INSTALL/ventoy/ipxe.krn differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index b94fd473..cfc127bb 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi index c508090c..a8bf53e5 100644 Binary files a/INSTALL/ventoy/ventoy_x64.efi and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/IPXE/ipxe-3fe683e/src/include/ventoy.h b/IPXE/ipxe-3fe683e/src/include/ventoy.h index 07b8d3c7..81be2d75 100644 --- a/IPXE/ipxe-3fe683e/src/include/ventoy.h +++ b/IPXE/ipxe-3fe683e/src/include/ventoy.h @@ -163,6 +163,7 @@ typedef struct ventoy_sector_flag #define VENTOY_BIOS_FAKE_DRIVE 0xFE +extern int g_debug; extern char *g_cmdline_copy; extern void *g_initrd_addr; extern size_t g_initrd_len; @@ -208,6 +209,17 @@ struct smbios3_entry { } __attribute__ (( packed )); +typedef struct isolinux_boot_info +{ + uint32_t isolinux0; + uint32_t isolinux1; + uint32_t PvdLocation; + uint32_t BootFileLocation; + uint32_t BootFileLen; + uint32_t BootFileChecksum; + uint8_t Reserved[40]; +}isolinux_boot_info; + //#undef DBGLVL //#define DBGLVL 7 diff --git a/VtoyTool/vtoydump.c b/VtoyTool/vtoydump.c index 003fd1ae..c393ee24 100644 --- a/VtoyTool/vtoydump.c +++ b/VtoyTool/vtoydump.c @@ -389,6 +389,11 @@ static int vtoy_print_os_param(ventoy_os_param *param, char *diskname) { cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname); } + else if (cnt == 0) + { + cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname); + debug("find 0 disk by size, try with guid cnt=%d...\n", cnt); + } if (param->vtoy_disk_part_type == 0) { diff --git a/VtoyTool/vtoytool/00/vtoytool_32 b/VtoyTool/vtoytool/00/vtoytool_32 index ebc99f80..098b4527 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_64 b/VtoyTool/vtoytool/00/vtoytool_64 index 8b89d0d1..1f9ec62e 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ