Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dadigang
Ventoy
Commits
5d0ebf45
Commit
5d0ebf45
authored
Jul 27, 2021
by
longpanda
Browse files
support custom arch iso (#1021)
parent
cf94487a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
497 additions
and
0 deletions
+497
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c
GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c
+257
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
+207
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
+11
-0
INSTALL/grub/grub.cfg
INSTALL/grub/grub.cfg
+22
-0
No files found.
GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c
0 → 100644
View file @
5d0ebf45
/* loopback.c - command to add loopback devices. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
GRUB_MOD_LICENSE
(
"GPLv3+"
);
struct
grub_loopback
{
char
*
devname
;
grub_file_t
file
;
struct
grub_loopback
*
next
;
unsigned
long
id
;
grub_off_t
skip
;
};
static
struct
grub_loopback
*
loopback_list
;
static
unsigned
long
last_id
=
0
;
static
const
struct
grub_arg_option
options
[]
=
{
/* TRANSLATORS: The disk is simply removed from the list of available ones,
not wiped, avoid to scare user. */
{
"delete"
,
'd'
,
0
,
N_
(
"Delete the specified loopback drive."
),
0
,
0
},
{
"skip"
,
's'
,
0
,
"skip sectors of the file."
,
"SECTORS"
,
ARG_TYPE_INT
},
{
0
,
0
,
0
,
0
,
0
,
0
}
};
/* Delete the loopback device NAME. */
static
grub_err_t
delete_loopback
(
const
char
*
name
)
{
struct
grub_loopback
*
dev
;
struct
grub_loopback
**
prev
;
/* Search for the device. */
for
(
dev
=
loopback_list
,
prev
=
&
loopback_list
;
dev
;
prev
=
&
dev
->
next
,
dev
=
dev
->
next
)
if
(
grub_strcmp
(
dev
->
devname
,
name
)
==
0
)
break
;
if
(
!
dev
)
return
grub_error
(
GRUB_ERR_BAD_DEVICE
,
"device not found"
);
/* Remove the device from the list. */
*
prev
=
dev
->
next
;
grub_free
(
dev
->
devname
);
grub_file_close
(
dev
->
file
);
grub_free
(
dev
);
return
0
;
}
/* The command to add and remove loopback devices. */
static
grub_err_t
grub_cmd_loopback
(
grub_extcmd_context_t
ctxt
,
int
argc
,
char
**
args
)
{
struct
grub_arg_list
*
state
=
ctxt
->
state
;
grub_file_t
file
;
struct
grub_loopback
*
newdev
;
grub_err_t
ret
;
grub_off_t
skip
=
0
;
if
(
argc
<
1
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"device name required"
);
/* Check if `-d' was used. */
if
(
state
[
0
].
set
)
return
delete_loopback
(
args
[
0
]);
if
(
state
[
1
].
set
)
skip
=
(
grub_off_t
)
grub_strtoull
(
state
[
1
].
arg
,
NULL
,
10
);
if
(
argc
<
2
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"filename expected"
));
file
=
grub_file_open
(
args
[
1
],
GRUB_FILE_TYPE_LOOPBACK
|
GRUB_FILE_TYPE_NO_DECOMPRESS
);
if
(
!
file
)
return
grub_errno
;
/* First try to replace the old device. */
for
(
newdev
=
loopback_list
;
newdev
;
newdev
=
newdev
->
next
)
if
(
grub_strcmp
(
newdev
->
devname
,
args
[
0
])
==
0
)
break
;
if
(
newdev
)
{
grub_file_close
(
newdev
->
file
);
newdev
->
file
=
file
;
newdev
->
skip
=
skip
;
return
0
;
}
/* Unable to replace it, make a new entry. */
newdev
=
grub_malloc
(
sizeof
(
struct
grub_loopback
));
if
(
!
newdev
)
goto
fail
;
newdev
->
devname
=
grub_strdup
(
args
[
0
]);
if
(
!
newdev
->
devname
)
{
grub_free
(
newdev
);
goto
fail
;
}
newdev
->
file
=
file
;
newdev
->
skip
=
skip
;
newdev
->
id
=
last_id
++
;
/* Add the new entry to the list. */
newdev
->
next
=
loopback_list
;
loopback_list
=
newdev
;
return
0
;
fail:
ret
=
grub_errno
;
grub_file_close
(
file
);
return
ret
;
}
static
int
grub_loopback_iterate
(
grub_disk_dev_iterate_hook_t
hook
,
void
*
hook_data
,
grub_disk_pull_t
pull
)
{
struct
grub_loopback
*
d
;
if
(
pull
!=
GRUB_DISK_PULL_NONE
)
return
0
;
for
(
d
=
loopback_list
;
d
;
d
=
d
->
next
)
{
if
(
hook
(
d
->
devname
,
hook_data
))
return
1
;
}
return
0
;
}
static
grub_err_t
grub_loopback_open
(
const
char
*
name
,
grub_disk_t
disk
)
{
struct
grub_loopback
*
dev
;
for
(
dev
=
loopback_list
;
dev
;
dev
=
dev
->
next
)
if
(
grub_strcmp
(
dev
->
devname
,
name
)
==
0
)
break
;
if
(
!
dev
)
return
grub_error
(
GRUB_ERR_UNKNOWN_DEVICE
,
"can't open device"
);
/* Use the filesize for the disk size, round up to a complete sector. */
if
(
dev
->
file
->
size
!=
GRUB_FILE_SIZE_UNKNOWN
)
disk
->
total_sectors
=
((
dev
->
file
->
size
+
GRUB_DISK_SECTOR_SIZE
-
1
)
/
GRUB_DISK_SECTOR_SIZE
);
else
disk
->
total_sectors
=
GRUB_DISK_SIZE_UNKNOWN
;
/* Avoid reading more than 512M. */
disk
->
max_agglomerate
=
1
<<
(
29
-
GRUB_DISK_SECTOR_BITS
-
GRUB_DISK_CACHE_BITS
);
disk
->
id
=
dev
->
id
;
disk
->
data
=
dev
;
return
0
;
}
static
grub_err_t
grub_loopback_read
(
grub_disk_t
disk
,
grub_disk_addr_t
sector
,
grub_size_t
size
,
char
*
buf
)
{
grub_file_t
file
=
((
struct
grub_loopback
*
)
disk
->
data
)
->
file
;
grub_off_t
skip
=
((
struct
grub_loopback
*
)
disk
->
data
)
->
skip
;
grub_off_t
pos
;
grub_file_seek
(
file
,
(
sector
+
skip
)
<<
GRUB_DISK_SECTOR_BITS
);
grub_file_read
(
file
,
buf
,
size
<<
GRUB_DISK_SECTOR_BITS
);
if
(
grub_errno
)
return
grub_errno
;
/* In case there is more data read than there is available, in case
of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
the rest with zeros. */
pos
=
(
sector
+
skip
+
size
)
<<
GRUB_DISK_SECTOR_BITS
;
if
(
pos
>
file
->
size
)
{
grub_size_t
amount
=
pos
-
file
->
size
;
grub_memset
(
buf
+
(
size
<<
GRUB_DISK_SECTOR_BITS
)
-
amount
,
0
,
amount
);
}
return
0
;
}
static
grub_err_t
grub_loopback_write
(
grub_disk_t
disk
__attribute
((
unused
)),
grub_disk_addr_t
sector
__attribute
((
unused
)),
grub_size_t
size
__attribute
((
unused
)),
const
char
*
buf
__attribute
((
unused
)))
{
return
grub_error
(
GRUB_ERR_NOT_IMPLEMENTED_YET
,
"loopback write is not supported"
);
}
static
struct
grub_disk_dev
grub_loopback_dev
=
{
.
name
=
"loopback"
,
.
id
=
GRUB_DISK_DEVICE_LOOPBACK_ID
,
.
disk_iterate
=
grub_loopback_iterate
,
.
disk_open
=
grub_loopback_open
,
.
disk_read
=
grub_loopback_read
,
.
disk_write
=
grub_loopback_write
,
.
next
=
0
};
static
grub_extcmd_t
cmd
;
GRUB_MOD_INIT
(
loopback
)
{
cmd
=
grub_register_extcmd
(
"loopback"
,
grub_cmd_loopback
,
0
,
N_
(
"[-d] DEVICENAME FILE."
),
/* TRANSLATORS: The file itself is not destroyed
or transformed into drive. */
N_
(
"Make a virtual drive from a file."
),
options
);
grub_disk_dev_register
(
&
grub_loopback_dev
);
}
GRUB_MOD_FINI
(
loopback
)
{
grub_unregister_extcmd
(
cmd
);
grub_disk_dev_unregister
(
&
grub_loopback_dev
);
}
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
View file @
5d0ebf45
...
...
@@ -3148,6 +3148,22 @@ static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int ar
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static grub_err_t ventoy_cmd_get_replace_file_cnt(grub_extcmd_context_t ctxt, int argc, char **args)
{
char buf[32];
ventoy_grub_param_file_replace *replace = &(g_grub_param->file_replace);
(void)ctxt;
if (argc >= 1)
{
grub_snprintf(buf, sizeof(buf), "%u", replace->old_name_cnt);
grub_env_set(args[0], buf);
}
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
...
...
@@ -4425,6 +4441,194 @@ static grub_err_t ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt, int argc
VENTOY_CMD_RETURN(0);
}
static grub_err_t ventoy_cmd_get_efivdisk_offset(grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_uint32_t i;
grub_uint32_t loadsector = 0;
grub_file_t file;
char value[32];
grub_uint32_t boot_catlog = 0;
grub_uint8_t buf[512];
(void)ctxt;
if (argc != 2)
{
debug("ventoy_cmd_get_efivdisk_offset, invalid param num %d\n", argc);
return 1;
}
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (!file)
{
debug("failed to open %s\n", args[0]);
return 1;
}
boot_catlog = ventoy_get_iso_boot_catlog(file);
if (boot_catlog == 0)
{
debug("No bootcatlog found\n");
grub_file_close(file);
return 1;
}
grub_memset(buf, 0, sizeof(buf));
grub_file_seek(file, boot_catlog * 2048);
grub_file_read(file, buf, sizeof(buf));
grub_file_close(file);
for (i = 0; i < sizeof(buf); i += 32)
{
if ((buf[i] == 0 || buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF)
{
if (buf[i + 32] == 0x88)
{
loadsector = *(grub_uint32_t *)(buf + i + 32 + 8);
grub_snprintf(value, sizeof(value), "%u", loadsector * 4); //change to sector size 512
break;
}
}
}
if (loadsector == 0)
{
debug("No EFI eltorito info found\n");
return 1;
}
debug("ventoy_cmd_get_efivdisk_offset <%s>\n", value);
grub_env_set(args[1], value);
VENTOY_CMD_RETURN(0);
}
static int ventoy_collect_replace_initrd(const char *filename, const struct grub_dirhook_info *info, void *data)
{
int curpos;
int printlen;
grub_size_t len;
replace_fs_dir *pfsdir = (replace_fs_dir *)data;
if (pfsdir->initrd[0])
{
return 1;
}
curpos = pfsdir->curpos;
len = grub_strlen(filename);
if (info->dir)
{
if ((len == 1 && filename[0] == '.') ||
(len == 2 && filename[0] == '.' && filename[1] == '.'))
{
return 0;
}
//debug("#### [DIR] <%s> <%s>\n", pfsdir->fullpath, filename);
pfsdir->dircnt++;
printlen = grub_snprintf(pfsdir->fullpath + curpos, 512 - curpos, "%s/", filename);
pfsdir->curpos = curpos + printlen;
pfsdir->fs->fs_dir(pfsdir->dev, pfsdir->fullpath, ventoy_collect_replace_initrd, pfsdir);
pfsdir->curpos = curpos;
pfsdir->fullpath[curpos] = 0;
}
else
{
//debug("#### [FILE] <%s> <%s>\n", pfsdir->fullpath, filename);
pfsdir->filecnt++;
/* We consider the xxx.img file bigger than 32MB is the initramfs file */
if (len > 4 && grub_strncmp(filename + len - 4, ".img", 4) == 0)
{
if (info->size > 32 * VTOY_SIZE_1MB)
{
grub_snprintf(pfsdir->initrd, sizeof(pfsdir->initrd), "%s%s", pfsdir->fullpath, filename);
return 1;
}
}
}
return 0;
}
static grub_err_t ventoy_cmd_search_replace_initrd(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i;
char *pos = NULL;
char *device_name = NULL;
grub_device_t dev = NULL;
grub_fs_t fs = NULL;
replace_fs_dir *pfsdir = NULL;
(void)ctxt;
if (argc != 2)
{
debug("ventoy_cmd_search_replace_initrd, invalid param num %d\n", argc);
return 1;
}
pfsdir = grub_zalloc(sizeof(replace_fs_dir));
if (!pfsdir)
{
return 1;
}
device_name = grub_file_get_device_name(args[0]);
if (!device_name)
{
goto fail;
}
dev = grub_device_open(device_name);
if (!dev)
{
goto fail;
}
fs = grub_fs_probe(dev);
if (!fs)
{
goto fail;
}
pfsdir->dev = dev;
pfsdir->fs = fs;
pfsdir->curpos = 1;
pfsdir->fullpath[0] = '/';
fs->fs_dir(dev, "/", ventoy_collect_replace_initrd, pfsdir);
if (pfsdir->initrd[0])
{
debug("Replace initrd <%s> <%d %d>\n", pfsdir->initrd, pfsdir->dircnt, pfsdir->filecnt);
for (i = 0; i < (int)sizeof(pfsdir->initrd) && pfsdir->initrd[i]; i++)
{
if (pfsdir->initrd[i] == '/')
{
pfsdir->initrd[i] = '\\';
}
}
pos = (pfsdir->initrd[0] == '\\') ? pfsdir->initrd + 1 : pfsdir->initrd;
grub_env_set(args[1], pos);
}
else
{
debug("Replace initrd NOT found <%s> <%d %d>\n", args[0], pfsdir->dircnt, pfsdir->filecnt);
}
fail:
grub_check_free(pfsdir);
grub_check_free(device_name);
check_free(dev, grub_device_close);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
int ventoy_env_init(void)
{
char buf[64];
...
...
@@ -4560,6 +4764,7 @@ static cmd_para ventoy_cmds[] =
{ "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL },
{ "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL },
{ "vt_get_replace_file_cnt", ventoy_cmd_get_replace_file_cnt, 0, NULL, "", "", NULL },
{ "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL },
{ "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL },
...
...
@@ -4596,6 +4801,8 @@ static cmd_para ventoy_cmds[] =
{ "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL },
{ "vt_set_theme", ventoy_cmd_set_theme, 0, NULL, "", "", NULL },
{ "vt_get_efi_vdisk_offset", ventoy_cmd_get_efivdisk_offset, 0, NULL, "", "", NULL },
{ "vt_search_replace_initrd", ventoy_cmd_search_replace_initrd, 0, NULL, "", "", NULL },
};
int ventoy_register_all_cmd(void)
...
...
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
View file @
5d0ebf45
...
...
@@ -533,6 +533,17 @@ typedef struct plugin_entry
ventoy_plugin_check_pf
checkfunc
;
}
plugin_entry
;
typedef
struct
replace_fs_dir
{
grub_device_t
dev
;
grub_fs_t
fs
;
char
fullpath
[
512
];
char
initrd
[
512
];
int
curpos
;
int
dircnt
;
int
filecnt
;
}
replace_fs_dir
;
int
ventoy_strcmp
(
const
char
*
pattern
,
const
char
*
str
);
int
ventoy_strncmp
(
const
char
*
pattern
,
const
char
*
str
,
grub_size_t
n
);
void
ventoy_fill_os_param
(
grub_file_t
file
,
ventoy_os_param
*
param
);
...
...
INSTALL/grub/grub.cfg
View file @
5d0ebf45
...
...
@@ -548,6 +548,23 @@ function uefi_windows_menu_func {
fi
}
function uefi_find_replace_initrd {
if vt_get_efi_vdisk_offset "${1}${2}" vt_efivdisk_offset; then
loopback -s $vt_efivdisk_offset vtefivdisk "${1}${2}"
unset vt_rp_initrd
vt_search_replace_initrd (vtefivdisk) vt_rp_initrd
if [ -n "$vt_rp_initrd" ]; then
vt_add_replace_file $3 "$vt_rp_initrd"
echo vt_add_replace_file $3 "$vt_rp_initrd"
fi
loopback -d vtefivdisk
ventoy_debug_pause
fi
}
function uefi_linux_menu_func {
if [ "$ventoy_compatible" = "NO" ]; then
...
...
@@ -629,6 +646,11 @@ function uefi_linux_menu_func {
elif [ -f (loop)/loader/entries/pisi-efi-x86_64.conf ]; then
vt_add_replace_file $vtindex "EFI\\pisi\\initrd.img"
fi
vt_get_replace_file_cnt vt_replace_cnt
if [ $vt_replace_cnt -eq 0 ]; then
uefi_find_replace_initrd "$1" "$2" $vtindex
fi
elif [ -d (loop)/EFI/boot/entries ]; then
if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then
vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment