-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90ed05d
commit fe8c338
Showing
2 changed files
with
168 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,28 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Copyright (C) 2022 Aditya Garg <[email protected]> | ||
# Copyright (C) 2022 Orlando Chamberlain <[email protected]> | ||
|
||
# Copyright (C) 2024 Aditya Garg <[email protected]> | ||
# Copyright (C) 2024 Orlando Chamberlain <[email protected]> | ||
# Copyright (C) 2024 Sharpened Blade <[email protected]> | ||
# | ||
# The python script is based upon the original work by The Asahi Linux Contributors. | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
|
||
# The above copyright notice and this permission notice shall be included in all | ||
# copies or substantial portions of the Software. | ||
|
||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
# SOFTWARE. | ||
|
||
rename_firmware () { | ||
python3 - "$@" <<'EOF' | ||
|
@@ -336,16 +355,114 @@ EOF | |
set -euo pipefail | ||
|
||
verbose="" | ||
while getopts "vhxp" option; do | ||
subcmd="" | ||
target_pkg_manager="" | ||
args=() | ||
interactive="true" | ||
while getopts "ivhxp" option; do | ||
case $option in | ||
i) interactive="false" ;; | ||
v) verbose="-v" ;; | ||
h) echo "usage: $0 [-vhxp] [fw_dir_path output_archive_path]"; exit 0 ;; | ||
h) | ||
cat <<- EOF | ||
usage: $0 [-vhx] subcommand [subcmd args] | ||
Subcommands: | ||
rename_only /path/to/firmware archive.tar | ||
copy_to_efi | ||
create_archive | ||
create_package apt|rpm|pacman | ||
get_from_efi | ||
get_from_macos | ||
get_from_online | ||
EOF | ||
exit 0 ;; | ||
x) set -x;; | ||
p) rename_firmware "${@:2:2}" ${verbose} && exit 0 ;; | ||
?) exit 1 ;; | ||
esac | ||
done | ||
|
||
if [[ "${1-}" == -* ]]; then | ||
subcmd="${2-}" | ||
args=( "${@:3}" ) | ||
else | ||
subcmd="${1-}" | ||
args=( "${@:2}" ) | ||
fi | ||
|
||
if [[ "$subcmd" = "" ]] && [[ "$interactive" = "true" ]]; then | ||
case "$(uname -s)" in | ||
(Darwin) | ||
echo "Detected macOS" | ||
cat <<- EOF | ||
How do you want to copy the firmware to Linux? | ||
1. Copy the firmware to the EFI partition and run the same script on Linux to retrieve it. | ||
2. Create a tarball of the firmware and extract it to Linux. | ||
3. Create a Linux specific package which can be installed using a package manager. | ||
Note: Option 2 and 3 require additional software like python3 and tools specific for your package manager. Requirements will be told as you proceed further. | ||
EOF | ||
read -r choice | ||
case ${choice} in | ||
(1) subcmd="copy_to_efi" ;; | ||
(2) subcmd="create_archive" ;; | ||
(3) subcmd="create_package" | ||
echo -e "\nWhat package manager does your Linux distribution use?\n" | ||
echo "1. apt" | ||
echo "2. dnf" | ||
echo "3. pacman" | ||
read -r target_pkg_manager | ||
case ${target_pkg_manager} in | ||
(1) target_pkg_manager="apt" ;; | ||
(2) target_pkg_manager="rpm" ;; | ||
(3) target_pkg_manager="pacman" ;; | ||
(*) echo -e "\nError: Invalid option!" && exit 1 ;; | ||
esac | ||
;; | ||
(*) echo -e "\nError: Invalid option!" && exit 1 ;; | ||
esac | ||
;; | ||
(Linux) | ||
echo "Detected Linux" | ||
cat <<- EOF | ||
How do you want to copy the firmware to Linux? | ||
1. Retrieve the firmware from the EFI partition. | ||
2. Retrieve the firmware directly from macOS. | ||
3. Download a macOS Recovery Image from Apple and extract the firmware from there. | ||
Note: If you are choosing Option 1, then make sure you have run the same script on macOS before and chose Option 1 (Copy the firmware to the EFI partition and run the same script on Linux to retrieve it) there. | ||
EOF | ||
read -r choice | ||
case ${choice} in | ||
(1) | ||
subcmd="get_from_efi" ;; | ||
(2) | ||
subcmd="get_from_macos" ;; | ||
(3) | ||
subcmd="get_from_online" ;; | ||
(*) | ||
echo -e "\nError: Invalid option!" | ||
exit 1 | ||
;; | ||
esac | ||
;; | ||
(*) | ||
echo "Error: unsupported platform" | ||
;; | ||
esac | ||
fi | ||
|
||
if [[ "$subcmd" = "" ]]; then | ||
echo "No subcommand specified" | ||
exit 1 | ||
elif [[ "$subcmd" = "create_package" ]] && [[ "$target_pkg_manager" = "" ]]; then | ||
target_pkg_manager="${args[0]}" | ||
fi | ||
|
||
aur_install() { | ||
local aur_package=$1 | ||
local dir | ||
|
@@ -397,6 +514,11 @@ install_package() { | |
local package=$1 | ||
local package_manager | ||
package_manager=$(detect_package_manager) | ||
if [[ "$interactive" = "false" ]]; then | ||
echo "$package is missing. Install it then try again" | ||
echo "Exiting" | ||
exit 1 | ||
fi | ||
if [[ $package = "linux-apfs-rw" ]] | ||
then | ||
local apfs_driver_link=https://github.com/linux-apfs/linux-apfs-rw.git | ||
|
@@ -480,6 +602,11 @@ create_firmware_archive() { | |
} | ||
|
||
python_check () { | ||
if [[ "$interactive" = "false" ]]; then | ||
echo "Xcode command line tools are missing." | ||
echo "Exiting" | ||
exit 1 | ||
fi | ||
echo -e "\nChecking for missing dependencies" | ||
if [ ! -f "/Library/Developer/CommandLineTools/usr/bin/python3" ] && [ ! -f "/Applications/Xcode.app/Contents/Developer/usr/bin/python3" ] | ||
then | ||
|
@@ -708,7 +835,6 @@ nvram_txcap_quirk() { | |
os=$(uname -s) | ||
case "$os" in | ||
(Darwin) | ||
echo "Detected macOS" | ||
ver=$(sw_vers -productVersion) | ||
ver_check=$(sw_vers -productVersion | cut -d "." -f 1) | ||
identifier=$(system_profiler SPHardwareDataType | grep "Model Identifier" | cut -d ":" -f 2 | xargs) | ||
|
@@ -726,19 +852,8 @@ case "$os" in | |
EOF | ||
fi | ||
cat <<- EOF | ||
How do you want to copy the firmware to Linux? | ||
1. Copy the firmware to the EFI partition and run the same script on Linux to retrieve it. | ||
2. Create a tarball of the firmware and extract it to Linux. | ||
3. Create a Linux specific package which can be installed using a package manager. | ||
Note: Option 2 and 3 require additional software like python3 and tools specific for your package manager. Requirements will be told as you proceed further. | ||
EOF | ||
read -r choice | ||
case ${choice} in | ||
(1) | ||
case ${subcmd} in | ||
("copy_to_efi") | ||
echo -e "\nMounting the EFI partition" | ||
EFILABEL=$(diskutil info disk0s1 | grep "Volume Name" | cut -d ":" -f 2 | xargs) | ||
sudo diskutil mount disk0s1 | ||
|
@@ -751,11 +866,10 @@ case "$os" in | |
echo "Copying this script to EFI" | ||
cp "$0" "/Volumes/${EFILABEL}/firmware.sh" 2>/dev/null \ | ||
|| curl -s https://wiki.t2linux.org/tools/firmware.sh > "/Volumes/${EFILABEL}/firmware.sh" \ | ||
|| (echo && cat <<- EOF && read -r | ||
|| ( echo && cat <<- EOF && [ "$interactive" = "true" ] && echo "Press enter after you have copied" && read -r | ||
Failed to copy script. | ||
Please copy the script manually to the EFI partition using Finder | ||
Make sure the name of the script is firmware.sh in the EFI partition | ||
Press enter after you have copied" | ||
EOF | ||
) | ||
sudo diskutil unmount "/Volumes/${EFILABEL}/" | ||
|
@@ -769,7 +883,7 @@ case "$os" in | |
sudo umount /tmp/apple-wifi-efi | ||
EOF | ||
;; | ||
(2) | ||
("create_archive") | ||
python_check | ||
echo -e "\nCreating a tarball of the firmware" | ||
create_firmware_archive /usr/share/firmware "$HOME/Downloads/firmware.tar" | ||
|
@@ -786,21 +900,16 @@ case "$os" in | |
sudo modprobe hci_bcm4377 | ||
EOF | ||
;; | ||
(3) | ||
echo -e "\nWhat package manager does your Linux distribution use?\n" | ||
echo "1. apt" | ||
echo "2. dnf" | ||
echo "3. pacman" | ||
read -r package | ||
("create_package") | ||
python_check | ||
case ${package} in | ||
(1) | ||
case ${target_pkg_manager} in | ||
("apt") | ||
create_deb | ||
;; | ||
(2) | ||
("dnf") | ||
create_rpm | ||
;; | ||
(3) | ||
("pacman") | ||
create_arch_pkg | ||
;; | ||
(*) | ||
|
@@ -809,6 +918,9 @@ case "$os" in | |
;; | ||
esac | ||
;; | ||
("rename_only") | ||
rename_firmware "${args[@]}" ${verbose} | ||
;; | ||
(*) | ||
echo -e "\nError: Invalid option!" | ||
exit 1 | ||
|
@@ -817,7 +929,6 @@ case "$os" in | |
;; | ||
|
||
(Linux) | ||
echo "Detected Linux" | ||
if [[ ! -e /lib/firmware/brcm ]]; then | ||
cat <<- EOF | ||
/lib/firmware/brcm does not seem to exist. This script requires that directory to function. | ||
|
@@ -827,19 +938,8 @@ case "$os" in | |
EOF | ||
exit 1 | ||
fi | ||
cat <<- EOF | ||
How do you want to copy the firmware to Linux? | ||
1. Retrieve the firmware from the EFI partition. | ||
2. Retrieve the firmware directly from macOS. | ||
3. Download a macOS Recovery Image from Apple and extract the firmware from there. | ||
Note: If you are choosing Option 1, then make sure you have run the same script on macOS before and chose Option 1 (Copy the firmware to the EFI partition and run the same script on Linux to retrieve it) there. | ||
EOF | ||
read -r choice | ||
case ${choice} in | ||
(1) | ||
case ${subcmd} in | ||
("get_from_efi") | ||
echo -e "\nRe-mounting the EFI partition" | ||
mountpoint=$(mktemp -d) | ||
workdir=$(mktemp -d) | ||
|
@@ -860,7 +960,11 @@ case "$os" in | |
done | ||
reload_kernel_modules | ||
echo -e "\nKeeping a copy of the firmware and the script in the EFI partition shall allow you to set up Wi-Fi again in the future by running this script or the commands told in the macOS step in Linux only, without the macOS step." | ||
read -rp "Do you want to keep a copy? (y/N)" input | ||
if [ "$interactive" = "true" ]; then | ||
read -rp "Do you want to keep a copy? (y/N)" input | ||
else | ||
input="y" | ||
fi | ||
if [[ ($input != y) && ($input != Y) ]] | ||
then | ||
echo -e "\nRemoving the copy from the EFI partition" | ||
|
@@ -878,7 +982,7 @@ case "$os" in | |
sudo rmdir ${verbose} "$mountpoint" | ||
echo -e "\nDone!" | ||
;; | ||
(2) | ||
("get_from_macos") | ||
echo -e "\nChecking for missing dependencies" | ||
# Load the apfs driver, and install if missing | ||
sudo modprobe ${verbose} apfs 2>/dev/null || install_package linux-apfs-rw | ||
|
@@ -925,7 +1029,7 @@ case "$os" in | |
unmount_macos_and_cleanup | ||
echo "Done!" | ||
;; | ||
(3) | ||
("get_from_online") | ||
# Detect whether curl and dmg2img are installed | ||
echo -e "\nChecking for missing dependencies" | ||
curl --version >/dev/null 2>&1 || install_package curl | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[Unit] | ||
Description=Get Apple WiFi and Bluetooth firmware | ||
ConditionFirstBoot=yes | ||
ConditionPathExists=/lib/firmware/brcm | ||
Wants=first-boot-complete.target | ||
Before=first-boot-complete.target | ||
|
||
[Service] | ||
Type=oneshot | ||
RemainAfterExit=yes | ||
ExecStart=/usr/libexec/get-apple-firmware -i get_from_macos | ||
|
||
[Install] | ||
WantedBy=multi-user.target |