mirror of
https://github.com/raspberrypi/rpi-update.git
synced 2026-01-20 21:13:38 +08:00
Added RAM split detection, added offline mode, added option to skip kernel update (thanks AndrewS!)
This commit is contained in:
30
README.md
30
README.md
@@ -21,7 +21,10 @@ To then update your firmware, simply run the following command as root:
|
|||||||
rpi-update
|
rpi-update
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
By default, the 224MB memory split will be used. If you'd like to use the 192MB split, then type:
|
|
||||||
|
By default, rpi-update will attempt to determine the split you're currently using, and then use that split. If it cannot determine what split you are using, it will default to 224MB.
|
||||||
|
|
||||||
|
If you'd like to explicitly select a split, simply provide the RAM split value after the command as follows:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
rpi-update 192
|
rpi-update 192
|
||||||
@@ -32,3 +35,28 @@ If you'd like to use the 128MB memory split, then the command is the same as the
|
|||||||
After the firmware has been sucessfully updated, you'll need to reboot to load the new firmware.
|
After the firmware has been sucessfully updated, you'll need to reboot to load the new firmware.
|
||||||
|
|
||||||
This tool is experimental, and may screw up your install. If you have problems with it, post an issue to this GitHub repo and I'll see if I can help you.
|
This tool is experimental, and may screw up your install. If you have problems with it, post an issue to this GitHub repo and I'll see if I can help you.
|
||||||
|
|
||||||
|
Expert options
|
||||||
|
--------------
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### SKIP_KERNEL
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
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 a kernel update.
|
||||||
|
|
||||||
|
### ROOT_PATH/BOOT_PATH
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
ROOT_PATH=/media/root BOOT_PATH=/media/boot rpi-update
|
||||||
|
|
||||||
|
#### Effect
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
224
rpi-update
224
rpi-update
@@ -3,94 +3,188 @@
|
|||||||
set -o nounset
|
set -o nounset
|
||||||
set -o errexit
|
set -o errexit
|
||||||
|
|
||||||
UPDATE=${2:-1}
|
UPDATE=${UPDATE:-1}
|
||||||
UPDATE_URI="https://raw.github.com/Hexxeh/rpi-update/master/rpi-update"
|
UPDATE_URI="https://github.com/Hexxeh/rpi-update/raw/master/rpi-update"
|
||||||
|
|
||||||
|
ROOT_PATH=${ROOT_PATH:-"/"}
|
||||||
|
BOOT_PATH=${BOOT_PATH:-"/boot"}
|
||||||
|
SKIP_KERNEL=${SKIP_KERNEL:-0}
|
||||||
FW_REPO="git://github.com/Hexxeh/rpi-firmware.git"
|
FW_REPO="git://github.com/Hexxeh/rpi-firmware.git"
|
||||||
FW_REPOLOCAL="/root/.rpi-firmware"
|
FW_REPOLOCAL="${ROOT_PATH}/root/.rpi-firmware"
|
||||||
FW_PATH="/boot"
|
FW_PATH="${BOOT_PATH}"
|
||||||
FW_REPONAME=`basename ${FW_REPOLOCAL}`
|
FW_MODPATH="${ROOT_PATH}/lib/modules"
|
||||||
FW_RAM=${1:-224}
|
FW_RAM=${1:-0}
|
||||||
FW_GPU=$((256-FW_RAM))
|
GITCMD="git --git-dir=\"${FW_REPOLOCAL}/.git\" --work-tree=\"${FW_REPOLOCAL}\""
|
||||||
|
|
||||||
|
function detect_split() {
|
||||||
|
if [[ -f "$FW_PATH/start.elf" && ${FW_RAM} -eq 0 ]]; then
|
||||||
|
FW_RAM=224
|
||||||
|
for R in 128 192 224
|
||||||
|
do
|
||||||
|
if [[ -f "$FW_PATH/arm${R}_start.elf" ]]
|
||||||
|
then
|
||||||
|
if diff "$FW_PATH/arm${R}_start.elf" "$FW_PATH/start.elf" >/dev/null
|
||||||
|
then
|
||||||
|
FW_RAM=$R
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
FW_GPU=$((256-FW_RAM))
|
||||||
|
}
|
||||||
|
|
||||||
function update_self() {
|
function update_self() {
|
||||||
echo "Performing self-update"
|
echo "Performing self-update"
|
||||||
_tempFileName="$0.tmp"
|
_tempFileName="$0.tmp"
|
||||||
_payloadName="$0.payload"
|
|
||||||
|
if ! wget --quiet --output-document="${_tempFileName}" "${UPDATE_URI}"; then
|
||||||
if ! wget --quiet --output-document="$_payloadName" $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
|
||||||
|
|
||||||
_interpreter=$(head --lines=1 "$0")
|
OCTAL_MODE=$(stat -c '%a' "$0")
|
||||||
echo $_interpreter > "$_tempFileName"
|
if ! chmod ${OCTAL_MODE} "${_tempFileName}" ; then
|
||||||
tail --lines=+2 "$_payloadName" >> "$_tempFileName"
|
echo "Failed: Error while trying to set mode on ${_tempFileName}"
|
||||||
rm "$_payloadName"
|
|
||||||
|
|
||||||
OCTAL_MODE=$(stat -c '%a' $0)
|
|
||||||
if ! chmod $OCTAL_MODE "$_tempFileName" ; then
|
|
||||||
echo "Failed: Error while trying to set mode on $_tempFileName."
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat > updateScript.sh << EOF
|
cat > /tmp/updateScript.sh << EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
if mv "$_tempFileName" "$0"; then
|
if mv "${_tempFileName}" "$0"; then
|
||||||
rm -- \$0
|
rm -- "\$0"
|
||||||
exec /bin/bash $0 ${FW_RAM} 0
|
exec env UPDATE=0 /bin/bash "$0" "$@"
|
||||||
else
|
else
|
||||||
echo "Failed!"
|
echo "Failed!"
|
||||||
fi
|
fi
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
exec /bin/bash updateScript.sh "$@"
|
exec /bin/bash /tmp/updateScript.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_modules {
|
function update_modules {
|
||||||
cp -R ${FW_REPOLOCAL}/modules/* /lib/modules/
|
if [[ ${SKIP_KERNEL} -eq 0 ]]; then
|
||||||
for D in `find ${FW_REPOLOCAL}/modules -mindepth 1 -maxdepth 1 -type d`; do
|
cp -R "${FW_REPOLOCAL}/modules/"* "${FW_MODPATH}/"
|
||||||
depmod -a `basename $D`
|
find "${FW_REPOLOCAL}/modules" -mindepth 1 -maxdepth 1 -type d | while read DIR; do
|
||||||
done
|
depmod -b "${ROOT_PATH}" -a $(basename "${DIR}")
|
||||||
|
done
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_sdk {
|
function update_sdk {
|
||||||
ELFOUTPUT=`readelf -a /bin/bash`
|
if [[ -f /etc/init.d/vcfiled ]]; then
|
||||||
if [ "$ELFOUTPUT" != "${ELFOUTPUT/VFP_args/}" ]; then
|
/etc/init.d/vcfiled stop
|
||||||
|
fi
|
||||||
|
|
||||||
|
ELFOUTPUT=$(readelf -a "${ROOT_PATH}/bin/bash")
|
||||||
|
if [ "${ELFOUTPUT}" != "${ELFOUTPUT/VFP_args/}" ]; then
|
||||||
echo "Using HardFP libraries"
|
echo "Using HardFP libraries"
|
||||||
cp -R ${FW_REPOLOCAL}/vc/hardfp/* /
|
cp -R "${FW_REPOLOCAL}/vc/hardfp/"* "${ROOT_PATH}/"
|
||||||
else
|
else
|
||||||
echo "Using SoftFP libraries"
|
echo "Using SoftFP libraries"
|
||||||
cp -R ${FW_REPOLOCAL}/vc/softfp/* /
|
cp -R "${FW_REPOLOCAL}/vc/softfp/"* "${ROOT_PATH}/"
|
||||||
|
fi
|
||||||
|
cp -R "${FW_REPOLOCAL}/vc/sdk/"* "${ROOT_PATH}/"
|
||||||
|
|
||||||
|
if [[ -f /etc/init.d/vcfiled ]]; then
|
||||||
|
/etc/init.d/vcfiled start
|
||||||
fi
|
fi
|
||||||
cp -R ${FW_REPOLOCAL}/vc/sdk/* /
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_split {
|
function set_split {
|
||||||
cp ${FW_REPOLOCAL}/arm${FW_RAM}_start.elf ${FW_PATH}/start.elf
|
cp "${FW_PATH}/arm${FW_RAM}_start.elf" "${FW_PATH}/start.elf"
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_firmware {
|
function update_firmware {
|
||||||
cp ${FW_REPOLOCAL}/*.elf ${FW_PATH}/
|
cp "${FW_REPOLOCAL}/"*.elf "${FW_PATH}/"
|
||||||
cp ${FW_REPOLOCAL}/*.bin ${FW_PATH}/
|
cp "${FW_REPOLOCAL}/"*.bin "${FW_PATH}/"
|
||||||
cp ${FW_REPOLOCAL}/*.img ${FW_PATH}/
|
if [[ ${SKIP_KERNEL} -eq 0 ]]; then
|
||||||
|
cp "${FW_REPOLOCAL}/"*.img "${FW_PATH}/"
|
||||||
|
else
|
||||||
|
echo "Skipping kernel/modules updated as requested"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalise {
|
function finalise {
|
||||||
ldconfig
|
ldconfig -r "${ROOT_PATH}"
|
||||||
|
eval ${GITCMD} rev-parse master > "${FW_PATH}/.firmware_revision"
|
||||||
sync
|
sync
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
function download_repo {
|
||||||
|
echo "Setting up firmware (this will take a few minutes)"
|
||||||
|
mkdir -p "${FW_REPOLOCAL}"
|
||||||
|
git clone "${FW_REPO}" "${FW_REPOLOCAL}" --depth=1 --quiet
|
||||||
|
RETVAL=$?
|
||||||
|
if [[ ${RETVAL} -ne 0 ]]; then
|
||||||
|
echo "Failed to download new firmware files"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_repo {
|
||||||
|
echo "Updating firmware (this will take a few minutes)"
|
||||||
|
eval ${GITCMD} fetch --quiet
|
||||||
|
RETVAL=$?
|
||||||
|
if [[ ${RETVAL} -ne 0 ]]; then
|
||||||
|
echo "Failed to download updated firmware files"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
eval ${GITCMD} merge origin/master -m "automerge" --quiet
|
||||||
|
RETVAL=$?
|
||||||
|
if [[ ${RETVAL} -ne 0 ]]; then
|
||||||
|
echo "Failed to download updated firmware files"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_backup {
|
||||||
|
cp -a "${FW_PATH}" "${FW_PATH}.bak"
|
||||||
|
cp -a "${FW_MODPATH}" "${FW_MODPATH}.bak"
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_update {
|
||||||
|
update_firmware
|
||||||
|
update_modules
|
||||||
|
update_sdk
|
||||||
|
set_split
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 [[ $UPDATE -ne 0 ]]; then
|
if [[ ${UPDATE} -ne 0 ]]; then
|
||||||
echo "Raspberry Pi firmware updater by Hexxeh"
|
echo "Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS"
|
||||||
update_self
|
update_self
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ( "${ROOT_PATH}" == "/" && "${BOOT_PATH}" != "/boot" ) ]] ||
|
||||||
|
[[ ( "${BOOT_PATH}" == "/boot" && "${ROOT_PATH}" != "/" ) ]]; then
|
||||||
|
echo "You need to specify both ROOT_PATH and BOOT_PATH, or neither"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "${FW_PATH}" ]]; then
|
||||||
|
echo "${FW_PATH} doesn't exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "${FW_PATH}/start.elf" ]]; then
|
||||||
|
echo "${FW_PATH}/start.elf doesn't exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -d "${FW_MODPATH}" ]]; then
|
||||||
|
echo "${FW_MODPATH} doesn't exist"
|
||||||
|
exit 1
|
||||||
|
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"
|
||||||
@@ -105,35 +199,25 @@ command -v readelf >/dev/null 2>&1 || {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Using memory split of ${FW_RAM}MB/${FW_GPU}MB"
|
detect_split
|
||||||
|
if [[ ${FW_RAM} -ne 224 ]] && [[ ${FW_RAM} -ne 192 ]] && [[ ${FW_RAM} -ne 128 ]]; then
|
||||||
|
echo "RAM value must be one of: 224, 192, 128"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Using ARM/GPU memory split of ${FW_RAM}MB/${FW_GPU}MB"
|
||||||
|
|
||||||
GITCMD="git --git-dir=${FW_REPOLOCAL}/.git --work-tree=${FW_REPOLOCAL}"
|
if [[ -f "${FW_REPOLOCAL}/.git/config" ]]; then
|
||||||
|
update_repo
|
||||||
mkdir -p ${FW_REPOLOCAL}
|
if [[ -f "${FW_PATH}/.firmware_revision" ]] && [[ $(cat "${FW_PATH}/.firmware_revision") == $(eval ${GITCMD} rev-parse master) ]]; then
|
||||||
if $($GITCMD rev-parse &> /dev/null); then
|
echo "Your firmware is already up to date"
|
||||||
echo "Updating firmware (this will take a few minutes)"
|
|
||||||
$GITCMD fetch --quiet
|
|
||||||
$GITCMD merge origin/master -m "automerge" --quiet
|
|
||||||
update_firmware
|
|
||||||
update_modules
|
|
||||||
update_sdk
|
|
||||||
set_split
|
|
||||||
finalise
|
|
||||||
echo "If no errors appeared, your firmware was successfully updated"
|
|
||||||
else
|
|
||||||
echo "We're running for the first time"
|
|
||||||
echo "Setting up firmware (this will take a few minutes)"
|
|
||||||
cp -R ${FW_PATH} ${FW_PATH}.bak
|
|
||||||
git clone ${FW_REPO} ${FW_REPOLOCAL} --depth=1 --quiet
|
|
||||||
RETVAL=$?
|
|
||||||
if [[ $RETVAL != 0 ]]; then
|
|
||||||
echo "Failed to download new firmware files"
|
|
||||||
else
|
|
||||||
update_firmware
|
|
||||||
update_modules
|
|
||||||
update_sdk
|
|
||||||
set_split
|
set_split
|
||||||
finalise
|
finalise
|
||||||
echo "If no errors appeared, your firmware was successfully setup"
|
else
|
||||||
|
do_update "updated"
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
echo "We're running for the first time"
|
||||||
|
download_repo
|
||||||
|
do_backup
|
||||||
|
do_update "setup"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user