Add support for custom Syslinux-based ISO (#3760)

This commit is contained in:
longpanda
2026-09-29 14:32:50 +08:00
parent f9669af70c
commit b327e92a34
6 changed files with 218 additions and 77 deletions
@@ -51,8 +51,8 @@ struct syslinux_menuentry
char hotkey; char hotkey;
int make_default; int make_default;
struct syslinux_say *say; struct syslinux_say *say;
enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER, enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER,
KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB, KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB,
KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT } KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT }
entry_type; entry_type;
@@ -170,7 +170,7 @@ print_num (struct output_buffer *outbuf, int n)
{ {
char buf[20]; char buf[20];
grub_snprintf (buf, sizeof (buf), "%d", n); grub_snprintf (buf, sizeof (buf), "%d", n);
return print (outbuf, buf, grub_strlen (buf)); return print (outbuf, buf, grub_strlen (buf));
} }
static grub_err_t static grub_err_t
@@ -233,7 +233,7 @@ kernel (const char *line, struct syslinux_menu *menu)
if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0) if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0)
menu->entries->entry_type = KERNEL_IMG; menu->entries->entry_type = KERNEL_IMG;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -247,7 +247,7 @@ cmd_linux (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_LINUX; menu->entries->entry_type = KERNEL_LINUX;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -261,7 +261,7 @@ cmd_boot (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_CHAINLOADER; menu->entries->entry_type = KERNEL_CHAINLOADER;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -275,7 +275,7 @@ cmd_bss (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; menu->entries->entry_type = KERNEL_CHAINLOADER_BPB;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -289,7 +289,7 @@ cmd_pxe (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_PXE; menu->entries->entry_type = KERNEL_PXE;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -303,7 +303,7 @@ cmd_fdimage (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_IMG; menu->entries->entry_type = KERNEL_IMG;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -317,7 +317,7 @@ cmd_comboot (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_COM; menu->entries->entry_type = KERNEL_COM;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -331,7 +331,7 @@ cmd_com32 (const char *line, struct syslinux_menu *menu)
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = KERNEL_COM32; menu->entries->entry_type = KERNEL_COM32;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -354,7 +354,7 @@ cmd_config (const char *line, struct syslinux_menu *menu)
return grub_errno; return grub_errno;
} }
menu->entries->entry_type = KERNEL_CONFIG; menu->entries->entry_type = KERNEL_CONFIG;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -368,7 +368,7 @@ cmd_append (const char *line, struct syslinux_menu *menu)
menu->entries->append = grub_strdup (line); menu->entries->append = grub_strdup (line);
if (!menu->entries->append) if (!menu->entries->append)
return grub_errno; return grub_errno;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -377,6 +377,8 @@ cmd_initrd (const char *line, struct syslinux_menu *menu)
{ {
struct initrd_list *ninitrd; struct initrd_list *ninitrd;
const char *comma; const char *comma;
char *pcPos;
if (!menu->entries) if (!menu->entries)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
@@ -393,6 +395,14 @@ cmd_initrd (const char *line, struct syslinux_menu *menu)
grub_free (ninitrd); grub_free (ninitrd);
return grub_errno; return grub_errno;
} }
pcPos = grub_strstr(ninitrd->file, " quiet");
if (pcPos)
{
*pcPos = 0;
}
ninitrd->next = NULL; ninitrd->next = NULL;
if (menu->entries->initrds_last) if (menu->entries->initrds_last)
menu->entries->initrds_last->next = ninitrd; menu->entries->initrds_last->next = ninitrd;
@@ -406,7 +416,7 @@ cmd_initrd (const char *line, struct syslinux_menu *menu)
while (*line == ',') while (*line == ',')
line++; line++;
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -416,7 +426,7 @@ cmd_default (const char *line, struct syslinux_menu *menu)
menu->def = grub_strdup (line); menu->def = grub_strdup (line);
if (!menu->def) if (!menu->def)
return grub_errno; return grub_errno;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -434,7 +444,7 @@ cmd_menudefault (const char *line __attribute__ ((unused)),
if (!menu->entries) if (!menu->entries)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
menu->entries->make_default = 1; menu->entries->make_default = 1;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -457,7 +467,7 @@ cmd_localboot (const char *line,
if (!menu->entries->kernel_file) if (!menu->entries->kernel_file)
return grub_errno; return grub_errno;
menu->entries->entry_type = LOCALBOOT; menu->entries->entry_type = LOCALBOOT;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -485,7 +495,7 @@ cmd_extlabel (const char *line, struct syslinux_menu *menu)
*out++ = *in++; *out++ = *in++;
} }
*out = 0; *out = 0;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -548,7 +558,7 @@ syslinux_parse (const char *filename,
ret = syslinux_parse_real (menu); ret = syslinux_parse_real (menu);
if (ret == GRUB_ERR_FILE_NOT_FOUND if (ret == GRUB_ERR_FILE_NOT_FOUND
|| ret == GRUB_ERR_BAD_FILENAME) || ret == GRUB_ERR_BAD_FILENAME)
{ {
grub_errno = ret = GRUB_ERR_NONE; grub_errno = ret = GRUB_ERR_NONE;
add_comment (menu, "# File ", 0); add_comment (menu, "# File ", 0);
add_comment (menu, nf, 0); add_comment (menu, nf, 0);
@@ -761,7 +771,7 @@ syslinux_parse_real (struct syslinux_menu *menu)
} }
static grub_err_t static grub_err_t
print_escaped (struct output_buffer *outbuf, print_escaped (struct output_buffer *outbuf,
const char *from, const char *to) const char *from, const char *to)
{ {
const char *ptr; const char *ptr;
@@ -1037,7 +1047,7 @@ write_entry (struct output_buffer *outbuf,
case KERNEL_COM: case KERNEL_COM:
{ {
char *basename = NULL; char *basename = NULL;
{ {
char *ptr; char *ptr;
for (ptr = curentry->kernel_file; *ptr; ptr++) for (ptr = curentry->kernel_file; *ptr; ptr++)
@@ -1244,8 +1254,8 @@ write_entry (struct output_buffer *outbuf,
if (grub_strcasecmp (basename, "whichsys.c32") == 0) if (grub_strcasecmp (basename, "whichsys.c32") == 0)
{ {
grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX; grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX;
const char *flav[] = const char *flav[] =
{ {
[GRUB_SYSLINUX_ISOLINUX] = "iso", [GRUB_SYSLINUX_ISOLINUX] = "iso",
[GRUB_SYSLINUX_PXELINUX] = "pxe", [GRUB_SYSLINUX_PXELINUX] = "pxe",
[GRUB_SYSLINUX_SYSLINUX] = "sys" [GRUB_SYSLINUX_SYSLINUX] = "sys"
@@ -1416,7 +1426,7 @@ free_menu (struct syslinux_menu *menu)
grub_free (initrd->file); grub_free (initrd->file);
grub_free (initrd); grub_free (initrd);
} }
grub_free (entry->comments); grub_free (entry->comments);
grub_free (entry->kernel_file); grub_free (entry->kernel_file);
grub_free (entry->label); grub_free (entry->label);
@@ -1455,7 +1465,7 @@ config_file (struct output_buffer *outbuf,
{ {
menu.timeout = 100; menu.timeout = 100;
} }
err = syslinux_parse_real (&menu); err = syslinux_parse_real (&menu);
if (err) if (err)
return err; return err;
@@ -1512,7 +1522,7 @@ config_file (struct output_buffer *outbuf,
print_string ("\n"); print_string ("\n");
} }
for (curentry = lentry; curentry; curentry = curentry->prev) for (curentry = lentry; curentry; curentry = curentry->prev)
{ {
print_string ("menuentry "); print_string ("menuentry ");
err = print_escaped (outbuf, err = print_escaped (outbuf,
curentry->extlabel ? : curentry->label, NULL); curentry->extlabel ? : curentry->label, NULL);
@@ -4288,6 +4288,11 @@ static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, ch
} }
else if (args[0][0] == '1') else if (args[0][0] == '1')
{ {
if (argc == 2 && ventoy_check_mode_by_name(args[1], "vtcompat"))
{
return 0;
}
return g_ventoy_iso_raw ? 0 : 1; return g_ventoy_iso_raw ? 0 : 1;
} }
else if (args[0][0] == '2') else if (args[0][0] == '2')
@@ -6249,7 +6254,8 @@ static grub_err_t ventoy_cmd_need_secondary_menu(grub_extcmd_context_t ctxt, int
if (ventoy_check_mode_by_name(args[0], "vtgrub2") || if (ventoy_check_mode_by_name(args[0], "vtgrub2") ||
ventoy_check_mode_by_name(args[0], "vtwimboot") || ventoy_check_mode_by_name(args[0], "vtwimboot") ||
ventoy_check_mode_by_name(args[0], "vtmemdisk") || ventoy_check_mode_by_name(args[0], "vtmemdisk") ||
ventoy_check_mode_by_name(args[0], "vtnormal") ventoy_check_mode_by_name(args[0], "vtnormal") ||
ventoy_check_mode_by_name(args[0], "vtcompat")
) )
{ {
return 1; return 1;
@@ -30,6 +30,9 @@ elif $GREP -q 'setting up the root filesystem' /init; then
elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then
ventoy_systemd_udevd_work_around ventoy_systemd_udevd_work_around
ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
elif $GREP -q 'NVIDIA CORPORATION' /init; then
$SED "s/while true; do/while false; do/" -i /init
$SED "/^FOUNDDEV=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/mats-hook.sh \"\${ROOTFS}/\${MNTNV}\"" -i /init
else else
$SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
fi fi
+9 -1
View File
@@ -414,7 +414,9 @@ function distro_specify_initrd_file_phase2 {
elif [ -f (loop)/initramfs-linux.img ]; then elif [ -f (loop)/initramfs-linux.img ]; then
vt_linux_specify_initrd_file /initramfs-linux.img vt_linux_specify_initrd_file /initramfs-linux.img
elif [ -f (loop)/boot/isolinux/initrd.gz ]; then elif [ -f (loop)/boot/isolinux/initrd.gz ]; then
vt_linux_specify_initrd_file /boot/isolinux/initrd.gz vt_linux_specify_initrd_file /boot/isolinux/initrd.gz
elif [ -f (loop)/tiny/initrd ]; then
vt_linux_specify_initrd_file /tiny/initrd
elif vt_str_begin "$vt_volume_id" "AERYNOS"; then elif vt_str_begin "$vt_volume_id" "AERYNOS"; then
vt_vcfg_pre_proc vt_vcfg_pre_proc
@@ -861,6 +863,9 @@ function uefi_linux_menu_func {
elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then
syslinux_configfile (loop)/boot/syslinux/porteus.cfg syslinux_configfile (loop)/boot/syslinux/porteus.cfg
set vtback_cfg_find=1 set vtback_cfg_find=1
elif [ -f (loop)/syslinux.cfg ]; then
syslinux_configfile (loop)/syslinux.cfg
set vtback_cfg_find=1
fi fi
fi fi
@@ -1315,6 +1320,9 @@ function legacy_linux_menu_func {
elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then
syslinux_configfile (loop)/boot/syslinux/porteus.cfg syslinux_configfile (loop)/boot/syslinux/porteus.cfg
set vtback_cfg_find=1 set vtback_cfg_find=1
elif [ -f (loop)/syslinux.cfg ]; then
syslinux_configfile (loop)/syslinux.cfg
set vtback_cfg_find=1
fi fi
fi fi
+153 -41
View File
@@ -7,12 +7,12 @@
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the * published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
* *
@@ -69,6 +69,7 @@ static int verbose = 0;
#define CMD_EXTRACT_ISO_FILE 4 #define CMD_EXTRACT_ISO_FILE 4
#define CMD_PRINT_EXTRACT_ISO_FILE 5 #define CMD_PRINT_EXTRACT_ISO_FILE 5
#define CMD_PRINT_RAW_TABLE 6 #define CMD_PRINT_RAW_TABLE 6
#define CMD_COPY_ISO 7
static uint64_t g_iso_file_size; static uint64_t g_iso_file_size;
static char g_disk_name[128]; static char g_disk_name[128];
@@ -82,7 +83,7 @@ ventoy_img_chunk * vtoydm_get_img_map_data(const char *img_map_file, int *plen)
int rc = 1; int rc = 1;
FILE *fp = NULL; FILE *fp = NULL;
ventoy_img_chunk *chunk = NULL; ventoy_img_chunk *chunk = NULL;
fp = fopen(img_map_file, "rb"); fp = fopen(img_map_file, "rb");
if (NULL == fp) if (NULL == fp)
{ {
@@ -111,7 +112,7 @@ ventoy_img_chunk * vtoydm_get_img_map_data(const char *img_map_file, int *plen)
if (len % sizeof(ventoy_img_chunk)) if (len % sizeof(ventoy_img_chunk))
{ {
fprintf(stderr, "image map file size %d is not aligned with %d\n", fprintf(stderr, "image map file size %d is not aligned with %d\n",
len, (int)sizeof(ventoy_img_chunk)); len, (int)sizeof(ventoy_img_chunk));
goto end; goto end;
} }
@@ -139,7 +140,7 @@ UINT64 vtoydm_get_file_size(const char *pcFileName)
(void)pcFileName; (void)pcFileName;
debug("vtoydm_get_file_size %s %lu\n", pcFileName, (unsigned long)g_iso_file_size); debug("vtoydm_get_file_size %s %lu\n", pcFileName, (unsigned long)g_iso_file_size);
return g_iso_file_size; return g_iso_file_size;
} }
@@ -157,14 +158,14 @@ BISO_FILE_S * vtoydm_open_file(const char *pcFileName)
file->FileSize = g_iso_file_size; file->FileSize = g_iso_file_size;
file->CurPos = 0; file->CurPos = 0;
} }
return file; return file;
} }
void vtoydm_close_file(BISO_FILE_S *pstFile) void vtoydm_close_file(BISO_FILE_S *pstFile)
{ {
debug("vtoydm_close_file\n"); debug("vtoydm_close_file\n");
if (pstFile) if (pstFile)
{ {
free(pstFile); free(pstFile);
@@ -187,7 +188,7 @@ UINT64 vtoydm_map_iso_sector(UINT64 sector)
{ {
int i; int i;
UINT64 disk_sector = 0; UINT64 disk_sector = 0;
for (i = 0; i < g_img_chunk_num; i++) for (i = 0; i < g_img_chunk_num; i++)
{ {
if (sector >= g_img_chunk[i].img_start_sector && sector <= g_img_chunk[i].img_end_sector) if (sector >= g_img_chunk[i].img_start_sector && sector <= g_img_chunk[i].img_end_sector)
@@ -205,7 +206,7 @@ int vtoydm_read_iso_sector(UINT64 sector, void *buf)
int i; int i;
int fd; int fd;
UINT64 disk_sector = 0; UINT64 disk_sector = 0;
for (i = 0; i < g_img_chunk_num; i++) for (i = 0; i < g_img_chunk_num; i++)
{ {
if (sector >= g_img_chunk[i].img_start_sector && sector <= g_img_chunk[i].img_end_sector) if (sector >= g_img_chunk[i].img_start_sector && sector <= g_img_chunk[i].img_end_sector)
@@ -232,9 +233,9 @@ int vtoydm_read_iso_sector(UINT64 sector, void *buf)
UINT64 vtoydm_read_file UINT64 vtoydm_read_file
( (
BISO_FILE_S *pstFile, BISO_FILE_S *pstFile,
UINT uiBlkSize, UINT uiBlkSize,
UINT uiBlkNum, UINT uiBlkNum,
VOID *pBuf VOID *pBuf
) )
{ {
@@ -249,7 +250,7 @@ UINT64 vtoydm_read_file
if (pos > 0) if (pos > 0)
{ {
align = 2048 - pos; align = 2048 - pos;
vtoydm_read_iso_sector(pstFile->CurPos / 2048, g_iso_sector_buf); vtoydm_read_iso_sector(pstFile->CurPos / 2048, g_iso_sector_buf);
if (readlen > align) if (readlen > align)
{ {
@@ -270,7 +271,7 @@ UINT64 vtoydm_read_file
{ {
vtoydm_read_iso_sector(pstFile->CurPos / 2048, curbuf); vtoydm_read_iso_sector(pstFile->CurPos / 2048, curbuf);
pstFile->CurPos += 2048; pstFile->CurPos += 2048;
curbuf += 2048; curbuf += 2048;
readlen -= 2048; readlen -= 2048;
} }
@@ -281,7 +282,7 @@ UINT64 vtoydm_read_file
memcpy(curbuf, g_iso_sector_buf, readlen); memcpy(curbuf, g_iso_sector_buf, readlen);
pstFile->CurPos += readlen; pstFile->CurPos += readlen;
} }
return uiBlkSize * uiBlkNum; return uiBlkSize * uiBlkNum;
} }
@@ -295,7 +296,7 @@ int vtoydm_dump_iso(const char *img_map_file, const char *diskname)
BISO_READ_S *iso; BISO_READ_S *iso;
BISO_PARSER_S *parser = NULL; BISO_PARSER_S *parser = NULL;
char label[64] = {0}; char label[64] = {0};
chunk = vtoydm_get_img_map_data(img_map_file, &len); chunk = vtoydm_get_img_map_data(img_map_file, &len);
if (NULL == chunk) if (NULL == chunk)
{ {
@@ -324,7 +325,7 @@ int vtoydm_dump_iso(const char *img_map_file, const char *diskname)
ret = BISO_OpenImage("XXX", iso); ret = BISO_OpenImage("XXX", iso);
debug("open iso image ret=0x%lx\n", ret); debug("open iso image ret=0x%lx\n", ret);
parser = (BISO_PARSER_S *)iso; parser = (BISO_PARSER_S *)iso;
memcpy(label, parser->pstPVD->szVolumeId, 32); memcpy(label, parser->pstPVD->szVolumeId, 32);
for (i = 32; i >=0; i--) for (i = 32; i >=0; i--)
{ {
@@ -340,11 +341,11 @@ int vtoydm_dump_iso(const char *img_map_file, const char *diskname)
if (label[0]) if (label[0])
{ {
printf("VENTOY_ISO_LABEL %s\n", label); printf("VENTOY_ISO_LABEL %s\n", label);
} }
BISO_DumpFileTree(iso); BISO_DumpFileTree(iso);
BISO_FreeReadHandle(iso); BISO_FreeReadHandle(iso);
free(chunk); free(chunk);
@@ -353,7 +354,7 @@ int vtoydm_dump_iso(const char *img_map_file, const char *diskname)
static int vtoydm_extract_iso static int vtoydm_extract_iso
( (
const char *img_map_file, const char *img_map_file,
const char *diskname, const char *diskname,
unsigned long first_sector, unsigned long first_sector,
unsigned long long file_size, unsigned long long file_size,
@@ -394,16 +395,119 @@ static int vtoydm_extract_iso
file_size = 0; file_size = 0;
} }
} }
fclose(fp); fclose(fp);
free(g_img_chunk); free(g_img_chunk);
return 0; return 0;
} }
static int vtoydm_copy_iso
(
const char *img_map_file,
const char *diskname,
const char *outfile
)
{
int i;
int len;
int fd = -1;
int ret = 1;
uint32_t bufsize = 1048576;
uint64_t TotSize = 0;
uint64_t ChunkSize = 0;
uint64_t Second1 = 0;
uint64_t Second2 = 0;
FILE *fp = NULL;
char *pcBuf = NULL;
Second1 = time(NULL);
debug("Start copy iso file ...\n");
pcBuf = (char *)malloc(bufsize);
if (!pcBuf)
{
goto end;
}
g_img_chunk = vtoydm_get_img_map_data(img_map_file, &len);
if (NULL == g_img_chunk)
{
goto end;
}
g_img_chunk_num = len / sizeof(ventoy_img_chunk);
strncpy(g_disk_name, diskname, sizeof(g_disk_name) - 1);
fd = open(g_disk_name, O_RDONLY | O_BINARY);
if (fd < 0)
{
debug("Failed to open %s\n", g_disk_name);
goto end;
}
fp = fopen(outfile, "wb");
if (fp == NULL)
{
fprintf(stderr, "Failed to create file %s err:%d\n", outfile, errno);
goto end;
}
for (i = 0; i < g_img_chunk_num; i++)
{
ChunkSize = (g_img_chunk[i].img_end_sector + 1 - g_img_chunk[i].img_start_sector) * 2048;
TotSize += ChunkSize;
lseek(fd, g_img_chunk[i].disk_start_sector * 512, SEEK_SET);
while (ChunkSize > 0)
{
if (ChunkSize >= bufsize)
{
read(fd, pcBuf, bufsize);
fwrite(pcBuf, bufsize, 1, fp);
ChunkSize -= bufsize;
}
else
{
read(fd, pcBuf, ChunkSize);
fwrite(pcBuf, ChunkSize, 1, fp);
ChunkSize = 0;
}
}
}
Second2 = time(NULL);
debug("Copy finish, iso size:%llu seconds:%d\n", (_ULL)TotSize, (int)(Second2 - Second1));
ret = 0;
end:
if (fp)
{
fclose(fp);
}
if (fd >= 0)
{
close(fd);
}
if (g_img_chunk)
{
free(g_img_chunk);
}
if (pcBuf)
{
free(pcBuf);
}
return ret;
}
static int vtoydm_print_extract_iso static int vtoydm_print_extract_iso
( (
const char *img_map_file, const char *img_map_file,
const char *diskname, const char *diskname,
unsigned long first_sector, unsigned long first_sector,
unsigned long long file_size, unsigned long long file_size,
@@ -461,7 +565,7 @@ static int vtoydm_print_extract_iso
last = sector; last = sector;
count = 4; count = 4;
} }
if (file_size > 2048) if (file_size > 2048)
{ {
file_size -= 2048; file_size -= 2048;
@@ -478,7 +582,7 @@ static int vtoydm_print_extract_iso
buf[1] = count; buf[1] = count;
fwrite(buf, 1, sizeof(buf), fp); fwrite(buf, 1, sizeof(buf), fp);
} }
fclose(fp); fclose(fp);
free(g_img_chunk); free(g_img_chunk);
return 0; return 0;
@@ -494,7 +598,7 @@ static int vtoydm_print_linear_table(const char *img_map_file, const char *diskn
uint32_t disk_sector_num; uint32_t disk_sector_num;
uint32_t sector_start; uint32_t sector_start;
ventoy_img_chunk *chunk = NULL; ventoy_img_chunk *chunk = NULL;
chunk = vtoydm_get_img_map_data(img_map_file, &len); chunk = vtoydm_get_img_map_data(img_map_file, &len);
if (NULL == chunk) if (NULL == chunk)
{ {
@@ -508,20 +612,20 @@ static int vtoydm_print_linear_table(const char *img_map_file, const char *diskn
/* TBD: to be more flexible */ /* TBD: to be more flexible */
#if 0 #if 0
printf("%u %u linear %s %llu\n", printf("%u %u linear %s %llu\n",
(sector_start << 2), disk_sector_num, (sector_start << 2), disk_sector_num,
diskname, (unsigned long long)chunk[i].disk_start_sector); diskname, (unsigned long long)chunk[i].disk_start_sector);
#else #else
if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd")) if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
{ {
printf("%u %u linear %sp%d %llu\n", printf("%u %u linear %sp%d %llu\n",
(sector_start << 2), disk_sector_num, (sector_start << 2), disk_sector_num,
diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset); diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset);
} }
else else
{ {
printf("%u %u linear %s%d %llu\n", printf("%u %u linear %s%d %llu\n",
(sector_start << 2), disk_sector_num, (sector_start << 2), disk_sector_num,
diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset); diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset);
} }
#endif #endif
@@ -539,7 +643,7 @@ static int vtoydm_print_help(FILE *fp)
" vtoydm -i -f img_map_file -d diskname [ -v ] \n" " vtoydm -i -f img_map_file -d diskname [ -v ] \n"
" vtoydm -e -f img_map_file -d diskname -s sector -l len -o file [ -v ] \n" " vtoydm -e -f img_map_file -d diskname -s sector -l len -o file [ -v ] \n"
); );
return 0; return 0;
} }
static uint64_t vtoydm_get_part_start(const char *diskname, int part) static uint64_t vtoydm_get_part_start(const char *diskname, int part)
@@ -561,7 +665,7 @@ static uint64_t vtoydm_get_part_start(const char *diskname, int part)
if (access(diskpath, F_OK) >= 0) if (access(diskpath, F_OK) >= 0)
{ {
debug("get part start from sysfs for %s %d\n", diskname, part); debug("get part start from sysfs for %s %d\n", diskname, part);
fd = open(diskpath, O_RDONLY | O_BINARY); fd = open(diskpath, O_RDONLY | O_BINARY);
if (fd >= 0) if (fd >= 0)
{ {
@@ -600,7 +704,7 @@ static uint64_t vtoydm_get_part_secnum(const char *diskname, int part)
if (access(diskpath, F_OK) >= 0) if (access(diskpath, F_OK) >= 0)
{ {
debug("get part size from sysfs for %s %d\n", diskname, part); debug("get part size from sysfs for %s %d\n", diskname, part);
fd = open(diskpath, O_RDONLY | O_BINARY); fd = open(diskpath, O_RDONLY | O_BINARY);
if (fd >= 0) if (fd >= 0)
{ {
@@ -647,12 +751,12 @@ static int vtoydm_vlnk_convert(char *disk, int len, int *part, uint64_t *offset)
if (param.vtoy_reserved[6]) if (param.vtoy_reserved[6])
{ {
cnt = vtoy_find_disk_by_guid(&param, diskname); cnt = vtoy_find_disk_by_guid(&param, diskname);
debug("vtoy_find_disk_by_guid cnt=%d\n", cnt); debug("vtoy_find_disk_by_guid cnt=%d\n", cnt);
if (cnt == 1) if (cnt == 1)
{ {
*part = param.vtoy_disk_part_id; *part = param.vtoy_disk_part_id;
*offset = vtoydm_get_part_start(diskname, *part); *offset = vtoydm_get_part_start(diskname, *part);
debug("VLNK <%s> <%s> <P%d> <%llu>\n", disk, diskname, *part, (unsigned long long)(*offset)); debug("VLNK <%s> <%s> <P%d> <%llu>\n", disk, diskname, *part, (unsigned long long)(*offset));
snprintf(disk, len, "/dev/%s", diskname); snprintf(disk, len, "/dev/%s", diskname);
@@ -681,7 +785,7 @@ static int vtoydm_print_raw_linear_table(const char *img_map_file, const char *d
{ {
printf("0 %lu linear %s%d 0\n", (unsigned long)disk_sector_num, diskname, part); printf("0 %lu linear %s%d 0\n", (unsigned long)disk_sector_num, diskname, part);
} }
return 0; return 0;
} }
@@ -697,7 +801,7 @@ int vtoydm_main(int argc, char **argv)
char filepath[300] = {0}; char filepath[300] = {0};
char outfile[300] = {0}; char outfile[300] = {0};
while ((ch = getopt(argc, argv, "s:l:o:d:f:v::i::p::r::c::h::e::E::")) != -1) while ((ch = getopt(argc, argv, "s:l:o:d:f:v::i::p::r::c::h::e::E::C::")) != -1)
{ {
if (ch == 'd') if (ch == 'd')
{ {
@@ -719,6 +823,10 @@ int vtoydm_main(int argc, char **argv)
{ {
cmd = CMD_CREATE_DM; cmd = CMD_CREATE_DM;
} }
else if (ch == 'C')
{
cmd = CMD_COPY_ISO;
}
else if (ch == 'i') else if (ch == 'i')
{ {
cmd = CMD_DUMP_ISO_INFO; cmd = CMD_DUMP_ISO_INFO;
@@ -764,11 +872,11 @@ int vtoydm_main(int argc, char **argv)
return 1; return 1;
} }
debug("cmd=%d file=<%s> disk=<%s> first_sector=%lu file_size=%llu\n", debug("cmd=%d file=<%s> disk=<%s> first_sector=%lu file_size=%llu\n",
cmd, filepath, diskname, first_sector, file_size); cmd, filepath, diskname, first_sector, file_size);
vtoydm_vlnk_convert(diskname, sizeof(diskname), &part, &offset); vtoydm_vlnk_convert(diskname, sizeof(diskname), &part, &offset);
switch (cmd) switch (cmd)
{ {
case CMD_PRINT_TABLE: case CMD_PRINT_TABLE:
@@ -795,6 +903,10 @@ int vtoydm_main(int argc, char **argv)
{ {
return vtoydm_print_extract_iso(filepath, diskname, first_sector, file_size, outfile); return vtoydm_print_extract_iso(filepath, diskname, first_sector, file_size, outfile);
} }
case CMD_COPY_ISO:
{
return vtoydm_copy_iso(filepath, diskname, outfile);
}
default : default :
{ {
fprintf(stderr, "Invalid cmd \n"); fprintf(stderr, "Invalid cmd \n");
+10 -8
View File
@@ -7,12 +7,12 @@
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the * published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
* *
@@ -67,7 +67,7 @@ typedef struct ventoy_image_disk_region
typedef struct ventoy_image_location typedef struct ventoy_image_location
{ {
ventoy_guid guid; ventoy_guid guid;
/* image sector size, currently this value is always 2048 */ /* image sector size, currently this value is always 2048 */
uint32_t image_sector_size; uint32_t image_sector_size;
@@ -75,12 +75,12 @@ typedef struct ventoy_image_location
uint32_t disk_sector_size; uint32_t disk_sector_size;
uint32_t region_count; uint32_t region_count;
/* /*
* disk region data * disk region data
* If the image file has more than one fragments in disk, * If the image file has more than one fragments in disk,
* there will be more than one region data here. * there will be more than one region data here.
* You can calculate the region count by * You can calculate the region count by
*/ */
ventoy_image_disk_region regions[1]; ventoy_image_disk_region regions[1];
@@ -99,7 +99,7 @@ typedef struct ventoy_os_param
char vtoy_img_path[384]; // It seems to be enough, utf-8 format char vtoy_img_path[384]; // It seems to be enough, utf-8 format
uint64_t vtoy_img_size; // image file size in bytes uint64_t vtoy_img_size; // image file size in bytes
/* /*
* Ventoy will write a copy of ventoy_image_location data into runtime memory * Ventoy will write a copy of ventoy_image_location data into runtime memory
* this is the physically address and length of that memory. * this is the physically address and length of that memory.
* Address 0 means no such data exist. * Address 0 means no such data exist.
@@ -112,7 +112,7 @@ typedef struct ventoy_os_param
uint8_t vtoy_reserved[32]; // Internal use by ventoy uint8_t vtoy_reserved[32]; // Internal use by ventoy
uint8_t vtoy_disk_signature[4]; uint8_t vtoy_disk_signature[4];
uint8_t reserved[27]; uint8_t reserved[27];
}ventoy_os_param; }ventoy_os_param;
@@ -121,3 +121,5 @@ typedef struct ventoy_os_param
int vtoy_find_disk_by_guid(ventoy_os_param *param, char *diskname); int vtoy_find_disk_by_guid(ventoy_os_param *param, char *diskname);
#endif #endif
#define _ULL unsigned long long