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 ea53303c..296c0fea 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 @@ -5253,6 +5253,7 @@ static cmd_para ventoy_cmds[] = { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, + { "vt_unix_ko_fillmap", ventoy_cmd_unix_ko_fillmap, 0, NULL, "", "", NULL }, { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc, 0, NULL, "", "", NULL }, { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko, 0, NULL, "", "", NULL }, { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, 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 82428770..28817ba1 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 @@ -1088,6 +1088,7 @@ int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_gzip_newko(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); @@ -1128,5 +1129,27 @@ int ventoy_chain_file_read(const char *path, int offset, int len, void *buf); extern ventoy_grub_param *g_grub_param; +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + grub_uint64_t seg_start_bytes; + grub_uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + grub_uint32_t magic1[4]; + grub_uint32_t magic2[4]; + grub_uint64_t segnum; + grub_uint64_t disksize; + grub_uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + grub_uint32_t magic3[4]; +}; +#pragma pack() + #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c index 179739b2..0eac9e41 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c @@ -47,6 +47,11 @@ char *g_conf_new_data = NULL; int g_mod_new_len = 0; char *g_mod_new_data = NULL; +int g_mod_search_magic = 0; + +int g_ko_fillmap_len = 0; +char *g_ko_fillmap_data = NULL; + grub_uint64_t g_mod_override_offset = 0; grub_uint64_t g_conf_override_offset = 0; @@ -82,6 +87,15 @@ static grub_uint32_t ventoy_unix_get_override_chunk_count(void) { count++; } + + if (g_ko_fillmap_len > 0) + { + count += (g_ko_fillmap_len / 512); + if ((g_ko_fillmap_len % 512) > 0) + { + count++; + } + } return count; } @@ -121,15 +135,49 @@ static grub_uint32_t ventoy_unix_get_virt_chunk_size(void) return size; } -static void ventoy_unix_fill_override_data( grub_uint64_t isosize, void *override) +static void ventoy_unix_fill_map_data(ventoy_chain_head *chain, struct g_ventoy_map *map) { + grub_uint32_t i; + ventoy_img_chunk *chunk = NULL; + + debug("Fill unix map data: <%llu> <%u>\n", (unsigned long long)chain->os_param.vtoy_disk_size, g_img_chunk_list.cur_chunk); + + map->magic1[0] = map->magic2[0] = map->magic3[0] = VENTOY_UNIX_SEG_MAGIC0; + map->magic1[1] = map->magic2[1] = map->magic3[1] = VENTOY_UNIX_SEG_MAGIC1; + map->magic1[2] = map->magic2[2] = map->magic3[2] = VENTOY_UNIX_SEG_MAGIC2; + map->magic1[3] = map->magic2[3] = map->magic3[3] = VENTOY_UNIX_SEG_MAGIC3; + + map->disksize = chain->os_param.vtoy_disk_size; + grub_memcpy(map->diskuuid, chain->os_param.vtoy_disk_guid, 16); + + map->segnum = g_img_chunk_list.cur_chunk; + if (g_img_chunk_list.cur_chunk > VENTOY_UNIX_MAX_SEGNUM) + { + debug("####[FAIL] Too many segments for the ISO file %u\n", g_img_chunk_list.cur_chunk); + map->segnum = VENTOY_UNIX_MAX_SEGNUM; + } + + for (i = 0; i < (grub_uint32_t)(map->segnum); i++) + { + chunk = g_img_chunk_list.chunk + i; + map->seglist[i].seg_start_bytes = chunk->disk_start_sector * 512ULL; + map->seglist[i].seg_end_bytes = (chunk->disk_end_sector + 1) * 512ULL; + } +} + +static void ventoy_unix_fill_override_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + int i; + int left; + char *data = NULL; + grub_uint64_t offset; grub_uint64_t sector; ventoy_override_chunk *cur; ventoy_iso9660_override *dirent; sector = (isosize + 2047) / 2048; - cur = (ventoy_override_chunk *)override; + cur = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); if (g_conf_new_len > 0) { @@ -158,6 +206,35 @@ static void ventoy_unix_fill_override_data( grub_uint64_t isosize, void *over sector += (dirent->size + 2047) / 2048; } + if (g_ko_fillmap_len > 0) + { + data = g_ko_fillmap_data; + offset = g_mod_override_offset; + + ventoy_unix_fill_map_data(chain, (struct g_ventoy_map *)data); + + for (i = 0; i < g_ko_fillmap_len / 512; i++) + { + cur++; + cur->img_offset = offset; + cur->override_size = 512; + grub_memcpy(cur->override_data, data, 512); + + offset += 512; + data += 512; + } + + left = (g_ko_fillmap_len % 512); + if (left > 0) + { + cur++; + cur->img_offset = offset; + cur->override_size = left; + grub_memcpy(cur->override_data, data, left); + offset += left; + } + } + return; } @@ -182,6 +259,11 @@ static void ventoy_unix_fill_virt_data( grub_uint64_t isosize, ventoy_chain_h if (g_mod_new_len > 0) { + if (g_mod_search_magic > 0) + { + ventoy_unix_fill_map_data(chain, (struct g_ventoy_map *)(g_mod_new_data + g_mod_search_magic)); + } + ventoy_unix_fill_virt(g_mod_new_data, g_mod_new_len); } @@ -210,6 +292,12 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath) vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES"); vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path); + if (g_mod_search_magic) + { + debug("hint.ventoy NO need\n"); + goto out; + } + disk = isofile->device->disk; ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig); @@ -232,8 +320,8 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath) (ulonglong)((chunk->disk_end_sector + 1) * 512)); } +out: grub_file_close(isofile); - return pos; } @@ -258,13 +346,16 @@ grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **ar (void)argc; (void)args; + g_mod_search_magic = 0; g_conf_new_len = 0; g_mod_new_len = 0; g_mod_override_offset = 0; g_conf_override_offset = 0; + g_ko_fillmap_len = 0; check_free(g_mod_new_data, grub_free); check_free(g_conf_new_data, grub_free); + check_free(g_ko_fillmap_data, grub_free); VENTOY_CMD_RETURN(GRUB_ERR_NONE); } @@ -624,6 +715,27 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static int ventoy_unix_search_magic(char *data, int len) +{ + int i; + grub_uint32_t *magic = NULL; + + for (i = 0; i < len; i += 65536) + { + magic = (grub_uint32_t *)(data + i); + if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && + magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) + { + debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 16)); + g_mod_search_magic = i; + return 0; + } + } + + debug("unix can not find search magic\n"); + return 1; +} + grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args) { char *data; @@ -673,10 +785,72 @@ grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char g_mod_new_data = data; g_mod_new_len = (int)file->size; + + ventoy_unix_search_magic(g_mod_new_data, g_mod_new_len); VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_file_t file; + grub_uint32_t magic[4]; + grub_uint32_t len; + + (void)ctxt; + + if (argc != 1) + { + debug("Fillmap ko invalid argc %d\n", argc); + return 1; + } + + debug("Fillmap ko %s\n", args[0]); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", args[0]); + if (file) + { + g_mod_override_offset = grub_iso9660_get_last_read_pos(file); + } + else + { + debug("Can't find replace ko file from %s\n", args[0]); + return 1; + } + + for (i = 0; i < (int)(file->size); i += 65536) + { + magic[0] = 0; + grub_file_seek(file, i); + grub_file_read(file, magic, sizeof(magic)); + + if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && + magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) + { + debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 16)); + g_mod_override_offset += i; + break; + } + } + + len = (grub_uint32_t)OFFSET_OF(struct g_ventoy_map, seglist) + + (sizeof(struct g_ventoy_seg) * g_img_chunk_list.cur_chunk); + + g_ko_fillmap_len = (int)len; + g_ko_fillmap_data = grub_malloc(len); + if (!g_ko_fillmap_data) + { + g_ko_fillmap_len = 0; + debug("Failed to malloc fillmap data\n"); + } + + debug("Fillmap ko segnum:%u, override len:%d", g_img_chunk_list.cur_chunk, g_ko_fillmap_len); + + grub_file_close(file); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args) { int i; @@ -908,7 +1082,7 @@ grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char /* part 4: override chunk */ chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; chain->override_chunk_num = override_count; - ventoy_unix_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset); + ventoy_unix_fill_override_data(isosize, chain); /* part 5: virt chunk */ chain->virt_chunk_offset = chain->override_chunk_offset + override_size; diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 92497b45..f68f2c3f 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -129,6 +129,9 @@ function get_os_type { elif [ -e (loop)/bin/freebsd-version ]; then set vtoy_os=Unix set vt_unix_type=FreeBSD + elif [ -e (loop)/boot/kernel/geom_ventoy.ko ]; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD elif vt_str_begin "$vt_system_id" "DragonFly"; then set vtoy_os=Unix set vt_unix_type=DragonFly @@ -469,6 +472,10 @@ function ventoy_freebsd_proc { set vt_freebsd_ver=9.x fi + if [ -e (loop)/boot/kernel/geom_ventoy.ko ]; then + vt_unix_ko_fillmap /boot/kernel/geom_ventoy.ko + return + fi if [ -e (loop)/usr/freebsd-dist/cloninst.sh ]; then set vtFreeBsdDistro=ClonOS diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio index f888ffb6..83fdf00b 100644 Binary files a/INSTALL/ventoy/ventoy_unix.cpio and b/INSTALL/ventoy/ventoy_unix.cpio differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz index 280d1487..2de91458 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz index 8636888e..a4b74178 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c index 585c0537..5477c5ea 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c @@ -65,12 +65,22 @@ static g_taste_t g_ventoy_taste; static g_ctl_req_t g_ventoy_config; static g_dumpconf_t g_ventoy_dumpconf; -static const char *g_ventoy_disk_uuid = NULL; +static char g_ventoy_disk_uuid[64]; static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (65536))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; + struct g_class g_ventoy_class = { .name = G_VENTOY_CLASS_NAME, .version = G_VERSION, @@ -719,16 +729,36 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) if (g_ventoy_disk_size == 0) { - if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - G_DEBUG("ventoy.disksize: %s\n", value); - g_ventoy_disk_size = strtouq(value, NULL, 0); - } + G_DEBUG("ventoy map data is valid. [OK]\n"); - if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) - { + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } } if (g_ventoy_disk_size != pp->mediasize) @@ -812,7 +842,16 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); - resource_int_value("ventoy", 0, "segnum", &disknum); + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); md.md_version = G_VENTOY_VERSION; @@ -834,18 +873,29 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) for (i = 0; i < disknum; i ++) { - if (resource_string_value("ventoy", i, "seg", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - g_disk_map_start = strtouq(value, &endpos, 0); - g_disk_map_end = strtouq(endpos + 1, NULL, 0); + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; } else { - printf("Failed to parse ventoy seg %d\n", i); - continue; + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); } - - G_DEBUG("ventoy segment%d: %s\n", i, value); G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); error = g_ventoy_add_disk(sc, pp, i); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h index e442b246..abe565bd 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h @@ -76,6 +76,33 @@ struct g_ventoy_softc { struct mtx sc_lock; }; #define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + #endif /* _KERNEL */ struct g_ventoy_metadata {