Skip to content

Commit

Permalink
armbian-update: add kernel rescue method(-r)
Browse files Browse the repository at this point in the history
  • Loading branch information
ophub committed Jan 26, 2023
1 parent 829e332 commit 2a75cbb
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 15 deletions.
3 changes: 3 additions & 0 deletions README.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ armbian-update
| -k | auto latest | [内核名称](https://github.com/ophub/kernel/tree/main/pub/stable) | 设置更新内核名称 |
| -v | stable | stable/rk3588/dev | 指定内核版本分支 |
| -m | no | yes/no | 使用主线 u-boot |
| -r | "" | "" | [救援专用] 使用 USB 中的系统内核更新 eMMC |

举例: `armbian-update -k 5.15.50 -v dev -m yes`

如果当前目录下有成套的内核文件,将使用当前目录的内核进行更新(更新需要的 4 个内核文件是 `header-xxx.tar.gz`, `boot-xxx.tar.gz`, `dtb-amlogic-xxx.tar.gz`, `modules-xxx.tar.gz`。其他内核文件不需要,如果同时存在也不影响更新,系统可以准确识别需要的内核文件)。如果当前目录没有内核文件,将从服务器查询并下载同系列的最新内核进行更新。在设备支持的可选内核里可以自由更新,如从 5.10.125 内核更新为 5.15.50 内核。

因特殊原因导致的更新不完整等问题,造成系统无法从 eMMC 启动时,可以从 USB 中启动任意内核版本的 Armbian 系统,运行 `armbian-update -r` 命令可以把 USB 中的系统内核更新至 eMMC 中,实现救援的目的。

- ### 安装常用软件

登录 Armbian 系统 → 输入命令:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ armbian-update
| -k | auto latest | [kernel name](https://github.com/ophub/kernel/tree/main/pub/stable) | Set the kernel name |
| -v | stable | stable/rk3588/dev | Set the kernel version branch |
| -m | no | yes/no | Use Mainline u-boot |
| -r | "" | "" | [Rescue]. Update eMMC using the system kernel in USB |

Example: `armbian-update -k 5.15.50 -v dev -m yes`

If there is a set of kernel files in the current directory, it will be updated with the kernel in the current directory (The 4 kernel files required for the update are `header-xxx.tar.gz`, `boot-xxx.tar.gz`, `dtb-amlogic-xxx.tar.gz`, `modules-xxx.tar.gz`. Other kernel files are not required. If they exist at the same time, it will not affect the update. The system can accurately identify the required kernel files). If there is no kernel file in the current directory, it will query and download the latest kernel of the same series from the server for update. The optional kernel supported by the device can be freely updated, such as from 5.10.125 kernel to 5.15.50 kernel.

When the system cannot be started from eMMC due to incomplete updates and other problems caused by special reasons, you can start any kernel version of the Armian system from USB, and run the `armbian-update -r` command to update the system kernel in USB to eMMC to achieve the purpose of rescue.

- ### Install common software

Login in to armbian → input command:
Expand Down
105 changes: 90 additions & 15 deletions build-armbian/armbian-files/common-files/usr/sbin/armbian-update
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@
# Optional parameter meaning: -k = set the kernel name
# -v = set the kernel version branch
# -m = ues mainline_u-boot
# -r = Rescue the kernel
#
# Command optional parameters: armbian-update -k 5.15.50 -v stable/dev -m yes/no
# Set the kernel name command: armbian-update -k 5.15.50
# Set the kernel branch command: armbian-update -v dev
# Use mainline u-boot command: armbian-update -m yes
# Use mainline u-boot command: armbian-update -m yes/no
# Rescue the Armbian kernel: armbian-update -r
#
#========================================= Functions list =========================================
#
# error_msg : Output error message
# check_depends : Check dependencies
# get_textoffset : Get kernel TEXT_OFFSET
# init_var : Initialize all variables
# rescue_kernel : Rescue the kernel
# download_kernel : Download the kernel
# check_kernel : Check kernel files list
# update_kernel : Update the kernel
Expand All @@ -39,6 +42,8 @@
#
# Set current path
current_path="${PWD}"
# Set the kernel backup directory
backup_path="/backup/kernel"
# Set the release check file
ophub_release_file="/etc/ophub-release"
# Set the kernel download repository
Expand Down Expand Up @@ -203,6 +208,78 @@ init_var() {
sync && echo ""
}

# Rescue the kernel
rescue_kernel() {
echo -e "${STEPS} Start restoring kernel files..."

# Check the current system running disk
root_devname="$(df / | tail -n1 | awk '{print $1}' | awk -F '/' '{print substr($3, 1, length($3)-2)}')"
if lsblk -l | grep -E "^${root_devname}boot0" >/dev/null; then
error_msg "You are running in eMMC mode, please boot system with usb or tf card!"
fi

# Find emmc disk, first find emmc containing boot0 partition
box_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?boot0)' | sed "s/boot0//g")"
# Find emmc disk, find emmc that does not contain the boot0 partition
[[ -z "${box_emmc}" ]] && box_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?)' | grep -vE ^${root_devname} | uniq)"
# Check if emmc exists
[[ -z "${box_emmc}" ]] && error_msg "The eMMC storage not found in this device!"
# Location of emmc
restore_emmc="/dev/${box_emmc}"
echo -e "${INFO} The device eMMC name: [ ${restore_emmc} ]"

# Check if there is enough free space
available_space="$(df -Tk / | grep '/dev/' | awk '{print $5}' | echo $(($(xargs) / 1024 / 1024)))"
if [[ -z "$(echo "${available_space}" | sed -n "/^[0-9]\+$/p")" ]]; then
error_msg "The remaining space cannot be obtained."
fi
if [[ "${available_space}" -lt "3" ]]; then
error_msg "The remaining space is [ ${available_space}GiB ], less than 3GiB, please use [ armbian-tf ] to expand the USB."
fi

# Create a temporary mount directory
rm -rf ${backup_path}/*
mkdir -p ${backup_path}/{bootfs/,rootfs/}

# Mount eMMC to USB
mount ${restore_emmc}p1 ${backup_path}/bootfs
[[ "${?}" -eq "0" ]] || error_msg "mount ${restore_emmc}p1 failed!"
mount ${restore_emmc}p2 ${backup_path}/rootfs
[[ "${?}" -eq "0" ]] || error_msg "mount ${restore_emmc}p2 failed!"

# Identify the current kernel files
kernel_signature="$(uname -r)"

# 01. For /boot files
cd ${backup_path}/bootfs
rm -rf config-* initrd.img-* System.map-* vmlinuz-* uInitrd* *Image dtb*
[[ "${PLATFORM}" == "amlogic" ]] && cp -rf /boot/{u-boot.ext,u-boot.emmc} -t . 2>/dev/null
cp -rf /boot/{*-${kernel_signature},uInitrd,*Image,dtb} -t .
[[ "$?" -ne "0" ]] && error_msg "(1/3) [ boot ] files recovery failed."
echo -e "${INFO} (1/3) [ boot ] files restored successful."

# 02. For /usr/lib/modules/${kernel_signature}
cd ${backup_path}/rootfs/usr/lib/modules
rm -rf *
cp -rf /usr/lib/modules/${kernel_signature} -t .
[[ "$?" -ne "0" ]] && error_msg "(2/3) [ modules ] files recovery failed."
echo -e "${INFO} (2/3) [ modules ] files restored successful."

# 03. For /usr/src/linux-headers-${kernel_signature}
cd ${backup_path}/rootfs/usr/src
rm -rf linux-headers-*
cp -rf /usr/src/linux-headers-${kernel_signature} -t .
[[ "$?" -ne "0" ]] && error_msg "(3/3) [ headers ] files recovery failed."
echo -e "${INFO} (3/3) [ headers ] files restored successful."

# Unmount the emmc partition
cd ${backup_path}
umount -f ${backup_path}/bootfs
umount -f ${backup_path}/rootfs

sync && echo ""
}

# Download the kernel
download_kernel() {
cd ${current_path}
Expand Down Expand Up @@ -384,20 +461,18 @@ update_uboot() {
# Check script permission
[[ "$(id -u)" == "0" ]] || error_msg "Please run this script as root: [ sudo $0 ]"
echo -e "${STEPS} Welcome to the kernel update tool."
#
# Check dependencies
check_depends
# Initialize all variables
init_var "${@}"
# Download the kernel
download_kernel
# Check kernel files list
check_kernel
# Update the kernel
update_kernel
# Update the uboot for Amlogic boxes
[[ "${PLATFORM}" == "amlogic" ]] && update_uboot
#

if [[ "${1}" == "-r" ]]; then
rescue_kernel
else
check_depends
init_var "${@}"
download_kernel
check_kernel
update_kernel
[[ "${PLATFORM}" == "amlogic" ]] && update_uboot
fi

sync && sleep 3
echo -e "${SUCCESS} Successfully updated, automatic restarting..."
reboot
Expand Down

0 comments on commit 2a75cbb

Please sign in to comment.