Skip to content

Instantly share code, notes, and snippets.

@nospam2000
Forked from ryandesign/add_oclp_ext4_driver.sh
Last active January 6, 2025 12:12
Show Gist options
  • Save nospam2000/79239dd0c9dfb57f821991c4e8fb63ac to your computer and use it in GitHub Desktop.
Save nospam2000/79239dd0c9dfb57f821991c4e8fb63ac to your computer and use it in GitHub Desktop.
Adds ext4 driver to OpenCore Legacy Patcher so that a Linux partition can be selected. Use EFI binaries from original refind repo and not from outdated OC bin repo
#!/bin/bash
# SPDX-FileCopyrightText: © 2024 Ryan Carsten Schmidt <https://github.com/ryandesign>
# SPDX-License-Identifier: MIT
#
# Adds ext4 driver to OpenCore Legacy Patcher so that a Linux partition can be selected.
# Based on instructions by rikerjoe at:
# https://tinkerdifferent.com/threads/dual-boot-linux-mint-21-2-and-macos-with-opencore-legacy-patcher-and-opencore-bootpicker.3115/
set -u
: "${OC_DRIVER_URL:=https://sourceforge.net/projects/refind/files/0.14.2/refind-bin-0.14.2.zip/download}"
: "${PLISTBUDDY:=/usr/libexec/PlistBuddy}"
: "${TMPDIR:=/tmp}"
script_name="${0##*/}"
err() {
echo "$script_name: $1"
exit "${2:-1}"
}
get_efi_device() {
local device=
diskutil list -plist > "$tmpfile" || return $?
local disk=0
while [[ -z $device ]]; do
"$PLISTBUDDY" -c "Print :AllDisksAndPartitions:$disk:DeviceIdentifier" "$tmpfile" >/dev/null 2>&1 || break
local partition=0
while [[ -z $device ]]; do
local content
content=$("$PLISTBUDDY" -c "Print :AllDisksAndPartitions:$disk:Partitions:$partition:Content" "$tmpfile" 2>/dev/null) || break
[[ $content = "EFI" ]] && device=$("$PLISTBUDDY" -c "Print :AllDisksAndPartitions:$disk:Partitions:$partition:DeviceIdentifier" "$tmpfile")
partition=$((partition + 1))
done
disk=$((disk + 1))
done
[[ -n $device ]] || return 1
echo "$device"
}
get_device_mountpoint() {
diskutil info -plist "$1" > "$tmpfile" || return $?
local mountpoint
mountpoint=$("$PLISTBUDDY" -c "Print :MountPoint" "$tmpfile") || return $?
[[ -n $mountpoint ]] || return 1
echo "$mountpoint"
}
mount_device() {
sudo diskutil mount "$1" >/dev/null
}
unmount_device() {
sudo diskutil unmount "$1" >/dev/null
}
plist_has_array_item() {
local plist="$1"
local array_path="$2"
local dict_key="$3"
local dict_value="$4"
local found=
local index=0
while [[ -z $found ]]; do
value=$("$PLISTBUDDY" -c "Print $array_path:$index:$dict_key" "$plist" 2>/dev/null) || break
if [[ $value = "$dict_value" ]]; then
found=1
break
fi
index=$((index + 1))
done
[[ -n $found ]] || return 1
}
cleanup() {
if [[ -n "${oc_config_bak-}" ]] && cmp -s "$oc_config" "$oc_config_bak"; then
echo "Deleting $oc_config_bak because no changes were made"
rm -f "$oc_config_bak"
fi
if [[ -n "${unmount_efi_device-}" ]]; then
unmount_device "$efi_device" && echo "Unmounted EFI partition"
elif [[ -n "${efi_mountpoint-}" ]]; then
echo "Leaving EFI partition mounted"
fi
rm -f "$tmpfilearchive"
rm -f "$tmpfile"
}
tmpfilearchive=$(mktemp "$TMPDIR/$script_name.XXXXXXXX") || exit $?
tmpfile=$(mktemp "$TMPDIR/${script_name}_ext4_x64_efi.XXXXXXXX") || exit $?
trap cleanup EXIT
efi_device=$(get_efi_device) || err "Cannot find EFI partition"
if efi_mountpoint=$(get_device_mountpoint "$efi_device"); then
echo "EFI partition is already mounted at $efi_mountpoint"
else
#[[ $(id -u) = 0 ]] || err "Must be run as root to mount and unmount EFI partition"
mount_device "$efi_device" || exit $?
efi_mountpoint=$(get_device_mountpoint "$efi_device")
unmount_efi_device=1
echo "Mounted EFI partition at $efi_mountpoint"
fi
oc_dir="$efi_mountpoint/EFI/OC"
oc_config="$oc_dir/config.plist"
oc_driver="ext4_x64.efi"
oc_drivers_dir="$oc_dir/Drivers"
if [[ -e "$oc_drivers_dir/$oc_driver" ]]; then
echo "Driver $oc_driver is already on EFI partition"
else
[[ -d "$oc_drivers_dir" ]] || err "$oc_drivers_dir does not exist"
echo "Downloading driver $oc_driver"
curl -fLsSo "$tmpfilearchive" "$OC_DRIVER_URL" || exit $?
unzip > "$tmpfile" -p "$tmpfilearchive" "*/drivers_x64/${oc_driver}" || exit $?
echo "extracting driver archive"
mime=$(file --brief --mime-type "$tmpfile") || exit $?
[[ "$mime" = "application/x-dosexec" ]] || err "$oc_driver does not look like an EFI driver"
echo "Moving driver $oc_driver to EFI partition"
mv "$tmpfile" "$oc_drivers_dir/$oc_driver" || exit $?
fi
[[ -e "$oc_config" ]] || err "$oc_config does not exist"
oc_config_bak="$oc_config.bak"
[[ -e "$oc_config_bak" ]] && oc_config_bak="$oc_config_bak.$(date +%s)"
echo "Backing up $oc_config to $oc_config_bak"
cp -a "$oc_config" "$oc_config_bak"
if plist_has_array_item "$oc_config" :UEFI:Drivers Path "OpenLinuxBoot.efi"; then
echo "Driver OpenLinuxBoot.efi is already in $oc_config"
else
err "Driver OpenLinuxBoof.efi is not in $oc_config"
fi
if plist_has_array_item "$oc_config" :UEFI:Drivers Path "$oc_driver"; then
echo "Driver $oc_driver is already in $oc_config"
else
echo "Adding driver $oc_driver to $oc_config"
"$PLISTBUDDY" \
-c "Add :UEFI:Drivers:0 dict" \
-c "Add :UEFI:Drivers:0:Arguments string" \
-c "Add :UEFI:Drivers:0:Comment string" \
-c "Add :UEFI:Drivers:0:Enabled bool" \
-c "Set :UEFI:Drivers:0:Enabled true" \
-c "Add :UEFI:Drivers:0:LoadEarly bool" \
-c "Set :UEFI:Drivers:0:LoadEarly false" \
-c "Add :UEFI:Drivers:0:Path string" \
-c "Set :UEFI:Drivers:0:Path $oc_driver" \
"$oc_config" || exit $?
fi
for key in RequestBootVarRouting LauncherOption HideAuxiliary; do
path=":UEFI:Quirks:$key"
desired_value=true
if value=$("$PLISTBUDDY" -c "Print $path" "$oc_config" 2>/dev/null); then
if [[ $value = "$desired_value" ]]; then
echo "$path is already $desired_value"
else
echo "Setting $path to $desired_value"
"$PLISTBUDDY" -c "Set $path $desired_value" "$oc_config" || exit $?
fi
else
echo "Adding new key $path and setting to $desired_value"
"$PLISTBUDDY" -c "Add $path bool $desired_value" "$oc_config" || exit $?
fi
done
@nospam2000
Copy link
Author

Now works with OCLP 2.2, OSX Sequoia 15.2 and Linux trixie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment