From 41e23a0924d18786ac2374b04277d1223bdec614 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 5 Apr 2014 15:28:52 +0100 Subject: [PATCH] Download firmware without using git This removes the requirement for git. We never make use of partial git updates, and it is quicker to download the tarball with curl than use git. Also piping the curl output into tar is quicker than downloading then un-tarring. Remove the verbose options from the copies (they don't fail, slow down the copies and swamp any more useful output messages). By default delete /root/.rpi_firmware (as it's easy to recreate). Use SKIP_REPODELETE=1 if you want to keep it. Add option SKIP_BACKUP=1 if you don't want a backup of old firmware and modules. --- rpi-update | 157 ++++++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/rpi-update b/rpi-update index fb0a773..16fa599 100755 --- a/rpi-update +++ b/rpi-update @@ -20,6 +20,9 @@ BOOT_PATH=${BOOT_PATH:-"/boot"} WORK_PATH=${WORK_PATH:-"${ROOT_PATH}/root"} SKIP_KERNEL=${SKIP_KERNEL:-0} SKIP_SDK=${SKIP_SDK:-0} +SKIP_REPODELETE=${SKIP_REPODELETE:-0} +SKIP_BACKUP=${SKIP_BACKUP:-0} +WANT_SYMVERS=${WANT_SYMVERS:-0} RPI_UPDATE_UNSUPPORTED=${RPI_UPDATE_UNSUPPORTED:-0} FW_REPO="${REPO_URI}.git" FW_REPOLOCAL="${WORK_PATH}/.rpi-firmware" @@ -61,7 +64,7 @@ EOF function update_modules { if [[ ${SKIP_KERNEL} -eq 0 ]]; then echo " *** Updating kernel modules" - cp -vR "${FW_REPOLOCAL}/modules/"* "${FW_MODPATH}/" + cp -R "${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}" @@ -78,17 +81,17 @@ function update_vc_libs { 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}/" + cp -R "${FW_REPOLOCAL}/vc/hardfp/"* "${ROOT_PATH}/" else echo " *** Using SoftFP libraries" - cp -vR "${FW_REPOLOCAL}/vc/softfp/"* "${ROOT_PATH}/" + cp -R "${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}/" + cp -R "${FW_REPOLOCAL}/vc/sdk/"* "${ROOT_PATH}/" else echo " *** As requested, not updating SDK" fi @@ -98,66 +101,60 @@ 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}/" + cp "${FW_REPOLOCAL}/"*.elf "${FW_PATH}/" + cp "${FW_REPOLOCAL}/"*.bin "${FW_PATH}/" + cp "${FW_REPOLOCAL}/"*.dat "${FW_PATH}/" if [[ ${SKIP_KERNEL} -eq 0 ]]; then - cp -v "${FW_REPOLOCAL}/"*.img "${FW_PATH}/" + cp "${FW_REPOLOCAL}/"*.img "${FW_PATH}/" if [[ -n $(shopt -s nullglob; echo "${FW_REPOLOCAL}/"*.dtb) ]]; then - cp -v "${FW_REPOLOCAL}/"*.dtb "${FW_PATH}/" + cp "${FW_REPOLOCAL}/"*.dtb "${FW_PATH}/" fi else echo " *** As requested, not updating kernel" fi + if [[ ${WANT_SYMVERS} -ne 0 ]]; then + if [[ -f "${FW_REPOLOCAL}/"Module.symvers ]]; then + cp "${FW_REPOLOCAL}/"Module.symvers "${FW_PATH}/" + fi + if [[ -f "${FW_REPOLOCAL}/"git_hash ]]; then + cp "${FW_REPOLOCAL}/"git_hash "${FW_PATH}/" + fi + 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" + cp "${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 + echo " *** Storing current firmware revision" + echo "${FW_REV}" > "${FW_REVFILE}" } 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" + if [[ ${SKIP_BACKUP} -eq 0 ]]; then + echo " *** Backing up files (this will take a few minutes)" + if [[ -f "${FW_PATH}.bak" ]]; then + echo " *** Remove old firmware backup" + rm -rf "${FW_PATH}.bak" + fi + echo " *** Backing up firmware" + cp -a "${FW_PATH}" "${FW_PATH}.bak" + if [[ ${SKIP_KERNEL} -eq 0 ]]; then + if [[ -f "${FW_MODPATH}.bak" ]]; then + echo " *** Remove old modules backup" + rm -rf "${FW_MODPATH}.bak" + fi + echo " *** Backing up modules $(uname -r)" + mkdir -p "${FW_MODPATH}.bak" && cp -a "${FW_MODPATH}/$(uname -r)" "${FW_MODPATH}.bak" + fi fi } function do_update { + download_rev if [[ -f "${FW_REPOLOCAL}/pre-install" ]]; then echo " *** Running pre-install script" source "${FW_REPOLOCAL}/pre-install" @@ -171,7 +168,10 @@ function do_update { echo " *** Running post-install script" source "${FW_REPOLOCAL}/post-install" fi - echo " *** If no errors appeared, your firmware was successfully $1" + remove_rev + echo " *** Syncing changes to disk" + sync + echo " *** If no errors appeared, your firmware was successfully updated to ${FW_REV}" if [[ "${ROOT_PATH}" == "/" ]]; then echo " *** A reboot is needed to activate the new firmware" fi @@ -179,12 +179,16 @@ function do_update { function download_rev { echo " *** Downloading specific firmware revision (this will take a few minutes)" + rm -rf "${FW_REPOLOCAL}" mkdir -p "${FW_REPOLOCAL}" - FW_TARBALL="${FW_REPOLOCAL}/${FW_REV}.tar.gz" - echo " *** Decompressing downloaded firmware archive" - curl -L --output "${FW_TARBALL}" "${REPO_URI}/tarball/${FW_REV}" - tar xzf "${FW_TARBALL}" -C "${FW_REPOLOCAL}" --strip-components=1 - rm "${FW_TARBALL}" + curl -L "${REPO_URI}/tarball/${FW_REV}" | tar xzf - -C "${FW_REPOLOCAL}" --strip-components=1 +} + +function remove_rev { + echo " *** Deleting downloaded files" + if [[ ${SKIP_REPODELETE} -eq 0 ]]; then + rm -rf "${FW_REPOLOCAL}" + fi } if [[ ${EUID} -ne 0 ]]; then @@ -192,7 +196,7 @@ if [[ ${EUID} -ne 0 ]]; then exit 1 fi -echo " *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS" +echo " *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom" if [[ ${UPDATE_SELF} -ne 0 ]]; then update_self @@ -208,13 +212,6 @@ if [[ ${SKIP_KERNEL} -eq 0 ]] && [[ ! -d "${FW_MODPATH}" ]]; then 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" @@ -222,28 +219,26 @@ command -v readelf >/dev/null 2>&1 || { 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" +# ask github for latest version hash +REPO_API=${REPO_URI/github.com/api.github.com\/repos}/git/refs/heads/${BRANCH} +GITREV=$(curl -s ${REPO_URI/github.com/api.github.com\/repos}/git/refs/heads/${BRANCH} | awk '{ if ($1 == "\"sha\":") { print substr($2, 2, 40) } }') +FW_REV=${FW_REV:-${GITREV}} + +if [[ "${FW_REV}" == "" ]]; then + echo " *** No hash received from github: ${REPO_API}" + # run again with errors not suppressed + curl ${REPO_API} + exit 1 fi + +if [[ ! -f "${FW_REVFILE}" ]]; then + echo " *** We're running for the first time" + do_backup +else + if [[ $(cat "${FW_REVFILE}") == "$FW_REV" ]]; then + echo " *** Your firmware is already up to date" + exit 0 + fi +fi + +do_update