Add complete guide and all config variants
This commit is contained in:
BIN
hackintosh-guide/Utilities/EnableGop/EnableGopDirect_1.4.efi
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/EnableGopDirect_1.4.efi
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/EnableGopDirect_1.4.ffs
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/EnableGopDirect_1.4.ffs
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/EnableGop_1.4.efi
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/EnableGop_1.4.efi
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/EnableGop_1.4.ffs
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/EnableGop_1.4.ffs
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGopDirect_1.5-dev.efi
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGopDirect_1.5-dev.efi
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGopDirect_1.5-dev.ffs
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGopDirect_1.5-dev.ffs
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGop_1.5-dev.efi
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGop_1.5-dev.efi
Executable file
Binary file not shown.
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGop_1.5-dev.ffs
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/Pre-release/EnableGop_1.5-dev.ffs
Executable file
Binary file not shown.
184
hackintosh-guide/Utilities/EnableGop/README.md
Executable file
184
hackintosh-guide/Utilities/EnableGop/README.md
Executable file
@@ -0,0 +1,184 @@
|
||||
# Provides standalone GOP driver for EFI era Mac Pro and iMac
|
||||
|
||||
## Releases
|
||||
|
||||
EnableGop version (OpenCore version)
|
||||
|
||||
### 1.4 (0.9.3)
|
||||
- Incorporates recent updates to OpenCore console control code, but no difference in behaviour compared
|
||||
to version 1.3 is expected on any supported systems.
|
||||
|
||||
### 1.3 (0.9.2)
|
||||
- Included fix to GopBurstMode for non-standard frame buffer information on AMD Radeon HD 7970 and similar
|
||||
- Applied GopBurstMode even on natively supported cards, as it can provide a noticable speed up
|
||||
|
||||
### 1.2 (0.9.1)
|
||||
- Added GopBurstMode support
|
||||
|
||||
*Note 1*: This should provide faster GOP rendering on all EnableGopDirect systems; and rendering at least at
|
||||
the same speed as before, and on some systems noticeably faster than before, on almost all EnableGop systems.
|
||||
|
||||
*Note 2*: The compressed driver for version 1.2 is 1KB larger than for version 1.1, so for AMD GPU firmware which is
|
||||
tight on space version 1.1 may be used instead to avoid the need for VGA stripping to make additional space.
|
||||
|
||||
### 1.1 (0.9.0)
|
||||
- Fixed early verbose boot lines appearing over picker
|
||||
- Added EnableGop version number to UI section
|
||||
|
||||
### 1.0 (0.8.9)
|
||||
- Initial public release
|
||||
|
||||
## Status
|
||||
**Current status: Beta release.**
|
||||
|
||||
This driver has been tested and is working on several iMac models
|
||||
with several different GPUs, and on several MacPro4,1/5,1 machines with several different GPUs. However, in the worst
|
||||
case (and still possible) scenario, an incompatible or incorrectly installed driver
|
||||
in firmware may brick your hardware.
|
||||
|
||||
*In all cases take a backup of the main firmware or GPU firmware which you are modifying, and confirm that
|
||||
you can successfully restore from this, before starting.*
|
||||
|
||||
## Recovery from bricked hardware
|
||||
- If attempting main firmware insertion on a MacPro4,1/5,1, for recovery from a bricked device you will either
|
||||
need a Matt card (which may breach intellectual property laws in some jurisdictions) or the ability to
|
||||
desolder and reprogram your own SPI flash chip.
|
||||
- If testing via main firmware insertion on an iMac, you will need the ability to disassemble your iMac and
|
||||
reprogram its SPI flash chip using a SOIC clip attached to a CH341A controller running on another computer.
|
||||
- If testing via GPU firmware insertion (iMac or Mac Pro), you will need the ability to disassemble your system,
|
||||
likely remove the heat sink from the graphics card, and then reprogram its SPI flash chip using a SOIC
|
||||
clip attached to a CH341A controller running on another computer.
|
||||
- If testing via GPU firmware insertion, in some cases it may also be possible
|
||||
to use physical electrical connection to your GPU in order to enable booting with no graphics even though the GPU
|
||||
is present, then connect to your machine with `ssh` (which must have been enabled beforehand) and reprogram the GPU
|
||||
firmware. Advice on this headless boot approach is not provided here, but may be found for instance on the iMac GPU
|
||||
related forum threads listed below.
|
||||
|
||||
*If you are not familiar with the above procedures, you are strongly recommended to wait for further testing by
|
||||
users who are. No further help can be provided here, and you proceed entirely at your own risk.*
|
||||
|
||||
## Summary
|
||||
Targetting EFI-era (~2009-2012) MacPro4,1/5,1 and iMac firmware, this driver gathers and injects the parts of
|
||||
OpenCore needed for pre-boot graphics support with non-natively supported GPUs.
|
||||
|
||||
The requirements for using this driver are:
|
||||
|
||||
- EFI-era (~2009-2012) MacPro4,1/5,1 or iMac with most recent main firmware.
|
||||
- A GPU which does not produce native pre-boot graphics (such as native picker when pressing ALT key during boot)
|
||||
before OpenCore starts (otherwise, you do not need it).
|
||||
- A GPU which produces graphics when using OpenCore (this must include successfully showing the native Apple boot
|
||||
picker when started via the latest version of OpenCore tool `BootKicker.efi`) (otherwise, the driver will not work).
|
||||
- *Note*: If your OpenCore installation includes a required GOP driver for your graphics card, then you would
|
||||
also need to burn that driver to the firmware of your graphics card in order to obtain pre-OpenCore graphics;
|
||||
instructions for this are outside the scope of this tutorial, although the procedures required for modifying
|
||||
GPU firmware are similar to what is covered here.
|
||||
Note that such a driver is added by the OCLP **Enable AMD GOP** option, which is enabled automatically on some
|
||||
systems by recent versions of OpenCore Legacy Patcher, as a way to enable the OpenCore menu in cards such as ex-mining GPUs.
|
||||
|
||||
When installed, the driver should enable:
|
||||
|
||||
- Native boot picker via ALT key
|
||||
- Firmware password UI
|
||||
- Target disk mode UI
|
||||
- macOS boot progress screen
|
||||
- etc.
|
||||
|
||||
Compiled versions of the driver files and these instructions may be found in the `Utilities/EnableGop`
|
||||
directory of the OpenCore release package.
|
||||
|
||||
For GPUs needing `DirectGopRendering` in OpenCore configuration, use `EnableGopDirect.efi`, otherwise use `EnableGop.efi`
|
||||
as it renders faster on most other systems.
|
||||
|
||||
The driver may be installed to GPU or main motherboard firmware. It is expected that most Mac Pro users will use main firmware insertion
|
||||
and most iMac users will chose GPU firmware insertion, however both techniques work on both systems (but it is harder to modify the
|
||||
iMac main firmware, since there is no simple way to enable writing to it).
|
||||
|
||||
Further discussion and community support for this driver is available at:
|
||||
|
||||
- https://forums.macrumors.com/threads/pre-opencore-gop-support-for-efi-era-imacs-and-mac-pros.2378942/
|
||||
|
||||
## Usage
|
||||
|
||||
## Install to main firmware
|
||||
|
||||
For reading and writing to main firmware on the Mac Pro, @Macschrauber's [Rom Dump](https://github.com/Macschrauber/Macschrauber-s-Rom-Dump) works
|
||||
well. Alternatively the kexts and executables which this uses can be sourced individually (or extracted from the Rom Dump app) and
|
||||
run from the command line.
|
||||
|
||||
The main firmware on the iMac cannot be updated without an initial hardware flash (SOIC clip plus CH341A controller), therefore
|
||||
the recommended approach on iMac systems is [GPU firmware injection](#install-to-gpu-firmware). However, the below instructions for firmware
|
||||
injection do work, if you are willing to do a hardware flash of the resulting firmware file, or if you have already
|
||||
[unprotected your iMac firmware](https://forums.macrumors.com/threads/imac-2011-see-more-uefi-firmware-mod.2257435/page-3?post=31087001#post-31087001) -
|
||||
which reduces security, and is only recommended for those actively developing firmware modifications.
|
||||
|
||||
The `.ffs` file provided in this directory can be manually added to the extracted firmware file using [`UEFITool`](https://github.com/LongSoft/UEFITool),
|
||||
or automatically added using @dosdude1's [`DXEInject`](https://dosdude1.com/apps/). Once more, if you are not familiar with these procedures,
|
||||
you are recommended to proceed with extreme caution.
|
||||
|
||||
### Using DXEInject
|
||||
|
||||
To install the driver via `DXEInject`, the command is:
|
||||
|
||||
- `DXEInject {original}.rom {modified}.rom EnableGop.ffs`
|
||||
|
||||
The file `{modifed}.rom` is ready for burning, although the result can be checked using UEFITool, if required.
|
||||
|
||||
> *Note*: If only reading a file with UEFITool, the latest version is recommended, as it provides the most information.
|
||||
For writing, the older version 0.25.1 must be used, as described below.
|
||||
|
||||
### Using UEFITool
|
||||
|
||||
The `.ffs` file may be inserted anywhere within the same firmware volume which contains `DuetBds`
|
||||
(file GUID `A6F691AC-31C8-4444-854C-E2C1A6950F92`). However, for simplicity, these instructions
|
||||
will insert it in the same place that `DXEInject` does:
|
||||
|
||||
- Use UEFITool 0.25.1 (it must be that old version, not the newer NE or new engine versions, which
|
||||
cannot yet edit)
|
||||
- Perform a header-only GUID search for `BAE7599F-3C6B-43B7-BDF0-9CE07AA91AA6`
|
||||
- Double-click on the search result
|
||||
- Right-click on the DXE driver with that GUID which should then appear
|
||||
- Choose "Insert after..." and select `EnableGop.ffs`
|
||||
- Save the modified firmware
|
||||
|
||||
The end result, after saving and re-loading, should look like this:
|
||||
|
||||
<img src="UEFITool_Inserted_Screenshot.png">
|
||||
|
||||
## Install to GPU firmware
|
||||
|
||||
Instructions and a script for inserting the driver into Nvidia or AMD GPU firmware (aka VBIOS) are provided.
|
||||
|
||||
Please note all the cautions already given above about the difficulty of recovering, unless you are familiar with
|
||||
the procedures necessary, if this process fails.
|
||||
|
||||
To use the provided `vBiosInsert.sh` script:
|
||||
|
||||
- Locate an appropriate version of the `nvflash` tool (Nvidia) or `amdvbflash` tool (AMD) (both are available for
|
||||
Linux and Windows), which can be used to read from and write to the GPU firmware.
|
||||
- Use that tool to read a copy of the GPU firmware.
|
||||
- Run `./vBiosInsert.sh [-a|-n] {original}.rom EnableGop.efi {modified}.rom`, with `-a` for AMD and `-n` for Nvidia.
|
||||
- If you have any problems with `vBiosInsert.sh` from a specific release
|
||||
of EnableGop, please try the version included with the latest release of OpenCore
|
||||
before reporting any issues.
|
||||
The script receives updates to support additional graphics cards independently
|
||||
of any bumps to the release version of EnableGop. If you need to, you can use
|
||||
the latest version of `vBiosInsert.sh` to inject older versions of EnableGop.
|
||||
- The new file `{modified}.rom` may be burnt to the GPU firmware.
|
||||
|
||||
In the case of AMD, considerably less space is normally available, due to a strict limit of 128k for legacy and EFI
|
||||
parts of the larger ROM image. If there is not enough space (i.e. script reports
|
||||
data would be truncated) then it is necessary to [strip some legacy VGA parts of the
|
||||
GPU firmware](https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN/wiki/Deleting-the-VGA). This is beyond the scope
|
||||
of these instructions.
|
||||
|
||||
If required to manually detect the GOP offset (this should normally be autodetected):
|
||||
|
||||
> Using a hex editor, search in the GPU firmware dump for the byte sequence `F1 0E 00 00` with the byte sequence `55 AA` coming
|
||||
close before it; the start address of the `55 AA` is the GOP offset value needed.
|
||||
|
||||
For further information on GPU firmware modification, see:
|
||||
|
||||
- https://forums.macrumors.com/threads/2011-imac-graphics-card-upgrade.1596614/
|
||||
- https://forums.macrumors.com/threads/imac-2011-maxwell-and-pascal-gpu-upgrade.2300989/
|
||||
- https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN/wiki
|
||||
- https://winraid.level1techs.com/t/amd-and-nvidia-gop-update-no-requests-diy/30917
|
||||
BIN
hackintosh-guide/Utilities/EnableGop/UEFITool_Inserted_Screenshot.png
Executable file
BIN
hackintosh-guide/Utilities/EnableGop/UEFITool_Inserted_Screenshot.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 694 KiB |
334
hackintosh-guide/Utilities/EnableGop/vBiosInsert.sh
Executable file
334
hackintosh-guide/Utilities/EnableGop/vBiosInsert.sh
Executable file
@@ -0,0 +1,334 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Copyright © 2023 Mike Beaton. All rights reserved.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Insert EFI into AMD or Nvidia VBIOS.
|
||||
# Tested back to Mac OS X 10.11 El Capitan.
|
||||
#
|
||||
|
||||
usage() {
|
||||
echo "Usage: ./${SELFNAME} [args] {rom-file} {efi-file} {out-file}"
|
||||
echo "Args:"
|
||||
echo " -a : AMD"
|
||||
echo " -n : Nvidia"
|
||||
echo " -o {GOP offset} : GOP offset (auto-detected if Homebrew grep is installed)"
|
||||
echo " Can specify 0x{hex} or {decimal}"
|
||||
echo " -t {temp dir} : Specify temporary directory, and keep temp files"
|
||||
echo " -m {max size} : Specify VBIOS max size (Nvidia only)"
|
||||
echo " (For AMD first 128KB is modified, any remainder is kept)"
|
||||
echo "Examples:"
|
||||
echo " ./${SELFNAME} -n -o 0xFC00 nv.rom EnableGop.efi nv_mod.rom"
|
||||
echo " ./${SELFNAME} -n nv.rom EnableGop.efi nv_mod.rom"
|
||||
echo " ./${SELFNAME} -a amd.rom EnableGop.efi amd_mod.rom"
|
||||
echo ""
|
||||
}
|
||||
|
||||
SELFNAME="$(/usr/bin/basename "${0}")"
|
||||
|
||||
commands=(
|
||||
"EfiRom"
|
||||
"UEFIRomExtract"
|
||||
"hexdump"
|
||||
"grep"
|
||||
)
|
||||
|
||||
FOUND=1
|
||||
for command in "${commands[@]}"; do
|
||||
if ! command -v "$command" 1>/dev/null ; then
|
||||
echo "${command} not available!"
|
||||
FOUND=0
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$FOUND" -eq 0 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AMD=0
|
||||
AMD_SAFE_SIZE="0x20000"
|
||||
NVIDIA_SAFE_SIZE="0x40000"
|
||||
GOP_OFFSET="-"
|
||||
NVIDIA=0
|
||||
POS=0
|
||||
TRUNCATE=0
|
||||
|
||||
while true; do
|
||||
if [ "$1" = "-a" ] ; then
|
||||
AMD=1
|
||||
NVIDIA=0
|
||||
shift
|
||||
elif [ "$1" = "-n" ] ; then
|
||||
AMD=0
|
||||
NVIDIA=1
|
||||
shift
|
||||
elif [ "$1" = "-o" ] ; then
|
||||
shift
|
||||
if [ "$1" != "" ] && ! [ "${1:0:1}" = "-" ] ; then
|
||||
GOP_OFFSET=$1
|
||||
shift
|
||||
else
|
||||
echo "No GOP offset specified" && exit 1
|
||||
fi
|
||||
elif [ "$1" = "-s" ] ; then # semi-secret option to modify AMD safe size
|
||||
shift
|
||||
if [ "$1" != "" ] && ! [ "${1:0:1}" = "-" ] ; then
|
||||
AMD_SAFE_SIZE=$1
|
||||
shift
|
||||
else
|
||||
echo "No AMD safe size specified" && exit 1
|
||||
fi
|
||||
elif [ "$1" = "-m" ] ; then
|
||||
shift
|
||||
if [ "$1" != "" ] && ! [ "${1:0:1}" = "-" ] ; then
|
||||
TRUNCATE=1
|
||||
TRUNCATE_SIZE=$1
|
||||
NVIDIA_SAFE_SIZE=$TRUNCATE_SIZE
|
||||
shift
|
||||
else
|
||||
echo "No max size specified" && exit 1
|
||||
fi
|
||||
elif [ "$1" = "-t" ] ; then
|
||||
shift
|
||||
if [ "$1" != "" ] && ! [ "${1:0:1}" = "-" ] ; then
|
||||
TEMP_DIR=$1
|
||||
shift
|
||||
else
|
||||
echo "No temp dir specified" && exit 1
|
||||
fi
|
||||
elif [ "${1:0:1}" = "-" ] ; then
|
||||
echo "Unknown option: ${1}" && exit 1
|
||||
elif [ "$1" != "" ] ; then
|
||||
case "$POS" in
|
||||
0 )
|
||||
ROM_FILE="$1"
|
||||
;;
|
||||
1 )
|
||||
EFI_FILE="$1"
|
||||
;;
|
||||
2 )
|
||||
OUT_FILE="$1"
|
||||
;;
|
||||
* )
|
||||
echo "Too many filenames specified" && exit 1
|
||||
;;
|
||||
esac
|
||||
POS=$(($POS+1))
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$ROM_FILE" = "" ] ||
|
||||
[ "$EFI_FILE" = "" ] ||
|
||||
[ "$OUT_FILE" = "" ] ; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$AMD" -eq 0 ] && [ "$NVIDIA" -eq 0 ] ; then
|
||||
echo "Must specify -a or -n" && exit 1
|
||||
fi
|
||||
|
||||
if [ "$AMD" -eq 1 ] && [ "$TRUNCATE" -eq 1 ] ; then
|
||||
echo "-m is not valid with -a" && exit 1
|
||||
fi
|
||||
|
||||
if [ "$TEMP_DIR" != "" ] ; then
|
||||
mkdir -p "$TEMP_DIR" || exit 1
|
||||
tmpdir="$TEMP_DIR"
|
||||
else
|
||||
# https://unix.stackexchange.com/a/84980/340732
|
||||
tmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'vbios') || exit 1
|
||||
fi
|
||||
|
||||
ORIGINAL_SIZE=$(stat -f%z "$ROM_FILE") || exit 1
|
||||
|
||||
if [ "$AMD" -eq 1 ] ; then
|
||||
# For AMD we can only modify the first 128KB, anything above 128KB
|
||||
# should not be moved, and is not mapped to memory visible by the CPU
|
||||
# for loading EFI drivers.
|
||||
TRUNCATE=1
|
||||
TRUNCATE_SIZE="$AMD_SAFE_SIZE"
|
||||
|
||||
# Also works, with empty keep_part.rom, in the atypical case where we
|
||||
# are provided with only the used part of the ROM below 128KB.
|
||||
dd bs=1 if="$ROM_FILE" of="$tmpdir/modify_part.rom" count="$AMD_SAFE_SIZE" 2>/dev/null || exit 1
|
||||
dd bs=1 if="$ROM_FILE" of="$tmpdir/keep_part.rom" skip="$AMD_SAFE_SIZE" 2>/dev/null || exit 1
|
||||
else
|
||||
if [ "$TRUNCATE" -eq 0 ] ; then
|
||||
# If original size is a plausible ROM size (exact power of two, 64KB or
|
||||
# larger; 64KB chosen partly for neat regexp) treat it as the full available
|
||||
# size of the VBIOS chip unless overridden with -m.
|
||||
printf '%x' "$ORIGINAL_SIZE" | grep -Eq "^(1|2|4|8)0000+$" && TRUNCATE=1
|
||||
if [ "$TRUNCATE" -eq 1 ] ; then
|
||||
echo "Detected standard ROM size."
|
||||
TRUNCATE_SIZE="$ORIGINAL_SIZE"
|
||||
else
|
||||
if [ "$ORIGINAL_SIZE" -gt "$((NVIDIA_SAFE_SIZE))" ] ; then
|
||||
echo " - File size of ${ORIGINAL_SIZE} bytes must be no more than $((NVIDIA_SAFE_SIZE)) bytes; use -m or check file" && exit 1
|
||||
fi
|
||||
TRUNCATE=1
|
||||
TRUNCATE_SIZE="$NVIDIA_SAFE_SIZE"
|
||||
fi
|
||||
fi
|
||||
|
||||
cp "$ROM_FILE" "$tmpdir/modify_part.rom" || exit 1
|
||||
fi
|
||||
|
||||
if [ "$GOP_OFFSET" = "-" ] ; then
|
||||
echo "Auto-detecting GOP offset..."
|
||||
|
||||
# nicer techniques which do not assume nice alignment of what is being searched for do not work on older Mac OS X
|
||||
OUTPUT=$(hexdump -C "$tmpdir/modify_part.rom" | grep '55 aa .. .. f1 0e 00 00' | head -1)
|
||||
# Make macOS bash to split as expected:
|
||||
# shellcheck disable=SC2206
|
||||
GOP_ARRAY=($OUTPUT)
|
||||
GOP_OFFSET=${GOP_ARRAY[0]}
|
||||
if [ "$GOP_OFFSET" != "" ] ; then
|
||||
GOP_OFFSET="0x${GOP_OFFSET}"
|
||||
GOP_OFFSET=$(($GOP_OFFSET))
|
||||
else
|
||||
GOP_OFFSET=-1
|
||||
fi
|
||||
|
||||
if [ "$GOP_OFFSET" -eq -1 ] ; then
|
||||
echo " - No GOP found in ROM!" && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
dd bs=1 if="$tmpdir/modify_part.rom" of="$tmpdir/original_first_part.rom" count=$(($GOP_OFFSET)) 2>/dev/null || exit 1
|
||||
dd bs=1 if="$tmpdir/modify_part.rom" of="$tmpdir/original_last_part.rom" skip=$(($GOP_OFFSET)) 2>/dev/null || exit 1
|
||||
|
||||
echo "Compressing EFI using EfiRom..."
|
||||
if [ "$AMD" -eq 1 ] ; then
|
||||
EfiRom -o "$tmpdir/insert.rom" -ec "$EFI_FILE" -f 0xAAAA -i 0xBBBB -l 0x30000 -p || exit 1
|
||||
else
|
||||
EfiRom -o "$tmpdir/insert.rom" -ec "$EFI_FILE" -f 0xAAAA -i 0xBBBB -l 0x30000 || exit 1
|
||||
fi
|
||||
|
||||
if [ "$NVIDIA" -eq 1 ] ; then
|
||||
dd bs=1 if="$tmpdir/insert.rom" of="$tmpdir/insert_first_part" count=$((0x38)) 2>/dev/null || exit 1
|
||||
dd bs=1 if="$tmpdir/insert.rom" of="$tmpdir/insert_last_part" skip=$((0x38)) 2>/dev/null || exit 1
|
||||
|
||||
# TODO: truncation logic should be fixed for when there is not enough spare padding in output of EfiRom;
|
||||
# we currently assume without checking that there is enough space to fit in the NPDE header (if not,
|
||||
# script will report failure to verify with UEFIRomExtract below).
|
||||
INSERT_SIZE=$(stat -f%z "$tmpdir/insert.rom") || exit 1
|
||||
|
||||
# Calculate NPDE size from original GOP and add to new image
|
||||
EfiImageOffset=$(dd if="$tmpdir/original_last_part.rom" ibs=1 skip=$((0x16)) count=2 2>/dev/null | od -t u4 -An | xargs)
|
||||
if [ "$EfiImageOffset" -eq $((0x50)) ] ; then
|
||||
NpdeSize=$((0x18))
|
||||
elif [ "$EfiImageOffset" -eq $((0x4C)) ] ; then
|
||||
NpdeSize=$((0x14))
|
||||
elif [ "$EfiImageOffset" -eq $((0x38)) ] ; then
|
||||
NpdeSize=0
|
||||
else
|
||||
# Note: We need at least 0x14 NPDE size for the patch-ups we do below for size and end-marker to make sense
|
||||
printf "Unsupported EFI Image Offset 0x%x, cannot calculate NPDE Size!\n" "$EfiImageOffset"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$NVIDIA" -eq 1 ] && [ "$NpdeSize" -ne 0 ] ; then
|
||||
echo "Adding Nvidia header..."
|
||||
|
||||
dd bs=1 if="$tmpdir/original_last_part.rom" of="$tmpdir/insert_first_part" skip=$((0x38)) seek=$((0x38)) count="$NpdeSize" 2>/dev/null || exit 1
|
||||
cat "$tmpdir/insert_first_part" "$tmpdir/insert_last_part" > "$tmpdir/insert_oversize.rom" || exit 1
|
||||
# Note: `truncate` command is not present by default on macOS
|
||||
dd bs=1 if="$tmpdir/insert_oversize.rom" of="$tmpdir/insert_fixed.rom" count="$INSERT_SIZE" 2>/dev/null || exit 1
|
||||
|
||||
# Patch size in NPDE
|
||||
dd bs=1 if="$tmpdir/insert.rom" of="$tmpdir/insert_fixed.rom" skip=$((0x2)) seek=$((0x48)) count=1 conv=notrunc 2>/dev/null || exit 1
|
||||
else
|
||||
cp "$tmpdir/insert.rom" "$tmpdir/insert_fixed.rom" || exit 1
|
||||
fi
|
||||
|
||||
# patch with vendor and device id from original GOP
|
||||
dd bs=1 if="$tmpdir/original_last_part.rom" of="$tmpdir/insert_fixed.rom" skip=$((0x20)) seek=$((0x20)) count=4 conv=notrunc 2>/dev/null || exit 1
|
||||
|
||||
if [ "$NVIDIA" -eq 1 ] && [ "$NpdeSize" -ne 0 ] ; then
|
||||
# Patch EFI image offset in PCIR
|
||||
dd bs=1 if="$tmpdir/original_last_part.rom" of="$tmpdir/insert_fixed.rom" skip=$((0x16)) seek=$((0x16)) count=1 conv=notrunc 2>/dev/null || exit 1
|
||||
|
||||
# Patch end marker in NPDE in fixed ROM (leave PCIR correct and EFI extractable from fixed ROM)
|
||||
echo -n -e '\x00' | dd bs=1 of="$tmpdir/insert_fixed.rom" seek=$((0x4A)) conv=notrunc 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
echo "Combining..."
|
||||
cat "$tmpdir/original_first_part.rom" "$tmpdir/insert_fixed.rom" "$tmpdir/original_last_part.rom" > "$tmpdir/combined.rom" || exit 1
|
||||
|
||||
# If new ROM is larger than truncate size, determine overflow by seeing
|
||||
# whether truncated ROM still has padding.
|
||||
# For Nvidia we would need to parse and navigate NVGI and NPDE headers
|
||||
# to calculate true occupied VBIOS space. To calcuate AMD occupation below
|
||||
# 128KB limit, we could navigate normal PCI expansion ROM headers.
|
||||
COMBINED_SIZE=$(stat -f%z "$tmpdir/combined.rom") || exit 1
|
||||
if [ "$COMBINED_SIZE" -le "$(($TRUNCATE_SIZE))" ] ; then
|
||||
TRUNCATE=0
|
||||
fi
|
||||
if [ "$TRUNCATE" -eq 1 ] ; then
|
||||
echo "Truncating to original size..."
|
||||
|
||||
dd bs=1 if="$tmpdir/combined.rom" of="$tmpdir/truncated.rom" count="$TRUNCATE_SIZE" 2>/dev/null || exit 1
|
||||
|
||||
COUNT=$(hexdump -v -e '1/8 " %016X\n"' "$tmpdir/truncated.rom" | tail -n 8 | grep "FFFFFFFFFFFFFFFF" | wc -l)
|
||||
if [ "$COUNT" -ne 8 ] ; then
|
||||
# Some Nvidia ROMs, at least, incorrectly have 00000000 padding after active contents
|
||||
# (it is incorrect, since writing only active contents using nvflash resets the rest to ffffffff).
|
||||
# May also be relevant if we ever have any truly 00000000 default ROM images.
|
||||
COUNT=$(hexdump -v -e '1/8 " %016X\n"' "$tmpdir/truncated.rom" | tail -n 8 | grep "0000000000000000" | wc -l)
|
||||
fi
|
||||
|
||||
if [ "$COUNT" -ne 8 ] ; then
|
||||
echo " - Not enough space within $((TRUNCATE_SIZE / 1024))k limit - aborting!" && exit 1
|
||||
fi
|
||||
|
||||
if [ "$AMD" -eq 1 ] ; then
|
||||
cat "$tmpdir/truncated.rom" "$tmpdir/keep_part.rom" > "$OUT_FILE" || exit 1
|
||||
else
|
||||
cp "$tmpdir/truncated.rom" "$OUT_FILE" || exit 1
|
||||
fi
|
||||
else
|
||||
cp "$tmpdir/combined.rom" "$OUT_FILE" || exit 1
|
||||
fi
|
||||
|
||||
# patch end marker in PCIR in out file
|
||||
echo -n -e '\x00' | dd bs=1 of="$OUT_FILE" seek=$(($GOP_OFFSET + 0x31)) conv=notrunc 2>/dev/null || exit 1
|
||||
|
||||
printf "Verifying (starting at 0x%X)...\n" "$GOP_OFFSET"
|
||||
dd bs=1 if="$OUT_FILE" of="$tmpdir/out_efi_part.rom" skip=$(($GOP_OFFSET)) 2>/dev/null || exit 1
|
||||
# UEFIRomExtract error messages are on stdout, so we cannot suppress unwanted normal output here
|
||||
UEFIRomExtract "$tmpdir/out_efi_part.rom" "$tmpdir/extracted.efi" || exit 1
|
||||
ERROR=0
|
||||
diff "$tmpdir/extracted.efi" "$EFI_FILE" 1>/dev/null || ERROR=1
|
||||
|
||||
if [ "$ERROR" -ne 0 ] ; then
|
||||
echo " - Failure comparing extracted EFI to original!"
|
||||
fi
|
||||
|
||||
OLD_EFI_COUNT=$(EfiRom -d "$tmpdir/original_last_part.rom" | grep "0x0EF1" | wc -l) || exit 1
|
||||
OLD_EFI_COUNT=$(($OLD_EFI_COUNT)) || exit 1
|
||||
|
||||
NEW_EFI_COUNT=$(EfiRom -d "$tmpdir/out_efi_part.rom" | grep "0x0EF1" | wc -l) || exit 1
|
||||
NEW_EFI_COUNT=$(($NEW_EFI_COUNT)) || exit 1
|
||||
|
||||
if [ "$NEW_EFI_COUNT" -ne $(($OLD_EFI_COUNT + 1)) ] ; then
|
||||
echo " - ${OLD_EFI_COUNT} EFI parts in original ROM, and detected ${NEW_EFI_COUNT} EFI parts in modified ROM, expected $(($OLD_EFI_COUNT + 1))!"
|
||||
ERROR=1
|
||||
fi
|
||||
|
||||
if [ "$ERROR" -eq 0 ] ; then
|
||||
echo "SUCCESS."
|
||||
else
|
||||
echo "*** WARNING - FAIL ***"
|
||||
fi
|
||||
|
||||
if [ "$TEMP_DIR" = "" ] ; then
|
||||
rm -rf "$tmpdir" || exit 1
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user