From e763d7590f830dc59aaa0c9dab8d6a3c0867944f Mon Sep 17 00:00:00 2001 From: longpanda Date: Tue, 2 Nov 2021 23:23:39 +0800 Subject: [PATCH] Fix a bug when booting HDM17x64_17.20.0_ADV_Linux_Downloadly.ir.iso --- .../grub-2.04/grub-core/script/function.c | 113 ++++++++++++++++++ .../grub-2.04/grub-core/ventoy/ventoy_cmd.c | 92 +++++++++++--- .../grub-2.04/grub-core/ventoy/ventoy_def.h | 12 ++ INSTALL/grub/grub.cfg | 13 +- 4 files changed, 208 insertions(+), 22 deletions(-) create mode 100644 GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c new file mode 100644 index 00000000..fc10ac4f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c @@ -0,0 +1,113 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,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 + +grub_script_function_t grub_script_function_list; + +grub_script_function_t +grub_script_function_create (struct grub_script_arg *functionname_arg, + struct grub_script *cmd) +{ + grub_script_function_t func; + grub_script_function_t *p; + + func = (grub_script_function_t) grub_malloc (sizeof (*func)); + if (! func) + return 0; + + func->name = grub_strdup (functionname_arg->str); + if (! func->name) + { + grub_free (func); + return 0; + } + + func->func = cmd; + + /* Keep the list sorted for simplicity. */ + p = &grub_script_function_list; + while (*p) + { + if (grub_strcmp ((*p)->name, func->name) >= 0) + break; + + p = &((*p)->next); + } + + /* If the function already exists, overwrite the old function. */ + if (*p && grub_strcmp ((*p)->name, func->name) == 0) + { + grub_script_function_t q; + + q = *p; + grub_script_free (q->func); + q->func = cmd; + grub_free (func); + func = q; + } + else + { + func->next = *p; + *p = func; + } + + return func; +} + +void +grub_script_function_remove (const char *name) +{ + grub_script_function_t *p, q; + + for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next) + if (grub_strcmp (name, q->name) == 0) + { + *p = q->next; + grub_free (q->name); + grub_script_free (q->func); + grub_free (q); + break; + } +} + +grub_script_function_t +grub_script_function_find (char *functionname) +{ + grub_script_function_t func; + + for (func = grub_script_function_list; func; func = func->next) + if (grub_strcmp (functionname, func->name) == 0) + break; + + if (! func) + { + char tmp[64]; + grub_strncpy (tmp, functionname, 63); + tmp[63] = 0; + /* Avoid truncating inside UTF-8 character. */ + tmp[grub_getend (tmp, tmp + grub_strlen (tmp))] = 0; + grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("can't find command `%s'"), tmp); + } + + return func; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c index f2e62b63..0879585b 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -2701,6 +2701,22 @@ grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) return desc.sector; } +static grub_uint32_t ventoy_get_bios_eltorito_rba(grub_file_t file, grub_uint32_t sector) +{ + grub_uint8_t buf[512]; + + grub_file_seek(file, sector * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (buf[0] == 0x01 && buf[1] == 0x00 && + buf[30] == 0x55 && buf[31] == 0xaa && buf[32] == 0x88) + { + return *((grub_uint32_t *)(buf + 40)); + } + + return 0; +} + int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) { int i; @@ -5007,26 +5023,71 @@ static grub_err_t grub_cmd_gptpriority(grub_extcmd_context_t ctxt, int argc, cha } - -/* : Deleted by longpanda, 20210916 PN:XX LABEL:XX */ -#if 0 -void ventoy_tip_set_menu_label(const char *vid) +static grub_err_t grub_cmd_syslinux_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) { - img_info *node; + int ret = 1; + int joliet = 0; + grub_file_t file = NULL; + grub_uint32_t loadrba = 0; + grub_uint32_t boot_catlog = 0; + grub_uint8_t sector[512]; + boot_info_table *info = NULL; + + (void)ctxt; + (void)argc; - g_ventoy_tip_msg1 = g_ventoy_tip_msg2 = NULL; - if (vid) + /* This also trigger a iso9660 fs parse */ + if (ventoy_check_file_exist("(loop)/isolinux/isolinux.cfg")) { - node = (img_info *)(void *)grub_strtoul(vid + 4, NULL, 16); - if (node) - { - g_ventoy_tip_msg1 = node->tip1; - g_ventoy_tip_msg2 = node->tip2; - } + return 0; } + + joliet = grub_iso9660_is_joliet(); + if (joliet == 0) + { + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("failed to open %s\n", args[0]); + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog == 0) + { + debug("no bootcatlog found %u\n", boot_catlog); + goto out; + } + + loadrba = ventoy_get_bios_eltorito_rba(file, boot_catlog); + if (loadrba == 0) + { + debug("no bios eltorito rba found %u\n", loadrba); + goto out; + } + + grub_file_seek(file, loadrba * 2048); + grub_file_read(file, sector, 512); + + info = (boot_info_table *)sector; + if (info->bi_data0 == 0x7c6ceafa && + info->bi_data1 == 0x90900000 && + info->bi_PrimaryVolumeDescriptor == 16 && + info->bi_BootFileLocation == loadrba) + { + debug("bootloader is syslinux, %u.\n", loadrba); + ret = 0; + } + +out: + + grub_file_close(file); + grub_errno = GRUB_ERR_NONE; + return ret; } -#endif /* #if 0 */ -/* : Deleted by longpanda, 20210916 PN:XX LABEL:XX */ int ventoy_env_init(void) { @@ -5211,6 +5272,7 @@ static cmd_para ventoy_cmds[] = { "vt_check_json_path_case", ventoy_cmd_chk_json_pathcase, 0, NULL, "", "", NULL }, { "vt_append_extra_sector", ventoy_cmd_append_ext_sector, 0, NULL, "", "", NULL }, { "gptpriority", grub_cmd_gptpriority, 0, NULL, "", "", NULL }, + { "vt_syslinux_need_nojoliet", grub_cmd_syslinux_nojoliet, 0, NULL, "", "", NULL }, }; int ventoy_register_all_cmd(void) diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 9c41c889..2b722316 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -199,6 +199,18 @@ typedef struct ventoy_iso9660_vd grub_uint32_t space; }ventoy_iso9660_vd; +/* https://wiki.osdev.org/El-Torito */ +typedef struct boot_info_table +{ + grub_uint32_t bi_data0; + grub_uint32_t bi_data1; + grub_uint32_t bi_PrimaryVolumeDescriptor; + grub_uint32_t bi_BootFileLocation; + grub_uint32_t bi_BootFileLength; + grub_uint32_t bi_Checksum; + grub_uint8_t bi_Reserved[40]; +}boot_info_table; + #pragma pack() #define img_type_start 0 diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index c108d60a..370b42f7 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -1017,14 +1017,13 @@ function legacy_linux_menu_func { loopback loop "$1$2" fi - if [ -f (loop)/isolinux/isolinux.cfg ]; then - if vt_iso9660_isjoliet; then - vt_iso9660_nojoliet 1 - loopback -d loop - loopback loop "$1$2" - fi + + if vt_syslinux_need_nojoliet "$1$2"; then + vt_iso9660_nojoliet 1 + loopback -d loop + loopback loop "$1$2" fi - + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" vt_linux_clear_initrd