Merge pull request #51 from nylen/pull1

A bunch of changes (v2)
This commit is contained in:
Liam McLoughlin
2013-01-03 08:27:02 -08:00
2 changed files with 116 additions and 84 deletions

View File

@@ -1,56 +1,74 @@
rpi-update # rpi-update
==========
An easier way to update the firmware of your Raspberry Pi An easier way to update the firmware of your Raspberry Pi.
Instructions ## Preparations
------------
There are two possible problems related to SSL certificates that may prevent
this tool from working.
- The time may be set incorrectly on your Raspberry Pi, which you can fix
by setting the time using NTP.
sudo ntpdate -u ntp.ubuntu.com
- The other possible issue is that you might not have the `ca-certificates`
package installed, and so GitHub's SSL certificate isn't trusted. If you are
on Debian, you can resolve this by typing:
sudo apt-get install ca-certificates
## Installing
To install the tool, run the following command: To install the tool, run the following command:
<pre> sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update && chmod +x /usr/bin/rpi-update
sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update && sudo chmod +x /usr/bin/rpi-update
</pre>
If you get errors relating to certificates, then the problem is likely due to one of two things. Either the time is set incorrectly on your Raspberry Pi, which you can fix by simply setting the time using NTP. The other possible issue is that you might not have the ca-certificates package installed, and so GitHub's SSL certificate isn't trusted. If you're on Debian, you can resolve this by typing: ## Updating
<pre> Then, to update your firmware, just run the following command:
sudo apt-get install ca-certificates
</pre>
To then update your firmware, simply run the following command:
<pre>
sudo rpi-update sudo rpi-update
</pre>
To upgrade/downgrade to a specific firmware revision, specify it's Git hash as follows: ## Activating
rpi-update <git hash> After the firmware has been sucessfully updated, you'll need to reboot to load
the new firmware.
If you'd like to set a different GPU/ARM memory split, then define gpu_mem in /boot/config.txt. ## Options
Expert options If you'd like to set a different GPU/ARM memory split, then define `gpu_mem` in
-------------- `/boot/config.txt`.
There are a number of options for experts you might like to use, these are all environment variables you must set if you wish to use them. To upgrade/downgrade to a specific firmware revision, specify its Git hash
(from the https://github.com/Hexxeh/rpi-firmware repository) as follows:
### SKIP_KERNEL sudo rpi-update fab7796df0cf29f9563b507a59ce5b17d93e0390
#### Usage ### Expert options
SKIP_KERNEL=1 rpi-update There are a number of options for experts you might like to use. These are all
environment variables you must set if you wish to use them.
#### Effect #### `UPDATE_SELF`
Will update everything EXCEPT the kernel.img files and the kernel modules. Use with caution, some firmware updates might depend a kernel update. By default, `rpi-update` will attempt to update itself each time it is run.
You can disable this behavior by:
### ROOT_PATH/BOOT_PATH sudo UPDATE_SELF=0 rpi-update
#### Usage #### `SKIP_KERNEL`
ROOT_PATH=/media/root BOOT_PATH=/media/boot rpi-update sudo SKIP_KERNEL=1 rpi-update
#### Effect Will update everything **except** the `kernel.img` files and the kernel modules.
Use with caution, some firmware updates might depend on a kernel update.
Allows you to perform an "offline" update, ie update firmware on an SD card you're not currently booted from. Useful for installing firmware/kernel to a non-RPI customised image. Be careful, you must specify both options or neither. Specifying only one will not work. #### `ROOT_PATH` and `BOOT_PATH`
sudo ROOT_PATH=/media/root BOOT_PATH=/media/boot rpi-update
Allows you to perform an "offline" update, ie update firmware on an SD card you
are not currently booted from. Useful for installing firmware/kernel to a
non-RPI customised image. Be careful, you must specify both options or neither.
Specifying only one will not work.

View File

@@ -5,12 +5,12 @@ set -o errexit
REPO_URI="http://github.com/Hexxeh/rpi-firmware" REPO_URI="http://github.com/Hexxeh/rpi-firmware"
UPDATE2=${UPDATE2:-1} UPDATE_SELF=${UPDATE_SELF:-1}
UPDATE_URI="https://github.com/Hexxeh/rpi-update/raw/master/rpi-update" UPDATE_URI="https://github.com/Hexxeh/rpi-update/raw/master/rpi-update"
if [[ ${BOOT_PATH:-"unset"} == "unset" && ${ROOT_PATH:-"unset"} != "unset" ]] || if [[ ${BOOT_PATH:-"unset"} == "unset" && ${ROOT_PATH:-"unset"} != "unset" ]] ||
[[ ${BOOT_PATH:-"unset"} != "unset" && ${ROOT_PATH:-"unset"} == "unset" ]]; then [[ ${BOOT_PATH:-"unset"} != "unset" && ${ROOT_PATH:-"unset"} == "unset" ]]; then
echo "You need to specify both ROOT_PATH and BOOT_PATH, or neither" echo " *** You need to specify both ROOT_PATH and BOOT_PATH, or neither"
exit 1 exit 1
fi fi
@@ -27,18 +27,18 @@ GITCMD="git --git-dir=\"${FW_REPOLOCAL}/.git\" --work-tree=\"${FW_REPOLOCAL}\""
[ "${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 [ "${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() { function update_self() {
echo "Performing self-update" echo " *** Performing self-update"
_tempFileName="$0.tmp" _tempFileName="$0.tmp"
if ! wget --quiet --output-document="${_tempFileName}" "${UPDATE_URI}"; then if ! wget --output-document="${_tempFileName}" "${UPDATE_URI}"; then
echo "Failed to download update for rpi-update!" echo " !!! Failed to download update for rpi-update!"
echo "Make sure you have ca-certificates installed and that the time is set correctly" echo " !!! Make sure you have ca-certificates installed and that the time is set correctly"
exit 1 exit 1
fi fi
OCTAL_MODE=$(stat -c '%a' "$0") OCTAL_MODE=$(stat -c '%a' "$0")
if ! chmod ${OCTAL_MODE} "${_tempFileName}" ; then if ! chmod ${OCTAL_MODE} "${_tempFileName}" ; then
echo "Failed: Error while trying to set mode on ${_tempFileName}" echo " !!! Failed: Error while trying to set mode on ${_tempFileName}"
exit 1 exit 1
fi fi
@@ -46,38 +46,45 @@ function update_self() {
#!/bin/bash #!/bin/bash
if mv "${_tempFileName}" "$0"; then if mv "${_tempFileName}" "$0"; then
rm -- "\$0" rm -- "\$0"
exec env UPDATE2=0 /bin/bash "$0" "${FW_REV}" exec env UPDATE_SELF=0 /bin/bash "$0" "${FW_REV}"
else else
echo "Failed!" echo " !!! Failed!"
fi fi
EOF EOF
echo " *** Relaunching after update"
exec /bin/bash /tmp/updateScript.sh exec /bin/bash /tmp/updateScript.sh
} }
function update_modules { function update_modules {
if [[ ${SKIP_KERNEL} -eq 0 ]]; then if [[ ${SKIP_KERNEL} -eq 0 ]]; then
cp -R "${FW_REPOLOCAL}/modules/"* "${FW_MODPATH}/" echo " *** Updating modules"
cp -vR "${FW_REPOLOCAL}/modules/"* "${FW_MODPATH}/"
find "${FW_REPOLOCAL}/modules" -mindepth 1 -maxdepth 1 -type d | while read DIR; do find "${FW_REPOLOCAL}/modules" -mindepth 1 -maxdepth 1 -type d | while read DIR; do
echo " *** depmod $(basename "${DIR}")"
depmod -b "${ROOT_PATH}" -a $(basename "${DIR}") depmod -b "${ROOT_PATH}" -a $(basename "${DIR}")
done done
else
echo " *** As requested, not updating modules"
fi fi
} }
function update_sdk { function update_sdk {
echo " *** Updating SDK"
if [[ -f /etc/init.d/vcfiled ]]; then if [[ -f /etc/init.d/vcfiled ]]; then
/etc/init.d/vcfiled stop /etc/init.d/vcfiled stop
fi fi
ELFOUTPUT=$(readelf -a "${ROOT_PATH}/bin/bash") ELFOUTPUT=$(readelf -a "${ROOT_PATH}/bin/bash")
if [ "${ELFOUTPUT}" != "${ELFOUTPUT/VFP_args/}" ]; then if [ "${ELFOUTPUT}" != "${ELFOUTPUT/VFP_args/}" ]; then
echo "Using HardFP libraries" echo " *** Using HardFP libraries"
cp -R "${FW_REPOLOCAL}/vc/hardfp/"* "${ROOT_PATH}/" cp -vR "${FW_REPOLOCAL}/vc/hardfp/"* "${ROOT_PATH}/"
else else
echo "Using SoftFP libraries" echo " *** Using SoftFP libraries"
cp -R "${FW_REPOLOCAL}/vc/softfp/"* "${ROOT_PATH}/" cp -vR "${FW_REPOLOCAL}/vc/softfp/"* "${ROOT_PATH}/"
fi fi
cp -R "${FW_REPOLOCAL}/vc/sdk/"* "${ROOT_PATH}/" cp -vR "${FW_REPOLOCAL}/vc/sdk/"* "${ROOT_PATH}/"
if [[ -f /etc/init.d/vcfiled ]]; then if [[ -f /etc/init.d/vcfiled ]]; then
/etc/init.d/vcfiled start /etc/init.d/vcfiled start
@@ -85,61 +92,67 @@ function update_sdk {
} }
function update_firmware { function update_firmware {
echo " *** Updating firmware"
rm -rf ${FW_PATH}/*.elf rm -rf ${FW_PATH}/*.elf
rm -rf ${FW_PATH}/*.bin rm -rf ${FW_PATH}/*.bin
cp ${FW_REPOLOCAL}/*.elf "${FW_PATH}/" cp -v ${FW_REPOLOCAL}/*.elf "${FW_PATH}/"
cp ${FW_REPOLOCAL}/*.bin "${FW_PATH}/" cp -v ${FW_REPOLOCAL}/*.bin "${FW_PATH}/"
cp ${FW_REPOLOCAL}/*.dat "${FW_PATH}/" cp -v ${FW_REPOLOCAL}/*.dat "${FW_PATH}/"
if [[ ${SKIP_KERNEL} -eq 0 ]]; then if [[ ${SKIP_KERNEL} -eq 0 ]]; then
cp "${FW_REPOLOCAL}/"*.img "${FW_PATH}/" cp -v "${FW_REPOLOCAL}/"*.img "${FW_PATH}/"
else else
echo "Skipping kernel/modules updated as requested" echo " *** As requested, not updating kernel"
fi fi
} }
function finalise { function finalise {
if [[ -f "${FW_PATH}/arm192_start.elf" ]]; then if [[ -f "${FW_PATH}/arm192_start.elf" ]]; then
cp "${FW_PATH}/arm192_start.elf" "${FW_PATH}/start.elf" echo " *** Setting 192M ARM split"
cp -v "${FW_PATH}/arm192_start.elf" "${FW_PATH}/start.elf"
fi fi
echo " *** Running ldconfig"
ldconfig -r "${ROOT_PATH}" ldconfig -r "${ROOT_PATH}"
if [[ ${FW_REV} == "" ]]; then if [[ ${FW_REV} == "" ]]; then
echo " *** Storing current firmware revision"
eval ${GITCMD} rev-parse master > "${FW_PATH}/.firmware_revision" eval ${GITCMD} rev-parse master > "${FW_PATH}/.firmware_revision"
fi fi
echo " *** Syncing changes to disk"
sync sync
} }
function download_repo { function download_repo {
echo "Setting up firmware (this will take a few minutes)" echo " *** Setting up firmware (this may take a few minutes)"
mkdir -p "${FW_REPOLOCAL}" mkdir -p "${FW_REPOLOCAL}"
git clone "${FW_REPO}" "${FW_REPOLOCAL}" --depth=1 --quiet git clone "${FW_REPO}" "${FW_REPOLOCAL}" --depth=1
RETVAL=$? RETVAL=$?
if [[ ${RETVAL} -ne 0 ]]; then if [[ ${RETVAL} -ne 0 ]]; then
echo "Failed to download new firmware files" echo " !!! Failed to download new firmware files"
exit 1 exit 1
fi fi
} }
function update_repo { function update_repo {
echo "Updating firmware (this will take a few minutes)" echo " *** Updating firmware (this may take a few minutes)"
eval ${GITCMD} fetch --quiet eval ${GITCMD} fetch
RETVAL=$? RETVAL=$?
if [[ ${RETVAL} -ne 0 ]]; then if [[ ${RETVAL} -ne 0 ]]; then
echo "Failed to download updated firmware files" echo " !!! Failed to download updated firmware files"
exit 1 exit 1
fi fi
eval ${GITCMD} reset --hard --quiet eval ${GITCMD} reset --hard
eval ${GITCMD} clean -f -d --quiet eval ${GITCMD} clean -f -d
eval ${GITCMD} merge origin/master -m "automerge" --quiet eval ${GITCMD} merge origin/master -m "automerge"
RETVAL=$? RETVAL=$?
if [[ ${RETVAL} -ne 0 ]]; then if [[ ${RETVAL} -ne 0 ]]; then
echo "Failed to download updated firmware files" echo " !!! Failed to download updated firmware files"
exit 1 exit 1
fi fi
} }
function do_backup { function do_backup {
cp -a "${FW_PATH}" "${FW_PATH}.bak" echo " *** Backing up files"
cp -a "${FW_MODPATH}" "${FW_MODPATH}.bak" cp -va "${FW_PATH}" "${FW_PATH}.bak"
cp -va "${FW_MODPATH}" "${FW_MODPATH}.bak"
} }
function do_update { function do_update {
@@ -147,71 +160,72 @@ function do_update {
update_modules update_modules
update_sdk update_sdk
finalise finalise
echo "If no errors appeared, your firmware was successfully $1" echo " *** If no errors appeared, your firmware was successfully $1"
if [[ "${ROOT_PATH}" == "/" ]]; then if [[ "${ROOT_PATH}" == "/" ]]; then
echo "A reboot is needed to activate the new firmware" echo " *** A reboot is needed to activate the new firmware"
fi fi
} }
function download_rev { function download_rev {
echo "Downloading specific firmware revision (this will take a few minutes)" echo " *** Downloading specific firmware revision (this will take a few minutes)"
mkdir -p "${FW_REPOLOCAL}" mkdir -p "${FW_REPOLOCAL}"
wget -q "${REPO_URI}/tarball/${FW_REV}" -O "${FW_REPOLOCAL}/${FW_REV}.tar.gz" wget "${REPO_URI}/tarball/${FW_REV}" -O "${FW_REPOLOCAL}/${FW_REV}.tar.gz"
tar xzf "${FW_REPOLOCAL}/${FW_REV}.tar.gz" -C "${FW_REPOLOCAL}" --strip-components=1 tar xzf "${FW_REPOLOCAL}/${FW_REV}.tar.gz" -C "${FW_REPOLOCAL}" --strip-components=1
rm "${FW_REPOLOCAL}/${FW_REV}.tar.gz" rm "${FW_REPOLOCAL}/${FW_REV}.tar.gz"
} }
if [[ ${EUID} -ne 0 ]]; then if [[ ${EUID} -ne 0 ]]; then
echo "This tool must be run as root" echo " !!! This tool must be run as root"
exit 1 exit 1
fi fi
if [[ ${UPDATE2} -ne 0 ]]; then echo " *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS"
echo "Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS"
if [[ ${UPDATE_SELF} -ne 0 ]]; then
update_self update_self
fi fi
if [[ ! -d "${FW_PATH}" ]]; then if [[ ! -d "${FW_PATH}" ]]; then
echo "${FW_PATH} doesn't exist" echo " !!! ${FW_PATH} doesn't exist"
exit 1 exit 1
fi fi
if [[ ! -f "${FW_PATH}/start.elf" ]]; then if [[ ! -f "${FW_PATH}/start.elf" ]]; then
echo "${FW_PATH}/start.elf doesn't exist." echo " !!! ${FW_PATH}/start.elf doesn't exist."
exit 1 exit 1
fi fi
if [[ ! -d "${FW_MODPATH}" ]]; then if [[ ! -d "${FW_MODPATH}" ]]; then
echo "${FW_MODPATH} doesn't exist" echo " !!! ${FW_MODPATH} doesn't exist"
exit 1 exit 1
fi fi
command -v git >/dev/null 2>&1 || { command -v git >/dev/null 2>&1 || {
echo "This tool requires you have Git installed, please install it first" echo " !!! This tool requires you have Git installed, please install it first"
echo " In Debian, try: sudo apt-get install git-core" echo " In Debian, try: sudo apt-get install git-core"
echo " In Arch, try: pacman -S git" echo " In Arch, try: pacman -S git"
exit 1 exit 1
} }
command -v readelf >/dev/null 2>&1 || { command -v readelf >/dev/null 2>&1 || {
echo "This tool requires you have readelf installed, please install it first" echo " !!! This tool requires you have readelf installed, please install it first"
echo " In Debian, try: sudo apt-get install binutils" echo " In Debian, try: sudo apt-get install binutils"
echo " In Arch, try: pacman -S binutils" echo " In Arch, try: pacman -S binutils"
exit 1 exit 1
} }
echo "ARM/GPU split is now defined in /boot/config.txt using the gpu_mem option!" echo " *** ARM/GPU split is now defined in /boot/config.txt using the gpu_mem option!"
if [[ ${FW_REV} != "" ]]; then if [[ ${FW_REV} != "" ]]; then
download_rev download_rev
do_update "updated to revision ${FW_REV}" do_update "updated to revision ${FW_REV}"
elif [[ -f "${FW_REPOLOCAL}/.git/config" ]]; then elif [[ -f "${FW_REPOLOCAL}/.git/config" ]]; then
update_repo update_repo
if [[ -f "${FW_PATH}/.firmware_revision" ]] && [[ $(cat "${FW_PATH}/.firmware_revision") == $(eval ${GITCMD} rev-parse master) ]]; then if [[ -f "${FW_PATH}/.firmware_revision" ]] && [[ $(cat "${FW_PATH}/.firmware_revision") == $(eval ${GITCMD} rev-parse master) ]]; then
echo "Your firmware is already up to date" echo " *** Your firmware is already up to date"
finalise finalise
else else
do_update "updated" do_update "updated"
fi fi
else else
echo "We're running for the first time" echo " *** We're running for the first time"
download_repo download_repo
do_backup do_backup
do_update "setup" do_update "setup"