live cd
fix bug
This commit is contained in:
longpanda
2020-09-12 02:46:44 +08:00
parent a29bdfbc3c
commit a287bf8907
21 changed files with 871 additions and 33 deletions

View File

@@ -1591,6 +1591,7 @@ module = {
common = ventoy/ventoy_linux.c;
common = ventoy/ventoy_unix.c;
common = ventoy/ventoy_windows.c;
common = ventoy/ventoy_vhd.c;
common = ventoy/ventoy_plugin.c;
common = ventoy/ventoy_json.c;
common = ventoy/lzx.c;

View File

@@ -40,6 +40,7 @@
#endif
#include <grub/time.h>
#include <grub/relocator.h>
#include <grub/charset.h>
#include <grub/ventoy.h>
#include "ventoy_def.h"
@@ -87,6 +88,8 @@ int g_wimboot_enable = 0;
ventoy_img_chunk_list g_wimiso_chunk_list;
char *g_wimiso_path = NULL;
int g_vhdboot_enable = 0;
static char *g_tree_script_buf = NULL;
static int g_tree_script_pos = 0;
@@ -98,12 +101,12 @@ static int g_part_list_pos = 0;
static const char *g_menu_class[] =
{
"vtoyiso", "vtoywim", "vtoyefi", "vtoyimg"
"vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd"
};
static const char *g_menu_prefix[] =
{
"iso", "wim", "efi", "img"
"iso", "wim", "efi", "img", "vhd"
};
void ventoy_debug(const char *fmt, ...)
@@ -115,6 +118,23 @@ void ventoy_debug(const char *fmt, ...)
va_end (args);
}
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid)
{
int i;
if (!g_ventoy_debug)
{
return;
}
debug("%s", prefix);
for (i = 0; i < 16; i++)
{
grub_printf("%02x ", guid[i]);
}
grub_printf("\n");
}
int ventoy_is_efi_os(void)
{
if (g_efi_os > 1)
@@ -1031,6 +1051,11 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
{
type = img_type_wim;
}
else if (g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") ||
0 == grub_strcasecmp(filename + len - 5, ".vhdx")))
{
type = img_type_vhd;
}
#ifdef GRUB_MACHINE_EFI
else if (0 == grub_strcasecmp(filename + len - 4, ".efi"))
{
@@ -1039,9 +1064,13 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
#endif
else if (0 == grub_strcasecmp(filename + len - 4, ".img"))
{
if (len == 18 && grub_strncmp(filename, "ventoy_wimboot", 14) == 0)
if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0)
{
return 0;
if (grub_strncmp(filename + 7, "wimboot", 7) == 0 ||
grub_strncmp(filename + 7, "vhdboot", 7) == 0)
{
return 0;
}
}
type = img_type_img;
}
@@ -1122,6 +1151,14 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
}
img->menu_prefix = g_menu_prefix[type];
if (img_type_iso == type)
{
if (ventoy_plugin_check_memdisk(img->path))
{
img->menu_prefix = "miso";
}
}
debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count);
}
}
@@ -1333,6 +1370,93 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
return 0;
}
int ventoy_check_device_result(int ret)
{
char buf[32];
grub_snprintf(buf, sizeof(buf), "%d", ret);
ventoy_set_env("VTOY_CHKDEV_RESULT_STRING", buf);
if (ret)
{
grub_printf(VTOY_WARNING"\n");
grub_printf(VTOY_WARNING"\n");
grub_printf(VTOY_WARNING"\n\n\n");
grub_printf("This is NOT a standard Ventoy device and is NOT officially supported.\n\n");
grub_printf("Recommend to follow the instructions in https://www.ventoy.net to use Ventoy.\n");
grub_printf("\n\nWill continue to boot after 10 seconds ...... ");
grub_refresh();
grub_sleep(10);
}
return ret;
}
int ventoy_check_device(grub_device_t dev)
{
grub_file_t file;
grub_uint64_t offset;
char devname[64];
grub_fs_t fs;
grub_device_t dev2;
char *label = NULL;
struct grub_partition *partition;
if (dev->disk == NULL || dev->disk->partition == NULL)
{
return ventoy_check_device_result(1);
}
partition = dev->disk->partition;
if (partition->number != 0 || partition->start != 2048)
{
return ventoy_check_device_result(2);
}
offset = partition->start + partition->len;
/* We must have partition 2 */
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name);
if (!file)
{
return ventoy_check_device_result(3);
}
partition = file->device->disk->partition;
if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start))
{
grub_file_close(file);
return ventoy_check_device_result(4);
}
grub_file_close(file);
grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name);
dev2 = grub_device_open(devname);
if (!dev2)
{
return ventoy_check_device_result(5);
}
fs = grub_fs_probe(dev2);
if (!fs)
{
grub_device_close(dev2);
return ventoy_check_device_result(6);
}
fs->fs_label(dev2, &label);
if ((!label) || grub_strncmp("VTOYEFI", label, 7))
{
grub_device_close(dev2);
return ventoy_check_device_result(7);
}
grub_device_close(dev2);
return ventoy_check_device_result(0);
}
static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
{
int len;
@@ -1379,6 +1503,9 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
goto fail;
}
/* make sure that we are running in a correct Ventoy device */
ventoy_check_device(dev);
g_enum_fs = fs = grub_fs_probe(dev);
if (!fs)
{
@@ -1392,6 +1519,8 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
goto fail;
}
ventoy_set_env("vtoy_iso_fs", fs->name);
strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE");
if (strdata && strdata[0] == '1')
{
@@ -3125,6 +3254,8 @@ static cmd_para ventoy_cmds[] =
{ "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL },
{ "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL },
{ "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL },
{ "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL },
{ "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL },
{ "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL },
{ "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },

View File

@@ -29,6 +29,7 @@
#define VTOY_SIZE_1GB 1073741824
#define VTOY_SIZE_512KB (512 * 1024)
#define VTOY_SIZE_1KB 1024
#define JSON_SUCCESS 0
#define JSON_FAILED 1
@@ -48,6 +49,8 @@
#define ventoy_get_env(key) ventoy_env_op1(get, key)
#define ventoy_set_env(key, val) ventoy_env_op2(set, key, val)
#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
typedef struct ventoy_initrd_ctx
{
const char *path_prefix;
@@ -99,6 +102,18 @@ typedef int (*grub_char_check_func)(int c);
#define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit)
#pragma pack(1)
typedef struct ventoy_patch_vhd
{
grub_uint8_t part_offset_or_guid[16];
grub_uint32_t reserved1;
grub_uint32_t part_type;
grub_uint8_t disk_signature_or_guid[16];
grub_uint8_t reserved2[16];
grub_uint8_t vhd_file_path[1];
}ventoy_patch_vhd;
#pragma pack()
// El Torito Boot Record Volume Descriptor
#pragma pack(1)
typedef struct eltorito_descriptor
@@ -141,6 +156,7 @@ typedef struct ventoy_iso9660_vd
#define img_type_wim 1
#define img_type_efi 2
#define img_type_img 3
#define img_type_vhd 4
typedef struct img_info
{
@@ -604,6 +620,42 @@ typedef struct ventoy_mbr_head
grub_uint8_t Byte55;
grub_uint8_t ByteAA;
}ventoy_mbr_head;
typedef struct ventoy_gpt_head
{
char Signature[8]; /* EFI PART */
grub_uint8_t Version[4];
grub_uint32_t Length;
grub_uint32_t Crc;
grub_uint8_t Reserved1[4];
grub_uint64_t EfiStartLBA;
grub_uint64_t EfiBackupLBA;
grub_uint64_t PartAreaStartLBA;
grub_uint64_t PartAreaEndLBA;
grub_uint8_t DiskGuid[16];
grub_uint64_t PartTblStartLBA;
grub_uint32_t PartTblTotNum;
grub_uint32_t PartTblEntryLen;
grub_uint32_t PartTblCrc;
grub_uint8_t Reserved2[420];
}ventoy_gpt_head;
typedef struct ventoy_gpt_part_tbl
{
grub_uint8_t PartType[16];
grub_uint8_t PartGuid[16];
grub_uint64_t StartLBA;
grub_uint64_t LastLBA;
grub_uint64_t Attr;
grub_uint16_t Name[36];
}ventoy_gpt_part_tbl;
typedef struct ventoy_gpt_info
{
ventoy_mbr_head MBR;
ventoy_gpt_head Head;
ventoy_gpt_part_tbl PartTbl[128];
}ventoy_gpt_info;
#pragma pack()
typedef struct file_fullpath
@@ -672,6 +724,14 @@ typedef struct injection_config
struct injection_config *next;
}injection_config;
typedef struct auto_memdisk
{
int pathlen;
char isopath[256];
struct auto_memdisk *next;
}auto_memdisk;
extern int g_ventoy_menu_esc;
extern int g_ventoy_suppress_esc;
extern int g_ventoy_last_entry;
@@ -680,6 +740,7 @@ extern int g_ventoy_iso_raw;
extern int g_ventoy_iso_uefi_drv;
extern int g_ventoy_case_insensitive;
extern grub_uint8_t g_ventoy_chain_type;
extern int g_vhdboot_enable;
#define ventoy_unix_fill_virt(new_data, new_len) \
@@ -711,6 +772,7 @@ int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, vento
const char * ventoy_plugin_get_injection(const char *isopath);
const char * ventoy_plugin_get_menu_alias(int type, const char *isopath);
const char * ventoy_plugin_get_menu_class(int type, const char *name);
int ventoy_plugin_check_memdisk(const char *isopath);
int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
void ventoy_plugin_dump_persistence(void);
@@ -726,6 +788,11 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch
grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args);
int ventoy_check_device_result(int ret);
int ventoy_check_device(grub_device_t dev);
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid);
grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
#endif /* __VENTOY_DEF_H__ */

View File

@@ -45,6 +45,7 @@ static persistence_config *g_persistence_head = NULL;
static menu_alias *g_menu_alias_head = NULL;
static menu_class *g_menu_class_head = NULL;
static injection_config *g_injection_head = NULL;
static auto_memdisk *g_auto_memdisk_head = NULL;
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
{
@@ -1010,6 +1011,83 @@ static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk)
return 0;
}
static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
{
VTOY_JSON *pNode = NULL;
auto_memdisk *node = NULL;
auto_memdisk *next = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY)
{
debug("Not array %d\n", json->enDataType);
return 0;
}
if (g_auto_memdisk_head)
{
for (node = g_auto_memdisk_head; node; node = next)
{
next = node->next;
grub_free(node);
}
g_auto_memdisk_head = NULL;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType == JSON_TYPE_STRING)
{
node = grub_zalloc(sizeof(auto_memdisk));
if (node)
{
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
if (g_auto_memdisk_head)
{
node->next = g_auto_memdisk_head;
}
g_auto_memdisk_head = node;
}
}
}
return 0;
}
static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk)
{
VTOY_JSON *pNode = NULL;
if (json->enDataType != JSON_TYPE_ARRAY)
{
grub_printf("Not array %d\n", json->enDataType);
return 1;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType == JSON_TYPE_STRING)
{
grub_printf("<%s> ", pNode->unData.pcStrVal);
if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
{
grub_printf(" [OK]\n");
}
else
{
grub_printf(" [NOT EXIST]\n");
}
}
}
return 0;
}
static plugin_entry g_plugin_entries[] =
{
{ "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
@@ -1019,6 +1097,7 @@ static plugin_entry g_plugin_entries[] =
{ "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
{ "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check },
{ "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
{ "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check },
};
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
@@ -1163,9 +1242,15 @@ void ventoy_plugin_dump_persistence(void)
install_template * ventoy_plugin_find_install_template(const char *isopath)
{
int len;
install_template *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_install_template_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_install_template_head; node; node = node->next)
{
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
@@ -1197,9 +1282,15 @@ char * ventoy_plugin_get_cur_install_template(const char *isopath)
persistence_config * ventoy_plugin_find_persistent(const char *isopath)
{
int len;
persistence_config *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_persistence_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_persistence_head; node; node = node->next)
{
if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0))
@@ -1272,9 +1363,15 @@ end:
const char * ventoy_plugin_get_injection(const char *isopath)
{
int len;
injection_config *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_injection_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_injection_head; node; node = node->next)
{
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
@@ -1288,9 +1385,15 @@ const char * ventoy_plugin_get_injection(const char *isopath)
const char * ventoy_plugin_get_menu_alias(int type, const char *isopath)
{
int len;
menu_alias *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_menu_alias_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_menu_alias_head; node; node = node->next)
{
if (node->type == type && node->pathlen &&
@@ -1305,9 +1408,16 @@ const char * ventoy_plugin_get_menu_alias(int type, const char *isopath)
const char * ventoy_plugin_get_menu_class(int type, const char *name)
{
int len;
menu_class *node = NULL;
int len = (int)grub_strlen(name);
if (!g_menu_class_head)
{
return NULL;
}
len = (int)grub_strlen(name);
if (vtoy_class_image_file == type)
{
for (node = g_menu_class_head; node; node = node->next)
@@ -1332,6 +1442,28 @@ const char * ventoy_plugin_get_menu_class(int type, const char *name)
return NULL;
}
int ventoy_plugin_check_memdisk(const char *isopath)
{
int len;
auto_memdisk *node = NULL;
if (!g_auto_memdisk_head)
{
return 0;
}
len = (int)grub_strlen(isopath);
for (node = g_auto_memdisk_head; node; node = node->next)
{
if (node->pathlen == len && grub_strncmp(isopath, node->isopath, len) == 0)
{
return 1;
}
}
return 0;
}
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;

View File

@@ -0,0 +1,304 @@
/******************************************************************************
* ventoy_vhd.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* 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 the Free Software Foundation; either version 3 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 this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/device.h>
#include <grub/term.h>
#include <grub/partition.h>
#include <grub/file.h>
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/datetime.h>
#include <grub/i18n.h>
#include <grub/net.h>
#include <grub/time.h>
#include <grub/crypto.h>
#include <grub/charset.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#endif
#include <grub/ventoy.h>
#include "ventoy_def.h"
GRUB_MOD_LICENSE ("GPLv3+");
static int g_vhdboot_bcd_offset = 0;
static int g_vhdboot_bcd_len = 0;
static int g_vhdboot_isolen = 0;
static char *g_vhdboot_totbuf = NULL;
static char *g_vhdboot_isobuf = NULL;
static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen)
{
grub_uint32_t offset;
grub_file_t file;
char cmdbuf[128];
grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback vhdiso mem:0x%lx:size:%d", (ulong)g_vhdboot_isobuf, g_vhdboot_isolen);
grub_script_execute_sourcecode(cmdbuf);
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(vhdiso)/boot/bcd");
if (!file)
{
grub_printf("Failed to open bcd file in the image file\n");
return 1;
}
grub_file_read(file, &offset, 4);
offset = (grub_uint32_t)grub_iso9660_get_last_read_pos(file);
*bcdoffset = (int)offset;
*bcdlen = (int)file->size;
debug("vhdiso bcd file offset:%d len:%d\n", *bcdoffset, *bcdlen);
grub_file_close(file);
grub_script_execute_sourcecode("loopback -d vhdiso");
return 0;
}
static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2)
{
int i;
int cnt = 0;
char *pos;
grub_size_t pathlen;
const char *plat;
grub_uint16_t *unicode_path;
const grub_uint8_t winloadexe[] =
{
0x77, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2E, 0x00,
0x65, 0x00, 0x78, 0x00, 0x65, 0x00
};
pathlen = sizeof(grub_uint16_t) * (grub_strlen(vhdpath) + 1);
debug("unicode path for <%s> len:%d\n", vhdpath, (int)pathlen);
unicode_path = grub_zalloc(pathlen);
if (!unicode_path)
{
return 0;
}
plat = grub_env_get("grub_platform");
if (plat && (plat[0] == 'e')) /* UEFI */
{
pos = g_vhdboot_isobuf + g_vhdboot_bcd_offset;
/* winload.exe ==> winload.efi */
for (i = 0; i + (int)sizeof(winloadexe) < g_vhdboot_bcd_len; i++)
{
if (*((grub_uint32_t *)(pos + i)) == 0x00690077 &&
grub_memcmp(pos + i, winloadexe, sizeof(winloadexe)) == 0)
{
pos[i + sizeof(winloadexe) - 4] = 0x66;
pos[i + sizeof(winloadexe) - 2] = 0x69;
cnt++;
}
}
debug("winload patch %d times\n", cnt);
}
for (pos = vhdpath; *pos; pos++)
{
if (*pos == '/')
{
*pos = '\\';
}
}
grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)vhdpath, -1, NULL);
grub_memcpy(patch1->vhd_file_path, unicode_path, pathlen);
grub_memcpy(patch2->vhd_file_path, unicode_path, pathlen);
return 0;
}
static int ventoy_vhd_patch_disk(char *isopart, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2)
{
char *pos;
grub_disk_t disk;
ventoy_gpt_info *gptinfo;
char efipart[16] = {0};
pos = grub_strchr(isopart, ',');
if (pos)
{
*pos = 0;
}
pos = isopart;
if (*pos == '(')
{
pos++;
}
debug("vhd disk <%s>\n", pos);
disk = grub_disk_open(pos);
if (!disk)
{
debug("Failed to open disk %s\n", pos);
return 1;
}
gptinfo = (ventoy_gpt_info *)(g_vhdboot_isobuf + g_vhdboot_isolen);
grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), gptinfo);
grub_memcpy(efipart, gptinfo->Head.Signature, sizeof(gptinfo->Head.Signature));
debug("part1 type: 0x%x <%s>\n", gptinfo->MBR.PartTbl[0].FsFlag, efipart);
if (grub_strncmp(efipart, "EFI PART", 8) == 0)
{
ventoy_debug_dump_guid("GPT disk GUID: ", gptinfo->Head.DiskGuid);
ventoy_debug_dump_guid("GPT part GUID: ", gptinfo->PartTbl[0].PartGuid);
grub_memcpy(patch1->disk_signature_or_guid, gptinfo->Head.DiskGuid, 16);
grub_memcpy(patch1->part_offset_or_guid, gptinfo->PartTbl[0].PartGuid, 16);
grub_memcpy(patch2->disk_signature_or_guid, gptinfo->Head.DiskGuid, 16);
grub_memcpy(patch2->part_offset_or_guid, gptinfo->PartTbl[0].PartGuid, 16);
patch1->part_type = patch2->part_type = 0;
}
else
{
debug("MBR disk signature: %02x%02x%02x%02x\n",
gptinfo->MBR.BootCode[0x1b8 + 0], gptinfo->MBR.BootCode[0x1b8 + 1],
gptinfo->MBR.BootCode[0x1b8 + 2], gptinfo->MBR.BootCode[0x1b8 + 3]);
grub_memcpy(patch1->disk_signature_or_guid, gptinfo->MBR.BootCode + 0x1b8, 4);
grub_memcpy(patch2->disk_signature_or_guid, gptinfo->MBR.BootCode + 0x1b8, 4);
}
grub_disk_close(disk);
return 0;
}
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args)
{
int rc;
ventoy_patch_vhd *patch1;
ventoy_patch_vhd *patch2;
char envbuf[64];
(void)ctxt;
(void)argc;
grub_env_unset("vtoy_vhd_buf_addr");
debug("patch vhd <%s> <%s>\n", args[0], args[1]);
if ((!g_vhdboot_enable) || (!g_vhdboot_totbuf))
{
debug("vhd boot not ready %d %p\n", g_vhdboot_enable, g_vhdboot_totbuf);
return 0;
}
rc = ventoy_vhd_find_bcd(&g_vhdboot_bcd_offset, &g_vhdboot_bcd_len);
if (rc)
{
debug("failed to get bcd location %d\n", rc);
return 0;
}
patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x495a);
patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x50aa);
ventoy_vhd_patch_disk(args[0], patch1, patch2);
ventoy_vhd_patch_path(args[1], patch1, patch2);
/* set buffer and size */
#ifdef GRUB_MACHINE_EFI
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_totbuf);
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", (int)(g_vhdboot_isolen + sizeof(ventoy_chain_head)));
grub_env_set("vtoy_vhd_buf_size", envbuf);
#else
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_isobuf);
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", g_vhdboot_isolen);
grub_env_set("vtoy_vhd_buf_size", envbuf);
#endif
return 0;
}
grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args)
{
int buflen;
grub_file_t file;
(void)ctxt;
(void)argc;
g_vhdboot_enable = 0;
grub_check_free(g_vhdboot_totbuf);
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (!file)
{
return 0;
}
debug("load vhd boot: <%s> <%lu>\n", args[0], (ulong)file->size);
if (file->size < VTOY_SIZE_1KB * 32)
{
grub_file_close(file);
return 0;
}
g_vhdboot_isolen = (int)file->size;
buflen = (int)(file->size + sizeof(ventoy_gpt_info) + sizeof(ventoy_chain_head));
#ifdef GRUB_MACHINE_EFI
g_vhdboot_totbuf = (char *)grub_efi_allocate_iso_buf(buflen);
#else
g_vhdboot_totbuf = (char *)grub_malloc(buflen);
#endif
if (!g_vhdboot_totbuf)
{
grub_file_close(file);
return 0;
}
g_vhdboot_isobuf = g_vhdboot_totbuf + sizeof(ventoy_chain_head);
grub_file_read(file, g_vhdboot_isobuf, file->size);
grub_file_close(file);
g_vhdboot_enable = 1;
return 0;
}

View File

@@ -20,9 +20,15 @@ all_modules_uefi="blocklist ventoy test newc search at_keyboard usb_keyboard gc
if [ "$1" = "uefi" ]; then
all_modules="$net_modules_uefi $all_modules_uefi "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos'
#grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/bootx64.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos'
else
all_modules="$net_modules_legacy $all_modules_legacy "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk'
#grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/cdrom.img" --format 'i386-pc-eltorito' --compression 'auto' $all_modules_legacy 'biosdisk' 'iso9660' 'fat' 'part_msdos'
#rm -f $VT_DIR/LiveCD/GRUB/boot_hybrid.img
#cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot_hybrid.img $VT_DIR/LiveCD/GRUB/boot_hybrid.img
fi
grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1