Major changes: mbr/fat32, gpt/fat32, gpt/ntfs, gpt+uefintfs

* Use FAT32 partition in MBR mode and also install EFI bootloader
* Use wimsplit to split 4+ GiB install.wim file to fit FAT32 partition
* Rework partitioning modes
This commit is contained in:
ValdikSS 2021-08-16 00:46:55 +03:00
parent df471fd672
commit 25abfc4a9f

View File

@ -13,7 +13,7 @@ dirpath="$(dirname "$scriptpath")"
function check_requirements() {
local reqs=(awk lsblk 7z mkfs.vfat mkfs.ntfs sfdisk ms-sys mktemp)
local reqs=(awk lsblk 7z mkfs.vfat mkfs.ntfs sfdisk ms-sys mktemp wimsplit)
for req in ${reqs[*]}; do
if ! command -v "$req" > /dev/null;
@ -69,9 +69,10 @@ function check_installwim_gt4gib() {
function create_partitions() {
local mbrscript="- - 7 *"
local gptscript="- - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 *"
local gptntfsscript="- 1MiB U *\n- - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 *"
local gptuefintfsscript="- 1MiB U *\n- - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 *"
if [[ "$1" == "dos" ]] || [[ "$1" == "gpt" ]] || [[ "$1" == "gptntfs" ]];
if [[ "$1" == "dos" ]] || [[ "$1" == "gpt" ]] || [[ "$1" == "gptntfs" ]] \
|| [[ "$1" == "gpt+uefintfs" ]];
then
if [[ "$1" == "dos" ]];
then
@ -83,7 +84,11 @@ function create_partitions() {
elif [[ "$1" == "gptntfs" ]];
then
echo -e "$gptntfsscript" | sfdisk "$2"
echo -e "$gptscript" | sfdisk "$2"
elif [[ "$1" == "gpt+uefintfs" ]];
then
echo -e "$gptuefintfsscript" | sfdisk "$2"
fi
else
echo "${bold} == create_partitions: INTERNAL ERROR ==${normal}"
@ -122,8 +127,23 @@ function write_uefintfs() {
function extract_iso() {
# $1 - isopath
# $2 - destdir
# $3 - exclude install.wim extraction flag
7z x "$1" -o"$2"
if [[ "$3" == "skipinstallwim" ]]; then
7z x "$1" -o"$2" '-x!sources/install.wim'
else
7z x "$1" -o"$2"
fi
}
function split_wim() {
# $1 - isopath
# $2 - isomountpath
# $3 - destdir
mount -o ro "$1" "$2"
wimsplit "$2/sources/install.wim" "$3/sources/install.swm" 3800
umount "$2"
}
function extract_bootmgfw_from_installwim() {
@ -134,28 +154,47 @@ function extract_bootmgfw_from_installwim() {
}
function umount_rm_path() {
if [ -d "$1" ];
then
if [ -d "$1" ]; then
umount "$1" || true
rm -r "$1"
fi
if [ -d "$2" ]; then
umount "$2" 2>/dev/null || true
rm -r "$2"
fi
}
function sigint_handler() {
umount_rm_path "$partpath"
umount_rm_path "$partpath" "$isomountpath"
}
if [[ ! "$3" ]];
then
echo "Windows 7/8/8.1/10 ISO to Flash Drive burning utility"
echo "WARNING: this program will delete all existing data on your drive!"
echo "${bold}Windows 7/8/8.1/10/11 ISO to Flash Drive burning utility"
echo "WARNING: this program will delete all existing data on your drive!${normal}"
echo
echo "$(basename "$0")" "<device> <windows iso> <mbr/gpt/gptntfs>"
echo "$(basename "$0")" "<device> <windows iso> <mbr/gpt/gptntfs/gpt+uefintfs>"
echo
echo "Use MBR mode for old computers with BIOS (without UEFI), or for UEFI legacy mode (CSM)."
echo "Use GPT mode for new UEFI computers."
echo "Use 'gptntfs' mode for custom ISO images with install.wim file greater than 4 GiB."
echo "NOTE: gptntfs does not support Secure Boot!"
echo "mbr mode: the most universal, RECOMMENDED method."
echo " This mode creates MBR partition table with FAT32 partition,"
echo " installs BIOS and UEFI bootloaders, supports Secure Boot."
echo " install.wim file larger than 4 GiB will be split."
echo " Suitable for all computers (UEFI/CSM/BIOS)."
echo
echo "gpt mode: less universal mode, for modern (UEFI) computers."
echo " GPT+FAT32, UEFI only, supports Secure Boot."
echo
echo "gptntfs mode: all the same as 'gpt' but NTFS is used."
echo " GPT+NTFS, UEFI only, supports Secure Boot."
echo " Large install.wim file will not be split."
echo " NOTE: not all UEFI are compatible with this mode,"
echo " NTFS driver should be present on the motherboard."
echo
echo "gpt+uefintfs mode: alternative hacky installation method, not recommended."
echo " This mode uses NTFS partition and third-party 'uefintfs' bootloader."
echo " GPT+NTFS(data)+FAT32(efi), UEFI only, NO Secure Boot support."
echo " Large install.wim file will not be split."
echo
echo "${bold} == Removable storage list ==${normal}"
@ -169,9 +208,6 @@ then
isopath="$2"
isolabel=""
labeltype="$3"
uefimode=
[[ "$labeltype" == "gpt" ]] && uefimode=1
[[ "$labeltype" == "gptntfs" ]] && uefimode=1
mountntfs_cmd="mount.ntfs-3g"
if ! command -v "$mountntfs_cmd" > /dev/null;
then
@ -188,10 +224,13 @@ then
fi
echo "${bold} == Working with ISO $isolabel ==${normal}"
skipinstallwim=""
splitinstallwim=1
partpath="$(mktemp -d /run/windows2usb.XXXXXXXXXX)"
isomountpath="$(mktemp -d /run/windows2usb-mount.XXXXXXXXXX)"
trap sigint_handler INT EXIT
# MBR
# MBR FAT32
if [[ "$labeltype" == "mbr" ]];
then
echo "${bold} == Creating new MBR-formatted partition table ==${normal}"
@ -200,44 +239,56 @@ then
echo "${bold} == Waiting 3 seconds to settle new partition layout ==${normal}"
sleep 3
echo "${bold} == Creating NTFS partition ==${normal}"
echo "${bold} == Creating FAT partition ==${normal}"
create_partitions "dos" "$dev"
mkfs.ntfs -L "$isolabel" -f "$(get_dev_partition_num "${dev}" "1")"
mkfs.vfat -n "${isolabel:0:11}" "$(get_dev_partition_num "${dev}" "1")"
echo "${bold} == Writing bootloader ==${normal}"
ms-sys -7 "${dev}"
ms-sys -n "$(get_dev_partition_num "${dev}" "1")"
ms-sys -e "$(get_dev_partition_num "${dev}" "1")"
echo "${bold} == Mounting data partition ==${normal}"
"$mountntfs_cmd" "$(get_dev_partition_num "${dev}" "1")" "$partpath"
mount "$(get_dev_partition_num "${dev}" "1")" "$partpath"
# GPT
# GPT FAT32
elif [[ "$labeltype" == "gpt" ]];
then
if check_installwim_gt4gib "$isopath";
then
echo "${bold} == ERROR: install.wim is greater than 4 GiB ==${normal}"
echo "${bold} == ERROR: Please use gptntfs mode ==${normal}"
echo "NOTE: gptntfs does not support Secure Boot!"
umount_rm_path "$partpath"
exit 103
fi
echo "${bold} == Creating new GPT-formatted partition table ==${normal}"
format_drive "gpt" "$dev"
echo "${bold} == Waiting 3 seconds to settle new partition layout ==${normal}"
sleep 3
echo "${bold} == Creating UEFI FAT partition ==${normal}"
echo "${bold} == Creating FAT partition ==${normal}"
create_partitions "gpt" "$dev"
mkfs.vfat -n "${isolabel:0:11}" "$(get_dev_partition_num "${dev}" "1")"
echo "${bold} == Mounting data partition ==${normal}"
mount "$(get_dev_partition_num "${dev}" "1")" "$partpath"
# GPT FAT32 + NTFS
# GPT NTFS
elif [[ "$labeltype" == "gptntfs" ]];
then
splitinstallwim="" # do NOT split install.wim in this mode
echo "${bold} == Creating new GPT-formatted partition table ==${normal}"
format_drive "gpt" "$dev"
echo "${bold} == Waiting 3 seconds to settle new partition layout ==${normal}"
sleep 3
echo "${bold} == Creating Microsoft NTFS partition ==${normal}"
create_partitions "gptntfs" "$dev"
mkfs.ntfs -L "$isolabel" -f "$(get_dev_partition_num "${dev}" "1")"
echo "${bold} == Mounting data partition ==${normal}"
"$mountntfs_cmd" "$(get_dev_partition_num "${dev}" "1")" "$partpath"
# GPT FAT32 (UEFINTFS) + NTFS
elif [[ "$labeltype" == "gpt+uefintfs" ]];
then
splitinstallwim="" # do NOT split install.wim in this mode
echo "${bold} == Creating new GPT-formatted partition table ==${normal}"
format_drive "gpt" "$dev"
@ -245,7 +296,7 @@ then
sleep 3
echo "${bold} == Creating UEFI FAT and Microsoft NTFS partitions ==${normal}"
create_partitions "gptntfs" "$dev"
create_partitions "gpt+uefintfs" "$dev"
write_uefintfs "$(get_dev_partition_num "${dev}" "1")"
mkfs.ntfs -L "$isolabel" -f "$(get_dev_partition_num "${dev}" "2")"
@ -253,24 +304,34 @@ then
"$mountntfs_cmd" "$(get_dev_partition_num "${dev}" "2")" "$partpath"
fi
echo "${bold} == Extracting files from ISO to the partition ==${normal}"
extract_iso "$isopath" "$partpath"
if [[ "$uefimode" ]];
if [[ "$splitinstallwim" ]] && check_installwim_gt4gib "$isopath";
then
if [ ! -f "$partpath/efi/boot/bootx64.efi" ] && \
[ ! -f "$partpath/efi/boot/bootia32.efi" ];
then
echo "${bold} == Extracting UEFI bootloader from install.wim ==${normal}"
mkdir -p "$partpath/efi/boot/" || true
extract_bootmgfw_from_installwim "$partpath/sources/install.wim" "$partpath/efi/boot/"
mv "$partpath/efi/boot/bootmgfw.efi" "$partpath/efi/boot/bootx64.efi"
cp "$partpath/efi/boot/bootx64.efi" "$partpath/efi/boot/bootia32.efi"
fi
echo "${bold} == NOTE: install.wim is greater than 4 GiB and will be split to fit FAT32 limit ==${normal}"
skipinstallwim="skipinstallwim"
fi
echo "${bold} == Extracting files from ISO to the partition ==${normal}"
extract_iso "$isopath" "$partpath" "$skipinstallwim"
if [[ "$skipinstallwim" ]]; then
split_wim "$isopath" "$isomountpath" "$partpath"
fi
# If there's no .efi bootloader files inside the iso,
# extract them from install.wim
# This is true for older Windows 7 ISO files.
if [ ! -f "$partpath/efi/boot/bootx64.efi" ] && \
[ ! -f "$partpath/efi/boot/bootia32.efi" ];
then
echo "${bold} == Extracting UEFI bootloader from install.wim ==${normal}"
mkdir -p "$partpath/efi/boot/" || true
extract_bootmgfw_from_installwim "$partpath/sources/install.wim" "$partpath/efi/boot/"
mv "$partpath/efi/boot/bootmgfw.efi" "$partpath/efi/boot/bootx64.efi"
cp "$partpath/efi/boot/bootx64.efi" "$partpath/efi/boot/bootia32.efi"
fi
echo "${bold} == Unmounting partition ==${normal}"
umount_rm_path "$partpath"
umount_rm_path "$partpath" "$isomountpath"
echo "${bold} == All done! ==${normal}"
else