Last active
December 26, 2015 22:29
-
-
Save dimme/7223634 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/bin/bash | |
set -o nounset | |
set -o errexit | |
REPO_URI=${REPO_URI:-"https://github.com/Hexxeh/rpi-firmware"} | |
UPDATE_SELF=${UPDATE_SELF:-1} | |
UPDATE_URI="https://gist.github.com/Dimme/7223634/raw/29c43a079ac472cb4f3f4912bbf13abb8649a85c/gistfile1.txt" | |
if [[ ${BOOT_PATH:-"unset"} == "unset" && ${ROOT_PATH:-"unset"} != "unset" ]] || | |
[[ ${BOOT_PATH:-"unset"} != "unset" && ${ROOT_PATH:-"unset"} == "unset" ]]; then | |
echo " *** You need to specify both ROOT_PATH and BOOT_PATH, or neither" | |
exit 1 | |
fi | |
BRANCH=${BRANCH:-"master"} | |
ROOT_PATH=${ROOT_PATH:-"/"} | |
BOOT_PATH=${BOOT_PATH:-"/boot"} | |
WORK_PATH=${WORK_PATH:-"${ROOT_PATH}/root"} | |
SKIP_KERNEL=${SKIP_KERNEL:-0} | |
SKIP_SDK=${SKIP_SDK:-0} | |
RPI_UPDATE_UNSUPPORTED=${RPI_UPDATE_UNSUPPORTED:-0} | |
FW_REPO="${REPO_URI}.git" | |
FW_REPOLOCAL="${WORK_PATH}/.rpi-firmware" | |
FW_PATH="${BOOT_PATH}" | |
FW_MODPATH="${ROOT_PATH}/lib/modules" | |
FW_REV=${1:-""} | |
FW_REVFILE="${FW_PATH}/.firmware_revision" | |
[ "${RPI_UPDATE_UNSUPPORTED}" -ne 0 ] && echo -e "You appear to be trying to update firmware on an incompatible distribution. To force update, run the following:\nsudo -E RPI_UPDATE_UNSUPPORTED=0 rpi-update" && exit 1 | |
function update_self() { | |
echo " *** Performing self-update" | |
_tempFileName="$0.tmp" | |
if ! wget --output-document="${_tempFileName}" "${UPDATE_URI}"; then | |
echo " !!! Failed to download update for rpi-update!" | |
echo " !!! Make sure you have ca-certificates installed and that the time is set correctly" | |
exit 1 | |
fi | |
OCTAL_MODE=$(stat -c '%a' "$0") | |
if ! chmod ${OCTAL_MODE} "${_tempFileName}" ; then | |
echo " !!! Failed: Error while trying to set mode on ${_tempFileName}" | |
exit 1 | |
fi | |
cat > "${WORK_PATH}/.updateScript.sh" << EOF | |
if mv "${_tempFileName}" "$0"; then | |
rm -- "\$0" | |
exec env UPDATE_SELF=0 /bin/bash "$0" "${FW_REV}" | |
else | |
echo " !!! Failed!" | |
fi | |
EOF | |
echo " *** Relaunching after update" | |
exec /bin/bash "${WORK_PATH}/.updateScript.sh" | |
} | |
function update_modules { | |
if [[ ${SKIP_KERNEL} -eq 0 ]]; then | |
echo " *** Updating kernel modules" | |
cp -vR "${FW_REPOLOCAL}/modules/"* "${FW_MODPATH}/" | |
find "${FW_REPOLOCAL}/modules" -mindepth 1 -maxdepth 1 -type d | while read DIR; do | |
BASEDIR=$(basename "${DIR}") | |
echo " *** depmod ${BASEDIR}" | |
depmod -b "${ROOT_PATH}" -a "${BASEDIR}" | |
done | |
else | |
echo " *** As requested, not updating kernel modules" | |
fi | |
} | |
function update_vc_libs { | |
echo " *** Updating VideoCore libraries" | |
ELFOUTPUT=$(readelf -a "${ROOT_PATH}/bin/bash") | |
if [ "${ELFOUTPUT}" != "${ELFOUTPUT/VFP_args/}" ]; then | |
echo " *** Using HardFP libraries" | |
cp -vR "${FW_REPOLOCAL}/vc/hardfp/"* "${ROOT_PATH}/" | |
else | |
echo " *** Using SoftFP libraries" | |
cp -vR "${FW_REPOLOCAL}/vc/softfp/"* "${ROOT_PATH}/" | |
fi | |
} | |
function update_sdk { | |
if [[ ${SKIP_SDK} -eq 0 ]]; then | |
echo " *** Updating SDK" | |
cp -vR "${FW_REPOLOCAL}/vc/sdk/"* "${ROOT_PATH}/" | |
else | |
echo " *** As requested, not updating SDK" | |
fi | |
} | |
function update_firmware { | |
echo " *** Updating firmware" | |
rm -rf "${FW_PATH}/"*.elf | |
rm -rf "${FW_PATH}/"*.bin | |
cp -v "${FW_REPOLOCAL}/"*.elf "${FW_PATH}/" | |
cp -v "${FW_REPOLOCAL}/"*.bin "${FW_PATH}/" | |
cp -v "${FW_REPOLOCAL}/"*.dat "${FW_PATH}/" | |
if [[ ${SKIP_KERNEL} -eq 0 ]]; then | |
cp -v "${FW_REPOLOCAL}/"*.img "${FW_PATH}/" | |
else | |
echo " *** As requested, not updating kernel" | |
fi | |
} | |
function finalise { | |
if [[ -f "${FW_PATH}/arm192_start.elf" ]]; then | |
echo " *** Setting 192M ARM split" | |
cp -v "${FW_PATH}/arm192_start.elf" "${FW_PATH}/start.elf" | |
fi | |
echo " *** Running ldconfig" | |
ldconfig -r "${ROOT_PATH}" | |
if [[ "${FW_REV}" == "" ]]; then | |
echo " *** Storing current firmware revision" | |
git --git-dir="${FW_REPOLOCAL}/.git" rev-parse "${BRANCH}" > "${FW_REVFILE}" | |
else | |
echo "${FW_REV}" > "${FW_REVFILE}" | |
fi | |
echo " *** Syncing changes to disk" | |
sync | |
} | |
function download_repo { | |
echo " *** Setting up firmware (this may take a few minutes)" | |
mkdir -p "${FW_REPOLOCAL}" | |
set +e | |
git clone "${FW_REPO}" "${FW_REPOLOCAL}" --depth=1 --branch "${BRANCH}" | |
RETVAL=$? | |
set -e | |
if [[ ${RETVAL} -ne 0 ]]; then | |
echo " !!! Failed to download new firmware files" | |
exit 1 | |
fi | |
} | |
function update_repo { | |
# updating a depth=1 git tree doesn't work, so just kill it and clone a new one | |
rm -rf "${FW_REPOLOCAL}" | |
download_repo | |
} | |
function do_backup { | |
echo " *** Backing up files" | |
rm -rf "${FW_PATH}.bak" | |
cp -va "${FW_PATH}" "${FW_PATH}.bak" | |
if [[ ${SKIP_KERNEL} -eq 0 ]]; then | |
rm -rf "${FW_MODPATH}.bak" | |
cp -va "${FW_MODPATH}" "${FW_MODPATH}.bak" | |
fi | |
} | |
function do_update { | |
update_firmware | |
update_modules | |
update_vc_libs | |
update_sdk | |
finalise | |
echo " *** If no errors appeared, your firmware was successfully $1" | |
if [[ "${ROOT_PATH}" == "/" ]]; then | |
echo " *** A reboot is needed to activate the new firmware" | |
fi | |
} | |
function download_rev { | |
echo " *** Downloading specific firmware revision (this will take a few minutes)" | |
mkdir -p "${FW_REPOLOCAL}" | |
FW_TARBALL="${FW_REPOLOCAL}/${FW_REV}.tar.gz" | |
echo " *** Decompressing downloaded firmware archive" | |
wget "${REPO_URI}/tarball/${FW_REV}" -O "${FW_TARBALL}" | |
tar xzf "${FW_TARBALL}" -C "${FW_REPOLOCAL}" --strip-components=1 | |
rm "${FW_TARBALL}" | |
} | |
if [[ ${EUID} -ne 0 ]]; then | |
echo " !!! This tool must be run as root" | |
exit 1 | |
fi | |
echo " *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS" | |
if [[ ${UPDATE_SELF} -ne 0 ]]; then | |
update_self | |
fi | |
if [[ ! -d "${FW_PATH}" ]]; then | |
echo " !!! ${FW_PATH} doesn't exist" | |
exit 1 | |
fi | |
if [[ ${SKIP_KERNEL} -eq 0 ]] && [[ ! -d "${FW_MODPATH}" ]]; then | |
echo " !!! ${FW_MODPATH} doesn't exist" | |
exit 1 | |
fi | |
command -v git >/dev/null 2>&1 || { | |
echo " !!! This tool requires you have Git installed, please install it first" | |
echo " In Debian, try: sudo apt-get install git-core" | |
echo " In Arch, try: pacman -S git" | |
exit 1 | |
} | |
command -v readelf >/dev/null 2>&1 || { | |
echo " !!! This tool requires you have readelf installed, please install it first" | |
echo " In Debian, try: sudo apt-get install binutils" | |
echo " In Arch, try: pacman -S binutils" | |
exit 1 | |
} | |
echo " *** ARM/GPU split is now defined in /boot/config.txt using the gpu_mem option!" | |
if [[ "${FW_REV}" != "" ]]; then | |
download_rev | |
do_update "updated to revision ${FW_REV}" | |
elif [[ -f "${FW_REPOLOCAL}/bootcode.bin" ]]; then | |
# ask git server version before spending time cloning | |
GITREV=$(git ls-remote -h "${REPO_URI}" "refs/heads/${BRANCH}" | awk '{print $1}') | |
if [[ -f "${FW_REVFILE}" ]] && [[ $(cat "${FW_REVFILE}") == "$GITREV" ]]; then | |
echo " *** Your firmware is already up to date" | |
# no changes made, nothing to finalise | |
# finalise | |
else | |
update_repo | |
do_update "updated" | |
fi | |
else | |
echo " *** We're running for the first time" | |
if [[ -d "${FW_REPOLOCAL}" ]]; then | |
# rpi-update must have errored during the first run | |
rm -rf "${FW_REPOLOCAL}" | |
fi | |
download_repo | |
do_backup | |
do_update "setup" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment