+ #For iKuai8 (<64MB)
+ if [ $vt_chosen_size -LE 67108864 ]; then
+ if vt_str_begin "$vt_chosen_name" "iKuai"; then
+ set vtMemDiskBoot=1
+ fi
+ fi
+ fi
+ vt_iso_vd_id_clear
+
+
+ if [ "$grub_platform" = "pc" ]; then
+ if [ -n "$vtMemDiskBoot" ]; then
+ legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path"
+ else
+ legacy_iso_menu_func $vtoy_iso_part "$vt_chosen_path"
+ fi
+ else
+ if [ -n "$vtMemDiskBoot" ]; then
+ uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path"
+ else
+ uefi_iso_menu_func $vtoy_iso_part "$vt_chosen_path"
+ fi
+ fi
+}
+
+function miso_common_menuentry {
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ echo "memdisk mode boot for $vt_chosen_path"
+ echo ""
+ ventoy_debug_pause
+
+ if [ "$grub_platform" = "pc" ]; then
+ legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path"
+ else
+ uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path"
+ fi
+}
+
+
+function common_unsupport_menuentry {
+ echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n"
+ echo -e " 文件名中不能有中文或空格 \n"
+ echo -e "\npress ENTER to exit (请按 回车 键返回) ..."
+ read vtInputKey
+}
+
+function miso_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+function iso_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+function wim_common_menuentry {
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ if ventoy_vcfg_proc "${vt_chosen_path}"; then
+ return
+ fi
+
+ if vt_wim_check_bootable "${vtoy_iso_part}${vt_chosen_path}"; then
+ vt_wim_chain_data "${vtoy_iso_part}${vt_chosen_path}"
+ else
+ echo -e "\n This is NOT a bootable WIM file. \n"
+ echo -e " 这不是一个可启动的 WIM 文件。\n"
+ fi
+
+ ventoy_debug_pause
+
+ if [ -n "$vtoy_chain_mem_addr" ]; then
+ if [ "$grub_platform" = "pc" ]; then
+ linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ else
+ ventoy_cli_console
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ ventoy_gui_console
+ fi
+ boot
+ else
+ echo "chain empty failed"
+ ventoy_pause
+ fi
+}
+
+function wim_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+function efi_common_menuentry {
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ if ventoy_vcfg_proc "${vt_chosen_path}"; then
+ return
+ fi
+
+ unset vt_vlnk_dst
+ if vt_is_vlnk_name "${vt_chosen_path}"; then
+ vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst
+ if [ -z "$vt_vlnk_dst" ]; then
+ echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n"
+ ventoy_pause
+ return
+ fi
+ else
+ vt_vlnk_dst="${vtoy_iso_part}${vt_chosen_path}"
+ fi
+
+ ventoy_debug_pause
+
+ ventoy_cli_console
+
+ #first try with chainload
+ set vtOldRoot=$root
+ set root=$vtoy_iso_part
+ chainloader "${vt_vlnk_dst}"
+ boot
+
+ #retry with isoboot
+ set root=$vtOldRoot
+ vt_concat_efi_iso "${vt_vlnk_dst}" vtoy_iso_buf
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} dotefi isoefi=on ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size}
+ boot
+
+ ventoy_gui_console
+}
+
+function efi_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+function vhdboot_common_func {
+ vt_patch_vhdboot "$1"
+
+ ventoy_debug_pause
+
+ if [ -n "$vtoy_vhd_buf_addr" ]; then
+ if [ "$grub_platform" = "pc" ]; then
+ ventoy_cli_console
+ linux16 $vtoy_path/memdisk iso raw
+ initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
+ boot
+ ventoy_gui_console
+ else
+ ventoy_cli_console
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
+ boot
+ ventoy_gui_console
+ fi
+ else
+ echo "Please put the right ventoy_vhdboot.img file to the 1st partition"
+ ventoy_pause
+ fi
+}
+
+function vhd_common_menuentry {
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ if ventoy_vcfg_proc "${vt_chosen_path}"; then
+ return
+ fi
+
+ unset vt_vlnk_dst
+ if vt_is_vlnk_name "${vt_chosen_path}"; then
+ vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst
+ if [ -z "$vt_vlnk_dst" ]; then
+ echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n"
+ ventoy_pause
+ return
+ fi
+ else
+ vt_vlnk_dst="${vt_chosen_path}"
+ if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then
+ if [ "$vtoy_iso_fs" != "ntfs" ]; then
+ echo -e "!!! WARNING !!!\n"
+ echo -e "\nPartition1 ($vtoy_iso_fs) is NOT ntfs, the VHD(x) file may not boot normally \n"
+ echo -e "\nVHD(x) 文件所在分区不是 ntfs 格式, 可能无法正常启动 \n\n"
+ echo -n "press ENTER to continue boot (请按 回车 键继续) ..."
+ read vtInputKey
+ fi
+ fi
+ fi
+
+ vhdboot_common_func "${vt_vlnk_dst}"
+}
+
+function vhd_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+function vtoyboot_common_func {
+ set AltBootPart=0
+ set vtoysupport=0
+
+ vt_get_vtoy_type "${1}" vtoytype parttype AltBootPart
+
+ if vt_str_begin $vtoytype vhd; then
+ set vtoysupport=1
+ elif [ "$vtoytype" = "raw" ]; then
+ set vtoysupport=1
+ elif [ "$vtoytype" = "vdi" ]; then
+ set vtoysupport=1
+ fi
+
+ if [ $vtoysupport -eq 1 ]; then
+ if [ "$grub_platform" = "pc" ]; then
+ if [ "$parttype" = "gpt" -a $AltBootPart -eq 0 ]; then
+ echo "The OS in the vdisk was created in UEFI mode, but current is Legacy BIOS mode."
+ echo "虚拟磁盘内的系统是在UEFI模式下创建的,而当前系统是Legacy BIOS模式,可能无法正常启动。"
+ ventoy_pause
+ fi
+ else
+ if [ "$parttype" = "mbr" -a $AltBootPart -eq 0 ]; then
+ echo "The OS in the vdisk was created in Legacy BIOS mode, but current is UEFI mode."
+ echo "虚拟磁盘内的系统是在Legacy BIOS模式下创建的,而当前系统是UEFI模式,可能无法正常启动。"
+ ventoy_pause
+ fi
+ fi
+
+ vt_img_sector "${1}"
+ vt_raw_chain_data "${1}"
+
+ ventoy_debug_pause
+
+ if [ -n "$vtoy_chain_mem_addr" ]; then
+ if [ "$grub_platform" = "pc" ]; then
+ vt_acpi_param ${vtoy_chain_mem_addr} 512
+ linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} bios80 sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ boot
+ else
+ if vt_check_secureboot_var; then
+ vt_acpi_param ${vtoy_chain_mem_addr} 512
+ fi
+ ventoy_cli_console
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${ventoy_env_param} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ boot
+ ventoy_gui_console
+ fi
+ else
+ echo "chain empty failed!"
+ ventoy_pause
+ fi
+ else
+ echo "Unsupported vtoy type $vtoytype"
+ ventoy_pause
+ fi
+}
+
+function vtoy_common_menuentry {
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ if ventoy_vcfg_proc "${vt_chosen_path}"; then
+ return
+ fi
+
+ unset vt_vlnk_dst
+ if vt_is_vlnk_name "${vt_chosen_path}"; then
+ vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst
+ if [ -z "$vt_vlnk_dst" ]; then
+ echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n"
+ ventoy_pause
+ return
+ fi
+ else
+ vt_vlnk_dst="${vtoy_iso_part}${vt_chosen_path}"
+ fi
+
+ vtoyboot_common_func "${vt_vlnk_dst}"
+}
+
+function vtoy_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+#
+#============================================================#
+# IMG file boot process #
+#============================================================#
+#
+
+function only_uefi_tip {
+ echo -e "\n This IMG file is only supported in UEFI mode. \n"
+ echo -e "\n press ENTER to exit ..."
+ read vtInputKey
+}
+
+function ventoy_img_easyos {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ loopback easysfs (vtimghd,1)/easy.sfs
+ vt_get_lib_module_ver (easysfs) /lib/modules/ vt_module_ver
+
+ if [ -n "$vt_module_ver" ]; then
+ for mod in "kernel/drivers/md/dm-mod.ko" "kernel/drivers/dax/dax.ko"; do
+ if [ -e (easysfs)/lib/modules/$vt_module_ver/$mod ]; then
+ vt_img_extra_initrd_append (easysfs)/lib/modules/$vt_module_ver/$mod
+ fi
+ done
+ fi
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy
+ vt_img_hook_root
+
+ syslinux_configfile (vtimghd,1)/syslinux.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+ loopback -d easysfs
+}
+
+function ventoy_img_volumio {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy imgpart=/dev/ventoy2 bootpart=/dev/ventoy1
+ vt_img_hook_root
+
+ syslinux_configfile (vtimghd,1)/syslinux.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_openelec {
+ elec_ver=$1
+
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ loopback vtloopex $vtoy_efi_part/ventoy/vtloopex.cpio
+ vt_img_extra_initrd_append (vtloopex)/$elec_ver/vtloopex.tar.xz
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=$elec_ver
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ syslinux_configfile (vtimghd,1)/syslinux.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+ loopback -d vtloopex
+}
+
+
+function ventoy_img_freedombox {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ vt_get_lib_module_ver (vtimghd,1) /lib/modules/ vt_module_ver
+ if [ -n "$vt_module_ver" ]; then
+ vt_img_extra_initrd_append (vtimghd,1)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko
+ fi
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=freedombox
+ vt_img_hook_root
+
+ configfile (vtimghd,1)/boot/grub/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_paldo {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=paldo
+ vt_img_hook_root
+
+ vt_fs_enum_1st_file (vtimghd,1) /loader/entries/ vt_paldo_entry_conf
+ vt_file_basename $vt_paldo_entry_conf vtPaldoVer
+
+ echo loading file...
+ linux (vtimghd,1)/linux-${vtPaldoVer} root=/dev/ventoy1 rootfstype=vfat
+ initrd (vtimghd,1)/initramfs-${vtPaldoVer}
+ boot
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_ubos {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ vt_get_lib_module_ver (vtimghd,3) /lib/modules/ vt_module_ver
+ if [ -n "$vt_module_ver" ]; then
+ vt_img_extra_initrd_append (vtimghd,3)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko.xz
+ fi
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=ubos
+ vt_img_hook_root
+
+ echo loading file...
+ linux (vtimghd,2)/vmlinuz-linux root=/dev/ventoy3 rw
+ initrd (vtimghd,2)/initramfs-linux.img
+ boot
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_recalbox {
+ if [ $vtoy_img_max_part_end -GT $vt_chosen_size ]; then
+ echo -e "\nPlease extend the img file size before boot it. \n"
+ ventoy_pause
+ return
+ fi
+
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ if [ -e (vtimghd,1)/boot/recalbox ]; then
+ loopback recalbox (vtimghd,1)/boot/recalbox
+ vt_get_lib_module_ver (recalbox) /lib/modules/ vt_module_ver
+ if [ -n "$vt_module_ver" ]; then
+ vt_img_extra_initrd_append (recalbox)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko
+ fi
+ fi
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=recalbox
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ configfile (vtimghd,1)/boot/grub/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_esysrescue {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=esysrescue
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ configfile (vtimghd,1)/boot/grub/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_batocera {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=batocera
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ syslinux_configfile (vtimghd,1)/boot/syslinux/syslinux.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_openwrt {
+ if [ -e (vtimghd,2)/lib64 ]; then
+ set ventoy_busybox_ver=64
+ fi
+
+ vt_fs_enum_1st_dir (vtimghd,2) /lib/modules/ vt_dir_name
+
+ if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko ]; then
+ set openwrt_plugin_need=0
+ vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko
+ if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko ]; then
+ vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko
+ fi
+ else
+ set openwrt_plugin_need=1
+ if [ ! -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then
+ ventoy_gui_console
+ echo -e "\n ventoy_openwrt.xz not found. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n"
+ echo -e " 未找到 ventoy_openwrt.xz 文件。请参考 https://www.ventoy.net/cn/doc_openwrt.html\n"
+ echo -e "\n press ENTER to exit (请按 回车 键返回) ..."
+ read vtInputKey
+ ventoy_cli_console
+ return
+ fi
+ fi
+
+ if vt_img_check_range "${vtoy_iso_part}${vt_chosen_path}"; then
+ ventoy_debug_pause
+ else
+ ventoy_gui_console
+ echo -e "\n IMG file need processed. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n"
+ echo -e " 此 IMG 文件必须处理之后才能支持。请参考 https://www.ventoy.net/cn/doc_openwrt.html\n"
+ echo -e "\n press ENTER to exit (请按 回车 键返回) ..."
+ read vtInputKey
+ ventoy_cli_console
+ return
+ fi
+
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ if [ $openwrt_plugin_need -eq 1 ]; then
+ if [ -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then
+ vt_img_extra_initrd_append ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz
+ fi
+ fi
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=openwrt
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ configfile (vtimghd,1)/boot/grub/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_tails {
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy live-media=/dev/dm-1 ventoyos=tails
+ vt_img_hook_root
+
+ set root=(vtimghd,1)
+ configfile (vtimghd,1)/efi/debian/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+}
+
+function ventoy_img_fydeos {
+ if [ "$grub_platform" = "pc" ]; then
+ only_uefi_tip
+ return
+ fi
+
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=64"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=fydeos
+ vt_img_hook_root
+
+ set grubdisk=vtimghd
+ set grubpartA=(vtimghd,3)
+ set grubpartB=(vtimghd,5)
+ set linuxpartA=(sda,3)
+ set linuxpartB=(sda,5)
+
+ set root=(vtimghd,12)
+ configfile (vtimghd,12)/efi/boot/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+
+ unset grubdisk
+ unset grubpartA
+ unset grubpartB
+ unset linuxpartA
+ unset linuxpartB
+}
+
+function ventoy_img_cloudready {
+ if [ "$grub_platform" = "pc" ]; then
+ only_uefi_tip
+ return
+ fi
+
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=64"
+ vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
+
+ ventoy_debug_pause
+
+ #boot image file
+ vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=cloudready
+ vt_img_hook_root
+
+ set grubdisk=vtimghd
+ set grubpartA=(vtimghd,3)
+ set grubpartB=(vtimghd,5)
+ set linuxpartA=(sda,3)
+ set linuxpartB=(sda,5)
+
+ set root=(vtimghd,12)
+ configfile (vtimghd,12)/efi/boot/grub.cfg
+
+ vt_img_unhook_root
+ vt_unset_boot_opt
+
+ unset grubdisk
+ unset grubpartA
+ unset grubpartB
+ unset linuxpartA
+ unset linuxpartB
+}
+
+function ventoy_img_memtest86 {
+ chainloader (vtimghd,1)/efi/boot/BOOTX64.efi
+ boot
+}
+
+function img_unsupport_tip {
+ echo -e "\n This IMG file is NOT supported now. \n"
+ echo -e " 当前不支持启动此 IMG 文件 \n"
+ echo -e "\npress ENTER to exit (请按 回车 键返回) ..."
+ read vtInputKey
+}
+
+function legacy_img_memdisk {
+ linux16 $vtoy_path/memdisk
+ echo "Loading img file to memory ..."
+ initrd16 "${1}${2}"
+
+ ventoy_cli_console
+ boot
+}
+
+function img_common_menuentry {
+ set ventoy_compatible=YES
+ set ventoy_busybox_ver=32
+ unset LoadIsoEfiDriver
+
+ vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name
+
+ if vt_check_password "${vt_chosen_path}"; then
+ return
+ fi
+
+ if ventoy_vcfg_proc "${vt_chosen_path}"; then
+ return
+ fi
+
+ if [ "$grub_platform" = "pc" ]; then
+ if vt_check_mode 0 "$vt_chosen_name"; then
+ legacy_img_memdisk $vtoy_iso_part "$vt_chosen_path"
+ return
+ fi
+ fi
+
+ loopback vtimghd "${vtoy_iso_part}${vt_chosen_path}"
+ vt_img_sector "${vtoy_iso_part}${vt_chosen_path}"
+
+ vt_img_part_info (vtimghd)
+
+ set vtback_root=$root
+ ventoy_cli_console
+ vt_push_last_entry
+ set vtback_theme=$theme
+ unset theme
+
+ vt_img_extra_initrd_reset
+
+
+ vt_get_fs_label (vtimghd,1) vtImgHd1Label
+
+ if [ "$vtImgHd1Label" = "STATE" ]; then
+ vt_get_fs_label (vtimghd,3) vtImgHd3Label
+ elif [ -d (vtimghd,2)/lib ]; then
+ vt_get_fs_label (vtimghd,2) vtImgHd2Label
+ fi
+
+ if [ -e (vtimghd,1)/etc/hostname ]; then
+ vt_1st_line (vtimghd,1)/etc/hostname vtImgHostname
+ fi
+
+ if vt_str_begin "$vtImgHd3Label" "ROOT-"; then
+ if [ -f (vtimghd,3)/etc/os-release.d/ID ]; then
+ vt_1st_line (vtimghd,3)/etc/os-release.d/ID vt_release_line1
+ if vt_str_begin "$vt_release_line1" "FydeOS"; then
+ ventoy_img_fydeos
+ else
+ ventoy_img_cloudready
+ fi
+ elif [ -f (vtimghd,3)/etc/cloudready-release ]; then
+ ventoy_img_cloudready
+ elif [ -f (vtimghd,3)/etc/chrome_dev.conf ]; then
+ ventoy_img_cloudready
+ fi
+ elif vt_str_begin "$vtImgHd1Label" "LAKKA"; then
+ ventoy_img_openelec lakka
+ elif vt_str_begin "$vtImgHd1Label" "LIBREELEC"; then
+ ventoy_img_openelec LibreELEC
+ elif vt_str_begin "$vtImgHd1Label" "paldo-live"; then
+ ventoy_img_paldo
+ elif vt_str_begin "$vtImgHostname" "freedombox"; then
+ ventoy_img_freedombox
+ elif vt_str_begin "$vtImgHd1Label" "BATOCERA"; then
+ ventoy_img_batocera
+ elif vt_str_begin "$vtImgHd1Label" "Tails"; then
+ ventoy_img_tails
+ elif [ "$vtImgHd2Label" = "RECALBOX" -o "$vtImgHd1Label" = "RECALBOX" ]; then
+ ventoy_img_recalbox
+ elif [ "$vtImgHd1Label" = "ESYSRESCUE" ]; then
+ ventoy_img_esysrescue
+ elif [ -e (vtimghd,1)/easy.sfs ]; then
+ ventoy_img_easyos
+ elif [ -e (vtimghd,1)/volumio.initrd ]; then
+ ventoy_img_volumio
+ elif [ -f (vtimghd,2)/loader/entries/ubos.conf ]; then
+ ventoy_img_ubos
+ elif [ -f (vtimghd,2)/etc/openwrt_version ]; then
+ ventoy_img_openwrt
+ elif [ -f (vtimghd,1)/efi/boot/mt86.png ]; then
+ if [ "$grub_platform" = "pc" ]; then
+ img_unsupport_tip
+ else
+ ventoy_img_memtest86
+ fi
+ else
+ vt_linux_chain_data "${vtoy_iso_part}${vt_chosen_path}"
+ ventoy_acpi_param ${vtoy_chain_mem_addr} 512
+ if [ "$grub_platform" = "pc" ]; then
+ linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ boot
+ else
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ boot
+ fi
+ fi
+
+ loopback -d vtimghd
+
+ set root=$vtback_root
+ vt_pop_last_entry
+ set theme=$vtback_theme
+ ventoy_gui_console
+ set ventoy_compatible=NO
+}
+
+function img_unsupport_menuentry {
+ common_unsupport_menuentry
+}
+
+#############################################################
+#############################################################
+#############################################################
+####### Main Process ###########
+#############################################################
+#############################################################
+#############################################################
+
+set VENTOY_VERSION="1.0.80"
+
+#ACPI not compatible with Window7/8, so disable by default
+set VTOY_PARAM_NO_ACPI=1
+
+# Default menu display mode, you can change it as you want.
+# 0: List mode
+# 1: TreeView mode
+set VTOY_DEFAULT_MENU_MODE=0
+
+set VTOY_MEM_DISK_STR="[Memdisk]"
+set VTOY_ISO_RAW_STR="Compatible Mode"
+set VTOY_GRUB2_MODE_STR="GRUB2 Mode"
+set VTOY_WIMBOOT_MODE_STR="WIMBOOT Mode"
+set VTOY_ISO_UEFI_DRV_STR="UEFI FS"
+
+set VTOY_F2_CMD="vt_browser_disk"
+set VTOY_F4_CMD="ventoy_localboot"
+set VTOY_F5_CMD="ventoy_diagnosis"
+set VTOY_F6_CMD="ventoy_ext_menu"
+set VTOY_HELP_CMD="ventoy_show_help"
+set VTOY_CHKSUM_CMD="ventoy_checksum"
+set VTOY_HELP_TXT_LANGUAGE="en_US"
+set VTOY_CHKSUM_FILE_PATH="X"
+
+
+if [ "$grub_platform" = "pc" ]; then
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net"
+else
+ if [ "$grub_cpu" = "i386" ]; then
+ set VTOY_EFI_ARCH=ia32
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION IA32 www.ventoy.net"
+ elif [ "$grub_cpu" = "arm64" ]; then
+ set VTOY_EFI_ARCH=aa64
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION AA64 www.ventoy.net"
+ elif [ "$grub_cpu" = "mips64el" ]; then
+ set VTOY_EFI_ARCH=mips
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION MIPS www.ventoy.net"
+ else
+ set VTOY_EFI_ARCH=x64
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net"
+ fi
+fi
+
+vt_device $root vtoy_dev
+
+if [ "$vtoy_dev" = "tftp" ]; then
+ set vtoy_path=($root)
+ for vtid in 0 1 2 3; do
+ if [ -f (hd$vtid,2)/ventoy/ventoy.cpio ]; then
+ set vtoy_iso_part=(hd$vtid,1)
+ set vtoy_efi_part=(hd$vtid,2)
+ set vtoydev=hd$vtid
+ break
+ fi
+ done
+ loadfont ascii
+
+ if [ -n "$vtoy_efi_part" ]; then
+ vt_load_file_to_mem "auto" $vtoy_efi_part/grub/fonts/unicode.pf2 vtoy_font_mem
+ loadfont mem:${vtoy_font_mem_addr}:size:${vtoy_font_mem_size}
+ fi
+
+ if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
+ set vt_plugin_path=$vtoy_iso_part
+ else
+ set vt_plugin_path=$prefix
+ vt_load_plugin $vt_plugin_path
+ fi
+else
+ if [ "$prefix" = "(ventoydisk)/grub" ]; then
+ set vtoy_path=(ventoydisk)/ventoy
+ else
+ set vtoy_path=($root)/ventoy
+ fi
+
+ set vtoydev=$vtoy_dev
+ set vtoy_iso_part=($vtoy_dev,1)
+ set vtoy_efi_part=($vtoy_dev,2)
+
+ vt_load_file_to_mem "auto" $prefix/fonts/unicode.pf2 vtoy_font_mem
+ loadfont mem:${vtoy_font_mem_addr}:size:${vtoy_font_mem_size}
+
+ set vt_plugin_path=$vtoy_iso_part
+fi
+
+#Load Partition Table
+vt_load_part_table $vtoydev
+
+#Load Plugin
+if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
+ clear
+ vt_load_plugin $vtoy_iso_part
+ clear
+else
+ vt_check_json_path_case $vtoy_iso_part
+fi
+
+if [ -n "$VTOY_MENU_TIMEOUT" ]; then
+ set timeout=$VTOY_MENU_TIMEOUT
+else
+ unset timeout
+fi
+
+if [ -f $vtoy_iso_part/ventoy/ventoy_wimboot.img ]; then
+ vt_load_wimboot $vtoy_iso_part/ventoy/ventoy_wimboot.img
+elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then
+ vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img
+fi
+
+if [ -f $vtoy_iso_part/ventoy/ventoy_vhdboot.img ]; then
+ vt_load_vhdboot $vtoy_iso_part/ventoy/ventoy_vhdboot.img
+elif [ -f $vtoy_efi_part/ventoy/ventoy_vhdboot.img ]; then
+ vt_load_vhdboot $vtoy_efi_part/ventoy/ventoy_vhdboot.img
+fi
+
+
+if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then
+ set VTOY_F3_CMD="vt_dynamic_menu 1 1"
+ set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Browser F3:TreeView F4:Localboot F5:Tools F6:ExMenu"
+else
+ set VTOY_F3_CMD="vt_dynamic_menu 1 0"
+ set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Browser F3:ListView F4:Localboot F5:Tools F6:ExMenu"
+fi
+
+terminal_output console
+
+if [ -n "$vtoy_gfxmode" ]; then
+ set gfxmode=$vtoy_gfxmode
+ set gfxpayload=keep
+else
+ set gfxmode=1024x768
+ set gfxpayload=keep
+fi
+
+
+if [ "$vtoy_display_mode" = "CLI" ]; then
+ terminal_output console
+elif [ "$vtoy_display_mode" = "serial" ]; then
+ if [ -n "$vtoy_serial_param" ]; then
+ serial $vtoy_serial_param
+ fi
+ terminal_input serial
+ terminal_output serial
+elif [ "$vtoy_display_mode" = "serial_console" ]; then
+ if [ -n "$vtoy_serial_param" ]; then
+ serial $vtoy_serial_param
+ fi
+ terminal_input serial console
+ terminal_output serial console
+else
+ if [ -n "$vtoy_theme" ]; then
+ vt_set_theme
+ else
+ set theme=$prefix/themes/ventoy/theme.txt
+ fi
+ terminal_output gfxterm
+fi
+
+if [ "$grub_platform" = "efi" ]; then
+ set mouse_delta=4000
+ # terminal_input --append mouse
+fi
+
+if [ -n "$VTOY_DEFAULT_KBD_LAYOUT" ]; then
+ set_keyboard_layout "$VTOY_DEFAULT_KBD_LAYOUT"
+fi
+
+if [ -n "$VTOY_PLUGIN_PATH_CASE_MISMATCH" ]; then
+ clear
+ echo "$VTOY_PLUGIN_PATH_CASE_MISMATCH"
+ echo -e "\n\nPath case does not match! ventoy directory and ventoy.json MUST be all lowercase!"
+ echo -e "\n路径大小写不匹配!ventoy 目录和 ventoy.json 文件的名字必须是全部小写,请修正!"
+ echo -e "\n\npress ENTER to continue (请按回车键继续) ..."
+ read vtInputKey
+fi
+
+if [ -n "$VTOY_PLUGIN_SYNTAX_ERROR" ]; then
+ clear
+ if [ -n "$VTOY_PLUGIN_ENCODE_ERROR" ]; then
+ echo -e "\n Encoding type for ventoy.json is not supported, please convert to UTF-8.\n"
+ echo -e " ventoy.json 文件编码格式不支持,请转换为 UTF-8 编码格式!\n"
+ else
+ echo -e "\n Syntax error detected in ventoy.json, please check! \n"
+ echo -e " ventoy.json 文件中有语法错误,所有配置都不会生效,请检查!\n"
+ fi
+
+ echo -e "\n press ENTER to continue (请按 回车 键继续) ..."
+ read vtInputKey
+fi
+
+
+for vtTFile in ventoy.json ventoy_grub.cfg; do
+ if [ -f $vtoy_efi_part/ventoy/$vtTFile ]; then
+ clear
+ echo -e "\n You need to put $vtTFile in the 1st partition which hold the ISO files.\n"
+ echo -e " $vtTFile 放错分区了,请放到镜像分区里的 ventoy 目录下(此目录需要手动创建)!\n"
+ echo -e "\n press ENTER to continue (请按 回车 键继续) ..."
+ read vtInputKey
+ fi
+done
+
+#clear all input key before show main menu
+vt_clear_key
+
+#export necessary variable
+export theme
+export gfxmode
+export gfxpayload
+export vtoydev
+export vtoy_path
+export vtdebug_flag
+export vtoy_iso_fs
+export vtoy_iso_part
+export vtoy_efi_part
+export VENTOY_VERSION
+export VTOY_CUR_VIDEO_MODE
+export VTOY_EFI_ARCH
+export VTOY_MEM_DISK_STR
+export VTOY_ISO_RAW_STR
+export VTOY_GRUB2_MODE_STR
+export VTOY_WIMBOOT_MODE_STR
+export VTOY_ISO_UEFI_DRV_STR
+export VTOY_F2_CMD
+export VTOY_F4_CMD
+export VTOY_F5_CMD
+export VTOY_F6_CMD
+export VTOY_HELP_CMD
+export VTOY_CHKSUM_CMD
+export VTOY_HELP_TXT_LANGUAGE
+export VTOY_CHKSUM_FILE_PATH
+
+
+#colect all image files (iso files)
+set ventoy_img_count=0
+vt_list_img $vtoy_iso_part ventoy_img_count
+
+#Main menu
+if [ $ventoy_img_count -gt 0 ]; then
+ if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then
+ vt_dynamic_menu 0 0
+ else
+ vt_dynamic_menu 0 1
+ fi
+else
+ if [ -n "$VTOY_NO_ISO_TIP" ]; then
+ NO_ISO_MENU="No ISO or supported IMG files found, $VTOY_NO_ISO_TIP"
+ elif [ -n "$VTOY_DEFAULT_SEARCH_ROOT" ]; then
+ NO_ISO_MENU="No ISO or supported IMG files found, please check VTOY_DEFAULT_SEARCH_ROOT"
+ else
+ NO_ISO_MENU="No ISO or supported IMG files found"
+ fi
+ menuentry "$NO_ISO_MENU (Press enter to reboot ...)" {
+ echo -e "\n Rebooting ... "
+ reboot
+ }
+fi
+
+
+#special VTOY_DEFAULT_IMAGE process
+if [ -n "$VTOY_DEFAULT_IMAGE" ]; then
+ if regexp --set 1:vtHotkey --set 2:vtDefault "(F[2-9])>(.*)" "$VTOY_DEFAULT_IMAGE"; then
+
+ set default="$vtDefault"
+ if [ -z "$VTOY_MENU_TIMEOUT" ]; then
+ set timeout=0
+ else
+ set timeout=$VTOY_MENU_TIMEOUT
+ fi
+
+ export timeout
+ export default
+
+ vt_fn_mutex_lock 1
+
+ if [ "$vtHotkey" = "F2" ]; then
+ unset timeout
+ vt_browser_disk
+ elif [ "$vtHotkey" = "F4" ]; then
+ ventoy_localboot
+ elif [ "$vtHotkey" = "F5" ]; then
+ ventoy_diagnosis
+ elif [ "$vtHotkey" = "F6" ]; then
+ ventoy_ext_menu
+ fi
+
+ vt_fn_mutex_lock 0
+
+ unset timeout
+ unset default
+ fi