mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-01 14:53:56 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
97c049ed0a
commit
0acff03804
14253 files changed
+3893239
No files matched your search
Executable
+165
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
|
||||
my $uci_config_name;
|
||||
if(-f "/etc/config/amlogic") {
|
||||
$uci_config_name="amlogic";
|
||||
} elsif(-f "/etc/config/cpufreq") {
|
||||
$uci_config_name="cpufreq";
|
||||
} else {
|
||||
print "Can not found amlogic or cpufreq config file!\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
my @policy_ids;
|
||||
my @policy_homes = </sys/devices/system/cpu/cpufreq/policy?>;
|
||||
if(@policy_homes) {
|
||||
foreach my $policy_home (@policy_homes) {
|
||||
push @policy_ids, substr($policy_home, -1);
|
||||
}
|
||||
} else {
|
||||
print "Can not found any policy!\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
our $need_commit = 0;
|
||||
for(my $i=0; $i <= $#policy_ids; $i++) {
|
||||
&fix_invalid_value($uci_config_name, $policy_ids[$i], $policy_homes[$i]);
|
||||
|
||||
}
|
||||
|
||||
if($need_commit > 0) {
|
||||
&uci_commit($uci_config_name);
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
################################# function ####################################
|
||||
sub fix_invalid_value {
|
||||
my($uci_config, $policy_id, $policy_home) = @_;
|
||||
|
||||
my %gove_hash = &get_gove_hash($policy_home);
|
||||
my @freqs = &get_freq_list($policy_home);
|
||||
my %freq_hash = &get_freq_hash(@freqs);
|
||||
my $min_freq = &get_min_freq(@freqs);
|
||||
my $max_freq = &get_max_freq(@freqs);
|
||||
|
||||
my $uci_section = "settings";
|
||||
my $uci_option;
|
||||
if($uci_config eq "cpufreq" ) {
|
||||
$uci_option = "governor";
|
||||
} else {
|
||||
$uci_option = "governor" . $policy_id;
|
||||
}
|
||||
# 如果未设置 governor, 或该 goveernor 不存在, 则修败默认值为 schedutil
|
||||
my $config_gove = &uci_get_by_type($uci_config, $uci_section, $uci_option, "NA");
|
||||
if( ($config_gove eq "NA") ||
|
||||
($gove_hash{$config_gove} != 1)) {
|
||||
&uci_set_by_type($uci_config, $uci_section, $uci_option, "schedutil");
|
||||
$need_commit++;
|
||||
}
|
||||
|
||||
# 如果出现不存在的 minfreq, 则修改为实际的 min_freq
|
||||
if($uci_config eq "cpufreq" ) {
|
||||
# "minifreq" is a spelling error that has always existed in the upstream source code
|
||||
$uci_option = "minifreq";
|
||||
} else {
|
||||
$uci_option = "minfreq" . $policy_id;
|
||||
}
|
||||
my $config_min_freq = &uci_get_by_type($uci_config, $uci_section, $uci_option, "0");
|
||||
if($freq_hash{$config_min_freq} != 1) {
|
||||
&uci_set_by_type($uci_config, $uci_section, $uci_option, $min_freq);
|
||||
$need_commit++;
|
||||
}
|
||||
|
||||
# 如果出现不存在的 maxfreq
|
||||
# 或 maxfreq < minfreq, 则修改为实际的 max_freq
|
||||
if($uci_config eq "cpufreq" ) {
|
||||
$uci_option = "maxfreq";
|
||||
} else {
|
||||
$uci_option = "maxfreq" . $policy_id;
|
||||
}
|
||||
my $config_max_freq = &uci_get_by_type($uci_config, $uci_section, $uci_option, "0");
|
||||
if( ( $freq_hash{$config_max_freq} != 1) ||
|
||||
( $config_max_freq < $config_min_freq)) {
|
||||
&uci_set_by_type($uci_config, $uci_section, $uci_option, $max_freq);
|
||||
$need_commit++;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_freq_list {
|
||||
my $policy_home = shift;
|
||||
my @ret_ary;
|
||||
open my $fh, "<", "${policy_home}/scaling_available_frequencies" or die;
|
||||
$_ = <$fh>;
|
||||
chomp;
|
||||
@ret_ary = split /\s+/;
|
||||
close($fh);
|
||||
return @ret_ary;
|
||||
}
|
||||
|
||||
sub get_freq_hash {
|
||||
my @freq_ary = @_;
|
||||
my %ret_hash;
|
||||
foreach my $freq (@freq_ary) {
|
||||
if($freq =~ m/\d+/) {
|
||||
$ret_hash{$freq} = 1;
|
||||
}
|
||||
}
|
||||
return %ret_hash;
|
||||
}
|
||||
|
||||
sub get_min_freq {
|
||||
my @freq_ary = @_;
|
||||
return (sort {$a<=>$b} @freq_ary)[0];
|
||||
}
|
||||
|
||||
sub get_max_freq {
|
||||
my @freq_ary = @_;
|
||||
return (sort {$a<=>$b} @freq_ary)[-1];
|
||||
}
|
||||
|
||||
sub get_gove_hash {
|
||||
my $policy_home = shift;
|
||||
my %ret_hash;
|
||||
open my $fh, "<", "${policy_home}/scaling_available_governors" or die;
|
||||
$_ = <$fh>;
|
||||
chomp;
|
||||
my @gov_ary = split /\s+/;
|
||||
foreach my $gov (@gov_ary) {
|
||||
#print "gov: $gov\n";
|
||||
if($gov =~ m/\w+/) {
|
||||
$ret_hash{$gov} = 1;
|
||||
}
|
||||
}
|
||||
close($fh);
|
||||
return %ret_hash;
|
||||
}
|
||||
|
||||
sub uci_get_by_type {
|
||||
my($config,$section,$option,$default) = @_;
|
||||
my $ret;
|
||||
$ret=`uci get ${config}.\@${section}\[0\].${option} 2>/dev/null`;
|
||||
# 消除回车换行
|
||||
$ret =~ s/[\n\r]//g;
|
||||
if($ret eq '') {
|
||||
return $default;
|
||||
} else {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
sub uci_set_by_type {
|
||||
my($config,$section,$option,$value) = @_;
|
||||
my $ret;
|
||||
system("uci set ${config}.\@${section}\[0\].${option}=${value}");
|
||||
return;
|
||||
}
|
||||
|
||||
sub uci_commit {
|
||||
my $config = shift;
|
||||
system("uci commit ${config}");
|
||||
return;
|
||||
}
|
||||
+598
@@ -0,0 +1,598 @@
|
||||
#!/bin/bash
|
||||
#======================================================================
|
||||
# Function: Backup and restore config files in the /etc directory
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#======================================================================
|
||||
|
||||
VERSION="v1.3"
|
||||
ZSTD_LEVEL=6
|
||||
SNAPSHOT_PRESTR=".snapshots/"
|
||||
BACKUP_DIR="/.reserved"
|
||||
BACKUP_NAME="openwrt_config.tar.gz"
|
||||
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_NAME}"
|
||||
# Customize backup list
|
||||
backup_list_conf="/etc/amlogic_backup_list.conf"
|
||||
if [[ -s "${backup_list_conf}" ]]; then
|
||||
while IFS= read -r line; do
|
||||
BACKUP_LIST+="${line} "
|
||||
done <"${backup_list_conf}"
|
||||
else
|
||||
BACKUP_LIST='./etc/AdGuardHome.yaml \
|
||||
./etc/amlogic_backup_list.conf \
|
||||
./etc/adblocklist/ \
|
||||
./etc/amule/ \
|
||||
./etc/balance_irq \
|
||||
./etc/bluetooth/ \
|
||||
./etc/china_ssr.txt \
|
||||
./etc/cifs/cifsdpwd.db \
|
||||
./etc/smbd/smbdpwd.db \
|
||||
./etc/ksmbd/ksmbdpwd.db \
|
||||
./etc/config/ \
|
||||
./etc/crontabs/ \
|
||||
./etc/dae/ \
|
||||
./etc/daed/ \
|
||||
./usr/share/openclash/core/ \
|
||||
./etc/openclash/backup/ \
|
||||
./etc/openclash/config/ \
|
||||
./etc/openclash/custom/ \
|
||||
./etc/openclash/game_rules/ \
|
||||
./etc/openclash/rule_provider/ \
|
||||
./etc/openclash/proxy_provider/ \
|
||||
./etc/dnsforwarder/ \
|
||||
./etc/dnsmasq.conf \
|
||||
./etc/dnsmasq.d/ \
|
||||
./etc/dnsmasq.oversea/ \
|
||||
./etc/dnsmasq.ssr/ \
|
||||
./etc/docker/daemon.json \
|
||||
./etc/docker/key.json \
|
||||
./etc/dropbear/ \
|
||||
./etc/easy-rsa/ \
|
||||
./etc/environment \
|
||||
./etc/exports \
|
||||
./etc/firewall.user \
|
||||
./etc/gfwlist/ \
|
||||
./etc/haproxy.cfg \
|
||||
./etc/hosts \
|
||||
./etc/ipsec.conf \
|
||||
./etc/ipsec.d/ \
|
||||
./etc/ipsec.secrets \
|
||||
./etc/ipsec.user \
|
||||
./etc/ipset/ \
|
||||
./etc/mosdns/config.yaml \
|
||||
./etc/mwan3.user \
|
||||
./etc/nginx/nginx.conf \
|
||||
./etc/ocserv/ \
|
||||
./etc/openvpn/ \
|
||||
./etc/pptpd.conf \
|
||||
./etc/qBittorrent/ \
|
||||
./etc/rc.local \
|
||||
./etc/samba/smbpasswd \
|
||||
./etc/shadow \
|
||||
./etc/smartdns/ \
|
||||
./etc/sqm/ \
|
||||
./etc/ssh/*key* \
|
||||
./etc/ssl/private/ \
|
||||
./etc/ssrplus/ \
|
||||
./etc/sysupgrade.conf \
|
||||
./etc/tailscale/ \
|
||||
./etc/transmission/ \
|
||||
./etc/uhttpd.crt \
|
||||
./etc/uhttpd.key \
|
||||
./etc/urandom.seed \
|
||||
./etc/v2raya/ \
|
||||
./etc/verysync/ \
|
||||
./root/.ssh/'
|
||||
fi
|
||||
|
||||
error_msg() {
|
||||
echo -e " [ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if dmesg | grep 'meson' >/dev/null 2>&1; then
|
||||
PLATFORM="amlogic"
|
||||
elif dmesg | grep 'rockchip' >/dev/null 2>&1; then
|
||||
PLATFORM="rockchip"
|
||||
elif dmesg | grep 'sun50i-h6' >/dev/null 2>&1; then
|
||||
PLATFORM="allwinner"
|
||||
else
|
||||
source /etc/flippy-openwrt-release
|
||||
case ${PLATFORM} in
|
||||
amlogic | rockchip | allwinner | qemu-aarch64) : ;;
|
||||
*) error_msg "Unknown platform, only support amlogic or rockchip or allwinner h6 or qemu-aarch64!" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_name}" ]] && error_msg "Cannot find the root partition!"
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition message of the root file system
|
||||
get_root_partition_msg() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_msg=$(lsblk -l -o NAME,PATH,MOUNTPOINT,UUID,FSTYPE,LABEL | awk '$3 ~ "^" "'"${path}"'" "$" {print $0}')
|
||||
[[ -n "${partition_msg}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_msg}" ]] && error_msg "Cannot find the root partition message!"
|
||||
echo "${partition_msg}"
|
||||
}
|
||||
|
||||
backup() {
|
||||
cd /
|
||||
echo -n "Backup config files ... "
|
||||
[ -d "${BACKUP_DIR}" ] || mkdir -p "${BACKUP_DIR}"
|
||||
eval tar czf "${BACKUP_FILE}" "${BACKUP_LIST}" 2>/dev/null
|
||||
sync
|
||||
if [ -f "${BACKUP_FILE}" ]; then
|
||||
echo "Has been backed up to [ ${BACKUP_FILE} ], please download and save."
|
||||
exit 0
|
||||
else
|
||||
error_msg "Backup failed!"
|
||||
fi
|
||||
}
|
||||
|
||||
restore() {
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="EMMC_"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
PARTITION_NAME=""
|
||||
LB_PRE=""
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -d "${BACKUP_DIR}" ] || mkdir -p "${BACKUP_DIR}"
|
||||
[ -f "/tmp/upload/${BACKUP_NAME}" ] && mv -f "/tmp/upload/${BACKUP_NAME}" ${BACKUP_FILE}
|
||||
[ -f "/mnt/${EMMC_NAME}${PARTITION_NAME}4/${BACKUP_NAME}" ] && mv -f "/mnt/${EMMC_NAME}${PARTITION_NAME}4/${BACKUP_NAME}" ${BACKUP_FILE}
|
||||
sync
|
||||
|
||||
if [ -f "${BACKUP_FILE}" ]; then
|
||||
echo -n "restore config files ... "
|
||||
cd /
|
||||
tar xzf "${BACKUP_FILE}" 2>/dev/null && sync
|
||||
|
||||
echo "Successful recovery. Will start automatically, please refresh later!"
|
||||
sleep 3
|
||||
reboot
|
||||
exit 0
|
||||
else
|
||||
error_msg "The backup file [ ${BACKUP_FILE} ] not found!"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_fstab() {
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
PARTITION_NAME=""
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
ROOT_MSG="$(get_root_partition_msg)"
|
||||
ROOT_NAME=$(echo $ROOT_MSG | awk '{print $1}')
|
||||
ROOT_DEV=$(echo $ROOT_MSG | awk '{print $2}')
|
||||
ROOT_UUID=$(echo $ROOT_MSG | awk '{print $4}')
|
||||
ROOT_FSTYPE=$(echo $ROOT_MSG | awk '{print $5}')
|
||||
ROOT_LABEL=$(echo $ROOT_MSG | awk '{print $6}')
|
||||
|
||||
BOOT_NAME="${EMMC_NAME}${PARTITION_NAME}1"
|
||||
BOOT_MSG=$(lsblk -l -o NAME,UUID,FSTYPE,LABEL | grep "${BOOT_NAME}")
|
||||
BOOT_DEV="/dev/${BOOT_NAME}"
|
||||
BOOT_UUID=$(echo $BOOT_MSG | awk '{print $2}')
|
||||
BOOT_FSTYPE=$(echo $BOOT_MSG | awk '{print $3}')
|
||||
BOOT_LABEL=$(echo $BOOT_MSG | awk '{print $4}')
|
||||
|
||||
cat >/etc/config/fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${ROOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype '${ROOT_FSTYPE}'
|
||||
EOF
|
||||
|
||||
if [ "${ROOT_FSTYPE}" == "btrfs" ]; then
|
||||
echo " option options 'compress=zstd:${ZSTD_LEVEL}'" >>/etc/config/fstab
|
||||
fi
|
||||
|
||||
cat >>/etc/config/fstab <<EOF
|
||||
|
||||
config mount
|
||||
option target '/boot'
|
||||
EOF
|
||||
|
||||
if [ "${BOOT_FSTYPE}" == "vfat" ]; then
|
||||
echo " option label '${BOOT_LABEL}'" >>/etc/config/fstab
|
||||
else
|
||||
echo " option uuid '${BOOT_UUID}'" >>/etc/config/fstab
|
||||
fi
|
||||
|
||||
cat >>/etc/config/fstab <<EOF
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype '${BOOT_FSTYPE}'
|
||||
|
||||
EOF
|
||||
echo "/etc/config/fstab generated."
|
||||
echo "Please reboot before continuing."
|
||||
exit 0
|
||||
}
|
||||
|
||||
print_list() {
|
||||
echo "${BACKUP_LIST}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
list_snapshot() {
|
||||
echo "----------------------------------------------------------------"
|
||||
btrfs subvolume list -rt /
|
||||
echo "----------------------------------------------------------------"
|
||||
read -p "Press [ enter ] to return." q
|
||||
}
|
||||
|
||||
create_snapshot() {
|
||||
default_snap_name="etc-$(date +"%m.%d.%H%M%S")"
|
||||
echo "The default snapshot name is: ${default_snap_name}"
|
||||
echo "If you want to modify the snapshot name, please enter it below. Cannot contain spaces."
|
||||
echo "If you do not want to modify it, just press [ Enter ]. Or press the [ q ] key to go back directly."
|
||||
while :; do
|
||||
read -p "[${default_snap_name}] : " nname
|
||||
if [ "${nname}" == "" ]; then
|
||||
snap_name="${default_snap_name}"
|
||||
break
|
||||
elif echo "${nname}" | grep -E "\s+" >/dev/null; then
|
||||
echo "The name [${nname}] contains spaces, please re-enter!"
|
||||
continue
|
||||
elif [ "${nname}" == "q" ] || [ "${nname}" == "Q" ]; then
|
||||
return
|
||||
else
|
||||
if btrfs subvolume list -rt / | awk '{print $4}' | grep "^\\${SNAPSHOT_PRESTR}${nname}$" >/dev/null; then
|
||||
echo "Name: [ ${nname} ] has been used, please re-enter!"
|
||||
continue
|
||||
else
|
||||
snap_name="${nname}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
(
|
||||
cd /
|
||||
chattr -ia etc/config/fstab
|
||||
btrfs subvolume snapshot -r /etc "${SNAPSHOT_PRESTR}${snap_name}"
|
||||
if [[ "$?" -eq "0" ]]; then
|
||||
echo "The snapshot is created successfully: ${snap_name}"
|
||||
else
|
||||
echo "Snapshot creation failed!"
|
||||
fi
|
||||
)
|
||||
read -p "Press [ enter ] to return." q
|
||||
}
|
||||
|
||||
restore_snapshot() {
|
||||
echo "Below are the existing etc snapshots, please enter the name of one of them."
|
||||
echo "Tip: [ etc-000 ] This is the factory initial configuration."
|
||||
echo " [ etc-001 ] if it exists, it is the initial configuration after upgrading from the previous version."
|
||||
echo "----------------------------------------------------------------"
|
||||
btrfs subvolume list -rt /
|
||||
echo "----------------------------------------------------------------"
|
||||
read -p "Please enter the name of the snapshot to be restored (only the part after ${SNAPSHOT_PRESTR} needs to be entered): " snap_name
|
||||
if btrfs subvolume list -rt / | grep "${SNAPSHOT_PRESTR}${snap_name}" >/dev/null; then
|
||||
while :; do
|
||||
echo "Once the snapshot is restored, the current [ /etc ] will be overwritten!"
|
||||
read -p "Are you sure you want to restore the snapshot: [$snap_name]? y/n [n] " yn
|
||||
case $yn in
|
||||
y | Y)
|
||||
(
|
||||
cd /
|
||||
chattr -ia etc/config/fstab
|
||||
mv etc etc.backup
|
||||
btrfs subvolume snapshot "${SNAPSHOT_PRESTR}${snap_name}" etc
|
||||
if [[ "$?" -eq "0" ]]; then
|
||||
btrfs subvolume delete -c etc.backup
|
||||
echo "Successfully restored, please enter [ reboot ] to restart the openwrt."
|
||||
else
|
||||
rm -rf etc
|
||||
mv etc.backup etc
|
||||
echo "Recovery failed, [ etc ] has not changed!"
|
||||
fi
|
||||
)
|
||||
read -p "Press [ enter ] to return." q
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
read -p "The snapshot name is incorrect, please run the program again! Press [ Enter ] to go back." q
|
||||
fi
|
||||
}
|
||||
|
||||
delete_snapshot() {
|
||||
echo "Below are the existing [ etc ] snapshots, please enter the name of one of them."
|
||||
echo "Tip: [ etc-000 ] This is the factory initial configuration (cannot be deleted)"
|
||||
echo " [ etc-001 ] if it exists, it is the initial configuration after upgrading from the previous version (cannot be deleted)"
|
||||
echo "----------------------------------------------------------------"
|
||||
btrfs subvolume list -rt /
|
||||
echo "----------------------------------------------------------------"
|
||||
read -p "Please enter the name of the snapshot to be deleted (only the part after ${SNAPSHOT_PRESTR} needs to be entered): " snap_name
|
||||
if [ "${snap_name}" == "etc-000" ] || [ "${snap_name}" == "etc-001" ]; then
|
||||
read -p "The key snapshot cannot be deleted! Press [ enter ] to return." q
|
||||
elif [ "${snap_name}" == "" ]; then
|
||||
read -p "Name is empty! Press [ enter ] to return." q
|
||||
else
|
||||
if btrfs subvolume list -rt / | grep "${SNAPSHOT_PRESTR}${snap_name}" >/dev/null; then
|
||||
read -p "Are you sure you want to delete ${snap_name}? y/n [n] " yn
|
||||
case $yn in
|
||||
y | Y)
|
||||
(
|
||||
cd /
|
||||
btrfs subvolume delete -c "${SNAPSHOT_PRESTR}${snap_name}"
|
||||
if [[ "$?" -eq "0" ]]; then
|
||||
echo "Snapshot [ ${snap_name} ] has been deleted."
|
||||
else
|
||||
echo "Snapshot [ ${snap_name} ] failed to delete!"
|
||||
fi
|
||||
)
|
||||
read -p "Press [ Enter ] to return." q
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
else
|
||||
read -p "The name of the snapshot is incorrect, press [ Enter ] to return." q
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
migrate_snapshot() {
|
||||
cur_rootdev="$(get_root_partition_name)"
|
||||
|
||||
dev_pre=$(echo "${cur_rootdev}" | awk '{print substr($1, 1, length($1)-1);}')
|
||||
rootdev_idx=$(echo "${cur_rootdev}" | awk '{print substr($1, length($1),1);}')
|
||||
case $rootdev_idx in
|
||||
2)
|
||||
old_rootpath="/mnt/${dev_pre}3"
|
||||
;;
|
||||
3)
|
||||
old_rootpath="/mnt/${dev_pre}2"
|
||||
;;
|
||||
*)
|
||||
echo "Judge the old version of rootfs path failed!"
|
||||
read -p "Press [ enter ] to return." q
|
||||
return
|
||||
;;
|
||||
esac
|
||||
echo "The following are snapshots of etc found from the old version of rootfs, please enter the name of one of them."
|
||||
echo "Tip: Automatically exclude etc-000 and etc-001"
|
||||
echo "-----------------------------------------------------------------------------------"
|
||||
btrfs subvolume list -rt "${old_rootpath}" | grep -v "${SNAPSHOT_PRESTR}etc-000" | grep -v "${SNAPSHOT_PRESTR}etc-001"
|
||||
echo "-----------------------------------------------------------------------------------"
|
||||
read -p "Please enter the name of the snapshot to be migrated (only the part after $(SNAPSHOT_PRESTR) needs to be entered): " old_snap_name
|
||||
if [ "${old_snap_name}" == "" ]; then
|
||||
read -p "The name is empty, Press [ enter ] to return." q
|
||||
return
|
||||
elif ! btrfs subvolume list -rt "${old_rootpath}" | awk '{print $4}' | grep "^${SNAPSHOT_PRESTR}${old_snap_name}$" >/dev/null; then
|
||||
echo "The name was entered incorrectly, and the corresponding snapshot was not found!"
|
||||
read -p "Press [ enter ] to return." q
|
||||
return
|
||||
elif [ "${old_snap_name}" == "etc-000" ] || [ "${old_snap_name}" == "etc-001" ]; then
|
||||
echo "Critical snapshots are not allowed to migrate!"
|
||||
read -p "Press [ enter ] to return." q
|
||||
return
|
||||
fi
|
||||
|
||||
# Find out if there is a snapshot with the same name under the current rootfs
|
||||
if btrfs subvolume list -rt / | awk '{print $4}' | grep "^\\${SNAPSHOT_PRESTR}${old_snap_name}$" >/dev/null; then
|
||||
echo "A snapshot with the name [ ${old_snap_name} ] already exists and cannot be migrated! (But you can delete the existing snapshot with the same name and then migrate)"
|
||||
read -p "Press [ enter ] to return." q
|
||||
return
|
||||
fi
|
||||
|
||||
need_size=$(du -h -d0 ${old_rootpath}/${SNAPSHOT_PRESTR}${old_snap_name} | tail -n1 | awk '{print $1}')
|
||||
echo "----------------------------------------------------------------------------------------------"
|
||||
df -h
|
||||
echo "----------------------------------------------------------------------------------------------"
|
||||
echo -e "Note: To migrate the snapshot [ ${old_snap_name} ] of [ ${old_rootpath} ] to the current rootfs, it takes about [ ${need_size} ] space,"
|
||||
echo -e " Please confirm whether the partition [/dev/${cur_rootdev}] where [/] is located has enough free space (Available)?"
|
||||
read -p "Are you sure to migrate? y/n [n] " yn
|
||||
if [ "$yn" == "y" ] || [ "$yn" == "Y" ]; then
|
||||
(
|
||||
cd /
|
||||
btrfs send ${old_rootpath}/${SNAPSHOT_PRESTR}${old_snap_name} | btrfs receive ${SNAPSHOT_PRESTR}
|
||||
if [ $? -eq 0 ]; then
|
||||
btrfs property set -ts ${SNAPSHOT_PRESTR}${old_snap_name} ro false
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/config/fstab ${SNAPSHOT_PRESTR}${old_snap_name}/config/
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/fstab ${SNAPSHOT_PRESTR}${old_snap_name}/
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/openwrt_release ${SNAPSHOT_PRESTR}${old_snap_name}/
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/openwrt_version ${SNAPSHOT_PRESTR}${old_snap_name}/
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/flippy-openwrt-release ${SNAPSHOT_PRESTR}${old_snap_name}/
|
||||
cp ${SNAPSHOT_PRESTR}etc-000/banner ${SNAPSHOT_PRESTR}${old_snap_name}/banner
|
||||
btrfs property set -ts ${SNAPSHOT_PRESTR}${old_snap_name} ro true
|
||||
echo "The migration is complete, if you want to apply the snapshot [ ${old_snap_name} ], please use the restore snapshot function."
|
||||
else
|
||||
echo "The migration failed!"
|
||||
fi
|
||||
read -p "Press [ enter ] to return." q
|
||||
return
|
||||
)
|
||||
fi
|
||||
}
|
||||
|
||||
snapshot_help() {
|
||||
clear
|
||||
cat <<EOF
|
||||
============================================================================================================================
|
||||
1. What is a snapshot?
|
||||
A snapshot is the state record of a certain subvolume at a certain point in time, and a snapshot is a special subvolume;
|
||||
When the local snapshot is first generated, it shares the disk space with the original subvolume,
|
||||
so it does not occupy additional space, and only the files that have changed subsequently occupy space;
|
||||
Snapshots migrated from other places are not snapshots in essence, but just ordinary subvolumes, so they take up space.
|
||||
2. How to display existing snapshots?
|
||||
input the command: btrfs subvolume list -rt /
|
||||
---------------------------------------------------------------------------------------------
|
||||
EOF
|
||||
btrfs subvolume list -rt /
|
||||
cat <<EOF
|
||||
---------------------------------------------------------------------------------------------
|
||||
2. How to create a snapshot?
|
||||
btrfs subvolume snapshot -r /etc /.snapshots/snapshot_1 # -r It means to generate a read-only snapshot
|
||||
3. How to delete a snapshot?
|
||||
btrfs subvolume delete -c /.snapshots/snapshot_1 # -c 是 commit 的意思
|
||||
4. How to rename a snapshot?
|
||||
Just use the [ mv ] command of the operating system, for example:
|
||||
mv /.snapshots/snapshot_1 /.snapshots/snapshot_2
|
||||
5. How to restore the snapshot?
|
||||
mv /etc /etc.backup # Back up /etc to /etc.backup, that is, rename the subvolume
|
||||
btrfs subvolume snapshot /.snapshots/etc-001 /etc # Use snapshot etc-001 to generate snapshot etc, no -r parameter
|
||||
# (Yes, snapshots can also be re-generated snapshots)
|
||||
btrfs delete -c /etc.backup # After the previous step is successful, you can delete the etc backup just now
|
||||
6. How to restore a certain file from the snapshot?
|
||||
Example A: Restore the mount point configuration file from snapshot etc-000: /etc/config/fstab
|
||||
cp /.snapshots/etc-000/config/fstab /etc/config/
|
||||
Example B: Restore network configuration from snapshot etc-001:
|
||||
cp /.snapshots/etc-001/config/network /etc/config/
|
||||
Example C: Restore the ssr configuration file from snapshot etc-001:
|
||||
cp /.snapshots/etc-001/config/shadowsocksr /etc/config/
|
||||
# (Yes, it is the [ cp ] command of the operating system)
|
||||
7. How to migrate snapshots from remote?
|
||||
btrfs supports ssh remote migration snapshots, for example:
|
||||
ssh 192.168.1.1 btrfs send /.snapshots/snapshot_x | btrfs receive /.snapshots
|
||||
After the command is completed, the remote snapshot_x is copied to the local /.snapshots/snapshot_x
|
||||
(as mentioned above, the migration is a subvolume, which takes up space)
|
||||
============================================================================================================================
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
print_help() {
|
||||
echo "Usage: $0 -b [ backup ]"
|
||||
echo " $0 -r [ restore ]"
|
||||
echo " $0 -g [ generate fstab ]"
|
||||
echo " $0 -p [ print backup list ]"
|
||||
echo " $0 -l [ list snapshots ]"
|
||||
echo " $0 -c [ create snapshot ]"
|
||||
echo " $0 -s [ restore snapshot ]"
|
||||
echo " $0 -d [ delete snapshot ]"
|
||||
echo " $0 -h [ help ]"
|
||||
echo " $0 -q [ quit ]"
|
||||
exit 0
|
||||
}
|
||||
|
||||
menu() {
|
||||
while :; do
|
||||
clear
|
||||
cat <<EOF
|
||||
|
||||
┌────────[ backup config ]────────┐
|
||||
│ │
|
||||
│ b. backup config │
|
||||
│ r. restore config │
|
||||
│ g. generate fstab │
|
||||
│ p. print backup list │
|
||||
│ │
|
||||
├─────[ Snapshot management ]─────┤
|
||||
│ │
|
||||
│ l. list snapshots │
|
||||
│ c. create snapshot │
|
||||
│ d. delete snapshot │
|
||||
│ R. restore snapshot │
|
||||
│ m. migrate snapshot │
|
||||
│ s. snapshot help │
|
||||
│ │
|
||||
╞═════════════════════════════════╡
|
||||
│ │
|
||||
│ h. help │
|
||||
│ q. quit │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
EOF
|
||||
echo -ne "please select: [ ]\b\b"
|
||||
read select
|
||||
case $select in
|
||||
b | backup) backup ;;
|
||||
r | restore)
|
||||
restore
|
||||
gen_fstab
|
||||
;;
|
||||
g | gen_fstab) gen_fstab ;;
|
||||
p | print_list) print_list ;;
|
||||
l | list_snapshot) list_snapshot ;;
|
||||
c | create_snapshot) create_snapshot ;;
|
||||
d | delete_snapshot) delete_snapshot ;;
|
||||
R | restore_snapshot) restore_snapshot ;;
|
||||
m | migrate_snapshot) migrate_snapshot ;;
|
||||
s | snapshot_help) snapshot_help ;;
|
||||
h | help) print_help ;;
|
||||
q | quit) exit 0 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
getopts 'brgplcRmsdhq' opts
|
||||
case $opts in
|
||||
b | backup) backup ;;
|
||||
r | restore)
|
||||
restore
|
||||
gen_fstab
|
||||
;;
|
||||
g | gen_fstab) gen_fstab ;;
|
||||
p | print_list) print_list ;;
|
||||
l | list_snapshot) list_snapshot ;;
|
||||
c | create_snapshot) create_snapshot ;;
|
||||
d | delete_snapshot) delete_snapshot ;;
|
||||
R | restore_snapshot) restore_snapshot ;;
|
||||
m | migrate_snapshot) migrate_snapshot ;;
|
||||
s | snapshot_help) snapshot_help ;;
|
||||
h | help) print_help ;;
|
||||
q | quit) exit 0 ;;
|
||||
*) menu ;;
|
||||
esac
|
||||
Executable
+155
@@ -0,0 +1,155 @@
|
||||
#!/bin/bash
|
||||
#===========================================================================
|
||||
#
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
#
|
||||
# This file is a part of the make OpenWrt for Amlogic s9xxx tv box
|
||||
# https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Description: Backup and restore the system in emmc
|
||||
# Copyright (C) 2017- The function borrowed from armbian/ddbr, Author: xXx
|
||||
# Copyright (C) 2021- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021- https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Command: openwrt-ddbr
|
||||
#
|
||||
#========================= Set default parameters ===========================
|
||||
#
|
||||
# Set font color
|
||||
blue_font_prefix="\033[34m"
|
||||
purple_font_prefix="\033[35m"
|
||||
green_font_prefix="\033[32m"
|
||||
yellow_font_prefix="\033[33m"
|
||||
red_font_prefix="\033[31m"
|
||||
font_color_suffix="\033[0m"
|
||||
INFO="[${blue_font_prefix}INFO${font_color_suffix}]"
|
||||
STEPS="[${purple_font_prefix}STEPS${font_color_suffix}]"
|
||||
SUCCESS="[${green_font_prefix}SUCCESS${font_color_suffix}]"
|
||||
OPT="[${yellow_font_prefix}OPT${font_color_suffix}]"
|
||||
ERROR="[${red_font_prefix}ERROR${font_color_suffix}]"
|
||||
#
|
||||
# Check the output path
|
||||
out_path="/ddbr"
|
||||
# File name for backup/restore
|
||||
ddbr_image="BACKUP-arm-64-emmc.img.gz"
|
||||
# Need remaining space, unit: GB
|
||||
need_space="2"
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "${ERROR} ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_name}" ]] && error_msg "Cannot find the root partition!"
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Check emmc
|
||||
do_checkemmc() {
|
||||
# Get device name
|
||||
mydevice_name="$(cat /proc/device-tree/model | tr -d '\000')"
|
||||
echo -e "${INFO} The device name: [ ${mydevice_name} ]"
|
||||
|
||||
# Find the partition where root is located
|
||||
root_ptname="$(get_root_partition_name)"
|
||||
|
||||
# Find the EMMC drive
|
||||
emmc="$(lsblk -l -o NAME | grep -oE "mmcblk[0-9]boot0" | sort | uniq | sed "s/boot0//g")"
|
||||
# Find emmc disk, find emmc that does not contain the boot0 partition
|
||||
[[ -z "${emmc}" ]] && emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?)' | grep -vE ^${root_ptname:0:-2} | uniq)"
|
||||
# Check if emmc exists
|
||||
[[ -z "${emmc}" ]] && error_msg "The eMMC storage not found in this device!"
|
||||
# Show the emmc name
|
||||
echo -e "${INFO} The device eMMC name: [ /dev/${emmc} ]"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case "${root_ptname}" in
|
||||
mmcblk?p[1-4])
|
||||
disk_name="$(echo ${root_ptname} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
if lsblk -l -o NAME | grep "${disk_name}boot0" >/dev/null; then
|
||||
error_msg "The current system is running on emmc. Please perform backup/restore operation in [ SD/TF/USB ]!"
|
||||
fi
|
||||
link_ptname="p"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
disk_name="$(echo ${root_ptname} | awk '{print substr($1, 1, length($1)-1)}')"
|
||||
link_ptname=""
|
||||
;;
|
||||
nvme?n?p[1-4])
|
||||
disk_name="$(echo ${root_ptname} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
link_ptname="p"
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${root_ptname}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set check parameters
|
||||
out_path="/mnt/${disk_name}${link_ptname}4"
|
||||
dev_intsize="$(fdisk -s /dev/${emmc})"
|
||||
[[ -z "$(echo "${dev_intsize}" | sed -n "/^[0-9]\+$/p")" ]] && error_msg "Unable to get EMMC size."
|
||||
echo -e "${INFO} The device EMMC size: [ $(($dev_intsize / 1024 / 1024))GB ]"
|
||||
|
||||
# check directory
|
||||
[[ -d "${out_path}" ]] || mkdir -p ${out_path}
|
||||
echo -e "${INFO} The ddbr file path: [ ${out_path}/${ddbr_image} ]\n"
|
||||
}
|
||||
|
||||
# Check the remaining space
|
||||
do_checkspace() {
|
||||
remaining_space="$(df -Tk ${out_path} | grep '/dev/' | awk '{print $5}' | echo $(($(xargs) / 1024 / 1024)))"
|
||||
if [[ -z "$(echo "${remaining_space}" | sed -n "/^[0-9]\+$/p")" ]]; then
|
||||
error_msg "The path is not available, the remaining space cannot be obtained."
|
||||
fi
|
||||
if [[ "${remaining_space}" -lt "${need_space}" ]]; then
|
||||
error_msg "The remaining space is [ ${remaining_space} ] Gb, and more than [ ${need_space} ] Gb space is required."
|
||||
fi
|
||||
}
|
||||
|
||||
# Backup the emmc system
|
||||
do_backup() {
|
||||
echo -e "${STEPS} Start to backup the system in emmc."
|
||||
do_checkspace
|
||||
echo -e "Saving and Compressing [ /dev/${emmc} ] to [ ${out_path}/${ddbr_image} ], Please wait..."
|
||||
rm -f ${out_path}/${ddbr_image} 2>/dev/null && sync
|
||||
dd if=/dev/${emmc} | pv -s ${dev_intsize}"K" | gzip >${out_path}/${ddbr_image}
|
||||
[[ "${?}" -eq "0" ]] && sync && echo -e "${SUCCESS} Backup is complete."
|
||||
}
|
||||
|
||||
# Restore the emmc system
|
||||
do_restore() {
|
||||
echo -e "${STEPS} Start to restore the system in emmc."
|
||||
[[ ! -f ${out_path}/${ddbr_image} ]] && error_msg "The [ ${out_path}/${ddbr_image} ] File not found."
|
||||
echo -e "Restoring [ ${out_path}/${ddbr_image} ] to [ /dev/${emmc} ], Please wait..."
|
||||
gunzip -c ${out_path}/${ddbr_image} | pv -s ${dev_intsize}"K" | dd of=/dev/${emmc}
|
||||
[[ "${?}" -eq "0" ]] && sync && echo -e "${SUCCESS} Restore is complete."
|
||||
}
|
||||
|
||||
echo -e "${STEPS} Welcome to use the EMMC system backup/restore service."
|
||||
# Check script permission
|
||||
[[ -x "/usr/sbin/openwrt-ddbr" ]] || error_msg "Please grant execution permission: [ chmod +x /usr/sbin/openwrt-ddbr ]"
|
||||
# Check emmc
|
||||
do_checkemmc
|
||||
# Prompt the user to select backup/restore
|
||||
echo -ne "${OPT} Do you want to backup or restore? Backup=(b) Restore=(r): "
|
||||
read br
|
||||
case "${br}" in
|
||||
b | B | backup) do_backup ;;
|
||||
r | R | restore) do_restore ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
+721
@@ -0,0 +1,721 @@
|
||||
#!/bin/bash
|
||||
#======================================================================================
|
||||
# Function: Install openwrt to emmc for Amlogic S9xxx STB
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#======================================================================================
|
||||
#
|
||||
# The script supports directly setting parameters for installation, skipping interactive selection
|
||||
# openwrt-install-amlogic ${AUTO_MAINLINE_UBOOT} ${ID} ${FDTFILE}:${SOC}:${UBOOT_OVERLOAD} ${SHARED_FSTYPE}
|
||||
# E.g: openwrt-install-amlogic yes 11 auto ext4
|
||||
# E.g: openwrt-install-amlogic no 99 meson-gxl-s905d-phicomm-n1.dtb:s905d:u-boot-n1.bin ext4
|
||||
# Tip: When custom dtb file, set ${SOC_ID} to 99, and parameter ${FDTFILE}:${SOC}:${UBOOT_OVERLOAD} must be set
|
||||
# Tip: ${SHARED_FSTYPE}: Shared partition can be ext4, xfs, btrfs, f2fs
|
||||
|
||||
# You can also execute the script directly, and interactively select related functions
|
||||
# E.g: openwrt-install-amlogic
|
||||
#
|
||||
#======================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_name}" ]] && error_msg "Cannot find the root partition!"
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Receive one-key command related parameters
|
||||
AUTO_MAINLINE_UBOOT="${1}"
|
||||
ZSTD_LEVEL="6"
|
||||
op_release="/etc/flippy-openwrt-release"
|
||||
|
||||
# For [luci-app-amlogic] input parameter: DTB, SOC & UBOOT_OVERLOAD
|
||||
# When there is no input parameter, select manually
|
||||
SPECIFY_ID=""
|
||||
SPECIFY_SOC=""
|
||||
SPECIFY_DTB=""
|
||||
SPECIFY_UBOOT=""
|
||||
[[ -n "${2}" ]] && {
|
||||
SPECIFY_ID="${2}"
|
||||
if [[ "${2}" -eq "99" ]]; then
|
||||
if [[ -n "${3}" ]]; then
|
||||
# E.g: meson-gxl-s905d-phicomm-n1.dtb:s905d:u-boot-n1.bin
|
||||
SPECIFY_DTB="$(echo "${3}" | awk -F ':' '{print $1}')"
|
||||
SPECIFY_SOC="$(echo "${3}" | awk -F ':' '{print $2}')"
|
||||
SPECIFY_UBOOT="$(echo "${3}" | awk -F ':' '{print $3}')"
|
||||
else
|
||||
error_msg "Please enter the DTB file name!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# shared partition can be ext4, xfs, btrfs, f2fs
|
||||
SHARED_FSTYPE="${4}"
|
||||
|
||||
echo "AUTO_MAINLINE_UBOOT: ${AUTO_MAINLINE_UBOOT}"
|
||||
echo "SPECIFY_DTB: ${SPECIFY_DTB}"
|
||||
echo "SPECIFY_SOC: ${SPECIFY_SOC}"
|
||||
echo "SPECIFY_UBOOT: ${SPECIFY_UBOOT}"
|
||||
echo "SHARED_FSTYPE: ${SHARED_FSTYPE}"
|
||||
|
||||
# Current device model
|
||||
MYDEVICE_NAME=$(cat /proc/device-tree/model | tr -d '\000')
|
||||
if [[ -z "${MYDEVICE_NAME}" ]]; then
|
||||
error_msg "The device name is empty and cannot be recognized."
|
||||
elif [[ ! -f "${op_release}" ]]; then
|
||||
error_msg "The [ ${op_release} ] file is missing."
|
||||
else
|
||||
echo -e "Current device: ${MYDEVICE_NAME} [ amlogic ]"
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Find the device name of /
|
||||
root_devname="$(get_root_partition_name)"
|
||||
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
|
||||
|
||||
install_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?boot0)' | sed "s/boot0//g")"
|
||||
if [[ "${install_emmc}" == "" ]]; then
|
||||
error_msg "No emmc can be found to install the openwrt system!"
|
||||
fi
|
||||
|
||||
# EMMC DEVICE NAME
|
||||
EMMC_NAME="${install_emmc}"
|
||||
EMMC_DEVPATH="/dev/${EMMC_NAME}"
|
||||
echo ${EMMC_DEVPATH}
|
||||
EMMC_SIZE=$(lsblk -l -b -o NAME,SIZE | grep ${EMMC_NAME} | sort | uniq | head -n1 | awk '{print $2}')
|
||||
echo "${EMMC_NAME} : ${EMMC_SIZE} bytes"
|
||||
|
||||
ROOT_NAME=$(lsblk -l -o NAME,MAJ:MIN,MOUNTPOINT | grep -e '/$' | awk '{print $1}')
|
||||
echo "ROOTFS: ${ROOT_NAME}"
|
||||
|
||||
BOOT_NAME=$(lsblk -l -o NAME,MAJ:MIN,MOUNTPOINT | grep -e '/boot$' | awk '{print $1}')
|
||||
echo "BOOT: ${BOOT_NAME}"
|
||||
|
||||
# box model database
|
||||
# The field separator is :
|
||||
# " " or "" or NA or NULL means this field is null
|
||||
# The fields list:
|
||||
# 1. id
|
||||
# 2. model name
|
||||
# 3. SOC
|
||||
# 4. FDTFILE
|
||||
# 5. UBOOT_OVERLOAD
|
||||
# 6. MAINLINE_UBOOT
|
||||
# 7. ANDROID_UBOOT
|
||||
# 8. brief description
|
||||
#
|
||||
|
||||
# allow use external modal database
|
||||
if [[ -f "/etc/model_database.txt" ]]; then
|
||||
model_database="$(cat /etc/model_database.txt)"
|
||||
else
|
||||
error_msg "[ /etc/model_database.txt ] file is missing."
|
||||
fi
|
||||
|
||||
function display_database() {
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ ^# ]]; then
|
||||
# Process comment lines, starting with #
|
||||
line="${line/#+\s+/}"
|
||||
echo "$line >>>"
|
||||
else
|
||||
# Process data lines, starting with id
|
||||
IFS=':' read -r -a fields <<<"$line"
|
||||
printf "%5s %-48s%-10s%-s\n" "${fields[0]}" "${fields[1]}" "${fields[2]}" "${fields[7]}"
|
||||
fi
|
||||
done < <(echo "${model_database}")
|
||||
}
|
||||
|
||||
function search_model() {
|
||||
local id="${1}"
|
||||
local ret_count="$(echo "${model_database}" | awk -F ':' "\$1~/^$id\$/ {print \$0}" | wc -l)"
|
||||
if [[ "${ret_count}" -eq "1" ]]; then
|
||||
echo "${model_database}" | awk -F ':' "\$1~/^$id\$/ {print \$0}" | sed -e 's/NA//g' -e 's/NULL//g' -e 's/[ ][ ]*//g'
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Please select s9xxx box model:"
|
||||
echo "----------------------------------------------------------------------------------------------------"
|
||||
display_database
|
||||
echo "----------------------------------------------------------------------------------------------------"
|
||||
|
||||
# For [luci-app-amlogic] input parameter: SOC & DTB
|
||||
# When there is no input parameter, select manually
|
||||
if [[ -n "${SPECIFY_ID}" ]]; then
|
||||
boxtype="${SPECIFY_ID}"
|
||||
else
|
||||
echo -n "Please choose: "
|
||||
read boxtype
|
||||
fi
|
||||
|
||||
if [[ "${boxtype}" -eq "99" ]]; then
|
||||
FDTFILE="${SPECIFY_DTB}"
|
||||
AMLOGIC_SOC="${SPECIFY_SOC}"
|
||||
UBOOT_OVERLOAD="${SPECIFY_UBOOT}"
|
||||
MAINLINE_UBOOT=""
|
||||
ANDROID_UBOOT=""
|
||||
elif [[ "${boxtype}" -eq "0" ]]; then
|
||||
read -p "Please Input SoC Name(such as s9xxx): " AMLOGIC_SOC
|
||||
AMLOGIC_SOC="${AMLOGIC_SOC}"
|
||||
|
||||
read -p "Please Input DTB Name(such as meson-xxx.dtb): " FDTFILE
|
||||
FDTFILE="${FDTFILE}"
|
||||
|
||||
read -p "Please Input UBOOT_OVERLOAD Name(such as u-boot-xxx.bin): " UBOOT_OVERLOAD
|
||||
UBOOT_OVERLOAD="${UBOOT_OVERLOAD}"
|
||||
|
||||
read -p "Please Input MAINLINE_UBOOT Name(such as /lib/u-boot/xxx-u-boot.bin.sd.bin): " MAINLINE_UBOOT
|
||||
MAINLINE_UBOOT="${MAINLINE_UBOOT}"
|
||||
|
||||
read -p "Please Input ANDROID_UBOOT Name(such as /lib/u-boot/xxx-bootloader.img): " ANDROID_UBOOT
|
||||
ANDROID_UBOOT="${ANDROID_UBOOT}"
|
||||
else
|
||||
ret="$(search_model ${boxtype})"
|
||||
if [[ -z "${ret}" ]]; then
|
||||
error_msg "Input error, exit!"
|
||||
fi
|
||||
# 3. soc
|
||||
# 4. FDTFILE
|
||||
# 5. UBOOT_OVERLOAD
|
||||
# 6. MAINLINE_UBOOT
|
||||
# 7. ANDROID_UBOOT
|
||||
AMLOGIC_SOC="$(echo "${ret}" | awk -F ':' '{print $3}')"
|
||||
FDTFILE="$(echo "${ret}" | awk -F ':' '{print $4}')"
|
||||
UBOOT_OVERLOAD="$(echo "${ret}" | awk -F ':' '{print $5}')"
|
||||
MAINLINE_UBOOT="$(echo "${ret}" | awk -F ':' '{print $6}')"
|
||||
ANDROID_UBOOT="$(echo "${ret}" | awk -F ':' '{print $7}')"
|
||||
fi
|
||||
|
||||
if [[ -z "${FDTFILE}" || ! -f "/boot/dtb/amlogic/${FDTFILE}" ]]; then
|
||||
error_msg "/boot/dtb/amlogic/${FDTFILE} does not exist!"
|
||||
fi
|
||||
|
||||
echo "AMLOGIC_SOC Value [ ${AMLOGIC_SOC} ]"
|
||||
echo "FDTFILE Value [ ${FDTFILE} ]"
|
||||
echo "UBOOT_OVERLOAD Value [ ${UBOOT_OVERLOAD} ]"
|
||||
echo "MAINLINE_UBOOT Value [ ${MAINLINE_UBOOT} ]"
|
||||
echo "ANDROID_UBOOT Value [ ${ANDROID_UBOOT} ]"
|
||||
|
||||
sed -i "s|^SOC=.*|SOC='${AMLOGIC_SOC}'|g" ${op_release} 2>/dev/null
|
||||
sed -i "s|^FDTFILE=.*|FDTFILE='${FDTFILE}'|g" ${op_release} 2>/dev/null
|
||||
sed -i "s|^UBOOT_OVERLOAD=.*|UBOOT_OVERLOAD='${UBOOT_OVERLOAD}'|g" ${op_release} 2>/dev/null
|
||||
sed -i "s|^MAINLINE_UBOOT=.*|MAINLINE_UBOOT='${MAINLINE_UBOOT}'|g" ${op_release} 2>/dev/null
|
||||
sed -i "s|^ANDROID_UBOOT=.*|ANDROID_UBOOT='${ANDROID_UBOOT}'|g" ${op_release} 2>/dev/null
|
||||
|
||||
K510="1"
|
||||
[[ "$(hexdump -n 15 -x "/boot/zImage" 2>/dev/null | head -n 1 | awk '{print $7}')" == "0108" ]] && K510="0"
|
||||
echo -e "K510 [ ${K510} ]"
|
||||
|
||||
# backup old bootloader
|
||||
if [[ ! -f "/root/BackupOldBootloader.img" ]]; then
|
||||
echo "Backup bootloader -> [ BackupOldBootloader.img ] ... "
|
||||
dd if=/dev/$EMMC_NAME of=/root/BackupOldBootloader.img bs=1M count=4 conv=fsync
|
||||
echo "Backup bootloader complete."
|
||||
echo
|
||||
fi
|
||||
|
||||
swapoff -a
|
||||
|
||||
# umount all other mount points
|
||||
MOUNTS=$(lsblk -l -o MOUNTPOINT)
|
||||
for mnt in $MOUNTS; do
|
||||
if [ "$mnt" == "MOUNTPOINT" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$mnt" == "" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$mnt" == "/" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$mnt" == "/boot" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$mnt" == "/opt" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$mnt" == "[SWAP]" ]; then
|
||||
echo "swapoff -a"
|
||||
swapoff -a
|
||||
continue
|
||||
fi
|
||||
|
||||
if echo $mnt | grep $EMMC_NAME; then
|
||||
echo "umount -f $mnt"
|
||||
umount -f $mnt
|
||||
if [ $? -ne 0 ]; then
|
||||
error_msg "$mnt Cannot be uninstalled, the installation process is aborted."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Delete old partition if exists
|
||||
p=$(lsblk -l | grep -e "${EMMC_NAME}p" | wc -l)
|
||||
echo "A total of [ $p ] old partitions on EMMC will be deleted"
|
||||
>/tmp/fdisk.script
|
||||
while [ $p -ge 1 ]; do
|
||||
echo "d" >>/tmp/fdisk.script
|
||||
if [ $p -gt 1 ]; then
|
||||
echo "$p" >>/tmp/fdisk.script
|
||||
fi
|
||||
p=$((p - 1))
|
||||
done
|
||||
|
||||
# you can change ROOT size(MB) >= 320
|
||||
ROOT1="2048"
|
||||
ROOT2="2048"
|
||||
if [[ "${AMLOGIC_SOC}" == "s912" ]] && [[ "${boxtype}" == "213" || "${boxtype}" == "2e" ]]; then
|
||||
BOOT="512"
|
||||
BLANK1="700"
|
||||
BLANK2="220"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s912" || "${AMLOGIC_SOC}" == "s905d" ]]; then
|
||||
BOOT="512"
|
||||
BLANK1="68"
|
||||
BLANK2="220"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s905x" ]]; then
|
||||
BOOT="160"
|
||||
BLANK1="700"
|
||||
BLANK2="0"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${FDTFILE}" == "meson-sm1-skyworth-lb2004-a4091.dtb" ]]; then
|
||||
BOOT="512"
|
||||
BLANK1="108"
|
||||
BLANK2="562"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s905l3a" ]] && [[ "${boxtype}" == "304" || "${boxtype}" == "34" ]]; then
|
||||
# e900v22c/d(s905l3a)
|
||||
BOOT="256"
|
||||
BLANK1="570"
|
||||
BLANK2="0"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s905l3a" ]] && [[ "${boxtype}" == "305" || "${boxtype}" == "33" ]]; then
|
||||
# CM311-1a-YST(s905l3a)
|
||||
BOOT="512"
|
||||
BLANK1="108"
|
||||
BLANK2="778"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s905l3b" ]]; then
|
||||
# M302A/M304A(s905l3b)
|
||||
BOOT="512"
|
||||
BLANK1="128"
|
||||
BLANK2="720"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${AMLOGIC_SOC}" == "s905x3" ]] && [[ "${boxtype}" == "525" || "${boxtype}" == "5n" ]]; then
|
||||
# Whale(s905x3)
|
||||
BOOT="512"
|
||||
BLANK1="108"
|
||||
BLANK2="650"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
elif [[ "${boxtype}" =~ ^(409|410|49|4a)$ ]]; then
|
||||
# WXY-OES(A311D):409/49, WXY-OES-PLUS(S922X):410/4a
|
||||
BOOT="512"
|
||||
BLANK1="700"
|
||||
BLANK2="0"
|
||||
BLANK3="0"
|
||||
BLANK4="0"
|
||||
else
|
||||
BOOT="160"
|
||||
BLANK1="68"
|
||||
BLANK2="0"
|
||||
BLANK3="162"
|
||||
BLANK4="0"
|
||||
fi
|
||||
|
||||
DST_TOTAL_MB=$((EMMC_SIZE / 1024 / 1024))
|
||||
|
||||
start1=$((BLANK1 * 2048))
|
||||
end1=$((start1 + (BOOT * 2048) - 1))
|
||||
|
||||
start2=$(((BLANK2 * 2048) + end1 + 1))
|
||||
end2=$((start2 + (ROOT1 * 2048) - 1))
|
||||
|
||||
start3=$(((BLANK3 * 2048) + end2 + 1))
|
||||
end3=$((start3 + (ROOT2 * 2048) - 1))
|
||||
|
||||
start4=$(((BLANK4 * 2048) + end3 + 1))
|
||||
end4=$((DST_TOTAL_MB * 2048 - 1))
|
||||
|
||||
cat >>/tmp/fdisk.script <<EOF
|
||||
n
|
||||
p
|
||||
1
|
||||
$start1
|
||||
$end1
|
||||
n
|
||||
p
|
||||
2
|
||||
$start2
|
||||
$end2
|
||||
n
|
||||
p
|
||||
3
|
||||
$start3
|
||||
$end3
|
||||
n
|
||||
p
|
||||
$start4
|
||||
$end4
|
||||
t
|
||||
1
|
||||
c
|
||||
t
|
||||
2
|
||||
83
|
||||
t
|
||||
3
|
||||
83
|
||||
t
|
||||
4
|
||||
83
|
||||
w
|
||||
EOF
|
||||
|
||||
fdisk /dev/${EMMC_NAME} </tmp/fdisk.script 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "The fdisk partition fails, Please try again."
|
||||
dd if=/root/BackupOldBootloader.img of=/dev/${EMMC_NAME} conv=fsync && sync
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=512 count=1 && sync
|
||||
exit 1
|
||||
fi
|
||||
echo "Partition complete."
|
||||
|
||||
# write some zero data to part begin
|
||||
seek=$((start1 / 2048))
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=1M count=1 seek=$seek conv=fsync
|
||||
|
||||
seek=$((start2 / 2048))
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=1M count=1 seek=$seek conv=fsync
|
||||
|
||||
seek=$((start3 / 2048))
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=1M count=1 seek=$seek conv=fsync
|
||||
|
||||
seek=$((start4 / 2048))
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=1M count=1 seek=$seek conv=fsync
|
||||
|
||||
#Mainline U-BOOT detection
|
||||
FLASH_MAINLINE_UBOOT=0
|
||||
if [[ -n "${MAINLINE_UBOOT}" && -f "${MAINLINE_UBOOT}" ]]; then
|
||||
cat <<EOF
|
||||
----------------------------------------------------------------------------------
|
||||
Found an available mainline bootloader (Mainline u-boot), you can flash into EMMC.
|
||||
----------------------------------------------------------------------------------
|
||||
EOF
|
||||
while :; do
|
||||
# For [luci-app-amlogic] input parameter: SOC & DTB
|
||||
# When there is no input parameter, select manually
|
||||
if [[ "${AUTO_MAINLINE_UBOOT}" == "yes" ]]; then
|
||||
if [[ "${K510}" -eq "1" ]]; then
|
||||
yn="y"
|
||||
else
|
||||
yn="n"
|
||||
fi
|
||||
elif [[ "${AUTO_MAINLINE_UBOOT}" == "no" ]]; then
|
||||
yn="n"
|
||||
else
|
||||
read -p "Please choose whether to write the mainline bootloader to EMMC? y/n " yn
|
||||
fi
|
||||
case $yn in
|
||||
y | Y)
|
||||
FLASH_MAINLINE_UBOOT=1
|
||||
break
|
||||
;;
|
||||
n | N)
|
||||
FLASH_MAINLINE_UBOOT=0
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${FLASH_MAINLINE_UBOOT}" -eq "1" ]]; then
|
||||
echo -e "Write Mainline bootloader: [ ${MAINLINE_UBOOT} ]"
|
||||
dd if=${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=1 count=444 conv=fsync
|
||||
dd if=${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=512 skip=1 seek=1 conv=fsync
|
||||
elif [[ -n "${ANDROID_UBOOT}" && -f "${ANDROID_UBOOT}" ]]; then
|
||||
echo -e "Write Android bootloader: [ ${ANDROID_UBOOT} ]"
|
||||
dd if=${ANDROID_UBOOT} of=/dev/${EMMC_NAME} bs=1 count=444 conv=fsync
|
||||
dd if=${ANDROID_UBOOT} of=/dev/${EMMC_NAME} bs=512 skip=1 seek=1 conv=fsync
|
||||
else
|
||||
echo "Did not change the original bootloader."
|
||||
fi
|
||||
|
||||
# fix wifi macaddr
|
||||
if [ -x /usr/bin/fix_wifi_macaddr.sh ]; then
|
||||
/usr/bin/fix_wifi_macaddr.sh
|
||||
fi
|
||||
|
||||
# mkfs
|
||||
echo "Start creating file system ... "
|
||||
echo "Create a boot file system ... "
|
||||
|
||||
echo "format boot partiton..."
|
||||
mkfs.fat -n EMMC_BOOT -F 32 /dev/${EMMC_NAME}p1
|
||||
mkdir -p /mnt/${EMMC_NAME}p1
|
||||
sleep 2
|
||||
umount -f /mnt/${EMMC_NAME}p1 2>/dev/null
|
||||
|
||||
echo "format rootfs1 partiton..."
|
||||
ROOTFS1_UUID=$(/usr/bin/uuidgen)
|
||||
mkfs.btrfs -f -U ${ROOTFS1_UUID} -L EMMC_ROOTFS1 -m single /dev/${EMMC_NAME}p2
|
||||
mkdir -p /mnt/${EMMC_NAME}p2
|
||||
sleep 2
|
||||
umount -f /mnt/${EMMC_NAME}p2 2>/dev/null
|
||||
|
||||
echo "format rootfs2 partiton..."
|
||||
ROOTFS2_UUID=$(/usr/bin/uuidgen)
|
||||
mkfs.btrfs -f -U ${ROOTFS2_UUID} -L EMMC_ROOTFS2 -m single /dev/${EMMC_NAME}p3
|
||||
mkdir -p /mnt/${EMMC_NAME}p3
|
||||
sleep 2
|
||||
umount -f /mnt/${EMMC_NAME}p3 2>/dev/null
|
||||
|
||||
# mount and copy
|
||||
echo "Wait for the boot file system to mount ... "
|
||||
i=1
|
||||
max_try=10
|
||||
while [ $i -le $max_try ]; do
|
||||
mount -t vfat /dev/${EMMC_NAME}p1 /mnt/${EMMC_NAME}p1 2>/dev/null
|
||||
sleep 2
|
||||
mnt=$(lsblk -l -o MOUNTPOINT | grep /mnt/${EMMC_NAME}p1)
|
||||
|
||||
if [ "$mnt" == "" ]; then
|
||||
if [ $i -lt $max_try ]; then
|
||||
echo "Not mounted successfully, try again ..."
|
||||
i=$((i + 1))
|
||||
else
|
||||
error_msg "Cannot mount the boot file system, give up!"
|
||||
fi
|
||||
else
|
||||
echo "Successfully mounted."
|
||||
echo "copy boot ..."
|
||||
cd /mnt/${EMMC_NAME}p1
|
||||
rm -rf /boot/'System Volume Information/'
|
||||
(cd /boot && tar cf - .) | tar xf -
|
||||
sync
|
||||
|
||||
echo "Edit uEnv.txt ..."
|
||||
[[ -f "uEnv.txt" ]] && {
|
||||
sed -i -E \
|
||||
-e "s|/dtb/amlogic.*|/dtb/amlogic/${FDTFILE}|" \
|
||||
-e "s|UUID=[^ ]*|UUID=${ROOTFS1_UUID}|" \
|
||||
-e "s|rootflags=compress=zstd:[^ ]*|rootflags=compress=zstd:${ZSTD_LEVEL}|" \
|
||||
uEnv.txt
|
||||
}
|
||||
|
||||
# Replace the extlinux/extlinux.conf if it exists
|
||||
[[ -f "extlinux/extlinux.conf" ]] && {
|
||||
sed -i -E \
|
||||
-e "s|/dtb/amlogic.*|/dtb/amlogic/${FDTFILE}|" \
|
||||
-e "s|UUID=[^ ]*|UUID=${ROOTFS1_UUID}|" \
|
||||
-e "s|rootflags=compress=zstd:[^ ]*|rootflags=compress=zstd:${ZSTD_LEVEL}|" \
|
||||
extlinux/extlinux.conf
|
||||
}
|
||||
|
||||
rm -f s905_autoscript* aml_autoscript*
|
||||
|
||||
if [ ${K510} -eq 1 ]; then
|
||||
if [ -f ${UBOOT_OVERLOAD} ]; then
|
||||
cp -f -v ${UBOOT_OVERLOAD} u-boot.emmc
|
||||
elif [ -f "u-boot.ext" ]; then
|
||||
cp -f -v u-boot.ext u-boot.emmc
|
||||
fi
|
||||
fi
|
||||
|
||||
mv -f boot-emmc.ini boot.ini
|
||||
mv -f boot-emmc.cmd boot.cmd
|
||||
mv -f boot-emmc.scr boot.scr
|
||||
|
||||
sync
|
||||
echo "complete."
|
||||
cd /
|
||||
umount -f /mnt/${EMMC_NAME}p1
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "complete."
|
||||
|
||||
echo "Wait for the rootfs file system to mount ... "
|
||||
i=1
|
||||
while [ $i -le $max_try ]; do
|
||||
mount -t btrfs -o compress=zstd:${ZSTD_LEVEL} /dev/${EMMC_NAME}p2 /mnt/${EMMC_NAME}p2 2>/dev/null
|
||||
sleep 2
|
||||
mnt=$(lsblk -l -o MOUNTPOINT | grep /mnt/${EMMC_NAME}p2)
|
||||
if [ "$mnt" == "" ]; then
|
||||
if [ $i -lt $max_try ]; then
|
||||
echo "Not mounted successfully, try again ..."
|
||||
i=$((i + 1))
|
||||
else
|
||||
error_msg "Cannot mount rootfs file system, give up!"
|
||||
fi
|
||||
else
|
||||
echo "Successfully mounted"
|
||||
echo "Create folder ... "
|
||||
cd /mnt/${EMMC_NAME}p2
|
||||
btrfs subvolume create etc
|
||||
mkdir -p bin boot dev lib opt mnt overlay proc rom root run sbin sys tmp usr www .reserved .snapshots
|
||||
ln -sf lib/ lib64
|
||||
ln -sf tmp/ var
|
||||
sync
|
||||
echo "complete."
|
||||
|
||||
COPY_SRC="root etc bin sbin lib opt usr www"
|
||||
echo "Copy data ... "
|
||||
for src in $COPY_SRC; do
|
||||
echo "copy [ $src ] ..."
|
||||
(cd / && tar cf - $src) | tar xf -
|
||||
sync
|
||||
done
|
||||
echo "Copy complete."
|
||||
sync
|
||||
|
||||
cat >etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"bip": "172.31.0.1/24",
|
||||
"data-root": "/mnt/${EMMC_NAME}p4/docker/",
|
||||
"log-level": "warn",
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "5"
|
||||
},
|
||||
"registry-mirrors": [
|
||||
"https://mirror.baidubce.com/",
|
||||
"https://hub-mirror.c.163.com"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# change data_root value in /etc/config/dockerd
|
||||
if [[ -f "/etc/init.d/dockerman" ]] && [[ -f "/etc/config/dockerd" ]]; then
|
||||
sed -i "s|option data_root.*|option data_root '/mnt/${EMMC_NAME}p4/docker/'|g" etc/config/dockerd
|
||||
fi
|
||||
rm -rf opt/docker && ln -sf /mnt/${EMMC_NAME}p4/docker/ opt/docker >/dev/null
|
||||
rm -rf usr/bin/AdGuardHome && ln -sf /mnt/${EMMC_NAME}p4/AdGuardHome usr/bin/ >/dev/null
|
||||
|
||||
echo "Edit configuration file ..."
|
||||
#cd /mnt/${EMMC_NAME}p2/usr/bin/
|
||||
#rm -f openwrt-install-amlogic openwrt-update-amlogic
|
||||
cd /mnt/${EMMC_NAME}p2/etc/rc.d
|
||||
ln -sf ../init.d/dockerd S99dockerd
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
cd /mnt/${EMMC_NAME}p2/etc
|
||||
cat >fstab <<EOF
|
||||
UUID=${ROOTFS1_UUID} / btrfs compress=zstd:${ZSTD_LEVEL} 0 1
|
||||
LABEL=EMMC_BOOT /boot vfat defaults 0 2
|
||||
#tmpfs /tmp tmpfs defaults,nosuid 0 0
|
||||
EOF
|
||||
|
||||
cd /mnt/${EMMC_NAME}p2/etc/config
|
||||
cat >fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${ROOTFS1_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'btrfs'
|
||||
option options 'compress=zstd:${ZSTD_LEVEL}'
|
||||
|
||||
config mount
|
||||
option target '/boot'
|
||||
option label 'EMMC_BOOT'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'vfat'
|
||||
|
||||
EOF
|
||||
|
||||
echo -n "Create initial etc snapshot -> .snapshots/etc-000"
|
||||
cd /mnt/${EMMC_NAME}p2 &&
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-000
|
||||
sync
|
||||
|
||||
cd /
|
||||
umount -f /mnt/${EMMC_NAME}p2
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "complete."
|
||||
|
||||
echo "Create a shared file system."
|
||||
mkdir -p /mnt/${EMMC_NAME}p4
|
||||
|
||||
# When there is no input parameter, select manually
|
||||
if [[ -n "${SHARED_FSTYPE}" ]]; then
|
||||
TARGET_SHARED_FSTYPE=${SHARED_FSTYPE}
|
||||
else
|
||||
cat <<EOF
|
||||
---------------------------------------------------------------------------------
|
||||
Please select the type of shared file system:
|
||||
1. ext4: [Default options] suitable for general use.
|
||||
2. btrfs: Which can extend the service life of ssd/mmc.
|
||||
3. f2fs: Fast reading and writing speed, but the compatibility is slightly poor.
|
||||
4. xfs: Very good file system, alternative to ext4.
|
||||
---------------------------------------------------------------------------------
|
||||
EOF
|
||||
read -p "Please Input ID: " TARGET_SHARED_FSTYPE
|
||||
fi
|
||||
case $TARGET_SHARED_FSTYPE in
|
||||
2 | btrfs)
|
||||
mkfs.btrfs -f -L EMMC_SHARED -m single /dev/${EMMC_NAME}p4 >/dev/null
|
||||
mount -t btrfs /dev/${EMMC_NAME}p4 /mnt/${EMMC_NAME}p4
|
||||
;;
|
||||
3 | f2fs)
|
||||
mkfs.f2fs -f -l EMMC_SHARED /dev/${EMMC_NAME}p4 >/dev/null
|
||||
mount -t f2fs /dev/${EMMC_NAME}p4 /mnt/${EMMC_NAME}p4
|
||||
;;
|
||||
4 | xfs)
|
||||
mkfs.xfs -f -L EMMC_SHARED /dev/${EMMC_NAME}p4 >/dev/null
|
||||
mount -t xfs /dev/${EMMC_NAME}p4 /mnt/${EMMC_NAME}p4
|
||||
;;
|
||||
*)
|
||||
mkfs.ext4 -F -L EMMC_SHARED /dev/${EMMC_NAME}p4 >/dev/null
|
||||
mount -t ext4 /dev/${EMMC_NAME}p4 /mnt/${EMMC_NAME}p4
|
||||
;;
|
||||
esac
|
||||
mkdir -p /mnt/${EMMC_NAME}p4/docker /mnt/${EMMC_NAME}p4/AdGuardHome/data
|
||||
sync
|
||||
|
||||
echo "Successful installed, please unplug the USB, re-insert the power supply to start the openwrt."
|
||||
exit 0
|
||||
+516
@@ -0,0 +1,516 @@
|
||||
#!/bin/bash
|
||||
#====================================================================================
|
||||
#
|
||||
# Function: Update the kernel for OpenWrt (Amlogic s9xxx, Allwinner, Rockchip)
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Support the kernel: boot-*.tar.gz, dtb-*.tar.gz, modules-*.tar.gz
|
||||
# It is recommended to install MAINLINE_UBOOT for kernel versions above 5.10.y
|
||||
# openwrt-kernel ${AUTO_MAINLINE_UBOOT}
|
||||
# E.g: openwrt-kernel yes
|
||||
# openwrt-kernel no
|
||||
#
|
||||
#================================== Functions list ==================================
|
||||
#
|
||||
# error_msg : Output error message
|
||||
# get_textoffset : Get kernel TEXT_OFFSET
|
||||
# init_var : Initialize all variables
|
||||
# check_kernel : Check kernel files list
|
||||
# chech_files_same : Check file consistency
|
||||
# restore_kernel : Restore current kernel
|
||||
# update_kernel : Update the kernel
|
||||
# update_uboot : Update the uboot
|
||||
#
|
||||
#============================== Set default parameters ==============================
|
||||
#
|
||||
# Receive one-key command related parameters
|
||||
AUTO_MAINLINE_UBOOT="no"
|
||||
# Set the release check file
|
||||
release_file="/etc/flippy-openwrt-release"
|
||||
#
|
||||
#====================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[Error] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the /boot file system
|
||||
get_boot_partition_name() {
|
||||
local paths="/boot"
|
||||
local partition_name
|
||||
|
||||
partition_name=$(df "${paths}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get kernel TEXT_OFFSET, For u-boot.ext and u-boot.emmc
|
||||
get_textoffset() {
|
||||
boot_tgz_file="${1}"
|
||||
vmlinuz_name="${2}"
|
||||
K510="1"
|
||||
temp_dir="$(mktemp -d)"
|
||||
(
|
||||
cd ${temp_dir}
|
||||
tar -xf "${boot_tgz_file}" "${vmlinuz_name}"
|
||||
)
|
||||
# With TEXT_OFFSET patch is [ 0108 ], without TEXT_OFFSET patch is [ 0000 ]
|
||||
[[ "$(hexdump -n 15 -x "${temp_dir}/${vmlinuz_name}" 2>/dev/null | head -n 1 | awk '{print $7}')" == "0108" ]] && K510="0"
|
||||
}
|
||||
|
||||
init_var() {
|
||||
# Receive one-key command related parameters
|
||||
[[ "${1}" == "yes" ]] && AUTO_MAINLINE_UBOOT="yes"
|
||||
|
||||
# Check dependencies
|
||||
[[ -n "$(busybox which tar)" ]] || error_msg "Missing [ tar ] in OpenWrt firmware, unable to update kernel"
|
||||
|
||||
# Check release file
|
||||
if [[ -s "${release_file}" ]]; then
|
||||
source "${release_file}"
|
||||
PLATFORM="${PLATFORM}"
|
||||
MODEL_ID="${MODEL_ID}"
|
||||
UBOOT_OVERLOAD="${UBOOT_OVERLOAD}"
|
||||
MAINLINE_UBOOT="${MAINLINE_UBOOT}"
|
||||
ANDROID_UBOOT="${ANDROID_UBOOT}"
|
||||
SOC="${SOC}"
|
||||
LOCK_KERNEL="${LOCK_KERNEL}"
|
||||
else
|
||||
error_msg "${release_file} file is missing!"
|
||||
fi
|
||||
[[ -n "${PLATFORM}" ]] || error_msg "Missing ${PLATFORM} value in ${release_file} file."
|
||||
|
||||
# Define supported platforms
|
||||
support_platform=("allwinner" "rockchip" "amlogic" "qemu-aarch64")
|
||||
[[ -n "$(echo "${support_platform[@]}" | grep -w "${PLATFORM}")" ]] || error_msg "[ ${PLATFORM} ] is not supported."
|
||||
|
||||
# Check and repair partition mount points
|
||||
[[ -z "$(get_boot_partition_name)" || -z "$(get_root_partition_name)" ]] && {
|
||||
echo -e "Partition mount point error, start repairing..."
|
||||
openwrt-backup -g
|
||||
}
|
||||
|
||||
# Set /boot/vmlinuz-* replication names for different SoCs
|
||||
MYBOOT_VMLINUZ="$(ls -l /boot/*Image 2>/dev/null | awk '{print $9}' | head -n 1)"
|
||||
MYBOOT_VMLINUZ="${MYBOOT_VMLINUZ##*/}"
|
||||
[[ -n "${MYBOOT_VMLINUZ}" ]] || error_msg "Failed to get Image name: [ ${MYBOOT_VMLINUZ} ]"
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case "${ROOT_PTNAME}" in
|
||||
mmcblk?p[1-9])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
[hsv]d[a-z][1-9])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')"
|
||||
PARTITION_NAME=""
|
||||
;;
|
||||
nvme?n?p[1-9])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
P4_PATH="/mnt/${EMMC_NAME}${PARTITION_NAME}4"
|
||||
# Move kernel related files to the ${P4_PATH} directory
|
||||
mv -f /tmp/upload/* ${P4_PATH} 2>/dev/null
|
||||
|
||||
# Current device model
|
||||
MYDEVICE_NAME="$(cat /proc/device-tree/model | tr -d '\000')"
|
||||
[[ "${PLATFORM}" == "qemu-aarch64" ]] && MYDEVICE_NAME="KVM Virtual Machine"
|
||||
echo -e "Current device: ${MYDEVICE_NAME} [ ${PLATFORM} ], Use in [ ${EMMC_NAME} ]"
|
||||
sync && echo ""
|
||||
}
|
||||
|
||||
# Check kernel files list
|
||||
check_kernel() {
|
||||
cd ${P4_PATH}
|
||||
|
||||
# Determine custom kernel filename
|
||||
kernel_boot="$(ls boot-*.tar.gz 2>/dev/null | head -n 1)"
|
||||
kernel_name="${kernel_boot:5:-7}"
|
||||
|
||||
KERNEL_VERSION="$(echo ${kernel_name} | grep -oE '^[1-9].[0-9]{1,3}.[0-9]+')"
|
||||
echo -e "Kernel name: ${kernel_name}"
|
||||
|
||||
# check if kernel is locked
|
||||
if [ -n "${LOCK_KERNEL}" ]; then
|
||||
if [ "${LOCK_KERNEL}" != "${kernel_name}" ]; then
|
||||
if ! echo "${kernel_name}" | grep -E '^5.10.\d+-.*?rk35.*?$' >/dev/null; then
|
||||
error_msg "The kernel version is locked to [ ${LOCK_KERNEL} ], but your kernel is [ ${kernel_name} ]. "
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if the file is added with TEXT_OFFSET patch
|
||||
get_textoffset "${P4_PATH}/${kernel_boot}" "vmlinuz-${kernel_name}"
|
||||
echo -e "K510 [ ${K510} ]"
|
||||
if [[ "${PLATFORM}" == "amlogic" && "${K510}" -eq "1" ]]; then
|
||||
[[ -n "${UBOOT_OVERLOAD}" && -f "/boot/${UBOOT_OVERLOAD}" ]] || error_msg "The UBOOT_OVERLOAD file is missing and cannot be update."
|
||||
fi
|
||||
|
||||
# Check the sha256sums file
|
||||
sha256sums_file="sha256sums"
|
||||
sha256sums_check="1"
|
||||
[[ -s "${sha256sums_file}" && -n "$(cat ${sha256sums_file})" ]] || sha256sums_check="0"
|
||||
[[ -n "$(busybox which sha256sum)" ]] || sha256sums_check="0"
|
||||
[[ "${sha256sums_check}" -eq "1" ]] && echo -e "Enable sha256sum checking..."
|
||||
|
||||
# Loop check file
|
||||
i="1"
|
||||
if [[ "${PLATFORM}" == "qemu-aarch64" ]]; then
|
||||
kernel_list=("boot" "modules")
|
||||
else
|
||||
kernel_list=("boot" "dtb-${PLATFORM}" "modules")
|
||||
fi
|
||||
for kernel_file in ${kernel_list[*]}; do
|
||||
# Set check filename
|
||||
tmp_file="${kernel_file}-${kernel_name}.tar.gz"
|
||||
# Check if file exists
|
||||
[[ -s "${tmp_file}" ]] || error_msg "The [ ${kernel_file} ] file is missing."
|
||||
# Check if the file sha256sum is correct
|
||||
if [[ "${sha256sums_check}" -eq "1" ]]; then
|
||||
tmp_sha256sum="$(sha256sum "${tmp_file}" | awk '{print $1}')"
|
||||
tmp_checkcode="$(cat ${sha256sums_file} | grep ${tmp_file} | awk '{print $1}')"
|
||||
[[ "${tmp_sha256sum}" == "${tmp_checkcode}" ]] || error_msg "${tmp_file}: sha256sum verification failed."
|
||||
echo -e "(${i}/3) [ ${tmp_file} ] file sha256sum check same."
|
||||
fi
|
||||
let i++
|
||||
done
|
||||
|
||||
sync && echo ""
|
||||
}
|
||||
|
||||
# Check the consistency of amlogic device files
|
||||
chech_files_same() {
|
||||
i="0"
|
||||
max_try="5"
|
||||
while [[ "${i}" -le "${max_try}" ]]; do
|
||||
if [[ "$(sha256sum "${1}" | awk '{print $1}')" == "$(sha256sum "${2}" | awk '{print $1}')" ]]; then
|
||||
echo "" && break
|
||||
else
|
||||
cp -f ${1} ${2}
|
||||
i="$((i + 1))"
|
||||
fi
|
||||
done
|
||||
[[ "${i}" -gt "${max_try}" ]] && echo "God, it's different after ${max_try} copies: [ ${1} ]"
|
||||
}
|
||||
|
||||
# Restore the kernel when the update fails
|
||||
restore_kernel() {
|
||||
(
|
||||
cd /boot
|
||||
rm -rf \
|
||||
config-${kernel_name} \
|
||||
System.map-${kernel_name} \
|
||||
initrd.img-${kernel_name} \
|
||||
uInitrd-${kernel_name} \
|
||||
vmlinuz-${kernel_name} \
|
||||
initrd.img \
|
||||
uInitrd \
|
||||
zImage \
|
||||
Image \
|
||||
vmlinuz \
|
||||
dtb* 2>/dev/null
|
||||
tar -xzf /tmp/boot-backup.tar.gz 2>/dev/null
|
||||
)
|
||||
error_msg "Kernel update failed and has been reverted."
|
||||
}
|
||||
|
||||
# Update the kernel
|
||||
update_kernel() {
|
||||
local cur_kernel_name=$(uname -r)
|
||||
local boot_fstype=$(df -T /boot | tail -n1 | awk '{print $2}')
|
||||
echo -e "Start unpacking the kernel..."
|
||||
|
||||
# 01. for /boot five files
|
||||
# Backup the current_kernel
|
||||
(
|
||||
cd /boot
|
||||
tar -czf /tmp/boot-backup.tar.gz \
|
||||
config-${cur_kernel_name} \
|
||||
System.map-${cur_kernel_name} \
|
||||
initrd.img-${cur_kernel_name} \
|
||||
uInitrd-${cur_kernel_name} \
|
||||
vmlinuz-${cur_kernel_name} \
|
||||
initrd.img \
|
||||
uInitrd \
|
||||
zImage \
|
||||
Image \
|
||||
vmlinuz \
|
||||
dtb* 2>/dev/null
|
||||
rm -rf \
|
||||
config-${cur_kernel_name} \
|
||||
System.map-${cur_kernel_name} \
|
||||
initrd.img-${cur_kernel_name} \
|
||||
uInitrd-${cur_kernel_name} \
|
||||
vmlinuz-${cur_kernel_name} \
|
||||
initrd.img \
|
||||
uInitrd \
|
||||
zImage \
|
||||
Image \
|
||||
vmlinuz \
|
||||
dtb* 2>/dev/null
|
||||
)
|
||||
# Extract the new kernel
|
||||
tar -xf ${P4_PATH}/boot-${kernel_name}.tar.gz -C /boot
|
||||
|
||||
# Check if the file exists
|
||||
local valid_files
|
||||
if [[ "${PLATFORM}" == "qemu-aarch64" ]]; then
|
||||
valid_files="vmlinuz-${kernel_name} initrd.img-${kernel_name} config-${kernel_name} System.map-${kernel_name}"
|
||||
rm -f /boot/uInitrd*
|
||||
else
|
||||
valid_files="vmlinuz-${kernel_name} uInitrd-${kernel_name} config-${kernel_name} System.map-${kernel_name}"
|
||||
# wxy-oect: MODEL_ID numbers r304,r306 and w[0-9]{3}, require special handling of uInitrd
|
||||
[[ "${MODEL_ID}" =~ ^(r304|r306|w[0-9]{3})$ ]] || rm -f /boot/initrd.img*
|
||||
fi
|
||||
for f in ${valid_files}; do [[ -f "/boot/${f}" ]] || restore_kernel; done
|
||||
|
||||
# Check if the files are the same
|
||||
(
|
||||
cd /boot
|
||||
if [[ "${PLATFORM}" == "qemu-aarch64" ]]; then
|
||||
ln -sf initrd.img-${kernel_name} initrd.img
|
||||
ln -sf vmlinuz-${kernel_name} ${MYBOOT_VMLINUZ}
|
||||
elif [[ "$boot_fstype" == "vfat" ]]; then
|
||||
cp -f uInitrd-${kernel_name} uInitrd
|
||||
[[ -z "$(chech_files_same uInitrd-${kernel_name} uInitrd)" ]] || restore_kernel
|
||||
cp -f vmlinuz-${kernel_name} ${MYBOOT_VMLINUZ}
|
||||
[[ -z "$(chech_files_same vmlinuz-${kernel_name} ${MYBOOT_VMLINUZ})" ]] || restore_kernel
|
||||
else
|
||||
ln -sf uInitrd-${kernel_name} uInitrd
|
||||
ln -sf vmlinuz-${kernel_name} ${MYBOOT_VMLINUZ}
|
||||
fi
|
||||
|
||||
# wxy-oect: MODEL_ID numbers r304 and r306, require special handling of uInitrd
|
||||
[[ "${MODEL_ID}" =~ ^(r304|r306)$ ]] && ln -sf initrd.img-${kernel_name} uInitrd
|
||||
)
|
||||
|
||||
echo -e "(1/3) Unpacking [ boot-${kernel_name}.tar.gz ] done."
|
||||
|
||||
if [[ "${PLATFORM}" == "qemu-aarch64" ]]; then
|
||||
echo -e "(2/3) skip unpack dtb files."
|
||||
else
|
||||
# 02. for /boot/dtb/${PLATFORM}/*
|
||||
if [[ "${boot_fstype}" == "vfat" ]]; then
|
||||
(cd /boot && mkdir -p dtb/${PLATFORM})
|
||||
else
|
||||
(cd /boot && mkdir -p dtb-${kernel_name}/${PLATFORM} && ln -sf dtb-${kernel_name} dtb)
|
||||
fi
|
||||
tar -xf ${P4_PATH}/dtb-${PLATFORM}-${kernel_name}.tar.gz -C /boot/dtb/${PLATFORM}
|
||||
[[ "$(ls /boot/dtb/${PLATFORM} -l 2>/dev/null | grep "^-" | wc -l)" -ge "1" ]] || error_msg "/boot/dtb/${PLATFORM} file is missing."
|
||||
echo -e "(2/3) Unpacking [ dtb-${PLATFORM}-${kernel_name}.tar.gz ] done."
|
||||
fi
|
||||
|
||||
# 03. for /lib/modules/*
|
||||
rm -rf /lib/modules/*
|
||||
tar -xf ${P4_PATH}/modules-${kernel_name}.tar.gz -C /lib/modules
|
||||
(
|
||||
cd /lib/modules/${kernel_name}
|
||||
rm -f *.ko
|
||||
find ./ -type f -name '*.ko' -exec ln -s {} ./ \;
|
||||
sync && sleep 3
|
||||
x=$(ls *.ko -l 2>/dev/null | grep "^l" | wc -l)
|
||||
[[ "${x}" -eq "0" ]] && error_msg "Error *.ko Files not found."
|
||||
)
|
||||
echo -e "(3/3) Unpacking [ modules-${kernel_name}.tar.gz ] done."
|
||||
|
||||
# Delete kernel tmpfiles
|
||||
rm -f ${P4_PATH}/*-${kernel_name}.tar.gz
|
||||
rm -f ${P4_PATH}/sha256sums
|
||||
|
||||
sync && echo ""
|
||||
}
|
||||
|
||||
# Update the uboot
|
||||
update_uboot() {
|
||||
# Only amlogic SoCs needs to be updated
|
||||
if [[ "${PLATFORM}" == "amlogic" ]]; then
|
||||
# Copy u-boot.ext and u-boot.emmc
|
||||
if [[ "${K510}" -eq "1" && -n "${UBOOT_OVERLOAD}" && -f "/boot/${UBOOT_OVERLOAD}" ]]; then
|
||||
[[ ! -f "/boot/u-boot.ext" ]] && cp -f "/boot/${UBOOT_OVERLOAD}" /boot/u-boot.ext && chmod +x /boot/u-boot.ext
|
||||
[[ ! -f "/boot/u-boot.emmc" ]] && cp -f "/boot/u-boot.ext" /boot/u-boot.emmc && chmod +x /boot/u-boot.emmc
|
||||
echo -e "The ${UBOOT_OVERLOAD} file copy is complete."
|
||||
elif [[ "${K510}" -eq "0" ]]; then
|
||||
rm -f "/boot/u-boot.ext" "/boot/u-boot.emmc"
|
||||
fi
|
||||
|
||||
# Write Mainline bootloader
|
||||
if [[ -f "${MAINLINE_UBOOT}" && "${AUTO_MAINLINE_UBOOT}" == "yes" ]]; then
|
||||
echo -e "Write Mainline bootloader: [ ${MAINLINE_UBOOT} ] to [ /dev/${EMMC_NAME} ]"
|
||||
dd if=${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=1 count=442 conv=fsync
|
||||
dd if=${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=512 skip=1 seek=1 conv=fsync
|
||||
echo -e "The MAINLINE_UBOOT file write is complete."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update release file
|
||||
sed -i "s|^KERNEL_VERSION=.*|KERNEL_VERSION='${kernel_name}'|g" ${release_file} 2>/dev/null
|
||||
# Update banner file
|
||||
sed -i "s| Kernel.*| Kernel: ${kernel_name}|g" /etc/banner 2>/dev/null
|
||||
|
||||
sync && echo ""
|
||||
}
|
||||
|
||||
# Rescue the kernel
|
||||
sos_kernel() {
|
||||
echo -e "Start rescuing kernel..."
|
||||
|
||||
# Supports specifying disks, such as: [ openwrt-kernel -s mmcblk1 ]
|
||||
box_disk="${2}"
|
||||
|
||||
if [[ -n "${box_disk}" ]]; then
|
||||
# Format the disk names
|
||||
box_disk="${box_disk//\/dev\//}"
|
||||
|
||||
# Check if the disk exists
|
||||
[[ -b "/dev/${box_disk}" ]] || error_msg "The specified disk [ ${box_disk} ] does not exist."
|
||||
|
||||
# Check if the disk is the same as the current system disk
|
||||
[[ "${box_disk}" == "${EMMC_NAME}" ]] && error_msg "The specified disk [ ${box_disk} ] is the same as the current system disk [ ${EMMC_NAME} ]."
|
||||
|
||||
echo -e "The device name of the specified disk: [ ${box_disk} ]"
|
||||
else
|
||||
# Find emmc disk, first find emmc containing boot0 partition
|
||||
box_disk="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?|nvme[0-9]?n[0-9]?|[hsv]d[a-z])' | grep -vE ^${EMMC_NAME} | sort -u | head -n 1)"
|
||||
|
||||
# Check if disk exists
|
||||
[[ -z "${box_disk}" ]] && error_msg "Unable to locate the storage requiring rescue."
|
||||
|
||||
echo -e "The device name of the target disk: [ ${box_disk} ]"
|
||||
fi
|
||||
|
||||
rescue_disk="/dev/${box_disk}"
|
||||
echo -e "The current OpenWrt is running on [ /dev/${EMMC_NAME} ], and the target disk for restoration is [ ${rescue_disk} ]."
|
||||
|
||||
# Create a temporary mount directory
|
||||
umount ${P4_PATH}/bootfs 2>/dev/null
|
||||
umount ${P4_PATH}/rootfs 2>/dev/null
|
||||
rm -rf ${P4_PATH}/bootfs ${P4_PATH}/rootfs 2>/dev/null
|
||||
mkdir -p ${P4_PATH}/{bootfs/,rootfs/} && sync
|
||||
[[ "${?}" -ne "0" ]] && error_msg "Failed to create temporary mount directory [ ${P4_PATH} ]"
|
||||
|
||||
# Mount target bootfs partition
|
||||
[[ "${box_disk}" =~ ^([hsv]d[a-z]) ]] && rescue_disk_partition_name="" || rescue_disk_partition_name="p"
|
||||
mount ${rescue_disk}${rescue_disk_partition_name}1 ${P4_PATH}/bootfs
|
||||
[[ "${?}" -ne "0" ]] && error_msg "mount ${rescue_disk}${PARTITION_NAME}1 failed!"
|
||||
echo -e "The [ ${rescue_disk}${rescue_disk_partition_name}1 ] partition is mounted on [ ${P4_PATH}/bootfs ]."
|
||||
|
||||
# Search uuid file
|
||||
if [[ -f "${P4_PATH}/bootfs/uEnv.txt" ]]; then
|
||||
search_file="uEnv.txt"
|
||||
elif [[ -f "${P4_PATH}/bootfs/armbianEnv.txt" ]]; then
|
||||
search_file="armbianEnv.txt"
|
||||
elif [[ -f "${P4_PATH}/bootfs/extlinux/extlinux.conf" ]]; then
|
||||
search_file="extlinux/extlinux.conf"
|
||||
else
|
||||
error_msg "The [ uEnv.txt, armbianEnv.txt, extlinux/extlinux.conf ] file does not exist, stop rescuing."
|
||||
fi
|
||||
|
||||
# Get the target partition uuid and rootfs
|
||||
target_parttion_uuid="$(grep '=UUID=' ${P4_PATH}/bootfs/${search_file} | sed -n 's/.*=UUID=\([a-f0-9-]*\).*/\1/p')"
|
||||
[[ -z "${target_parttion_uuid}" ]] && error_msg "The [ ${search_file} ] file does not contain the UUID value."
|
||||
target_rootfs="$(blkid | grep ${target_parttion_uuid} | awk -F':' '{print $1;}')"
|
||||
[[ -z "${target_rootfs}" ]] && error_msg "The [ ${target_parttion_uuid} ] UUID does not exist in the system."
|
||||
|
||||
# Mount target rootfs partition
|
||||
mount ${target_rootfs} ${P4_PATH}/rootfs
|
||||
[[ "${?}" -ne "0" ]] && error_msg "mount ${rescue_disk}${PARTITION_NAME}2 failed!"
|
||||
echo -e "The [ ${target_rootfs} ] partition is mounted on [ ${P4_PATH}/rootfs ]."
|
||||
|
||||
# Identify the current kernel files
|
||||
kernel_signature="$(uname -r)"
|
||||
|
||||
# 01. For /boot files
|
||||
[[ -d "${P4_PATH}/bootfs" ]] && {
|
||||
cd ${P4_PATH}/bootfs
|
||||
rm -rf config-* initrd.img-* System.map-* vmlinuz-* uInitrd* *Image dtb* u-boot.ext u-boot.emmc
|
||||
[[ -f "/boot/u-boot.ext" ]] && {
|
||||
cp -f /boot/u-boot.ext .
|
||||
cp -f /boot/u-boot.ext u-boot.emmc
|
||||
chmod +x u-boot.ext u-boot.emmc
|
||||
}
|
||||
cp -rf /boot/{*-${kernel_signature},uInitrd,*Image,dtb} .
|
||||
[[ "${?}" -ne "0" ]] && error_msg "(1/2) [ boot ] kernel files rescue failed."
|
||||
echo -e "(1/2) [ boot ] kernel files rescue succeeded."
|
||||
|
||||
[[ -f "/boot/emmc_autoscript.cmd" ]] && cp -f /boot/emmc_autoscript.cmd .
|
||||
[[ -f "/boot/emmc_autoscript" ]] && cp -f /boot/emmc_autoscript .
|
||||
[[ -f "/boot/s905_autoscript.cmd" ]] && cp -f /boot/s905_autoscript.cmd .
|
||||
[[ -f "/boot/s905_autoscript" ]] && cp -f /boot/s905_autoscript .
|
||||
} || error_msg "(1/2) The [ ${P4_PATH}/bootfs ] folder does not exist, stop rescuing."
|
||||
|
||||
# 02. For /lib/modules/${kernel_signature}
|
||||
[[ -d "${P4_PATH}/rootfs/lib/modules" ]] && {
|
||||
cd ${P4_PATH}/rootfs/lib/modules
|
||||
rm -rf *
|
||||
cp -rf /lib/modules/${kernel_signature} .
|
||||
[[ "${?}" -ne "0" ]] && error_msg "(2/2) [ modules ] kernel files rescue failed."
|
||||
echo -e "(2/2) [ modules ] kernel files rescue succeeded."
|
||||
} || error_msg "(2/2) The [ ${P4_PATH}/rootfs/lib/modules ] folder does not exist, stop rescuing."
|
||||
|
||||
# Unmount the emmc partition
|
||||
cd ${P4_PATH}
|
||||
umount -f ${P4_PATH}/bootfs
|
||||
[[ "${?}" -ne "0" ]] && error_msg "Failed to umount [ ${P4_PATH}/bootfs ]"
|
||||
umount -f ${P4_PATH}/rootfs
|
||||
[[ "${?}" -ne "0" ]] && error_msg "Failed to umount [ ${P4_PATH}/rootfs ]"
|
||||
# Remove the temporary mount directory
|
||||
rm -rf ${P4_PATH}/bootfs ${P4_PATH}/rootfs
|
||||
|
||||
sync && echo ""
|
||||
}
|
||||
|
||||
echo -e "Welcome to the OpenWrt Kernel Management Tool."
|
||||
# Operation environment check
|
||||
[[ -x "/usr/sbin/openwrt-kernel" ]] || error_msg "Please grant execution permission: chmod +x /usr/sbin/openwrt-kernel"
|
||||
|
||||
# Execute relevant functions based on the options
|
||||
if [[ "${@}" =~ ^-s(\s)* ]]; then
|
||||
# Initialize all variables
|
||||
init_var "${@}"
|
||||
# Start rescuing the kernel
|
||||
sos_kernel "${@}"
|
||||
|
||||
# Kernel restore successful
|
||||
sync && sleep 3
|
||||
echo -e "Kernel rescue successful, please remove the disk and restart the OpenWrt system."
|
||||
exit 0
|
||||
else
|
||||
# Initialize all variables
|
||||
init_var "${@}"
|
||||
# Check kernel files list
|
||||
check_kernel
|
||||
# Update the kernel
|
||||
update_kernel
|
||||
# Update the uboot
|
||||
update_uboot
|
||||
|
||||
# Kernel update successful
|
||||
sync && sleep 3
|
||||
echo "Successfully updated, automatic restarting..."
|
||||
reboot
|
||||
exit 0
|
||||
fi
|
||||
+662
@@ -0,0 +1,662 @@
|
||||
#!/bin/bash
|
||||
#======================================================================================
|
||||
# Function: Update openwrt to emmc for Allwinner STB
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#======================================================================================
|
||||
#
|
||||
# The script supports directly setting parameters for update, skipping interactive selection
|
||||
# openwrt-update-allwinner ${OPENWRT_FILE} ${AUTO_MAINLINE_UBOOT} ${RESTORE_CONFIG}
|
||||
# E.g: openwrt-update-allwinner openwrt_s905d.img.gz yes restore
|
||||
# E.g: openwrt-update-allwinner openwrt_s905d.img.gz no no-restore
|
||||
|
||||
# You can also execute the script directly, and interactively select related functions
|
||||
# E.g: openwrt-update-allwinner
|
||||
#
|
||||
#======================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the /boot file system
|
||||
get_boot_partition_name() {
|
||||
local paths="/boot"
|
||||
local partition_name
|
||||
|
||||
partition_name=$(df "${paths}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition message of the root file system
|
||||
get_root_partition_msg() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_msg=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ "^" "'"${path}"'" "$" {print $0}')
|
||||
[[ -n "${partition_msg}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_msg}" ]] && error_msg "Cannot find the root partition message!"
|
||||
echo "${partition_msg}"
|
||||
}
|
||||
|
||||
# Receive one-key command related parameters
|
||||
IMG_NAME=${1}
|
||||
AUTO_MAINLINE_UBOOT=${2}
|
||||
BACKUP_RESTORE_CONFIG=${3}
|
||||
|
||||
# Current FDT file
|
||||
if [[ -f "/boot/uEnv.txt" ]]; then
|
||||
source /boot/uEnv.txt 2>/dev/null
|
||||
MYDTB_FDTFILE=$(basename $FDT)
|
||||
elif [[ -f "/boot/armbianEnv.txt" ]]; then
|
||||
source /boot/armbianEnv.txt 2>/dev/null
|
||||
MYDTB_FDTFILE="$(basename $fdtfile)"
|
||||
elif [[ -f "/etc/flippy-openwrt-release" ]]; then
|
||||
source /etc/flippy-openwrt-release 2>/dev/null
|
||||
MYDTB_FDTFILE="${FDTFILE}"
|
||||
fi
|
||||
|
||||
[[ -z "${MYDTB_FDTFILE}" ]] && error_msg "Invalid FDTFILE: [ ${MYDTB_FDTFILE} ]"
|
||||
|
||||
# Current device model
|
||||
MYDEVICE_NAME=$(cat /proc/device-tree/model | tr -d '\000')
|
||||
if [[ -z "${MYDEVICE_NAME}" ]]; then
|
||||
error_msg "The device name is empty and cannot be recognized."
|
||||
elif [[ "$(echo ${MYDEVICE_NAME} | grep "V-Plus Cloud")" == "" ]]; then
|
||||
error_msg "[ ${MYDEVICE_NAME} ] is not [ V-Plus Cloud ] device, please select the correct script."
|
||||
else
|
||||
echo -e "Current device: ${MYDEVICE_NAME} [ vplus ]"
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Check and repair partition mount points
|
||||
[[ -z "$(get_boot_partition_name)" || -z "$(get_root_partition_name)" ]] && {
|
||||
echo -e "Partition mount point error, start repairing..."
|
||||
openwrt-backup -g
|
||||
}
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="EMMC_"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
PARTITION_NAME=""
|
||||
LB_PRE=""
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
cd /mnt/${EMMC_NAME}${PARTITION_NAME}4/
|
||||
mv -f /tmp/upload/* . 2>/dev/null && sync
|
||||
|
||||
if [[ "${IMG_NAME}" == *.img ]]; then
|
||||
echo -e "Update using [ ${IMG_NAME} ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
echo -e "Update using [ ${IMG_NAME} ] ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img.xz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
xz_file=$(ls *.img.xz | head -n 1)
|
||||
echo -e "Update using [ ${xz_file} ] file. Please wait a moment ..."
|
||||
xz -d ${xz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.img.gz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.img.gz | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
gzip -df ${gz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.7z -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.7z | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
bsdtar -xmf ${gz_file} 2>/dev/null
|
||||
[ $? -eq 0 ] || 7z x ${gz_file} -aoa -y 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.zip -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
zip_file=$(ls *.zip | head -n 1)
|
||||
echo -e "Update using [ ${zip_file} ] file. Please wait a moment ..."
|
||||
unzip -o ${zip_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
else
|
||||
echo -e "Please upload or specify the update openwrt firmware file."
|
||||
echo -e "Upload method: system menu → Amlogic Service → Manually Upload Update"
|
||||
echo -e "Specify method: Place the openwrt firmware file in [ /mnt/${EMMC_NAME}${PARTITION_NAME}4/ ]"
|
||||
echo -e "The supported file suffixes are: *.img, *.img.xz, *.img.gz, *.7z, *.zip"
|
||||
echo -e "After upload the openwrt firmware file, run again."
|
||||
exit 1
|
||||
fi
|
||||
sync
|
||||
|
||||
# check file
|
||||
if [ ! -f "${IMG_NAME}" ]; then
|
||||
error_msg "No update file found."
|
||||
else
|
||||
echo "Start update from [ ${IMG_NAME} ]"
|
||||
fi
|
||||
|
||||
# find boot partition
|
||||
BOOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ /^\/boot$/ {print $0}')
|
||||
if [ "${BOOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The boot partition is not exists or not mounted, so it cannot be upgraded with this script!"
|
||||
fi
|
||||
|
||||
BR_FLAG=1
|
||||
echo -ne "Whether to backup and restore the current config files? y/n [y]\b\b"
|
||||
if [[ ${BACKUP_RESTORE_CONFIG} == "restore" ]]; then
|
||||
yn="y"
|
||||
elif [[ ${BACKUP_RESTORE_CONFIG} == "no-restore" ]]; then
|
||||
yn="n"
|
||||
else
|
||||
read yn
|
||||
fi
|
||||
case $yn in
|
||||
n* | N*)
|
||||
BR_FLAG=0
|
||||
;;
|
||||
esac
|
||||
|
||||
BOOT_NAME=$(echo ${BOOT_PART_MSG} | awk '{print $1}')
|
||||
BOOT_PATH=$(echo ${BOOT_PART_MSG} | awk '{print $2}')
|
||||
BOOT_UUID=$(echo ${BOOT_PART_MSG} | awk '{print $4}')
|
||||
|
||||
# find root partition
|
||||
ROOT_PART_MSG="$(get_root_partition_msg)"
|
||||
ROOT_NAME=$(echo ${ROOT_PART_MSG} | awk '{print $1}')
|
||||
ROOT_PATH=$(echo ${ROOT_PART_MSG} | awk '{print $2}')
|
||||
ROOT_UUID=$(echo ${ROOT_PART_MSG} | awk '{print $4}')
|
||||
case ${ROOT_NAME} in
|
||||
${EMMC_NAME}${PARTITION_NAME}2)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}3"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS2"
|
||||
;;
|
||||
${EMMC_NAME}${PARTITION_NAME}3)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}2"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS1"
|
||||
;;
|
||||
*)
|
||||
error_msg "The root partition location is invalid, so it cannot be upgraded with this script!"
|
||||
;;
|
||||
esac
|
||||
|
||||
# find new root partition
|
||||
NEW_ROOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | grep "${NEW_ROOT_NAME}" | awk '$3 ~ /^part$/ && $5 !~ /^\/$/ && $5 !~ /^\/boot$/ {print $0}')
|
||||
if [ "${NEW_ROOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The new root partition is not exists, so it cannot be upgraded with this script!"
|
||||
fi
|
||||
NEW_ROOT_NAME=$(echo $NEW_ROOT_PART_MSG | awk '{print $1}')
|
||||
NEW_ROOT_PATH=$(echo $NEW_ROOT_PART_MSG | awk '{print $2}')
|
||||
NEW_ROOT_UUID=$(echo $NEW_ROOT_PART_MSG | awk '{print $4}')
|
||||
NEW_ROOT_MP=$(echo $NEW_ROOT_PART_MSG | awk '{print $5}')
|
||||
|
||||
# losetup
|
||||
losetup -f -P $IMG_NAME
|
||||
if [ $? -eq 0 ]; then
|
||||
LOOP_DEV=$(losetup | grep "$IMG_NAME" | awk '{print $1}')
|
||||
if [ "$LOOP_DEV" == "" ]; then
|
||||
error_msg "loop device not found!"
|
||||
fi
|
||||
else
|
||||
error_msg "losetup $IMG_FILE failed!"
|
||||
fi
|
||||
|
||||
# fix loopdev issue in kernel 5.19
|
||||
function fix_loopdev() {
|
||||
local parentdev=${1##*/}
|
||||
if [ ! -d /sys/block/${parentdev} ]; then
|
||||
return
|
||||
fi
|
||||
subdevs=$(lsblk -l -o NAME | grep -E "^${parentdev}.+\$")
|
||||
for subdev in $subdevs; do
|
||||
if [ ! -d /sys/block/${parentdev}/${subdev} ]; then
|
||||
return
|
||||
elif [ -b /dev/${sub_dev} ]; then
|
||||
continue
|
||||
fi
|
||||
source /sys/block/${parentdev}/${subdev}/uevent
|
||||
mknod /dev/${subdev} b ${MAJOR} ${MINOR}
|
||||
unset MAJOR MINOR DEVNAME DEVTYPE DISKSEQ PARTN PARTNAME
|
||||
done
|
||||
}
|
||||
fix_loopdev ${LOOP_DEV}
|
||||
|
||||
WAIT=3
|
||||
echo -n "The loopdev is $LOOP_DEV, wait ${WAIT} seconds "
|
||||
while [ $WAIT -ge 1 ]; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
WAIT=$((WAIT - 1))
|
||||
done
|
||||
echo
|
||||
|
||||
# umount loop devices (openwrt will auto mount some partition)
|
||||
MOUNTED_DEVS=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "$LOOP_DEV" | awk '$3 !~ /^$/ {print $2}')
|
||||
for dev in $MOUNTED_DEVS; do
|
||||
while :; do
|
||||
echo -n "umount $dev ... "
|
||||
umount -f $dev
|
||||
sleep 1
|
||||
mnt=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "$dev" | awk '$3 !~ /^$/ {print $2}')
|
||||
if [ "$mnt" == "" ]; then
|
||||
echo "ok"
|
||||
break
|
||||
else
|
||||
echo "try again ..."
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# mount src part
|
||||
WORK_DIR=$PWD
|
||||
P1=${WORK_DIR}/boot
|
||||
P2=${WORK_DIR}/root
|
||||
mkdir -p $P1 $P2
|
||||
echo -n "mount ${LOOP_DEV}p1 -> ${P1} ... "
|
||||
mount -t vfat -o ro ${LOOP_DEV}p1 ${P1}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "mount failed"
|
||||
losetup -D
|
||||
exit 1
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
echo -n "mount ${LOOP_DEV}p2 -> ${P2} ... "
|
||||
ZSTD_LEVEL=6
|
||||
mount -t btrfs -o ro,compress=zstd:${ZSTD_LEVEL} ${LOOP_DEV}p2 ${P2}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "mount failed"
|
||||
umount -f ${P1}
|
||||
losetup -D
|
||||
exit 1
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
# Prepare the dockerman config file
|
||||
if [ -f ${P2}/etc/init.d/dockerman ] && [ -f ${P2}/etc/config/dockerd ]; then
|
||||
|
||||
flg=0
|
||||
# get current docker data root
|
||||
data_root=$(uci get dockerd.globals.data_root 2>/dev/null)
|
||||
if [ "$data_root" == "" ]; then
|
||||
flg=1
|
||||
# get current config from /etc/docker/daemon.json
|
||||
if [ -f "/etc/docker/daemon.json" ] && [ -x "/usr/bin/jq" ]; then
|
||||
data_root=$(jq -r '."data-root"' /etc/docker/daemon.json)
|
||||
|
||||
bip=$(jq -r '."bip"' /etc/docker/daemon.json)
|
||||
[ "$bip" == "null" ] && bip="172.31.0.1/24"
|
||||
|
||||
log_level=$(jq -r '."log-level"' /etc/docker/daemon.json)
|
||||
[ "$log_level" == "null" ] && log_level="warn"
|
||||
|
||||
_iptables=$(jq -r '."iptables"' /etc/docker/daemon.json)
|
||||
[ "$_iptables" == "null" ] && _iptables="true"
|
||||
|
||||
registry_mirrors=$(jq -r '."registry-mirrors"[]' /etc/docker/daemon.json 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$data_root" == "" ]; then
|
||||
data_root="/opt/docker/" # the default data root
|
||||
fi
|
||||
|
||||
if ! uci get dockerd.globals >/dev/null 2>&1; then
|
||||
uci set dockerd.globals='globals'
|
||||
uci commit
|
||||
fi
|
||||
|
||||
# delete alter config , use inner config
|
||||
if uci get dockerd.globals.alt_config_file >/dev/null 2>&1; then
|
||||
uci delete dockerd.globals.alt_config_file
|
||||
uci commit
|
||||
fi
|
||||
|
||||
if [ $flg -eq 1 ]; then
|
||||
uci set dockerd.globals.data_root=$data_root
|
||||
[ "$bip" != "" ] && uci set dockerd.globals.bip=$bip
|
||||
[ "$log_level" != "" ] && uci set dockerd.globals.log_level=$log_level
|
||||
[ "$_iptables" != "" ] && uci set dockerd.globals.iptables=$_iptables
|
||||
if [ "$registry_mirrors" != "" ]; then
|
||||
for reg in $registry_mirrors; do
|
||||
uci add_list dockerd.globals.registry_mirrors=$reg
|
||||
done
|
||||
fi
|
||||
uci set dockerd.globals.auto_start='1'
|
||||
uci commit
|
||||
fi
|
||||
fi
|
||||
|
||||
#format NEW_ROOT
|
||||
echo "umount ${NEW_ROOT_MP}"
|
||||
umount -f "${NEW_ROOT_MP}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "umount failed, please reboot and try again!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "format ${NEW_ROOT_PATH}"
|
||||
NEW_ROOT_UUID=$(uuidgen)
|
||||
mkfs.btrfs -f -U ${NEW_ROOT_UUID} -L ${NEW_ROOT_LABEL} ${NEW_ROOT_PATH}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "format ${NEW_ROOT_PATH} failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "mount ${NEW_ROOT_PATH} to ${NEW_ROOT_MP}"
|
||||
mount -t btrfs -o compress=zstd:${ZSTD_LEVEL} ${NEW_ROOT_PATH} ${NEW_ROOT_MP}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "mount ${NEW_ROOT_PATH} to ${NEW_ROOT_MP} failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# begin copy rootfs
|
||||
cd ${NEW_ROOT_MP}
|
||||
echo "Start copy data from ${P2} to ${NEW_ROOT_MP} ..."
|
||||
ENTRYS=$(ls)
|
||||
for entry in $ENTRYS; do
|
||||
if [ "$entry" == "lost+found" ]; then
|
||||
continue
|
||||
fi
|
||||
echo -n "remove old $entry ... "
|
||||
rm -rf $entry
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok"
|
||||
else
|
||||
error_msg "failed"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo "create etc subvolume ..."
|
||||
btrfs subvolume create etc
|
||||
echo -n "make dirs ... "
|
||||
mkdir -p .snapshots .reserved bin boot dev lib opt mnt overlay proc rom root run sbin sys tmp usr www
|
||||
ln -sf lib/ lib64
|
||||
ln -sf tmp/ var
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
COPY_SRC="root etc bin sbin lib opt usr www"
|
||||
echo "copy data ... "
|
||||
for src in $COPY_SRC; do
|
||||
echo -n "copy $src ... "
|
||||
(cd ${P2} && tar cf - $src) | tar xf -
|
||||
sync
|
||||
echo "done"
|
||||
done
|
||||
|
||||
SHFS="/mnt/${EMMC_NAME}${PARTITION_NAME}4"
|
||||
echo "Modify config files ... "
|
||||
rm -f "./etc/rc.local.orig" "./etc/first_run.sh" "./etc/part_size"
|
||||
rm -f ./etc/bench.log
|
||||
if [ -x ./usr/sbin/balethirq.pl ]; then
|
||||
if grep "balethirq.pl" "./etc/rc.local"; then
|
||||
echo "balance irq is enabled"
|
||||
else
|
||||
echo "enable balance irq"
|
||||
sed -e "/exit/i\/usr/sbin/balethirq.pl" -i ./etc/rc.local
|
||||
fi
|
||||
fi
|
||||
cat >./etc/fstab <<EOF
|
||||
UUID=${NEW_ROOT_UUID} / btrfs compress=zstd:${ZSTD_LEVEL} 0 1
|
||||
LABEL=${LB_PRE}BOOT /boot vfat defaults 0 2
|
||||
#tmpfs /tmp tmpfs defaults,nosuid 0 0
|
||||
EOF
|
||||
|
||||
cat >./etc/config/fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${NEW_ROOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'btrfs'
|
||||
option options 'compress=zstd:${ZSTD_LEVEL}'
|
||||
|
||||
config mount
|
||||
option target '/boot'
|
||||
option label '${LB_PRE}BOOT'
|
||||
option enabled '1'
|
||||
option enabled_fsck '0'
|
||||
option fstype 'vfat'
|
||||
|
||||
EOF
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
sync
|
||||
|
||||
echo "create the first etc snapshot -> .snapshots/etc-000"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-000
|
||||
|
||||
[ -d ${SHFS}/docker ] || mkdir -p ${SHFS}/docker
|
||||
rm -rf opt/docker && ln -sf ${SHFS}/docker/ opt/docker
|
||||
|
||||
if [ -f /mnt/${NEW_ROOT_NAME}/etc/config/AdGuardHome ]; then
|
||||
[ -d ${SHFS}/AdGuardHome/data ] || mkdir -p ${SHFS}/AdGuardHome/data
|
||||
if [ ! -L /usr/bin/AdGuardHome ]; then
|
||||
[ -d /usr/bin/AdGuardHome ] &&
|
||||
cp -a /usr/bin/AdGuardHome/* ${SHFS}/AdGuardHome/
|
||||
fi
|
||||
ln -sf ${SHFS}/AdGuardHome /mnt/${NEW_ROOT_NAME}/usr/bin/AdGuardHome
|
||||
fi
|
||||
|
||||
BOOTLOADER="./lib/u-boot/u-boot-sunxi-with-spl.bin"
|
||||
if [ -f ${BOOTLOADER} ]; then
|
||||
echo "update u-boot ... "
|
||||
# erase from 8kb to 4mb
|
||||
dd if=/dev/zero of=/dev/${EMMC_NAME} bs=1024 seek=8 count=4088 conv=fsync
|
||||
# write u-boot
|
||||
dd if=${BOOTLOADER} of=/dev/${EMMC_NAME} bs=1024 seek=8 conv=fsync
|
||||
echo "done"
|
||||
fi
|
||||
sync
|
||||
echo "copy done"
|
||||
echo
|
||||
|
||||
BACKUP_LIST=$(${P2}/usr/sbin/openwrt-backup -p)
|
||||
if [ $BR_FLAG -eq 1 ]; then
|
||||
echo -n "Restore your old config files ... "
|
||||
(
|
||||
cd /
|
||||
eval tar czf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
)
|
||||
tar xzf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz
|
||||
[ -f ./etc/config/dockerman ] && sed -e "s/option wan_mode 'false'/option wan_mode 'true'/" -i ./etc/config/dockerman 2>/dev/null
|
||||
[ -f ./etc/config/dockerd ] && sed -e "s/option wan_mode '0'/option wan_mode '1'/" -i ./etc/config/dockerd 2>/dev/null
|
||||
[ -f ./etc/config/verysync ] && sed -e 's/config setting/config verysync/' -i ./etc/config/verysync
|
||||
|
||||
# 还原 fstab
|
||||
cp -f .snapshots/etc-000/fstab ./etc/fstab
|
||||
cp -f .snapshots/etc-000/config/fstab ./etc/config/fstab
|
||||
# 还原 luci
|
||||
cp -f .snapshots/etc-000/config/luci ./etc/config/luci
|
||||
# 还原/etc/config/rpcd
|
||||
cp -f .snapshots/etc-000/config/rpcd ./etc/config/rpcd
|
||||
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
fi
|
||||
|
||||
rm -f ./etc/bench.log
|
||||
cat >>./etc/crontabs/root <<EOF
|
||||
17 3 * * * /etc/coremark.sh
|
||||
EOF
|
||||
|
||||
sed -e 's/ttyAMA0/ttyS0/' -i ./etc/inittab
|
||||
sss=$(date +%s)
|
||||
ddd=$((sss / 86400))
|
||||
sed -e "s/:0:0:99999:7:::/:${ddd}:0:99999:7:::/" -i ./etc/shadow
|
||||
# 修复amule每次升级后重复添加条目的问题
|
||||
sed -e "/amule:x:/d" -i ./etc/shadow
|
||||
# 修复dropbear每次升级后重复添加sshd条目的问题
|
||||
sed -e "/sshd:x:/d" -i ./etc/shadow
|
||||
if ! grep "sshd:x:22:sshd" ./etc/group >/dev/null; then
|
||||
echo "sshd:x:22:sshd" >>./etc/group
|
||||
fi
|
||||
if ! grep "sshd:x:22:22:sshd:" ./etc/passwd >/dev/null; then
|
||||
echo "sshd:x:22:22:sshd:/var/run/sshd:/bin/false" >>./etc/passwd
|
||||
fi
|
||||
if ! grep "sshd:x:" ./etc/shadow >/dev/null; then
|
||||
echo "sshd:x:${ddd}:0:99999:7:::" >>./etc/shadow
|
||||
fi
|
||||
|
||||
if [ $BR_FLAG -eq 1 ]; then
|
||||
if [ -x ./bin/bash ] && [ -f ./etc/profile.d/30-sysinfo.sh ]; then
|
||||
sed -e 's/\/bin\/ash/\/bin\/bash/' -i ./etc/passwd
|
||||
fi
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
fi
|
||||
sed -e "s/option hw_flow '1'/option hw_flow '0'/" -i ./etc/config/turboacc
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
sync
|
||||
|
||||
eval tar czf .reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
|
||||
rm -f ./etc/part_size ./etc/first_run.sh
|
||||
mv ./etc/rc.local ./etc/rc.local.orig
|
||||
cat >"./etc/rc.local" <<EOF
|
||||
if ! ls /etc/rc.d/S??dockerd >/dev/null 2>&1;then
|
||||
/etc/init.d/dockerd enable
|
||||
/etc/init.d/dockerd start
|
||||
fi
|
||||
if ! ls /etc/rc.d/S??dockerman >/dev/null 2>&1 && [ -f /etc/init.d/dockerman ];then
|
||||
/etc/init.d/dockerman enable
|
||||
/etc/init.d/dockerman start
|
||||
fi
|
||||
opkg remove --force-removal-of-dependent-packages shairport-sync-openssl
|
||||
mv /etc/rc.local.orig /etc/rc.local
|
||||
chmod 755 /etc/rc.local
|
||||
exec /etc/rc.local
|
||||
exit
|
||||
EOF
|
||||
chmod 755 ./etc/rc.local*
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
|
||||
echo "create the second etc snapshot -> .snapshots/etc-001"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-001
|
||||
|
||||
# 2021.04.01添加
|
||||
# 强制锁定fstab,防止用户擅自修改挂载点
|
||||
# 开启了快照功能之后,不再需要锁定fstab
|
||||
#chattr +ia ./etc/config/fstab
|
||||
|
||||
cd ${WORK_DIR}
|
||||
|
||||
echo "Start copy data from ${P1} to /boot ..."
|
||||
cd /boot
|
||||
echo -n "remove old boot files ..."
|
||||
rm -rf *
|
||||
echo "done"
|
||||
echo -n "copy new boot files ... "
|
||||
(cd ${P1} && tar cf - .) | tar xf -
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
echo -n "Update boot args ... "
|
||||
cat >uEnv.txt <<EOF
|
||||
LINUX=/zImage
|
||||
INITRD=/uInitrd
|
||||
|
||||
# Example:
|
||||
# FDT=/dtb/allwinner/sun50i-h6-vplus-cloud.dtb
|
||||
# FDT=/dtb/allwinner/sun50i-h6-vplus-cloud-2ghz.dtb
|
||||
FDT=/dtb/allwinner/${MYDTB_FDTFILE}
|
||||
|
||||
APPEND=root=UUID=${NEW_ROOT_UUID} rootfstype=btrfs rootflags=compress=zstd:${ZSTD_LEVEL} console=ttyS0,115200n8 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1
|
||||
EOF
|
||||
|
||||
# Compatible with armbianEnv.txt file
|
||||
[[ -f "armbianEnv.txt" ]] && {
|
||||
echo "Update armbianEnv.txt settings."
|
||||
sed -i "s|^rootdev=.*|rootdev=UUID=${NEW_ROOT_UUID}|g" armbianEnv.txt
|
||||
rm -f uEnv.txt
|
||||
}
|
||||
|
||||
# Replace the UUID for extlinux/extlinux.conf if it exists
|
||||
[[ -f "extlinux/extlinux.conf" ]] && {
|
||||
sed -i -E "s|UUID=[^ ]*|UUID=${NEW_ROOT_UUID}|" extlinux/extlinux.conf 2>/dev/null
|
||||
}
|
||||
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
cd $WORK_DIR
|
||||
umount -f ${P1} ${P2} 2>/dev/null
|
||||
losetup -D 2>/dev/null
|
||||
rmdir ${P1} ${P2} 2>/dev/null
|
||||
rm -f ${IMG_NAME} 2>/dev/null
|
||||
rm -f sha256sums 2>/dev/null
|
||||
sync
|
||||
|
||||
echo "Successfully updated, automatic restarting..."
|
||||
sleep 3
|
||||
reboot
|
||||
exit 0
|
||||
+859
@@ -0,0 +1,859 @@
|
||||
#!/bin/bash
|
||||
#======================================================================================
|
||||
# Function: Update openwrt to emmc for Amlogic S9xxx STB
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#======================================================================================
|
||||
#
|
||||
# The script supports directly setting parameters for update, skipping interactive selection
|
||||
# openwrt-update-amlogic ${OPENWRT_FILE} ${AUTO_MAINLINE_UBOOT} ${RESTORE_CONFIG}
|
||||
# E.g: openwrt-update-amlogic openwrt_s905d.img.gz yes restore
|
||||
# E.g: openwrt-update-amlogic openwrt_s905d.img.gz no no-restore
|
||||
|
||||
# You can also execute the script directly, and interactively select related functions
|
||||
# E.g: openwrt-update-amlogic
|
||||
#
|
||||
#======================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the /boot file system
|
||||
get_boot_partition_name() {
|
||||
local paths="/boot"
|
||||
local partition_name
|
||||
|
||||
partition_name=$(df "${paths}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition message of the root file system
|
||||
get_root_partition_msg() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_msg=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ "^" "'"${path}"'" "$" {print $0}')
|
||||
[[ -n "${partition_msg}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_msg}" ]] && error_msg "Cannot find the root partition message!"
|
||||
echo "${partition_msg}"
|
||||
}
|
||||
|
||||
# Receive one-key command related parameters
|
||||
IMG_NAME="${1}"
|
||||
AUTO_MAINLINE_UBOOT="${2}"
|
||||
BACKUP_RESTORE_CONFIG="${3}"
|
||||
|
||||
# Current device model
|
||||
MYDEVICE_NAME=$(cat /proc/device-tree/model | tr -d '\000')
|
||||
if [[ -z "${MYDEVICE_NAME}" ]]; then
|
||||
error_msg "The device name is empty and cannot be recognized."
|
||||
elif [[ ! -f "/etc/flippy-openwrt-release" ]]; then
|
||||
error_msg "The [ /etc/flippy-openwrt-release ] file is missing."
|
||||
else
|
||||
echo -e "Current device: ${MYDEVICE_NAME} [ amlogic ]"
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Check and repair partition mount points
|
||||
[[ -z "$(get_boot_partition_name)" || -z "$(get_root_partition_name)" ]] && {
|
||||
echo -e "Partition mount point error, start repairing..."
|
||||
openwrt-backup -g
|
||||
}
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
if lsblk -l -o NAME | grep "${EMMC_NAME}boot0" >/dev/null; then
|
||||
ROOT_DISK_TYPE="EMMC"
|
||||
else
|
||||
ROOT_DISK_TYPE="SD"
|
||||
fi
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="${ROOT_DISK_TYPE}_"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
ROOT_DISK_TYPE="USB"
|
||||
PARTITION_NAME=""
|
||||
LB_PRE="${ROOT_DISK_TYPE}_"
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
DOCKER_ROOT="/mnt/${EMMC_NAME}${PARTITION_NAME}4/docker/"
|
||||
cd /mnt/${EMMC_NAME}${PARTITION_NAME}4/
|
||||
mv -f /tmp/upload/* . 2>/dev/null && sync
|
||||
|
||||
if [[ "${IMG_NAME}" == *.img ]]; then
|
||||
echo -e "Update using [ ${IMG_NAME} ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
echo -e "Update using [ ${IMG_NAME} ] ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img.xz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
xz_file=$(ls *.img.xz | head -n 1)
|
||||
echo -e "Update using [ ${xz_file} ] file. Please wait a moment ..."
|
||||
xz -d ${xz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.img.gz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.img.gz | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
gzip -df ${gz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.7z -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.7z | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
bsdtar -xmf ${gz_file} 2>/dev/null
|
||||
[ $? -eq 0 ] || 7z x ${gz_file} -aoa -y 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.zip -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
zip_file=$(ls *.zip | head -n 1)
|
||||
echo -e "Update using [ ${zip_file} ] file. Please wait a moment ..."
|
||||
unzip -o ${zip_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
else
|
||||
echo -e "Please upload or specify the update openwrt firmware file."
|
||||
echo -e "Upload method: system menu → Amlogic Service → Manually Upload Update"
|
||||
echo -e "Specify method: Place the openwrt firmware file in [ /mnt/${EMMC_NAME}${PARTITION_NAME}4/ ]"
|
||||
echo -e "The supported file suffixes are: *.img, *.img.xz, *.img.gz, *.7z, *.zip"
|
||||
echo -e "After upload the openwrt firmware file, run again."
|
||||
exit 1
|
||||
fi
|
||||
sync
|
||||
|
||||
# check file
|
||||
if [ ! -f "${IMG_NAME}" ]; then
|
||||
error_msg "No update file found."
|
||||
else
|
||||
echo "Start update from [ ${IMG_NAME} ]"
|
||||
fi
|
||||
|
||||
# Check the necessary dependencies
|
||||
DEPENDS="lsblk uuidgen grep awk btrfs mkfs.fat mkfs.btrfs md5sum fatlabel"
|
||||
echo "Check the necessary dependencies..."
|
||||
for dep in ${DEPENDS}; do
|
||||
WITCH=$(busybox which ${dep})
|
||||
if [ "${WITCH}" == "" ]; then
|
||||
error_msg "Dependent command: ${dep} does not exist, upgrade cannot be performed, only flash through U disk/TF card!"
|
||||
else
|
||||
echo "${dep} path: ${WITCH}"
|
||||
fi
|
||||
done
|
||||
echo "Check passed"
|
||||
|
||||
# find boot partition
|
||||
BOOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ /^\/boot$/ {print $0}')
|
||||
if [ "${BOOT_PART_MSG}" == "" ]; then
|
||||
error_msg "Boot The partition does not exist, so the update cannot be continued!"
|
||||
fi
|
||||
BOOT_NAME=$(echo ${BOOT_PART_MSG} | awk '{print $1}')
|
||||
BOOT_PATH=$(echo ${BOOT_PART_MSG} | awk '{print $2}')
|
||||
BOOT_UUID=$(echo ${BOOT_PART_MSG} | awk '{print $4}')
|
||||
|
||||
BR_FLAG=1
|
||||
echo -ne "Whether to backup and restore the current config files? y/n [y]\b\b"
|
||||
if [[ ${BACKUP_RESTORE_CONFIG} == "restore" ]]; then
|
||||
yn="y"
|
||||
elif [[ ${BACKUP_RESTORE_CONFIG} == "no-restore" ]]; then
|
||||
yn="n"
|
||||
else
|
||||
read yn
|
||||
fi
|
||||
case $yn in
|
||||
n* | N*)
|
||||
BR_FLAG=0
|
||||
;;
|
||||
esac
|
||||
|
||||
# find root partition
|
||||
ROOT_PART_MSG="$(get_root_partition_msg)"
|
||||
ROOT_NAME=$(echo ${ROOT_PART_MSG} | awk '{print $1}')
|
||||
ROOT_PATH=$(echo ${ROOT_PART_MSG} | awk '{print $2}')
|
||||
ROOT_UUID=$(echo ${ROOT_PART_MSG} | awk '{print $4}')
|
||||
|
||||
case ${ROOT_NAME} in
|
||||
${EMMC_NAME}${PARTITION_NAME}2)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}3"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS2"
|
||||
;;
|
||||
${EMMC_NAME}${PARTITION_NAME}3)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}2"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS1"
|
||||
;;
|
||||
*)
|
||||
error_msg "ROOTFS The partition location is incorrect, so the update cannot continue!"
|
||||
;;
|
||||
esac
|
||||
echo "NEW_ROOT_NAME: [ ${NEW_ROOT_NAME} ]"
|
||||
|
||||
# find new root partition
|
||||
NEW_ROOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | grep "${NEW_ROOT_NAME}" | awk '$3 ~ /^part$/ && $5 !~ /^\/$/ && $5 !~ /^\/boot$/ {print $0}')
|
||||
if [ "${NEW_ROOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The new ROOTFS partition does not exist, so the update cannot continue!"
|
||||
fi
|
||||
NEW_ROOT_NAME=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $1}')
|
||||
NEW_ROOT_PATH=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $2}')
|
||||
NEW_ROOT_UUID=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $4}')
|
||||
NEW_ROOT_MP=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $5}')
|
||||
echo "NEW_ROOT_MP: [ ${NEW_ROOT_MP} ]"
|
||||
|
||||
# backup old bootloader
|
||||
if [ ! -f /root/BackupOldBootloader.img ]; then
|
||||
echo "Backup bootloader -> [ BackupOldBootloader.img ] ... "
|
||||
dd if=/dev/${EMMC_NAME} of=/root/BackupOldBootloader.img bs=1M count=4 conv=fsync
|
||||
echo "Backup bootloader complete."
|
||||
echo
|
||||
fi
|
||||
|
||||
# losetup
|
||||
losetup -f -P ${IMG_NAME}
|
||||
if [ ${?} -eq 0 ]; then
|
||||
LOOP_DEV=$(losetup | grep "${IMG_NAME}" | awk '{print $1}')
|
||||
if [ "${LOOP_DEV}" == "" ]; then
|
||||
error_msg "loop device not found!"
|
||||
fi
|
||||
else
|
||||
error_msg "losetup [ ${IMG_FILE} ] failed!"
|
||||
fi
|
||||
|
||||
# fix loopdev issue in kernel 5.19
|
||||
function fix_loopdev() {
|
||||
local parentdev=${1##*/}
|
||||
if [ ! -d /sys/block/${parentdev} ]; then
|
||||
return
|
||||
fi
|
||||
subdevs=$(lsblk -l -o NAME | grep -E "^${parentdev}.+\$")
|
||||
for subdev in ${subdevs}; do
|
||||
if [ ! -d /sys/block/${parentdev}/${subdev} ]; then
|
||||
return
|
||||
elif [ -b /dev/${sub_dev} ]; then
|
||||
continue
|
||||
fi
|
||||
source /sys/block/${parentdev}/${subdev}/uevent
|
||||
mknod /dev/${subdev} b ${MAJOR} ${MINOR}
|
||||
unset MAJOR MINOR DEVNAME DEVTYPE DISKSEQ PARTN PARTNAME
|
||||
done
|
||||
}
|
||||
fix_loopdev ${LOOP_DEV}
|
||||
|
||||
WAIT=3
|
||||
echo "The loopdev is [ $LOOP_DEV ], wait [ ${WAIT} ] seconds. "
|
||||
while [[ "${WAIT}" -ge "1" ]]; do
|
||||
sleep 1
|
||||
WAIT=$((WAIT - 1))
|
||||
done
|
||||
|
||||
# umount loop devices (openwrt will auto mount some partition)
|
||||
MOUNTED_DEVS=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "${LOOP_DEV}" | awk '$3 !~ /^$/ {print $2}')
|
||||
for dev in ${MOUNTED_DEVS}; do
|
||||
while :; do
|
||||
echo "umount [ ${dev} ] ... "
|
||||
umount -f ${dev}
|
||||
sleep 1
|
||||
mnt=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "${dev}" | awk '$3 !~ /^$/ {print $2}')
|
||||
if [ "${mnt}" == "" ]; then
|
||||
break
|
||||
else
|
||||
echo "Retry ..."
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# mount src part
|
||||
WORK_DIR=${PWD}
|
||||
P1=${WORK_DIR}/boot
|
||||
P2=${WORK_DIR}/root
|
||||
mkdir -p $P1 $P2
|
||||
|
||||
echo "Mount [ ${LOOP_DEV}p1 ] -> [ ${P1} ] ... "
|
||||
mount -t vfat -o ro ${LOOP_DEV}p1 ${P1}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount p1 [ ${LOOP_DEV}p1 ] failed!"
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Mount [ ${LOOP_DEV}p2 ] -> [ ${P2} ] ... "
|
||||
ZSTD_LEVEL=6
|
||||
mount -t btrfs -o ro,compress=zstd:${ZSTD_LEVEL} ${LOOP_DEV}p2 ${P2}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount p2 [ ${LOOP_DEV}p2 ] failed!"
|
||||
umount -f ${P1}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prepare the dockerman config file
|
||||
if [ -f ${P2}/etc/init.d/dockerman ] && [ -f ${P2}/etc/config/dockerd ]; then
|
||||
|
||||
flg=0
|
||||
# get current docker data root
|
||||
data_root=$(uci get dockerd.globals.data_root 2>/dev/null)
|
||||
if [ "${data_root}" == "" ]; then
|
||||
flg=1
|
||||
# get current config from /etc/docker/daemon.json
|
||||
if [ -f "/etc/docker/daemon.json" ] && [ -x "/usr/bin/jq" ]; then
|
||||
data_root=$(jq -r '."data-root"' /etc/docker/daemon.json)
|
||||
|
||||
bip=$(jq -r '."bip"' /etc/docker/daemon.json)
|
||||
[ "${bip}" == "null" ] && bip="172.31.0.1/24"
|
||||
|
||||
log_level=$(jq -r '."log-level"' /etc/docker/daemon.json)
|
||||
[ "${log_level}" == "null" ] && log_level="warn"
|
||||
|
||||
_iptables=$(jq -r '."iptables"' /etc/docker/daemon.json)
|
||||
[ "${_iptables}" == "null" ] && _iptables="true"
|
||||
|
||||
registry_mirrors=$(jq -r '."registry-mirrors"[]' /etc/docker/daemon.json 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${data_root}" == "" ]; then
|
||||
data_root="/opt/docker/" # the default data root
|
||||
fi
|
||||
|
||||
if ! uci get dockerd.globals >/dev/null 2>&1; then
|
||||
uci set dockerd.globals='globals'
|
||||
uci commit
|
||||
fi
|
||||
|
||||
# delete alter config , use inner config
|
||||
if uci get dockerd.globals.alt_config_file >/dev/null 2>&1; then
|
||||
uci delete dockerd.globals.alt_config_file
|
||||
uci commit
|
||||
fi
|
||||
|
||||
if [ ${flg} -eq 1 ]; then
|
||||
uci set dockerd.globals.data_root=${data_root}
|
||||
[ "${bip}" != "" ] && uci set dockerd.globals.bip=${bip}
|
||||
[ "${log_level}" != "" ] && uci set dockerd.globals.log_level=${log_level}
|
||||
[ "${_iptables}" != "" ] && uci set dockerd.globals.iptables=${_iptables}
|
||||
if [ "${registry_mirrors}" != "" ]; then
|
||||
for reg in ${registry_mirrors}; do
|
||||
uci add_list dockerd.globals.registry_mirrors=${reg}
|
||||
done
|
||||
fi
|
||||
uci set dockerd.globals.auto_start='1'
|
||||
uci commit
|
||||
fi
|
||||
fi
|
||||
|
||||
#update version prompt
|
||||
source /boot/uEnv.txt 2>/dev/null
|
||||
CUR_FDTFILE=${FDT}
|
||||
echo -e "FDT Value [ ${CUR_FDTFILE} ]"
|
||||
cp /boot/uEnv.txt /tmp/uEnv.txt && sync
|
||||
|
||||
K510="1"
|
||||
[[ "$(hexdump -n 15 -x "${P1}/zImage" 2>/dev/null | head -n 1 | awk '{print $7}')" == "0108" ]] && K510="0"
|
||||
echo -e "K510 [ ${K510} ]"
|
||||
|
||||
# flippy-openwrt-release info
|
||||
UBOOT_OVERLOAD=""
|
||||
MAINLINE_UBOOT=""
|
||||
ANDROID_UBOOT=""
|
||||
env_openwrt_file=""
|
||||
|
||||
if [ -f "${P2}/etc/flippy-openwrt-release" ]; then
|
||||
env_openwrt_file="${P2}/etc/flippy-openwrt-release"
|
||||
elif [ -f "/etc/flippy-openwrt-release" ]; then
|
||||
env_openwrt_file="/etc/flippy-openwrt-release"
|
||||
else
|
||||
env_openwrt_file=""
|
||||
fi
|
||||
|
||||
if [ -n "${env_openwrt_file}" ]; then
|
||||
source "${env_openwrt_file}" 2>/dev/null
|
||||
# Update the parameters used
|
||||
UBOOT_OVERLOAD=${UBOOT_OVERLOAD}
|
||||
MAINLINE_UBOOT=${MAINLINE_UBOOT}
|
||||
ANDROID_UBOOT=${ANDROID_UBOOT}
|
||||
|
||||
# Unused parameters
|
||||
FDTFILE=${FDTFILE}
|
||||
U_BOOT_EXT=${U_BOOT_EXT}
|
||||
KERNEL_VERSION=${KERNEL_VERSION}
|
||||
SOC=${SOC}
|
||||
fi
|
||||
|
||||
#format NEW_ROOT
|
||||
echo "umount [ ${NEW_ROOT_MP} ]"
|
||||
umount -f "${NEW_ROOT_MP}"
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "Umount [ ${NEW_ROOT_MP} ] failed, Please restart and try again!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check and fix partition
|
||||
function check_and_fix_partition() {
|
||||
local target_dev_name=${1} # mmcblk2
|
||||
local target_pt_name=${2} # p2
|
||||
local target_pt_idx=${3} # 2
|
||||
local safe_pt_begin_mb=${4} # 800
|
||||
local safe_pt_begin_byte=$((${safe_pt_begin_mb} * 1024 * 1024))
|
||||
|
||||
local cur_pt_begin_sector=$(fdisk -l /dev/${target_dev_name} | grep ${target_dev_name}${target_pt_name} | awk '{printf $2}')
|
||||
local cur_pt_begin_mb=$((${cur_pt_begin_sector} * 512 / 1024 / 1024))
|
||||
|
||||
if [ ${cur_pt_begin_mb} -ge ${safe_pt_begin_mb} ]; then
|
||||
# check pass
|
||||
return
|
||||
fi
|
||||
|
||||
local cur_pt_end_sector=$(fdisk -l /dev/${target_dev_name} | grep ${target_dev_name}${target_pt_name} | awk '{printf $3}')
|
||||
local cur_pt_end_byte=$(((${cur_pt_end_sector} + 1) * 512 - 1))
|
||||
|
||||
echo "Unsafe partition found, repairing ... "
|
||||
parted /dev/${target_dev_name} rm ${target_pt_idx} ||
|
||||
(
|
||||
error_msg "rm partion ${target_pt_idx} failed"
|
||||
)
|
||||
parted /dev/${target_dev_name} mkpart primary btrfs "${safe_pt_begin_byte}b" "${cur_pt_end_byte}b" ||
|
||||
(
|
||||
error_msg "create new partion ${target_pt_idx} failed"
|
||||
)
|
||||
echo "Partition repaired"
|
||||
}
|
||||
|
||||
# check if need fix partition
|
||||
if [ "${NEW_ROOT_NAME}" == "mmcblk2p2" ]; then
|
||||
if [ "${MYDEVICE_NAME}" == "Phicomm N1" ] || [ "${MYDEVICE_NAME}" == "Octopus Planet" ]; then
|
||||
# 最新研究结果:
|
||||
# Phicomm N1当采用官方 "天天链" 固件底包时,
|
||||
# 796MB开始的 12 字节在每次重启后会被 bootloader 覆写,
|
||||
# 因此把安全位置设定在800MB之后
|
||||
# The latest research results:
|
||||
# When Phicomm N1 uses the official "tian tian lian" firmware bottom package,
|
||||
# the 12 bytes starting from 796MB will be overwritten by bootloader after each reboot,
|
||||
# so the safe location is set after 800MB
|
||||
SAFE_PT_BEGIN_MB=800
|
||||
check_and_fix_partition "${EMMC_NAME}" "p2" 2 ${SAFE_PT_BEGIN_MB}
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Format [ ${NEW_ROOT_PATH} ]"
|
||||
NEW_ROOT_UUID=$(uuidgen)
|
||||
mkfs.btrfs -f -U ${NEW_ROOT_UUID} -L ${NEW_ROOT_LABEL} -m single ${NEW_ROOT_PATH}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Format [ ${NEW_ROOT_PATH} ] failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Mount [ ${NEW_ROOT_PATH} ] -> [ ${NEW_ROOT_MP} ]"
|
||||
mount -t btrfs -o compress=zstd:${ZSTD_LEVEL} ${NEW_ROOT_PATH} ${NEW_ROOT_MP}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount [ ${NEW_ROOT_PATH} ] -> [ ${NEW_ROOT_MP} ] failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# begin copy rootfs
|
||||
cd ${NEW_ROOT_MP}
|
||||
echo "Start copying data, From [ ${P2} ] TO [ ${NEW_ROOT_MP} ] ..."
|
||||
ENTRYS=$(ls)
|
||||
for entry in ${ENTRYS}; do
|
||||
if [[ "${entry}" == "lost+found" ]]; then
|
||||
continue
|
||||
fi
|
||||
echo "Remove old [ ${entry} ] ... "
|
||||
rm -rf ${entry}
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
error_msg "failed."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Create folder ... "
|
||||
btrfs subvolume create etc
|
||||
mkdir -p .snapshots .reserved bin boot dev lib opt mnt overlay proc rom root run sbin sys tmp usr www
|
||||
ln -sf lib/ lib64
|
||||
ln -sf tmp/ var
|
||||
sync
|
||||
|
||||
COPY_SRC="root etc bin sbin lib opt usr www"
|
||||
echo "Copy data begin ... "
|
||||
for src in ${COPY_SRC}; do
|
||||
echo "Copy [ ${src} ] ... "
|
||||
(cd ${P2} && tar cf - ${src}) | tar xf -
|
||||
sync
|
||||
done
|
||||
|
||||
# if not backup, then force rewrite the etc/docker/daemon.json
|
||||
if [ "${BR_FLAG}" -eq 0 ]; then
|
||||
cat >./etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"bip": "172.31.0.1/24",
|
||||
"data-root": "${DOCKER_ROOT}",
|
||||
"log-level": "warn",
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "5"
|
||||
},
|
||||
"registry-mirrors": [
|
||||
"https://mirror.baidubce.com/",
|
||||
"https://hub-mirror.c.163.com"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >./etc/fstab <<EOF
|
||||
UUID=${NEW_ROOT_UUID} / btrfs compress=zstd:${ZSTD_LEVEL} 0 1
|
||||
LABEL=${LB_PRE}BOOT /boot vfat defaults 0 2
|
||||
#tmpfs /tmp tmpfs defaults,nosuid 0 0
|
||||
EOF
|
||||
|
||||
cat >./etc/config/fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${NEW_ROOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'btrfs'
|
||||
option options 'compress=zstd:${ZSTD_LEVEL}'
|
||||
|
||||
config mount
|
||||
option target '/boot'
|
||||
option label '${LB_PRE}BOOT'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'vfat'
|
||||
|
||||
EOF
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
sync
|
||||
|
||||
echo "Create initial etc snapshot -> .snapshots/etc-000"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-000
|
||||
sync
|
||||
|
||||
[ -d /mnt/${EMMC_NAME}${PARTITION_NAME}4/docker ] || mkdir -p /mnt/${EMMC_NAME}${PARTITION_NAME}4/docker
|
||||
rm -rf opt/docker && ln -sf /mnt/${EMMC_NAME}${PARTITION_NAME}4/docker/ opt/docker
|
||||
|
||||
if [ -f /mnt/${NEW_ROOT_NAME}/etc/config/AdGuardHome ]; then
|
||||
[ -d /mnt/${EMMC_NAME}${PARTITION_NAME}4/AdGuardHome/data ] || mkdir -p /mnt/${EMMC_NAME}${PARTITION_NAME}4/AdGuardHome/data
|
||||
if [ ! -L /usr/bin/AdGuardHome ]; then
|
||||
[ -d /usr/bin/AdGuardHome ] &&
|
||||
cp -a /usr/bin/AdGuardHome/* /mnt/${EMMC_NAME}${PARTITION_NAME}4/AdGuardHome/
|
||||
fi
|
||||
ln -sf /mnt/${EMMC_NAME}${PARTITION_NAME}4/AdGuardHome /mnt/${NEW_ROOT_NAME}/usr/bin/AdGuardHome
|
||||
fi
|
||||
|
||||
#rm -f /mnt/${NEW_ROOT_NAME}/usr/sbin/openwrt-install-amlogic
|
||||
#rm -f /mnt/${NEW_ROOT_NAME}/usr/sbin/openwrt-update-amlogic
|
||||
rm -f /mnt/${NEW_ROOT_NAME}/root/install-to-emmc.sh
|
||||
sync
|
||||
echo "Copy data complete ..."
|
||||
|
||||
BACKUP_LIST=$(${P2}/usr/sbin/openwrt-backup -p)
|
||||
if [[ "${BR_FLAG}" -eq "1" && -n "${BACKUP_LIST}" ]]; then
|
||||
echo -n "Start restoring configuration files ... "
|
||||
(
|
||||
cd /
|
||||
eval tar czf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
)
|
||||
tar xzf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz
|
||||
|
||||
[ -f ./etc/config/dockerman ] && sed -e "s/option wan_mode 'false'/option wan_mode 'true'/" -i ./etc/config/dockerman 2>/dev/null
|
||||
[ -f ./etc/config/dockerd ] && sed -e "s/option wan_mode '0'/option wan_mode '1'/" -i ./etc/config/dockerd 2>/dev/null
|
||||
[ -f ./etc/config/verysync ] && sed -e 's/config setting/config verysync/' -i ./etc/config/verysync 2>/dev/null
|
||||
|
||||
# Restore fstab
|
||||
cp -f .snapshots/etc-000/fstab ./etc/fstab
|
||||
cp -f .snapshots/etc-000/config/fstab ./etc/config/fstab
|
||||
# 还原 luci
|
||||
cp -f .snapshots/etc-000/config/luci ./etc/config/luci
|
||||
# 还原/etc/config/rpcd
|
||||
cp -f .snapshots/etc-000/config/rpcd ./etc/config/rpcd
|
||||
|
||||
sync
|
||||
echo "Restore configuration information complete."
|
||||
fi
|
||||
|
||||
echo "Modify the configuration file ... "
|
||||
rm -f "./etc/rc.local.orig" "./etc/first_run.sh" "./etc/part_size"
|
||||
rm -rf "./opt/docker" && ln -sf "/mnt/${EMMC_NAME}${PARTITION_NAME}4/docker" "./opt/docker"
|
||||
rm -f ./etc/bench.log
|
||||
cat >>./etc/crontabs/root <<EOF
|
||||
37 5 * * * /etc/coremark.sh
|
||||
EOF
|
||||
|
||||
sed -e 's/ttyAMA0/ttyAML0/' -i ./etc/inittab
|
||||
sed -e 's/ttyS0/tty0/' -i ./etc/inittab
|
||||
sss=$(date +%s)
|
||||
ddd=$((sss / 86400))
|
||||
sed -e "s/:0:0:99999:7:::/:${ddd}:0:99999:7:::/" -i ./etc/shadow
|
||||
# Fix the problem of repeatedly adding amule entries after each upgrade
|
||||
sed -e "/amule:x:/d" -i ./etc/shadow
|
||||
# Fix the problem of repeatedly adding sshd entries after each upgrade of dropbear
|
||||
sed -e "/sshd:x:/d" -i ./etc/shadow
|
||||
if ! grep "sshd:x:22:sshd" ./etc/group >/dev/null; then
|
||||
echo "sshd:x:22:sshd" >>./etc/group
|
||||
fi
|
||||
if ! grep "sshd:x:22:22:sshd:" ./etc/passwd >/dev/null; then
|
||||
echo "sshd:x:22:22:sshd:/var/run/sshd:/bin/false" >>./etc/passwd
|
||||
fi
|
||||
if ! grep "sshd:x:" ./etc/shadow >/dev/null; then
|
||||
echo "sshd:x:${ddd}:0:99999:7:::" >>./etc/shadow
|
||||
fi
|
||||
|
||||
if [ "${BR_FLAG}" -eq "1" ]; then
|
||||
if [ -x ./bin/bash ] && [ -f ./etc/profile.d/30-sysinfo.sh ]; then
|
||||
sed -e 's/\/bin\/ash/\/bin\/bash/' -i ./etc/passwd
|
||||
fi
|
||||
sync
|
||||
fi
|
||||
sed -e "s/option hw_flow '1'/option hw_flow '0'/" -i ./etc/config/turboacc
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
eval tar czf .reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
|
||||
rm -f ./etc/part_size ./etc/first_run.sh
|
||||
if [ -x ./usr/sbin/balethirq.pl ]; then
|
||||
if grep "balethirq.pl" "./etc/rc.local"; then
|
||||
echo "balance irq is enabled"
|
||||
else
|
||||
echo "enable balance irq"
|
||||
sed -e "/exit/i\/usr/sbin/balethirq.pl" -i ./etc/rc.local
|
||||
fi
|
||||
fi
|
||||
|
||||
mv ./etc/rc.local ./etc/rc.local.orig
|
||||
cat >"./etc/rc.local" <<EOF
|
||||
if ! ls /etc/rc.d/S??dockerd >/dev/null 2>&1;then
|
||||
/etc/init.d/dockerd enable
|
||||
/etc/init.d/dockerd start
|
||||
fi
|
||||
if ! ls /etc/rc.d/S??dockerman >/dev/null 2>&1 && [ -f /etc/init.d/dockerman ];then
|
||||
/etc/init.d/dockerman enable
|
||||
/etc/init.d/dockerman start
|
||||
fi
|
||||
mv /etc/rc.local.orig /etc/rc.local
|
||||
chmod 755 /etc/rc.local
|
||||
exec /etc/rc.local
|
||||
exit
|
||||
EOF
|
||||
chmod 755 ./etc/rc.local*
|
||||
|
||||
#Mainline U-BOOT detection
|
||||
FLASH_MAINLINE_UBOOT=0
|
||||
if [[ -n "${MAINLINE_UBOOT}" && -f "${P2}${MAINLINE_UBOOT}" ]]; then
|
||||
cat <<EOF
|
||||
----------------------------------------------------------------------------------
|
||||
Found an available mainline bootloader (Mainline u-boot), you can flash into EMMC.
|
||||
----------------------------------------------------------------------------------
|
||||
EOF
|
||||
while :; do
|
||||
if [[ "${AUTO_MAINLINE_UBOOT}" == "yes" ]]; then
|
||||
if [[ "${K510}" -eq "1" ]]; then
|
||||
yn="y"
|
||||
else
|
||||
yn="n"
|
||||
fi
|
||||
elif [[ "${AUTO_MAINLINE_UBOOT}" == "no" ]]; then
|
||||
yn="n"
|
||||
else
|
||||
read -p "Please choose whether to write the mainline bootloader to EMMC? y/n " yn
|
||||
fi
|
||||
|
||||
case ${yn} in
|
||||
y | Y)
|
||||
FLASH_MAINLINE_UBOOT=1
|
||||
break
|
||||
;;
|
||||
n | N)
|
||||
FLASH_MAINLINE_UBOOT=0
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${FLASH_MAINLINE_UBOOT}" -eq "1" ]]; then
|
||||
echo -e "Write Mainline bootloader: [ ${MAINLINE_UBOOT} ]"
|
||||
dd if=${P2}${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=1 count=444 conv=fsync
|
||||
dd if=${P2}${MAINLINE_UBOOT} of=/dev/${EMMC_NAME} bs=512 skip=1 seek=1 conv=fsync
|
||||
elif [[ -n "${ANDROID_UBOOT}" && -f "${P2}${ANDROID_UBOOT}" ]]; then
|
||||
echo -e "Write Android bootloader: [ ${ANDROID_UBOOT} ]"
|
||||
dd if=${P2}${ANDROID_UBOOT} of=/dev/${EMMC_NAME} bs=1 count=444 conv=fsync
|
||||
dd if=${P2}${ANDROID_UBOOT} of=/dev/${EMMC_NAME} bs=512 skip=1 seek=1 conv=fsync
|
||||
else
|
||||
echo "Did not change the original bootloader."
|
||||
fi
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
|
||||
echo "Create etc snapshot -> .snapshots/etc-001"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-001
|
||||
|
||||
cd ${WORK_DIR}
|
||||
|
||||
echo "Change the label of ${BOOT_PATH} ... "
|
||||
fatlabel ${BOOT_PATH} "${LB_PRE}BOOT"
|
||||
echo "Start copying data, from [ ${P1} ] to [ /boot ] ..."
|
||||
cd /boot
|
||||
echo "Delete the old boot file ..."
|
||||
rm -rf * && sync
|
||||
|
||||
echo "Copy the new boot file ... "
|
||||
(cd ${P1} && tar cf - .) | tar xf - 2>/dev/null
|
||||
sync
|
||||
|
||||
if [ -f ${P1}/uInitrd ]; then
|
||||
i=1
|
||||
max_try=10
|
||||
while [ "${i}" -le "${max_try}" ]; do
|
||||
uInitrd_original=$(md5sum ${P1}/uInitrd | awk '{print $1}')
|
||||
uInitrd_new=$(md5sum uInitrd | awk '{print $1}')
|
||||
if [ "${uInitrd_original}" = "${uInitrd_new}" ]; then
|
||||
break
|
||||
else
|
||||
rm -f uInitrd && sync
|
||||
cp -f ${P1}/uInitrd uInitrd 2>/dev/null && sync
|
||||
let i++
|
||||
continue
|
||||
fi
|
||||
done
|
||||
[ "${i}" -eq "10" ] && error_msg "uInitrd file copy failed."
|
||||
else
|
||||
echo "uInitrd file is missing."
|
||||
fi
|
||||
|
||||
if [ -f ${P1}/zImage ]; then
|
||||
i=1
|
||||
max_try=10
|
||||
while [ "${i}" -le "${max_try}" ]; do
|
||||
zImage_original=$(md5sum ${P1}/zImage | awk '{print $1}')
|
||||
zImage_new=$(md5sum zImage | awk '{print $1}')
|
||||
if [ "${zImage_original}" = "${zImage_new}" ]; then
|
||||
break
|
||||
else
|
||||
rm -f zImage && sync
|
||||
cp -f ${P1}/zImage zImage 2>/dev/null && sync
|
||||
let i++
|
||||
continue
|
||||
fi
|
||||
done
|
||||
[ "${i}" -eq "10" ] && error_msg "zImage file copy failed."
|
||||
else
|
||||
error_msg "zImage file is missing."
|
||||
fi
|
||||
|
||||
if [ ${ROOT_DISK_TYPE} == "EMMC" ]; then
|
||||
rm -f s905_autoscript* aml_autoscript*
|
||||
mv -f boot-emmc.ini boot.ini
|
||||
mv -f boot-emmc.cmd boot.cmd
|
||||
mv -f boot-emmc.scr boot.scr
|
||||
fi
|
||||
|
||||
if [ "${K510}" -eq "1" ]; then
|
||||
if [ -f "u-boot.ext" ]; then
|
||||
cp -vf u-boot.ext u-boot.emmc
|
||||
elif [ -f ${P1}/${UBOOT_OVERLOAD} ]; then
|
||||
cp -vf ${P1}/${UBOOT_OVERLOAD} ${UBOOT_OVERLOAD}
|
||||
cp -vf ${P1}/${UBOOT_OVERLOAD} u-boot.ext
|
||||
cp -vf ${P1}/${UBOOT_OVERLOAD} u-boot.emmc
|
||||
chmod +x u-boot*
|
||||
fi
|
||||
else
|
||||
rm -f u-boot.ext 2>/dev/null
|
||||
rm -f u-boot.emmc 2>/dev/null
|
||||
fi
|
||||
|
||||
sync
|
||||
|
||||
echo "Update boot parameters ... "
|
||||
if [ -f /tmp/uEnv.txt ]; then
|
||||
lines=$(wc -l </tmp/uEnv.txt)
|
||||
lines=$((lines - 1))
|
||||
head -n $lines /tmp/uEnv.txt >uEnv.txt
|
||||
cat >>uEnv.txt <<EOF
|
||||
APPEND=root=UUID=${NEW_ROOT_UUID} rootfstype=btrfs rootflags=compress=zstd:${ZSTD_LEVEL} console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1
|
||||
EOF
|
||||
else
|
||||
cat >uEnv.txt <<EOF
|
||||
LINUX=/zImage
|
||||
INITRD=/uInitrd
|
||||
FDT=${CUR_FDTFILE}
|
||||
APPEND=root=UUID=${NEW_ROOT_UUID} rootfstype=btrfs rootflags=compress=zstd:${ZSTD_LEVEL} console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1
|
||||
EOF
|
||||
fi
|
||||
sync
|
||||
|
||||
# Replace the UUID for extlinux/extlinux.conf if it exists
|
||||
[[ -f "extlinux/extlinux.conf" ]] && {
|
||||
sed -i -E "s|UUID=[^ ]*|UUID=${NEW_ROOT_UUID}|" extlinux/extlinux.conf 2>/dev/null
|
||||
}
|
||||
|
||||
cd $WORK_DIR
|
||||
umount -f ${P1} ${P2} 2>/dev/null
|
||||
losetup -D 2>/dev/null
|
||||
rm -rf ${P1} ${P2} 2>/dev/null
|
||||
rm -f ${IMG_NAME} 2>/dev/null
|
||||
rm -f sha256sums 2>/dev/null
|
||||
sync
|
||||
wait
|
||||
|
||||
echo "Successfully updated, automatic restarting..."
|
||||
sleep 3
|
||||
reboot
|
||||
exit 0
|
||||
+674
@@ -0,0 +1,674 @@
|
||||
#!/bin/bash
|
||||
#======================================================================================
|
||||
# Function: Update the QEMU AARCH64 KVM vitual machine openwrt firmware
|
||||
# Copyright (C) 2022-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2022-- https://github.com/ophub
|
||||
#======================================================================================
|
||||
#
|
||||
# The script supports directly setting parameters for update, skipping interactive selection
|
||||
# openwrt-update-amlogic ${OPENWRT_FILE} ${AUTO_MAINLINE_UBOOT} ${RESTORE_CONFIG} ${WORK_DIR}
|
||||
# E.g: openwrt-update-kvm openwrt_qemu-aarch64.img.gz no restore /mnt/vda4
|
||||
# E.g: openwrt-update-kvm openwrt_qemu-aarch64.img.gz no no-restore /mnt/data
|
||||
|
||||
# You can also execute the script directly, and interactively select related functions
|
||||
# E.g: openwrt-update-kvm
|
||||
#
|
||||
#======================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the /boot file system
|
||||
get_boot_partition_name() {
|
||||
local paths="/boot"
|
||||
local partition_name
|
||||
|
||||
partition_name=$(df "${paths}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition message of the root file system
|
||||
get_root_partition_msg() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_msg=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ "^" "'"${path}"'" "$" {print $0}')
|
||||
[[ -n "${partition_msg}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_msg}" ]] && error_msg "Cannot find the root partition message!"
|
||||
echo "${partition_msg}"
|
||||
}
|
||||
|
||||
# Receive one-key command related parameters
|
||||
IMG_NAME="${1}"
|
||||
AUTO_MAINLINE_UBOOT="${2}"
|
||||
BACKUP_RESTORE_CONFIG="${3}"
|
||||
WORK_DIR="${4}"
|
||||
|
||||
# Check the necessary dependencies
|
||||
DEPENDS="lsblk uuidgen grep awk btrfs mkfs.fat mkfs.btrfs md5sum fatlabel jq"
|
||||
echo "Check the necessary dependencies..."
|
||||
for dep in ${DEPENDS}; do
|
||||
WITCH=$(busybox which ${dep})
|
||||
if [ "${WITCH}" == "" ]; then
|
||||
error_msg "Dependent command: ${dep} does not exist, upgrade cannot be performed!"
|
||||
else
|
||||
echo "${dep} path: ${WITCH}"
|
||||
fi
|
||||
done
|
||||
echo "Check passed"
|
||||
|
||||
# Current device model
|
||||
source /etc/flippy-openwrt-release
|
||||
if [[ -z "${PLATFORM}" ]]; then
|
||||
error_msg "The platform is empty."
|
||||
elif [[ "${PLATFORM}" != "qemu-aarch64" ]]; then
|
||||
error_msg "The platform is missing, only support qemu-aarch64."
|
||||
else
|
||||
echo -e "Current platform: [ ${PLATFORM} ]"
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Check and repair partition mount points
|
||||
[[ -z "$(get_boot_partition_name)" || -z "$(get_root_partition_name)" ]] && {
|
||||
echo -e "Partition mount point error, start repairing..."
|
||||
openwrt-backup -g
|
||||
}
|
||||
|
||||
# Find the partition where root is located
|
||||
# vda2 or vda3
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports sd?? hd?? vd??
|
||||
case ${ROOT_PTNAME} in
|
||||
[hsv]d[a-z][1-4])
|
||||
DISK_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
PART_PRESTR=""
|
||||
LABEL_PRESTR=""
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
function get_docker_root {
|
||||
local data_root
|
||||
if [[ -f /etc/config/dockerd ]]; then
|
||||
data_root=$(uci get dockerd.globals.data_root)
|
||||
fi
|
||||
if [[ -z "${data_root}" ]] && [[ -f /etc/docker/daemon.json ]]; then
|
||||
data_root=$(jq -r '."data-root"' /etc/docker/daemon.json)
|
||||
fi
|
||||
echo "$data_root"
|
||||
}
|
||||
DOCKER_ROOT=$(get_docker_root)
|
||||
|
||||
if [[ -z "${WORK_DIR}" ]]; then
|
||||
WORK_DIR="/mnt/${DISK_NAME}${PART_PRESTR}4/"
|
||||
fi
|
||||
if [[ ! -d "${WORK_DIR}" ]]; then
|
||||
error_msg "the work directory is not exists. [ ${WORK_DIR} ]"
|
||||
fi
|
||||
|
||||
cd "${WORK_DIR}"
|
||||
if [[ -d "/tmp/upload" ]] && [[ -f "/tmp/upload/*img*" ]]; then
|
||||
mv -f /tmp/upload/*img* .
|
||||
if [[ $? -ne 0 ]]; then
|
||||
error_msg "move file failed."
|
||||
fi
|
||||
fi
|
||||
sync
|
||||
|
||||
if [[ "${IMG_NAME}" == *.img ]]; then
|
||||
echo -e "Update using [ ${IMG_NAME} ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
echo -e "Update using [ ${IMG_NAME} ] ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img.xz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
xz_file=$(ls *.img.xz | head -n 1)
|
||||
echo -e "Update using [ ${xz_file} ] file. Please wait a moment ..."
|
||||
xz -d ${xz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.img.gz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.img.gz | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
gzip -df ${gz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.7z -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.7z | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
bsdtar -xmf ${gz_file} 2>/dev/null
|
||||
[ $? -eq 0 ] || 7z x ${gz_file} -aoa -y 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.zip -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
zip_file=$(ls *.zip | head -n 1)
|
||||
echo -e "Update using [ ${zip_file} ] file. Please wait a moment ..."
|
||||
unzip -o ${zip_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
else
|
||||
echo -e "Please upload or specify the update openwrt firmware file."
|
||||
#echo -e "Upload method: system menu → Amlogic Service → Manually Upload Update"
|
||||
echo -e "Specify method: Place the openwrt firmware file in [ ${WORK_DIR} ]"
|
||||
echo -e "The supported file suffixes are: *.img, *.img.xz, *.img.gz, *.7z, *.zip"
|
||||
echo -e "After upload the openwrt firmware file, run again."
|
||||
exit 1
|
||||
fi
|
||||
sync
|
||||
|
||||
# check file
|
||||
if [ ! -f "${IMG_NAME}" ]; then
|
||||
error_msg "No update file found."
|
||||
else
|
||||
echo "Start update from [ ${IMG_NAME} ]"
|
||||
fi
|
||||
|
||||
# find efi partition
|
||||
EFI_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ /^\/boot\/efi$/ {print $0}')
|
||||
if [ "${EFI_PART_MSG}" == "" ]; then
|
||||
error_msg "The EFI partition does not exist, so the update cannot be continued!"
|
||||
fi
|
||||
EFI_NAME=$(echo $EFI_PART_MSG | awk '{print $1}')
|
||||
EFI_DEV=$(echo $EFI_PART_MSG | awk '{print $2}')
|
||||
EFI_UUID=$(echo $EFI_PART_MSG | awk '{print $4}')
|
||||
|
||||
BR_FLAG=1
|
||||
if [[ ${BACKUP_RESTORE_CONFIG} == "restore" ]]; then
|
||||
BR_FLAG=1
|
||||
elif [[ ${BACKUP_RESTORE_CONFIG} == "no-restore" ]]; then
|
||||
BR_FLAG=0
|
||||
else
|
||||
echo -ne "Whether to backup and restore the current config files? y/n [y]\b\b"
|
||||
read yn
|
||||
case $yn in
|
||||
n* | N*) BR_FLAG=0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# find root partition
|
||||
ROOT_PART_MSG="$(get_root_partition_msg)"
|
||||
ROOT_NAME=$(echo ${ROOT_PART_MSG} | awk '{print $1}')
|
||||
ROOT_DEV=$(echo ${ROOT_PART_MSG} | awk '{print $2}')
|
||||
ROOT_UUID=$(echo ${ROOT_PART_MSG} | awk '{print $4}')
|
||||
|
||||
case ${ROOT_NAME} in
|
||||
${DISK_NAME}${PART_PRESTR}2)
|
||||
NEW_ROOT_NAME="${DISK_NAME}${PART_PRESTR}3"
|
||||
NEW_ROOT_LABEL="${LABEL_PRESTR}ROOTFS2"
|
||||
;;
|
||||
${DISK_NAME}${PART_PRESTR}3)
|
||||
NEW_ROOT_NAME="${DISK_NAME}${PART_PRESTR}2"
|
||||
NEW_ROOT_LABEL="${LABEL_PRESTR}ROOTFS1"
|
||||
;;
|
||||
*)
|
||||
error_msg "ROOTFS The partition location is incorrect, so the update cannot continue!"
|
||||
;;
|
||||
esac
|
||||
echo "NEW_ROOT_NAME: [ ${NEW_ROOT_NAME} ]"
|
||||
|
||||
# find new root partition
|
||||
NEW_ROOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | grep "${NEW_ROOT_NAME}" | awk '$3 ~ /^part$/ && $5 !~ /^\/$/ && $5 !~ /^\/boot$/ {print $0}')
|
||||
if [ "${NEW_ROOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The new ROOTFS partition does not exist, so the update cannot continue!"
|
||||
fi
|
||||
NEW_ROOT_NAME=$(echo $NEW_ROOT_PART_MSG | awk '{print $1}')
|
||||
NEW_ROOT_DEV=$(echo $NEW_ROOT_PART_MSG | awk '{print $2}')
|
||||
NEW_ROOT_UUID=$(echo $NEW_ROOT_PART_MSG | awk '{print $4}')
|
||||
NEW_ROOT_MOUNTPOINT=$(echo $NEW_ROOT_PART_MSG | awk '{print $5}')
|
||||
echo "NEW_ROOT_MOUNTPOINT: [ ${NEW_ROOT_MOUNTPOINT} ]"
|
||||
|
||||
# losetup
|
||||
losetup -f -P $IMG_NAME
|
||||
if [ $? -eq 0 ]; then
|
||||
LOOP_DEV=$(losetup | grep "$IMG_NAME" | awk '{print $1}')
|
||||
if [ "$LOOP_DEV" == "" ]; then
|
||||
error_msg "loop device not found!"
|
||||
fi
|
||||
else
|
||||
error_msg "losetup [ $IMG_FILE ] failed!"
|
||||
fi
|
||||
|
||||
# fix loopdev issue in kernel 5.19
|
||||
function fix_loopdev() {
|
||||
local parentdev=${1##*/}
|
||||
if [ ! -d /sys/block/${parentdev} ]; then
|
||||
return
|
||||
fi
|
||||
subdevs=$(lsblk -l -o NAME | grep -E "^${parentdev}.+\$")
|
||||
for subdev in $subdevs; do
|
||||
if [ ! -d /sys/block/${parentdev}/${subdev} ]; then
|
||||
return
|
||||
elif [ -b /dev/${sub_dev} ]; then
|
||||
continue
|
||||
fi
|
||||
source /sys/block/${parentdev}/${subdev}/uevent
|
||||
mknod /dev/${subdev} b ${MAJOR} ${MINOR}
|
||||
unset MAJOR MINOR DEVNAME DEVTYPE DISKSEQ PARTN PARTNAME
|
||||
done
|
||||
}
|
||||
fix_loopdev ${LOOP_DEV}
|
||||
|
||||
WAIT=3
|
||||
echo "The loopdev is [ $LOOP_DEV ], wait [ ${WAIT} ] seconds. "
|
||||
while [ $WAIT -ge 1 ]; do
|
||||
sleep 1
|
||||
WAIT=$((WAIT - 1))
|
||||
done
|
||||
|
||||
# umount loop devices (openwrt will auto mount some partition)
|
||||
MOUNTED_DEVS=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "$LOOP_DEV" | awk '$3 !~ /^$/ {print $2}')
|
||||
for dev in $MOUNTED_DEVS; do
|
||||
while :; do
|
||||
echo "umount [ $dev ] ... "
|
||||
umount -f $dev
|
||||
sleep 1
|
||||
mnt=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "$dev" | awk '$3 !~ /^$/ {print $2}')
|
||||
if [ "$mnt" == "" ]; then
|
||||
break
|
||||
else
|
||||
echo "Retry ..."
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# mount src part
|
||||
P1=${WORK_DIR}/efi
|
||||
P2=${WORK_DIR}/root
|
||||
mkdir -p $P1 $P2
|
||||
|
||||
echo "Mount [ ${LOOP_DEV}p1 ] -> [ ${P1} ] ... "
|
||||
mount -t vfat -o ro ${LOOP_DEV}p1 ${P1}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount p1 [ ${LOOP_DEV}p1 ] failed!"
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Mount [ ${LOOP_DEV}p2 ] -> [ ${P2} ] ... "
|
||||
ZSTD_LEVEL="6"
|
||||
mount -t btrfs -o ro,compress=zstd:${ZSTD_LEVEL} ${LOOP_DEV}p2 ${P2}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount p2 [ ${LOOP_DEV}p2 ] failed!"
|
||||
umount -f ${P1}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prepare the dockerman config file
|
||||
if [ -f ${P2}/etc/init.d/dockerman ] && [ -f ${P2}/etc/config/dockerd ]; then
|
||||
|
||||
flg=0
|
||||
# get current docker data root
|
||||
data_root=$(uci get dockerd.globals.data_root 2>/dev/null)
|
||||
if [ "$data_root" == "" ]; then
|
||||
flg=1
|
||||
# get current config from /etc/docker/daemon.json
|
||||
if [ -f "/etc/docker/daemon.json" ] && [ -x "/usr/bin/jq" ]; then
|
||||
data_root=$(jq -r '."data-root"' /etc/docker/daemon.json)
|
||||
|
||||
bip=$(jq -r '."bip"' /etc/docker/daemon.json)
|
||||
[ "$bip" == "null" ] && bip="172.31.0.1/24"
|
||||
|
||||
log_level=$(jq -r '."log-level"' /etc/docker/daemon.json)
|
||||
[ "$log_level" == "null" ] && log_level="warn"
|
||||
|
||||
_iptables=$(jq -r '."iptables"' /etc/docker/daemon.json)
|
||||
[ "$_iptables" == "null" ] && _iptables="true"
|
||||
|
||||
registry_mirrors=$(jq -r '."registry-mirrors"[]' /etc/docker/daemon.json 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$data_root" == "" ]; then
|
||||
data_root="/opt/docker/" # the default data root
|
||||
fi
|
||||
|
||||
if ! uci get dockerd.globals >/dev/null 2>&1; then
|
||||
uci set dockerd.globals='globals'
|
||||
uci commit
|
||||
fi
|
||||
|
||||
# delete alter config , use inner config
|
||||
if uci get dockerd.globals.alt_config_file >/dev/null 2>&1; then
|
||||
uci delete dockerd.globals.alt_config_file
|
||||
uci commit
|
||||
fi
|
||||
|
||||
if [ $flg -eq 1 ]; then
|
||||
uci set dockerd.globals.data_root=$data_root
|
||||
[ "$bip" != "" ] && uci set dockerd.globals.bip=$bip
|
||||
[ "$log_level" != "" ] && uci set dockerd.globals.log_level=$log_level
|
||||
[ "$_iptables" != "" ] && uci set dockerd.globals.iptables=$_iptables
|
||||
if [ "$registry_mirrors" != "" ]; then
|
||||
for reg in $registry_mirrors; do
|
||||
uci add_list dockerd.globals.registry_mirrors=$reg
|
||||
done
|
||||
fi
|
||||
uci set dockerd.globals.auto_start='1'
|
||||
uci commit
|
||||
fi
|
||||
fi
|
||||
|
||||
#format NEW_ROOT
|
||||
echo "umount [ ${NEW_ROOT_MOUNTPOINT} ]"
|
||||
umount -f "${NEW_ROOT_MOUNTPOINT}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Umount [ ${NEW_ROOT_MOUNTPOINT} ] failed, Please restart and try again!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Format [ ${NEW_ROOT_DEV} ]"
|
||||
NEW_ROOT_UUID=$(uuidgen)
|
||||
mkfs.btrfs -f -U ${NEW_ROOT_UUID} -L ${NEW_ROOT_LABEL} ${NEW_ROOT_DEV}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Format [ ${NEW_ROOT_DEV} ] failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Mount [ ${NEW_ROOT_DEV} ] -> [ ${NEW_ROOT_MOUNTPOINT} ]"
|
||||
mount -t btrfs -o compress=zstd:${ZSTD_LEVEL} ${NEW_ROOT_DEV} ${NEW_ROOT_MOUNTPOINT}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mount [ ${NEW_ROOT_DEV} ] -> [ ${NEW_ROOT_MOUNTPOINT} ] failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# begin copy rootfs
|
||||
cd ${NEW_ROOT_MOUNTPOINT}
|
||||
echo "Start copying data, From [ ${P2} ] TO [ ${NEW_ROOT_MOUNTPOINT} ] ..."
|
||||
ENTRYS=$(ls)
|
||||
for entry in $ENTRYS; do
|
||||
if [ "$entry" == "lost+found" ]; then
|
||||
continue
|
||||
fi
|
||||
echo "Remove old [ $entry ] ... "
|
||||
rm -rf $entry
|
||||
if [ $? -ne 0 ]; then
|
||||
error_msg "failed."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Create folder ... "
|
||||
btrfs subvolume create etc
|
||||
mkdir -p .snapshots .reserved bin boot dev lib opt mnt overlay proc rom root run sbin sys tmp usr www
|
||||
ln -sf lib/ lib64
|
||||
ln -sf tmp/ var
|
||||
sync
|
||||
|
||||
COPY_SRC="boot root etc bin sbin lib opt usr www"
|
||||
echo "Copy data begin ... "
|
||||
for src in $COPY_SRC; do
|
||||
echo "Copy [ $src ] ... "
|
||||
(cd ${P2} && tar cf - $src) | tar xf -
|
||||
sync
|
||||
done
|
||||
|
||||
# if not backup, then force rewrite the etc/docker/daemon.json
|
||||
if [ "${BR_FLAG}" -eq 0 ]; then
|
||||
cat >./etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"bip": "172.31.0.1/24",
|
||||
"data-root": "${DOCKER_ROOT}",
|
||||
"log-level": "warn",
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "5"
|
||||
},
|
||||
"registry-mirrors": [
|
||||
"https://mirror.baidubce.com/",
|
||||
"https://hub-mirror.c.163.com"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >./etc/fstab <<EOF
|
||||
UUID=${NEW_ROOT_UUID} / btrfs compress=zstd:${ZSTD_LEVEL} 0 1
|
||||
LABEL=EFI /boot/efi vfat defaults 0 2
|
||||
#tmpfs /tmp tmpfs defaults,nosuid 0 0
|
||||
EOF
|
||||
|
||||
cat >./etc/config/fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${NEW_ROOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'btrfs'
|
||||
option options 'compress=zstd:${ZSTD_LEVEL}'
|
||||
|
||||
config mount
|
||||
option target '/boot/efi'
|
||||
option label 'EFI'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'vfat'
|
||||
|
||||
EOF
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
sync
|
||||
|
||||
echo "Create initial etc snapshot -> .snapshots/etc-000"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-000
|
||||
sync
|
||||
|
||||
[ -d /mnt/${DISK_NAME}${PART_PRESTR}4/docker ] || mkdir -p /mnt/${DISK_NAME}${PART_PRESTR}4/docker
|
||||
rm -rf opt/docker && ln -sf /mnt/${DISK_NAME}${PART_PRESTR}4/docker/ opt/docker
|
||||
|
||||
if [ -f /mnt/${NEW_ROOT_NAME}/etc/config/AdGuardHome ]; then
|
||||
[ -d /mnt/${DISK_NAME}${PART_PRESTR}4/AdGuardHome/data ] || mkdir -p /mnt/${DISK_NAME}${PART_PRESTR}4/AdGuardHome/data
|
||||
if [ ! -L /usr/bin/AdGuardHome ]; then
|
||||
[ -d /usr/bin/AdGuardHome ] &&
|
||||
cp -a /usr/bin/AdGuardHome/* /mnt/${DISK_NAME}${PART_PRESTR}4/AdGuardHome/
|
||||
fi
|
||||
ln -sf /mnt/${DISK_NAME}${PART_PRESTR}4/AdGuardHome /mnt/${NEW_ROOT_NAME}/usr/bin/AdGuardHome
|
||||
fi
|
||||
sync
|
||||
echo "Copy data complete ..."
|
||||
|
||||
BACKUP_LIST=$(${P2}/usr/sbin/openwrt-backup -p)
|
||||
if [[ "${BR_FLAG}" -eq "1" && -n "${BACKUP_LIST}" ]]; then
|
||||
echo -n "Start restoring configuration files ... "
|
||||
(
|
||||
cd /
|
||||
eval tar czf ${NEW_ROOT_MOUNTPOINT}/.reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
)
|
||||
tar xzf ${NEW_ROOT_MOUNTPOINT}/.reserved/openwrt_config.tar.gz
|
||||
|
||||
[ -f ./etc/config/dockerman ] && sed -e "s/option wan_mode 'false'/option wan_mode 'true'/" -i ./etc/config/dockerman 2>/dev/null
|
||||
[ -f ./etc/config/dockerd ] && sed -e "s/option wan_mode '0'/option wan_mode '1'/" -i ./etc/config/dockerd 2>/dev/null
|
||||
[ -f ./etc/config/verysync ] && sed -e 's/config setting/config verysync/' -i ./etc/config/verysync 2>/dev/null
|
||||
|
||||
# Restore fstab
|
||||
cp -f .snapshots/etc-000/fstab ./etc/fstab
|
||||
cp -f .snapshots/etc-000/config/fstab ./etc/config/fstab
|
||||
# 还原 luci
|
||||
cp -f .snapshots/etc-000/config/luci ./etc/config/luci
|
||||
# 还原/etc/config/rpcd
|
||||
cp -f .snapshots/etc-000/config/rpcd ./etc/config/rpcd
|
||||
|
||||
sync
|
||||
echo "Restore configuration information complete."
|
||||
fi
|
||||
|
||||
echo "Modify the configuration file ... "
|
||||
rm -f "./etc/rc.local.orig" "./etc/first_run.sh" "./etc/part_size"
|
||||
rm -rf "./opt/docker" && ln -sf "/mnt/${DISK_NAME}${PART_PRESTR}4/docker" "./opt/docker"
|
||||
rm -f ./etc/bench.log
|
||||
cat >>./etc/crontabs/root <<EOF
|
||||
37 5 * * * /etc/coremark.sh
|
||||
EOF
|
||||
|
||||
sss=$(date +%s)
|
||||
ddd=$((sss / 86400))
|
||||
sed -e "s/:0:0:99999:7:::/:${ddd}:0:99999:7:::/" -i ./etc/shadow
|
||||
# Fix the problem of repeatedly adding amule entries after each upgrade
|
||||
sed -e "/amule:x:/d" -i ./etc/shadow
|
||||
# Fix the problem of repeatedly adding sshd entries after each upgrade of dropbear
|
||||
sed -e "/sshd:x:/d" -i ./etc/shadow
|
||||
if ! grep "sshd:x:22:sshd" ./etc/group >/dev/null; then
|
||||
echo "sshd:x:22:sshd" >>./etc/group
|
||||
fi
|
||||
if ! grep "sshd:x:22:22:sshd:" ./etc/passwd >/dev/null; then
|
||||
echo "sshd:x:22:22:sshd:/var/run/sshd:/bin/false" >>./etc/passwd
|
||||
fi
|
||||
if ! grep "sshd:x:" ./etc/shadow >/dev/null; then
|
||||
echo "sshd:x:${ddd}:0:99999:7:::" >>./etc/shadow
|
||||
fi
|
||||
|
||||
if [ "${BR_FLAG}" -eq "1" ]; then
|
||||
if [ -x ./bin/bash ] && [ -f ./etc/profile.d/30-sysinfo.sh ]; then
|
||||
sed -e 's/\/bin\/ash/\/bin\/bash/' -i ./etc/passwd
|
||||
fi
|
||||
sync
|
||||
fi
|
||||
sed -e "s/option hw_flow '1'/option hw_flow '0'/" -i ./etc/config/turboacc
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
eval tar czf .reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
|
||||
rm -f ./etc/part_size ./etc/first_run.sh
|
||||
if [ -x ./usr/sbin/balethirq.pl ]; then
|
||||
if grep "balethirq.pl" "./etc/rc.local"; then
|
||||
echo "balance irq is enabled"
|
||||
else
|
||||
echo "enable balance irq"
|
||||
sed -e "/exit/i\/usr/sbin/balethirq.pl" -i ./etc/rc.local
|
||||
fi
|
||||
fi
|
||||
|
||||
mv ./etc/rc.local ./etc/rc.local.orig
|
||||
cat >"./etc/rc.local" <<EOF
|
||||
if ! ls /etc/rc.d/S??dockerd >/dev/null 2>&1;then
|
||||
/etc/init.d/dockerd enable
|
||||
/etc/init.d/dockerd start
|
||||
fi
|
||||
if ! ls /etc/rc.d/S??dockerman >/dev/null 2>&1 && [ -f /etc/init.d/dockerman ];then
|
||||
/etc/init.d/dockerman enable
|
||||
/etc/init.d/dockerman start
|
||||
fi
|
||||
mv /etc/rc.local.orig /etc/rc.local
|
||||
chmod 755 /etc/rc.local
|
||||
exec /etc/rc.local
|
||||
exit
|
||||
EOF
|
||||
chmod 755 ./etc/rc.local*
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
|
||||
echo "Create etc snapshot -> .snapshots/etc-001"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-001
|
||||
|
||||
cd ${WORK_DIR}
|
||||
|
||||
echo "Copy efi files ..."
|
||||
fatlabel ${EFI_DEV} "EFI"
|
||||
cd /boot/efi
|
||||
mv ./EFI/BOOT/grub.cfg /tmp/grub.cfg.prev
|
||||
rm -rf *
|
||||
cp -a ${P1}/* .
|
||||
# 如果想启动上一个版本的openwrt,可以把 /boot/efi/EFI/BOOT/grub.cfg.prev 复制成 /boot/efi/EFI/BOOT/grub.cfg
|
||||
mv /tmp/grub.cfg.prev ./EFI/BOOT/
|
||||
|
||||
echo "Modify efi configuration ... "
|
||||
cd /boot/efi/EFI/BOOT
|
||||
cat >grub.cfg <<EOF
|
||||
echo "search fs_uuid ${NEW_ROOT_UUID} ..."
|
||||
search.fs_uuid ${NEW_ROOT_UUID} root
|
||||
echo "root=\$root"
|
||||
echo "set prefix ... "
|
||||
set prefix=(\$root)'/boot/grub2'
|
||||
echo "prefix=\$prefix"
|
||||
source \${prefix}/grub.cfg
|
||||
EOF
|
||||
|
||||
echo "Modify boot configuration ... "
|
||||
cd ${NEW_ROOT_MOUNTPOINT}/boot/grub2
|
||||
cat >grub.cfg <<EOF
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod zstd
|
||||
insmod btrfs
|
||||
terminal_input console
|
||||
terminal_output console
|
||||
|
||||
set default="0"
|
||||
set timeout=3
|
||||
|
||||
menuentry "OpenWrt" {
|
||||
echo 'Loading linux kernel ...'
|
||||
linux /boot/vmlinuz root=UUID=${NEW_ROOT_UUID} rootfstype=btrfs rootflags=compress=zstd:${ZSTD_LEVEL} console=ttyAMA0,115200n8 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1
|
||||
echo 'Loading initial ramdisk ...'
|
||||
initrd /boot/initrd.img
|
||||
}
|
||||
EOF
|
||||
|
||||
sync
|
||||
|
||||
cd $WORK_DIR
|
||||
umount -f ${P1} ${P2} 2>/dev/null
|
||||
losetup -D 2>/dev/null
|
||||
rm -rf ${P1} ${P2} 2>/dev/null
|
||||
rm -f ${IMG_NAME} 2>/dev/null
|
||||
rm -f sha256sums 2>/dev/null
|
||||
sync
|
||||
wait
|
||||
|
||||
echo "Successfully updated, automatic restarting..."
|
||||
sleep 3
|
||||
reboot
|
||||
exit 0
|
||||
+916
@@ -0,0 +1,916 @@
|
||||
#!/bin/bash
|
||||
#======================================================================================
|
||||
# Function: Update openwrt to emmc for Rockchip STB
|
||||
# Copyright (C) 2020-- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021-- https://github.com/ophub/luci-app-amlogic
|
||||
#======================================================================================
|
||||
#
|
||||
# The script supports directly setting parameters for update, skipping interactive selection
|
||||
# openwrt-update-rockchip ${OPENWRT_FILE} ${AUTO_MAINLINE_UBOOT} ${RESTORE_CONFIG}
|
||||
# E.g: openwrt-update-rockchip openwrt_s905d.img.gz yes restore
|
||||
# E.g: openwrt-update-rockchip openwrt_s905d.img.gz no no-restore
|
||||
|
||||
# You can also execute the script directly, and interactively select related functions
|
||||
# E.g: openwrt-update-rockchip
|
||||
#
|
||||
#======================================================================================
|
||||
|
||||
# Encountered a serious error, abort the script execution
|
||||
error_msg() {
|
||||
echo -e "[ERROR] ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the /boot file system
|
||||
get_boot_partition_name() {
|
||||
local paths="/boot"
|
||||
local partition_name
|
||||
|
||||
partition_name=$(df "${paths}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Get the partition message of the root file system
|
||||
get_root_partition_msg() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_msg=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ "^" "'"${path}"'" "$" {print $0}')
|
||||
[[ -n "${partition_msg}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_msg}" ]] && error_msg "Cannot find the root partition message!"
|
||||
echo "${partition_msg}"
|
||||
}
|
||||
|
||||
# Receive one-key command related parameters
|
||||
IMG_NAME="${1}"
|
||||
AUTO_MAINLINE_UBOOT="${2}"
|
||||
BACKUP_RESTORE_CONFIG="${3}"
|
||||
|
||||
# Current device model
|
||||
if [ -f /boot/armbianEnv.txt ]; then
|
||||
source /boot/armbianEnv.txt 2>/dev/null
|
||||
CURRENT_FDTFILE=$(basename ${fdtfile})
|
||||
fi
|
||||
MYDEVICE_NAME=$(cat /proc/device-tree/model | tr -d '\000')
|
||||
case $MYDEVICE_NAME in
|
||||
"")
|
||||
error_msg "The device name is empty and cannot be recognized."
|
||||
;;
|
||||
|
||||
"Chainedbox L1 Pro")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3328-l1pro-1296mhz.dtb"
|
||||
fi
|
||||
SOC="l1pro"
|
||||
;;
|
||||
"BeikeYun")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3328-beikeyun-1296mhz.dtb"
|
||||
fi
|
||||
SOC="beikeyun"
|
||||
;;
|
||||
"ZCuble1 Max")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3399-zcube1-max.dtb"
|
||||
fi
|
||||
SOC="zcube1 max"
|
||||
;;
|
||||
"JP TVbox 3566")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3566-jp-tvbox.dtb"
|
||||
fi
|
||||
SOC="jp-tvbox"
|
||||
;;
|
||||
"Radxa CM3 RPI CM4 IO")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3566-radxa-cm3-rpi-cm4-io.dtb"
|
||||
fi
|
||||
SOC="radxa-cm3-rpi-cm4-io"
|
||||
;;
|
||||
"FastRhino R66S" | "Lunzn FastRhino R66S")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-fastrhino-r66s.dtb"
|
||||
fi
|
||||
SOC="r66s"
|
||||
;;
|
||||
"FastRhino R68S" | "Lunzn FastRhino R68S")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-fastrhino-r68s.dtb"
|
||||
fi
|
||||
SOC="r68s"
|
||||
;;
|
||||
"RK3568 EC-X")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-ec-x.dtb"
|
||||
fi
|
||||
SOC="ec-x"
|
||||
;;
|
||||
"HINLINK OPC-H66K Board" | "Hlink H66K")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-opc-h66k.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-hlink-h66k.dtb"
|
||||
fi
|
||||
SOC="h66k"
|
||||
;;
|
||||
"HINLINK OPC-H68K Board" | "Hlink H68K")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-opc-h68k.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-hlink-h68k.dtb"
|
||||
fi
|
||||
SOC="h68k"
|
||||
;;
|
||||
"HINLINK OPC-H69K Board" | "Hlink H69K")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-opc-h69k.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-hlink-h69k.dtb"
|
||||
fi
|
||||
SOC="h69k"
|
||||
;;
|
||||
"Radxa E25" | "Radxa E25 Carrier Board")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-radxa-e25.dtb"
|
||||
fi
|
||||
SOC="e25"
|
||||
;;
|
||||
"HINLINK OWL H88K-V3 Board" | "Hlink H88K-V3")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-hinlink-h88k-v3.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588-hlink-h88k-v3.dtb"
|
||||
fi
|
||||
SOC="h88k-v3"
|
||||
;;
|
||||
"Hlink H88K V3.1")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-hinlink-h88k-v31.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588-hlink-h88k-v31.dtb"
|
||||
fi
|
||||
SOC="h88k-v3"
|
||||
;;
|
||||
"HINLINK OWL H88K Board" | "Hlink H88K")
|
||||
if [ -n "${CURRENT_FDTFILE}" ] && [ "${CURRENT_FDTFILE}" != "rk3568-hinlink-h88k.dtb" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588-hlink-h88k.dtb"
|
||||
fi
|
||||
SOC="ak88/h88k"
|
||||
;;
|
||||
"Hlink H28K")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3528-hlink-h28k.dtb"
|
||||
fi
|
||||
SOC="h28k"
|
||||
;;
|
||||
"Hlink HT2")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3528-hlink-ht2.dtb"
|
||||
fi
|
||||
SOC="ht2"
|
||||
;;
|
||||
"Radxa E20C")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3528-radxa-e20c.dtb"
|
||||
fi
|
||||
SOC="e20c"
|
||||
;;
|
||||
"Radxa E24C")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3528-radxa-e24c.dtb"
|
||||
fi
|
||||
SOC="e24c"
|
||||
;;
|
||||
"YiXun Rs6Pro")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3528-yixun-rs6pro.dtb"
|
||||
fi
|
||||
SOC="rs6pro"
|
||||
;;
|
||||
"Ariaboard Photonicat")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-photonicat.dtb"
|
||||
fi
|
||||
SOC="photonicat"
|
||||
;;
|
||||
"NLnet Watermelon Pi V3")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-watermelon-pi-v3.dtb"
|
||||
fi
|
||||
SOC="watermelon-pi-v3"
|
||||
;;
|
||||
"NLnet Watermelon Pi")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3568-watermelon-pi.dtb"
|
||||
fi
|
||||
SOC="watermelon-pi"
|
||||
;;
|
||||
"Rockchip RK3576 DshanPi A1 Board")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3576-100ask-dshanpi-a1.dtb"
|
||||
fi
|
||||
SOC="100ask-dshanpi-a1"
|
||||
;;
|
||||
"Radxa ROCK 5B" | "Radxa ROCK 5 Model B")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588-rock-5b.dtb"
|
||||
fi
|
||||
SOC="rock5b"
|
||||
;;
|
||||
"Radxa ROCK 5C" | "Radxa ROCK 5 Model C")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588s-rock-5c.dtb"
|
||||
fi
|
||||
SOC="rock5c"
|
||||
;;
|
||||
"Radxa E52C")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588s-radxa-e52c.dtb"
|
||||
fi
|
||||
SOC="e52c"
|
||||
;;
|
||||
"Radxa E54C")
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588s-radxa-e54c.dtb"
|
||||
fi
|
||||
SOC="e54c"
|
||||
;;
|
||||
*) #default
|
||||
if [ -f "/etc/flippy-openwrt-release" ]; then
|
||||
source /etc/flippy-openwrt-release 2>/dev/null
|
||||
if [ -n "${CURRENT_FDTFILE}" ]; then
|
||||
MYDTB_FDTFILE="${CURRENT_FDTFILE}"
|
||||
else
|
||||
MYDTB_FDTFILE="${FDTFILE}"
|
||||
fi
|
||||
SOC="${SOC}"
|
||||
else
|
||||
error_msg "Unknown device: [ ${MYDEVICE_NAME} ], Not supported."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
[[ -z "${MYDTB_FDTFILE}" || -z "${SOC}" ]] && {
|
||||
error_msg "Invalid FDTFILE or SOC: [ ${MYDTB_FDTFILE} / ${SOC} ]"
|
||||
}
|
||||
|
||||
echo -e "Current device: ${MYDEVICE_NAME} [ ${SOC} ]"
|
||||
sleep 3
|
||||
|
||||
# Check and repair partition mount points
|
||||
[[ -z "$(get_boot_partition_name)" || -z "$(get_root_partition_name)" ]] && {
|
||||
echo -e "Partition mount point error, start repairing..."
|
||||
openwrt-backup -g
|
||||
}
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="EMMC_"
|
||||
;;
|
||||
nvme?n?p?)
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="NVME_"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
PARTITION_NAME=""
|
||||
LB_PRE="USB_"
|
||||
;;
|
||||
*)
|
||||
error_msg "Unable to recognize the disk type of ${ROOT_PTNAME}!"
|
||||
;;
|
||||
esac
|
||||
|
||||
cd /mnt/${EMMC_NAME}${PARTITION_NAME}4/
|
||||
mv -f /tmp/upload/* . 2>/dev/null && sync
|
||||
|
||||
if [[ "${IMG_NAME}" == *.img ]]; then
|
||||
echo -e "Update using [ ${IMG_NAME} ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
echo -e "Update using [ ${IMG_NAME} ] ] file. Please wait a moment ..."
|
||||
elif [ $(ls *.img.xz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
xz_file=$(ls *.img.xz | head -n 1)
|
||||
echo -e "Update using [ ${xz_file} ] file. Please wait a moment ..."
|
||||
xz -d ${xz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.img.gz -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.img.gz | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
gzip -df ${gz_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.7z -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
gz_file=$(ls *.7z | head -n 1)
|
||||
echo -e "Update using [ ${gz_file} ] file. Please wait a moment ..."
|
||||
bsdtar -xmf ${gz_file} 2>/dev/null
|
||||
[ $? -eq 0 ] || 7z x ${gz_file} -aoa -y 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
elif [ $(ls *.zip -l 2>/dev/null | grep "^-" | wc -l) -ge 1 ]; then
|
||||
zip_file=$(ls *.zip | head -n 1)
|
||||
echo -e "Update using [ ${zip_file} ] file. Please wait a moment ..."
|
||||
unzip -o ${zip_file} 2>/dev/null
|
||||
IMG_NAME=$(ls *.img | head -n 1)
|
||||
else
|
||||
echo -e "Please upload or specify the update openwrt firmware file."
|
||||
echo -e "Upload method: system menu → Amlogic Service → Manually Upload Update"
|
||||
echo -e "Specify method: Place the openwrt firmware file in [ /mnt/${EMMC_NAME}${PARTITION_NAME}4/ ]"
|
||||
echo -e "The supported file suffixes are: *.img, *.img.xz, *.img.gz, *.7z, *.zip"
|
||||
echo -e "After upload the openwrt firmware file, run again."
|
||||
exit 1
|
||||
fi
|
||||
sync
|
||||
|
||||
# check file
|
||||
if [ ! -f "${IMG_NAME}" ]; then
|
||||
error_msg "No update file found."
|
||||
else
|
||||
echo "Start update from [ ${IMG_NAME} ]"
|
||||
fi
|
||||
|
||||
# find boot partition
|
||||
BOOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | awk '$3~/^part$/ && $5 ~ /^\/boot$/ {print $0}')
|
||||
if [ "${BOOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The boot partition is not exists or not mounted, so it cannot be upgraded with this script!"
|
||||
fi
|
||||
|
||||
BR_FLAG=1
|
||||
echo -ne "Whether to backup and restore the current config files? y/n [y]\b\b"
|
||||
if [[ ${BACKUP_RESTORE_CONFIG} == "restore" ]]; then
|
||||
yn="y"
|
||||
elif [[ ${BACKUP_RESTORE_CONFIG} == "no-restore" ]]; then
|
||||
yn="n"
|
||||
else
|
||||
read yn
|
||||
fi
|
||||
case ${yn} in
|
||||
n* | N*)
|
||||
BR_FLAG=0
|
||||
;;
|
||||
esac
|
||||
|
||||
BOOT_NAME=$(echo ${BOOT_PART_MSG} | awk '{print $1}')
|
||||
BOOT_PATH=$(echo ${BOOT_PART_MSG} | awk '{print $2}')
|
||||
BOOT_UUID=$(echo ${BOOT_PART_MSG} | awk '{print $4}')
|
||||
|
||||
# find root partition
|
||||
ROOT_PART_MSG="$(get_root_partition_msg)"
|
||||
ROOT_NAME=$(echo ${ROOT_PART_MSG} | awk '{print $1}')
|
||||
ROOT_PATH=$(echo ${ROOT_PART_MSG} | awk '{print $2}')
|
||||
ROOT_UUID=$(echo ${ROOT_PART_MSG} | awk '{print $4}')
|
||||
case ${ROOT_NAME} in
|
||||
${EMMC_NAME}${PARTITION_NAME}2)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}3"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS2"
|
||||
;;
|
||||
${EMMC_NAME}${PARTITION_NAME}3)
|
||||
NEW_ROOT_NAME="${EMMC_NAME}${PARTITION_NAME}2"
|
||||
NEW_ROOT_LABEL="${LB_PRE}ROOTFS1"
|
||||
;;
|
||||
*)
|
||||
error_msg "The root partition location is invalid, so it cannot be upgraded with this script!"
|
||||
;;
|
||||
esac
|
||||
|
||||
# find new root partition
|
||||
NEW_ROOT_PART_MSG=$(lsblk -l -o NAME,PATH,TYPE,UUID,MOUNTPOINT | grep "${NEW_ROOT_NAME}" | awk '$3 ~ /^part$/ && $5 !~ /^\/$/ && $5 !~ /^\/boot$/ {print $0}')
|
||||
if [ "${NEW_ROOT_PART_MSG}" == "" ]; then
|
||||
error_msg "The new root partition is not exists, so it cannot be upgraded with this script!"
|
||||
fi
|
||||
NEW_ROOT_NAME=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $1}')
|
||||
NEW_ROOT_PATH=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $2}')
|
||||
NEW_ROOT_UUID=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $4}')
|
||||
NEW_ROOT_MP=$(echo ${NEW_ROOT_PART_MSG} | awk '{print $5}')
|
||||
|
||||
# losetup
|
||||
losetup -f -P ${IMG_NAME}
|
||||
if [[ "${?}" -eq "0" ]]; then
|
||||
LOOP_DEV=$(losetup | grep "${IMG_NAME}" | awk '{print $1}')
|
||||
if [ "$LOOP_DEV" == "" ]; then
|
||||
error_msg "loop device not found!"
|
||||
fi
|
||||
else
|
||||
error_msg "losetup ${IMG_FILE} failed!"
|
||||
fi
|
||||
|
||||
# fix loopdev issue in kernel 5.19
|
||||
function fix_loopdev() {
|
||||
local parentdev=${1##*/}
|
||||
if [ ! -d /sys/block/${parentdev} ]; then
|
||||
return
|
||||
fi
|
||||
subdevs=$(lsblk -l -o NAME | grep -E "^${parentdev}.+\$")
|
||||
for subdev in ${subdevs}; do
|
||||
if [ ! -d /sys/block/${parentdev}/${subdev} ]; then
|
||||
return
|
||||
elif [ -b /dev/${sub_dev} ]; then
|
||||
continue
|
||||
fi
|
||||
source /sys/block/${parentdev}/${subdev}/uevent
|
||||
mknod /dev/${subdev} b ${MAJOR} ${MINOR}
|
||||
unset MAJOR MINOR DEVNAME DEVTYPE DISKSEQ PARTN PARTNAME
|
||||
done
|
||||
}
|
||||
fix_loopdev ${LOOP_DEV}
|
||||
|
||||
WAIT=3
|
||||
echo -n "The loopdev is ${LOOP_DEV}, wait ${WAIT} seconds "
|
||||
while [ ${WAIT} -ge 1 ]; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
WAIT=$((WAIT - 1))
|
||||
done
|
||||
echo
|
||||
|
||||
# umount loop devices (openwrt will auto mount some partition)
|
||||
MOUNTED_DEVS=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "${LOOP_DEV}" | awk '$3 !~ /^$/ {print $2}')
|
||||
for dev in ${MOUNTED_DEVS}; do
|
||||
while :; do
|
||||
echo -n "umount ${dev} ... "
|
||||
umount -f ${dev}
|
||||
sleep 1
|
||||
mnt=$(lsblk -l -o NAME,PATH,MOUNTPOINT | grep "${dev}" | awk '$3 !~ /^$/ {print $2}')
|
||||
if [ "${mnt}" == "" ]; then
|
||||
echo "ok"
|
||||
break
|
||||
else
|
||||
echo "try again ..."
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# mount src part
|
||||
WORK_DIR=${PWD}
|
||||
P1=${WORK_DIR}/boot
|
||||
P2=${WORK_DIR}/root
|
||||
mkdir -p $P1 $P2
|
||||
echo -n "mount ${LOOP_DEV}p1 -> ${P1} ... "
|
||||
mount -t ext4 -o ro ${LOOP_DEV}p1 ${P1}
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "mount failed"
|
||||
losetup -D
|
||||
exit 1
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
echo -n "mount ${LOOP_DEV}p2 -> ${P2} ... "
|
||||
ZSTD_LEVEL=6
|
||||
mount -t btrfs -o ro,compress=zstd:${ZSTD_LEVEL} ${LOOP_DEV}p2 ${P2}
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "mount failed"
|
||||
umount -f ${P1}
|
||||
losetup -D
|
||||
exit 1
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
# Prepare the dockerman config file
|
||||
if [ -f ${P2}/etc/init.d/dockerman ] && [ -f ${P2}/etc/config/dockerd ]; then
|
||||
|
||||
flg=0
|
||||
# get current docker data root
|
||||
data_root=$(uci get dockerd.globals.data_root 2>/dev/null)
|
||||
if [ "${data_root}" == "" ]; then
|
||||
flg=1
|
||||
# get current config from /etc/docker/daemon.json
|
||||
if [ -f "/etc/docker/daemon.json" ] && [ -x "/usr/bin/jq" ]; then
|
||||
data_root=$(jq -r '."data-root"' /etc/docker/daemon.json)
|
||||
|
||||
bip=$(jq -r '."bip"' /etc/docker/daemon.json)
|
||||
[ "${bip}" == "null" ] && bip="172.31.0.1/24"
|
||||
|
||||
log_level=$(jq -r '."log-level"' /etc/docker/daemon.json)
|
||||
[ "${log_level}" == "null" ] && log_level="warn"
|
||||
|
||||
_iptables=$(jq -r '."iptables"' /etc/docker/daemon.json)
|
||||
[ "${_iptables}" == "null" ] && _iptables="true"
|
||||
|
||||
registry_mirrors=$(jq -r '."registry-mirrors"[]' /etc/docker/daemon.json 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${data_root}" == "" ]; then
|
||||
data_root="/opt/docker/" # the default data root
|
||||
fi
|
||||
|
||||
if ! uci get dockerd.globals >/dev/null 2>&1; then
|
||||
uci set dockerd.globals='globals'
|
||||
uci commit
|
||||
fi
|
||||
|
||||
# delete alter config , use inner config
|
||||
if uci get dockerd.globals.alt_config_file >/dev/null 2>&1; then
|
||||
uci delete dockerd.globals.alt_config_file
|
||||
uci commit
|
||||
fi
|
||||
|
||||
if [[ "${flg}" -eq "1" ]]; then
|
||||
uci set dockerd.globals.data_root=${data_root}
|
||||
[ "${bip}" != "" ] && uci set dockerd.globals.bip=${bip}
|
||||
[ "${log_level}" != "" ] && uci set dockerd.globals.log_level=${log_level}
|
||||
[ "${_iptables}" != "" ] && uci set dockerd.globals.iptables=${_iptables}
|
||||
if [ "${registry_mirrors}" != "" ]; then
|
||||
for reg in ${registry_mirrors}; do
|
||||
uci add_list dockerd.globals.registry_mirrors=${reg}
|
||||
done
|
||||
fi
|
||||
uci set dockerd.globals.auto_start='1'
|
||||
uci commit
|
||||
fi
|
||||
fi
|
||||
|
||||
#format NEW_ROOT
|
||||
echo "umount ${NEW_ROOT_MP}"
|
||||
umount -f "${NEW_ROOT_MP}"
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "umount failed, please reboot and try again!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "format ${NEW_ROOT_PATH}"
|
||||
NEW_ROOT_UUID=$(uuidgen)
|
||||
mkfs.btrfs -f -U ${NEW_ROOT_UUID} -L ${NEW_ROOT_LABEL} -m single ${NEW_ROOT_PATH}
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "format ${NEW_ROOT_PATH} failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "mount ${NEW_ROOT_PATH} to ${NEW_ROOT_MP}"
|
||||
mount -t btrfs -o compress=zstd:${ZSTD_LEVEL} ${NEW_ROOT_PATH} ${NEW_ROOT_MP}
|
||||
if [[ "${?}" -ne "0" ]]; then
|
||||
echo "mount ${NEW_ROOT_PATH} to ${NEW_ROOT_MP} failed!"
|
||||
umount -f ${P1}
|
||||
umount -f ${P2}
|
||||
losetup -D
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# begin copy rootfs
|
||||
cd ${NEW_ROOT_MP}
|
||||
echo "Start copy data from ${P2} to ${NEW_ROOT_MP} ..."
|
||||
ENTRYS=$(ls)
|
||||
for entry in ${ENTRYS}; do
|
||||
if [ "${entry}" == "lost+found" ]; then
|
||||
continue
|
||||
fi
|
||||
echo -n "remove old ${entry} ... "
|
||||
rm -rf ${entry}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok"
|
||||
else
|
||||
echo "failed"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo "create etc subvolume ..."
|
||||
btrfs subvolume create etc
|
||||
echo -n "make dirs ... "
|
||||
mkdir -p .snapshots .reserved bin boot dev lib opt mnt overlay proc rom root run sbin sys tmp usr www
|
||||
ln -sf lib/ lib64
|
||||
ln -sf tmp/ var
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
COPY_SRC="root etc bin sbin lib opt usr www"
|
||||
echo "copy data ... "
|
||||
for src in ${COPY_SRC}; do
|
||||
echo -n "copy ${src} ... "
|
||||
(cd ${P2} && tar cf - ${src}) | tar xf -
|
||||
sync
|
||||
echo "done"
|
||||
done
|
||||
|
||||
SHFS="/mnt/${EMMC_NAME}${PARTITION_NAME}4"
|
||||
echo "Modify config files ... "
|
||||
if [ -x ./usr/sbin/balethirq.pl ]; then
|
||||
if grep "balethirq.pl" "./etc/rc.local"; then
|
||||
echo "balance irq is enabled"
|
||||
else
|
||||
echo "enable balance irq"
|
||||
sed -e "/exit/i\/usr/sbin/balethirq.pl" -i ./etc/rc.local
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f ./etc/bench.log
|
||||
cat >./etc/fstab <<EOF
|
||||
UUID=${NEW_ROOT_UUID} / btrfs compress=zstd:${ZSTD_LEVEL} 0 1
|
||||
UUID=${BOOT_UUID} /boot ext4 defaults 0 2
|
||||
#tmpfs /tmp tmpfs defaults,nosuid 0 0
|
||||
EOF
|
||||
|
||||
cat >./etc/config/fstab <<EOF
|
||||
config global
|
||||
option anon_swap '0'
|
||||
option anon_mount '1'
|
||||
option auto_swap '0'
|
||||
option auto_mount '1'
|
||||
option delay_root '5'
|
||||
option check_fs '0'
|
||||
|
||||
config mount
|
||||
option target '/rom'
|
||||
option uuid '${NEW_ROOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '1'
|
||||
option fstype 'btrfs'
|
||||
option options 'compress=zstd:${ZSTD_LEVEL}'
|
||||
|
||||
config mount
|
||||
option target '/boot'
|
||||
option uuid '${BOOT_UUID}'
|
||||
option enabled '1'
|
||||
option enabled_fsck '0'
|
||||
option fstype 'ext4'
|
||||
|
||||
EOF
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
sync
|
||||
|
||||
echo "create the first etc snapshot -> .snapshots/etc-000"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-000
|
||||
|
||||
[ -d ${SHFS}/docker ] || mkdir -p ${SHFS}/docker
|
||||
rm -rf opt/docker && ln -sf ${SHFS}/docker/ opt/docker
|
||||
|
||||
if [ -f /mnt/${NEW_ROOT_NAME}/etc/config/AdGuardHome ]; then
|
||||
[ -d ${SHFS}/AdGuardHome/data ] || mkdir -p ${SHFS}/AdGuardHome/data
|
||||
if [ ! -L /usr/bin/AdGuardHome ]; then
|
||||
[ -d /usr/bin/AdGuardHome ] &&
|
||||
cp -a /usr/bin/AdGuardHome/* ${SHFS}/AdGuardHome/
|
||||
fi
|
||||
ln -sf ${SHFS}/AdGuardHome /mnt/${NEW_ROOT_NAME}/usr/bin/AdGuardHome
|
||||
fi
|
||||
|
||||
sync
|
||||
echo "copy done"
|
||||
echo
|
||||
|
||||
BACKUP_LIST=$(${P2}/usr/sbin/openwrt-backup -p)
|
||||
if [ $BR_FLAG -eq 1 ]; then
|
||||
echo -n "Restore your old config files ... "
|
||||
(
|
||||
cd /
|
||||
eval tar czf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
)
|
||||
tar xzf ${NEW_ROOT_MP}/.reserved/openwrt_config.tar.gz
|
||||
[ -f ./etc/config/dockerman ] && sed -e "s/option wan_mode 'false'/option wan_mode 'true'/" -i ./etc/config/dockerman 2>/dev/null
|
||||
[ -f ./etc/config/dockerd ] && sed -e "s/option wan_mode '0'/option wan_mode '1'/" -i ./etc/config/dockerd 2>/dev/null
|
||||
[ -f ./etc/config/verysync ] && sed -e 's/config setting/config verysync/' -i ./etc/config/verysync
|
||||
|
||||
# 还原 fstab
|
||||
cp -f .snapshots/etc-000/fstab ./etc/fstab
|
||||
cp -f .snapshots/etc-000/config/fstab ./etc/config/fstab
|
||||
# 还原 luci
|
||||
cp -f .snapshots/etc-000/config/luci ./etc/config/luci
|
||||
# 还原/etc/config/rpcd
|
||||
cp -f .snapshots/etc-000/config/rpcd ./etc/config/rpcd
|
||||
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
fi
|
||||
|
||||
cat >>./etc/crontabs/root <<EOF
|
||||
17 3 * * * /etc/coremark.sh
|
||||
EOF
|
||||
|
||||
sed -e 's/ttyAMA0/ttyS2/' -i ./etc/inittab
|
||||
|
||||
[ "${SOC}" != "h28k" ] && \
|
||||
[ "${SOC}" != "h29k" ] && \
|
||||
[ "${SOC}" != "ht2" ] && \
|
||||
[ "${SOC}" != "e20c" ] && \
|
||||
[ "${SOC}" != "e24c" ] && \
|
||||
sed -e 's/ttyS0/tty1/' -i ./etc/inittab
|
||||
|
||||
sss=$(date +%s)
|
||||
ddd=$((sss / 86400))
|
||||
sed -e "s/:0:0:99999:7:::/:${ddd}:0:99999:7:::/" -i ./etc/shadow
|
||||
# 修复amule每次升级后重复添加条目的问题
|
||||
sed -e "/amule:x:/d" -i ./etc/shadow
|
||||
# 修复dropbear每次升级后重复添加sshd条目的问题
|
||||
sed -e "/sshd:x:/d" -i ./etc/shadow
|
||||
if ! grep "sshd:x:22:sshd" ./etc/group >/dev/null; then
|
||||
echo "sshd:x:22:sshd" >>./etc/group
|
||||
fi
|
||||
if ! grep "sshd:x:22:22:sshd:" ./etc/passwd >/dev/null; then
|
||||
echo "sshd:x:22:22:sshd:/var/run/sshd:/bin/false" >>./etc/passwd
|
||||
fi
|
||||
if ! grep "sshd:x:" ./etc/shadow >/dev/null; then
|
||||
echo "sshd:x:${ddd}:0:99999:7:::" >>./etc/shadow
|
||||
fi
|
||||
|
||||
if [ $BR_FLAG -eq 1 ]; then
|
||||
if [ -x ./bin/bash ] && [ -f ./etc/profile.d/30-sysinfo.sh ]; then
|
||||
sed -e 's/\/bin\/ash/\/bin\/bash/' -i ./etc/passwd
|
||||
fi
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
fi
|
||||
sed -e "s/option hw_flow '1'/option hw_flow '0'/" -i ./etc/config/turboacc
|
||||
(
|
||||
cd etc/rc.d
|
||||
rm -f S??shortcut-fe
|
||||
if grep "sfe_flow '1'" ../config/turboacc >/dev/null; then
|
||||
if find ../../lib/modules -name 'shortcut-fe-cm.ko'; then
|
||||
ln -sf ../init.d/shortcut-fe S99shortcut-fe
|
||||
fi
|
||||
fi
|
||||
)
|
||||
|
||||
# move /etc/config/balance_irq to /etc/balance_irq
|
||||
[ -f "./etc/config/balance_irq" ] && mv ./etc/config/balance_irq ./etc/
|
||||
|
||||
rm -f "./etc/rc.local.orig" "./etc/first_run.sh" "./etc/part_size"
|
||||
|
||||
eval tar czf .reserved/openwrt_config.tar.gz "${BACKUP_LIST}" 2>/dev/null
|
||||
sync
|
||||
|
||||
mv ./etc/rc.local ./etc/rc.local.orig
|
||||
cat >"./etc/rc.local" <<EOF
|
||||
if ! ls /etc/rc.d/S??dockerd >/dev/null 2>&1;then
|
||||
/etc/init.d/dockerd enable
|
||||
/etc/init.d/dockerd start
|
||||
fi
|
||||
if ! ls /etc/rc.d/S??dockerman >/dev/null 2>&1 && [ -f /etc/init.d/dockerman ];then
|
||||
/etc/init.d/dockerman enable
|
||||
/etc/init.d/dockerman start
|
||||
fi
|
||||
mv /etc/rc.local.orig /etc/rc.local
|
||||
chmod 755 /etc/rc.local
|
||||
exec /etc/rc.local
|
||||
exit
|
||||
EOF
|
||||
chmod 755 ./etc/rc.local*
|
||||
|
||||
echo "create the second etc snapshot -> .snapshots/etc-001"
|
||||
btrfs subvolume snapshot -r etc .snapshots/etc-001
|
||||
|
||||
# 2021.04.01添加
|
||||
# 强制锁定fstab,防止用户擅自修改挂载点
|
||||
# 开启了快照功能之后,不再需要锁定fstab
|
||||
#chattr +ia ./etc/config/fstab
|
||||
|
||||
cd ${WORK_DIR}
|
||||
|
||||
echo "Start copy data from ${P2} to /boot ..."
|
||||
cd /boot
|
||||
echo -n "backup armbianEnv.txt ..."
|
||||
cp armbianEnv.txt /tmp/
|
||||
echo -n "backup current dtb file ..."
|
||||
cp -v dtb/rockchip/${CURRENT_FDTFILE} /tmp/
|
||||
echo -n "remove old boot files ..."
|
||||
rm -rf *
|
||||
echo "done"
|
||||
echo -n "copy new boot files ... "
|
||||
(cd ${P1} && tar cf - .) | tar xf -
|
||||
sync
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
echo -n "Update boot args ... "
|
||||
|
||||
if [ -f /tmp/armbianEnv.txt ]; then
|
||||
ORIG_OVERLAYS=$(grep '^overlays=' /tmp/armbianEnv.txt)
|
||||
ORIG_USER_OVERLAYS=$(grep '^user_overlays=' /tmp/armbianEnv.txt)
|
||||
sed -e '/user_overlays=/d' -i armbianEnv.txt
|
||||
sed -e '/overlays=/d' -i armbianEnv.txt
|
||||
echo "$ORIG_OVERLAYS" >>armbianEnv.txt
|
||||
echo "$ORIG_USER_OVERLAYS" >>armbianEnv.txt
|
||||
fi
|
||||
|
||||
sed -e '/fdtfile=/d' -i armbianEnv.txt
|
||||
sed -e '/rootdev=/d' -i armbianEnv.txt
|
||||
sed -e '/rootfstype=/d' -i armbianEnv.txt
|
||||
sed -e '/rootflags=/d' -i armbianEnv.txt
|
||||
case $SOC in
|
||||
l1pro | beikeyun)
|
||||
echo "fdtfile=/dtb/rockchip/${MYDTB_FDTFILE}" >>armbianEnv.txt
|
||||
;;
|
||||
*)
|
||||
echo "fdtfile=rockchip/${MYDTB_FDTFILE}" >>armbianEnv.txt
|
||||
;;
|
||||
esac
|
||||
cat >>armbianEnv.txt <<EOF
|
||||
rootdev=UUID=${NEW_ROOT_UUID}
|
||||
rootfstype=btrfs
|
||||
rootflags=compress=zstd:${ZSTD_LEVEL}
|
||||
EOF
|
||||
|
||||
# Replace the UUID for extlinux/extlinux.conf if it exists
|
||||
[[ -f "extlinux/extlinux.conf" ]] && {
|
||||
sed -i -E "s|UUID=[^ ]*|UUID=${NEW_ROOT_UUID}|" extlinux/extlinux.conf 2>/dev/null
|
||||
}
|
||||
|
||||
# 如果新的dtb文件不存在,则用旧的代替
|
||||
if [ ! -f "dtb/rockchip/${MYDTB_FDTFILE}" ]; then
|
||||
echo "The new dtb file does not exist, replace it with the old one."
|
||||
cp -v /tmp/${CURRENT_FDTFILE} dtb/rockchip/${MYDTB_FDTFILE}
|
||||
fi
|
||||
sync
|
||||
|
||||
echo "done"
|
||||
echo
|
||||
|
||||
cd $WORK_DIR
|
||||
umount -f ${P1} ${P2} 2>/dev/null
|
||||
losetup -D 2>/dev/null
|
||||
rmdir ${P1} ${P2} 2>/dev/null
|
||||
rm -f ${IMG_NAME} 2>/dev/null
|
||||
rm -f sha256sums 2>/dev/null
|
||||
sync
|
||||
|
||||
echo "Successfully updated, automatic restarting..."
|
||||
sleep 3
|
||||
reboot
|
||||
exit 0
|
||||
@@ -0,0 +1,299 @@
|
||||
#!/bin/bash
|
||||
#==================================================================
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
#
|
||||
# This file is a part of the luci-app-amlogic plugin
|
||||
# https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Description: Check and update OpenWrt firmware
|
||||
# Copyright (C) 2021- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021- https://github.com/ophub/luci-app-amlogic
|
||||
#==================================================================
|
||||
|
||||
# Set a fixed value
|
||||
check_option="${1}"
|
||||
download_version="${2}"
|
||||
TMP_CHECK_DIR="/tmp/amlogic"
|
||||
AMLOGIC_SOC_FILE="/etc/flippy-openwrt-release"
|
||||
START_LOG="${TMP_CHECK_DIR}/amlogic_check_firmware.log"
|
||||
RUNNING_LOG="${TMP_CHECK_DIR}/amlogic_running_script.log"
|
||||
LOG_FILE="${TMP_CHECK_DIR}/amlogic.log"
|
||||
support_platform=("allwinner" "rockchip" "amlogic" "qemu-aarch64")
|
||||
LOGTIME="$(date "+%Y-%m-%d %H:%M:%S")"
|
||||
[[ -d ${TMP_CHECK_DIR} ]] || mkdir -p ${TMP_CHECK_DIR}
|
||||
|
||||
# Clean the running log
|
||||
clean_running() {
|
||||
echo -e '' >${RUNNING_LOG} 2>/dev/null && sync
|
||||
}
|
||||
|
||||
# Add log
|
||||
tolog() {
|
||||
echo -e "${1}" >${START_LOG}
|
||||
echo -e "${LOGTIME} ${1}" >>${LOG_FILE}
|
||||
[[ -n "${2}" && "${2}" -eq "1" ]] && clean_running && exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_name}" ]] && tolog "Cannot find the root partition!" "1"
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Check running scripts, prohibit running concurrently
|
||||
this_running_log="3@OpenWrt update in progress, try again later!"
|
||||
running_script="$(cat ${RUNNING_LOG} 2>/dev/null | xargs)"
|
||||
if [[ -n "${running_script}" ]]; then
|
||||
run_num="$(echo "${running_script}" | awk -F "@" '{print $1}')"
|
||||
run_log="$(echo "${running_script}" | awk -F "@" '{print $2}')"
|
||||
fi
|
||||
if [[ -n "${run_log}" && "${run_num}" -ne "3" ]]; then
|
||||
echo -e "${run_log}" >${START_LOG} 2>/dev/null && sync && exit 1
|
||||
else
|
||||
echo -e "${this_running_log}" >${RUNNING_LOG} 2>/dev/null && sync
|
||||
fi
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case "${ROOT_PTNAME}" in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')"
|
||||
PARTITION_NAME=""
|
||||
;;
|
||||
nvme?n?p[1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
*)
|
||||
tolog "Unable to recognize the disk type of ${ROOT_PTNAME}!" "1"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set the default download path
|
||||
FIRMWARE_DOWNLOAD_PATH="/mnt/${EMMC_NAME}${PARTITION_NAME}4"
|
||||
[ -d "${FIRMWARE_DOWNLOAD_PATH}/.luci-app-amlogic" ] || mkdir -p "${FIRMWARE_DOWNLOAD_PATH}/.luci-app-amlogic"
|
||||
|
||||
# Check release file
|
||||
if [[ -s "${AMLOGIC_SOC_FILE}" ]]; then
|
||||
source "${AMLOGIC_SOC_FILE}" 2>/dev/null
|
||||
PLATFORM="${PLATFORM}"
|
||||
BOARD="${BOARD}"
|
||||
else
|
||||
tolog "${AMLOGIC_SOC_FILE} file is missing!" "1"
|
||||
fi
|
||||
if [[ -z "${PLATFORM}" || -z "$(echo "${support_platform[@]}" | grep -w "${PLATFORM}")" || -z "${BOARD}" ]]; then
|
||||
tolog "Missing [ PLATFORM / BOARD ] value in ${AMLOGIC_SOC_FILE} file." "1"
|
||||
fi
|
||||
|
||||
tolog "PLATFORM: [ ${PLATFORM} ], BOARD: [ ${BOARD} ], Use in [ ${EMMC_NAME} ]"
|
||||
sleep 2
|
||||
|
||||
# 01. Query local version information
|
||||
tolog "01. Query version information..."
|
||||
# 01.01 Query the current version
|
||||
current_kernel_v="$(uname -r 2>/dev/null | grep -oE '^[1-9].[0-9]{1,3}.[0-9]+')"
|
||||
tolog "01.01 current version: ${current_kernel_v}"
|
||||
sleep 2
|
||||
|
||||
# 01.01 Version comparison
|
||||
main_line_version="$(echo ${current_kernel_v} | awk -F '.' '{print $1"."$2}')"
|
||||
|
||||
# 01.02. Query the selected branch in the settings
|
||||
server_kernel_branch="$(uci get amlogic.config.amlogic_kernel_branch 2>/dev/null | grep -oE '^[1-9].[0-9]{1,3}')"
|
||||
if [[ -z "${server_kernel_branch}" ]]; then
|
||||
server_kernel_branch="${main_line_version}"
|
||||
uci set amlogic.config.amlogic_kernel_branch="${main_line_version}" 2>/dev/null
|
||||
uci commit amlogic 2>/dev/null
|
||||
fi
|
||||
if [[ "${server_kernel_branch}" != "${main_line_version}" ]]; then
|
||||
main_line_version="${server_kernel_branch}"
|
||||
tolog "01.02 Select branch: ${main_line_version}"
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# 01.03. Download server version documentation
|
||||
server_firmware_url="$(uci get amlogic.config.amlogic_firmware_repo 2>/dev/null)"
|
||||
[[ ! -z "${server_firmware_url}" ]] || tolog "01.03 The custom firmware download repo is invalid." "1"
|
||||
releases_tag_keywords="$(uci get amlogic.config.amlogic_firmware_tag 2>/dev/null)"
|
||||
[[ ! -z "${releases_tag_keywords}" ]] || tolog "01.04 The custom firmware tag keywords is invalid." "1"
|
||||
firmware_suffix="$(uci get amlogic.config.amlogic_firmware_suffix 2>/dev/null)"
|
||||
[[ ! -z "${firmware_suffix}" ]] || tolog "01.05 The custom firmware suffix is invalid." "1"
|
||||
|
||||
if [[ "${server_firmware_url}" == http* ]]; then
|
||||
server_firmware_url="${server_firmware_url#*com\/}"
|
||||
fi
|
||||
|
||||
# 02. Check Updated
|
||||
check_updated() {
|
||||
tolog "02.01 Search for tags in the first 5 pages of releases..."
|
||||
|
||||
# Get the tags list
|
||||
firmware_tags_array=()
|
||||
for i in {1..5}; do
|
||||
while IFS= read -r firmware_tags_name; do
|
||||
firmware_tags_name="$(echo "${firmware_tags_name}" | sed 's/releases\/tag\///g')"
|
||||
if [[ -n "${firmware_tags_name}" ]]; then
|
||||
firmware_tags_array+=("${firmware_tags_name}")
|
||||
fi
|
||||
done < <(
|
||||
curl -fsSL -m 10 \
|
||||
https://github.com/${server_firmware_url}/releases?page=${i} |
|
||||
grep -oE 'releases/tag/([^" ]+)'
|
||||
)
|
||||
done
|
||||
|
||||
if [[ "${#firmware_tags_array[*]}" -eq "0" ]]; then
|
||||
tolog "02.01.01 Unable to retrieve a list of firmware tags." "1"
|
||||
fi
|
||||
|
||||
tolog "02.02 Search for tags containing the keyword..."
|
||||
|
||||
# Search for tags containing the keyword
|
||||
for i in "${firmware_tags_array[@]}"; do
|
||||
if [[ "${i}" == *"${releases_tag_keywords}"* ]]; then
|
||||
firmware_releases_tag="${i}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "${firmware_releases_tag}" ]]; then
|
||||
tolog "02.02.01 Tags: ${firmware_releases_tag}"
|
||||
sleep 2
|
||||
else
|
||||
tolog "02.02.01 No matching tags found." "1"
|
||||
fi
|
||||
|
||||
tolog "02.03 Start searching for firmware download links..."
|
||||
|
||||
# Retrieve the HTML code of the tags list page
|
||||
html_code="$(
|
||||
curl -fsSL -m 10 \
|
||||
https://github.com/${server_firmware_url}/releases/expanded_assets/${firmware_releases_tag}
|
||||
)"
|
||||
|
||||
# Set the regular expression for the OpenWrt filename
|
||||
op_file_pattern=".*_${BOARD}_.*k${main_line_version}\.[0-9]+.*${firmware_suffix}"
|
||||
# Find the <li> list item where the OpenWrt file is located
|
||||
li_block=$(awk -v pattern="${op_file_pattern}" -v RS='</li>' '$0 ~ pattern { print $0 "</li>"; exit }' <<<"${html_code}")
|
||||
[[ -z "${li_block}" ]] && tolog "02.03.01 No matching download links found." "1"
|
||||
|
||||
# Find the OpenWrt filename
|
||||
latest_url=$(echo "${li_block}" | grep -oE "/[^\"]*_${BOARD}_.*k${main_line_version}\.[0-9]+[^\"]*${firmware_suffix}" | sort -urV | head -n 1 | xargs basename 2>/dev/null)
|
||||
tolog "02.03.02 OpenWrt file: ${latest_url}"
|
||||
|
||||
# Find the date of the latest update
|
||||
latest_updated_at=$(echo "${li_block}" | grep -o 'datetime="[^"]*"' | sed 's/datetime="//; s/"//')
|
||||
tolog "02.03.03 Latest updated at: ${latest_updated_at}"
|
||||
# Format the date for display
|
||||
date_display_format="$(echo ${latest_updated_at} | tr 'T' '(' | tr 'Z' ')')"
|
||||
[[ -z "${latest_url}" || -z "${latest_updated_at}" ]] && tolog "02.03.04 The download URL or date is invalid." "1"
|
||||
|
||||
# Find the firmware sha256 value
|
||||
latest_firmware_sha256="$(echo "${li_block}" | grep -o 'value="sha256:[^"]*' | sed 's/value="sha256://')"
|
||||
tolog "02.03.05 OpenWrt sha256: ${latest_firmware_sha256}"
|
||||
|
||||
# Check the firmware update code
|
||||
down_check_code="${latest_updated_at}.${main_line_version}"
|
||||
op_release_code="${FIRMWARE_DOWNLOAD_PATH}/.luci-app-amlogic/op_release_code"
|
||||
if [[ -s "${op_release_code}" ]]; then
|
||||
update_check_code="$(cat ${op_release_code} | xargs)"
|
||||
if [[ -n "${update_check_code}" && "${update_check_code}" == "${down_check_code}" ]]; then
|
||||
tolog "02.04 Already the latest version, no need to update." "1"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt to update
|
||||
if [[ -n "${latest_url}" ]]; then
|
||||
tolog '<input type="button" class="cbi-button cbi-button-reload" value="Download" onclick="return b_check_firmware(this, '"'download_${latest_updated_at}@${firmware_releases_tag}/${latest_url}@${latest_firmware_sha256}'"')"/> Latest updated: '${date_display_format}'' "1"
|
||||
else
|
||||
tolog "02.05 No OpenWrt available, please use another kernel branch." "1"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 03. Download Openwrt
|
||||
download_firmware() {
|
||||
tolog "03. Start download the Openwrt..."
|
||||
|
||||
# Get the openwrt firmware download path
|
||||
if [[ "${download_version}" == "download_"* ]]; then
|
||||
tolog "03.01 Start downloading..."
|
||||
else
|
||||
tolog "03.01 Invalid parameter." "1"
|
||||
fi
|
||||
|
||||
# Delete other residual firmware files
|
||||
rm -f ${FIRMWARE_DOWNLOAD_PATH}/*${firmware_suffix} 2>/dev/null && sync
|
||||
rm -f ${FIRMWARE_DOWNLOAD_PATH}/*.img 2>/dev/null && sync
|
||||
rm -f ${FIRMWARE_DOWNLOAD_PATH}/sha256sums 2>/dev/null && sync
|
||||
|
||||
# OpenWrt make data
|
||||
latest_updated_at="$(echo ${download_version} | awk -F'@' '{print $1}' | sed -e s'|download_||'g)"
|
||||
down_check_code="${latest_updated_at}.${main_line_version}"
|
||||
|
||||
# Download firmware
|
||||
opfile_path="$(echo ${download_version} | awk -F'@' '{print $2}')"
|
||||
# Restore converted characters in file names(%2B to +)
|
||||
firmware_download_oldname="${opfile_path//%2B/+}"
|
||||
latest_url="https://github.com/${server_firmware_url}/releases/download/${firmware_download_oldname}"
|
||||
|
||||
# Find the firmware sha256 value
|
||||
releases_firmware_sha256sums="$(echo ${download_version} | awk -F'@' '{print $3}')"
|
||||
|
||||
# Download to OpenWrt file
|
||||
firmware_download_name="openwrt_${BOARD}_k${main_line_version}_github${firmware_suffix}"
|
||||
curl -fsSL "${latest_url}" -o "${FIRMWARE_DOWNLOAD_PATH}/${firmware_download_name}"
|
||||
if [[ "$?" -eq "0" && -s "${FIRMWARE_DOWNLOAD_PATH}/${firmware_download_name}" ]]; then
|
||||
tolog "03.02 OpenWrt downloaded successfully."
|
||||
else
|
||||
tolog "03.02 OpenWrt download failed." "1"
|
||||
fi
|
||||
|
||||
# Verify sha256sums if available
|
||||
if [[ -n "${releases_firmware_sha256sums}" ]]; then
|
||||
tolog "03.03 Perform sha256 checksum verification."
|
||||
|
||||
# If there is a sha256sum file, compare it
|
||||
download_firmware_sha256sums="$(sha256sum ${FIRMWARE_DOWNLOAD_PATH}/${firmware_download_name} | awk '{print $1}')"
|
||||
if [[ "${releases_firmware_sha256sums}" != "${download_firmware_sha256sums}" ]]; then
|
||||
tolog "03.03.01 sha256sum verification mismatched." "1"
|
||||
else
|
||||
tolog "03.03.02 sha256sum verification succeeded."
|
||||
fi
|
||||
fi
|
||||
|
||||
sync && sleep 3
|
||||
|
||||
tolog "You can update."
|
||||
|
||||
tolog '<input type="button" class="cbi-button cbi-button-reload" value="Update" onclick="return amlogic_update(this, '"'${firmware_download_name}@${down_check_code}@${FIRMWARE_DOWNLOAD_PATH}'"')"/>' "1"
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
getopts 'cd' opts
|
||||
case "${opts}" in
|
||||
c | check)
|
||||
check_updated
|
||||
;;
|
||||
* | download)
|
||||
download_firmware
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,275 @@
|
||||
#!/bin/bash
|
||||
#==================================================================
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
#
|
||||
# This file is a part of the luci-app-amlogic plugin
|
||||
# https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Description: Check and update OpenWrt Kernel
|
||||
# Copyright (C) 2021- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021- https://github.com/ophub/luci-app-amlogic
|
||||
#==================================================================
|
||||
|
||||
# Set a fixed value
|
||||
check_option="${1}"
|
||||
download_version="${2}"
|
||||
TMP_CHECK_DIR="/tmp/amlogic"
|
||||
AMLOGIC_SOC_FILE="/etc/flippy-openwrt-release"
|
||||
START_LOG="${TMP_CHECK_DIR}/amlogic_check_kernel.log"
|
||||
RUNNING_LOG="${TMP_CHECK_DIR}/amlogic_running_script.log"
|
||||
LOG_FILE="${TMP_CHECK_DIR}/amlogic.log"
|
||||
support_platform=("allwinner" "rockchip" "amlogic" "qemu-aarch64")
|
||||
LOGTIME="$(date "+%Y-%m-%d %H:%M:%S")"
|
||||
[[ -d ${TMP_CHECK_DIR} ]] || mkdir -p ${TMP_CHECK_DIR}
|
||||
|
||||
# Clean the running log
|
||||
clean_running() {
|
||||
echo -e '' >${RUNNING_LOG} 2>/dev/null && sync
|
||||
}
|
||||
|
||||
# Add log
|
||||
tolog() {
|
||||
echo -e "${1}" >${START_LOG}
|
||||
echo -e "${LOGTIME} ${1}" >>${LOG_FILE}
|
||||
[[ -n "${2}" && "${2}" -eq "1" ]] && clean_running && exit 1
|
||||
}
|
||||
|
||||
# Get the partition name of the root file system
|
||||
get_root_partition_name() {
|
||||
local paths=("/" "/overlay" "/rom")
|
||||
local partition_name
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
partition_name=$(df "${path}" | awk 'NR==2 {print $1}' | awk -F '/' '{print $3}')
|
||||
[[ -n "${partition_name}" ]] && break
|
||||
done
|
||||
|
||||
[[ -z "${partition_name}" ]] && tolog "Cannot find the root partition!" "1"
|
||||
echo "${partition_name}"
|
||||
}
|
||||
|
||||
# Check running scripts, prohibit running concurrently
|
||||
this_running_log="2@Kernel update in progress, try again later!"
|
||||
running_script="$(cat ${RUNNING_LOG} 2>/dev/null | xargs)"
|
||||
if [[ -n "${running_script}" ]]; then
|
||||
run_num="$(echo "${running_script}" | awk -F "@" '{print $1}')"
|
||||
run_log="$(echo "${running_script}" | awk -F "@" '{print $2}')"
|
||||
fi
|
||||
if [[ -n "${run_log}" && "${run_num}" -ne "2" ]]; then
|
||||
echo -e "${run_log}" >${START_LOG} 2>/dev/null && sync && exit 1
|
||||
else
|
||||
echo -e "${this_running_log}" >${RUNNING_LOG} 2>/dev/null && sync
|
||||
fi
|
||||
|
||||
# Find the partition where root is located
|
||||
ROOT_PTNAME="$(get_root_partition_name)"
|
||||
|
||||
# Find the disk where the partition is located, only supports mmcblk?p? sd?? hd?? vd?? and other formats
|
||||
case "${ROOT_PTNAME}" in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')"
|
||||
PARTITION_NAME=""
|
||||
;;
|
||||
nvme?n?p[1-4])
|
||||
EMMC_NAME="$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')"
|
||||
PARTITION_NAME="p"
|
||||
;;
|
||||
*)
|
||||
tolog "Unable to recognize the disk type of ${ROOT_PTNAME}!" "1"
|
||||
;;
|
||||
esac
|
||||
# Set the default download path
|
||||
KERNEL_DOWNLOAD_PATH="/mnt/${EMMC_NAME}${PARTITION_NAME}4"
|
||||
|
||||
# Check release file
|
||||
if [[ -s "${AMLOGIC_SOC_FILE}" ]]; then
|
||||
source "${AMLOGIC_SOC_FILE}" 2>/dev/null
|
||||
PLATFORM="${PLATFORM}"
|
||||
else
|
||||
tolog "${AMLOGIC_SOC_FILE} file is missing!" "1"
|
||||
fi
|
||||
if [[ -z "${PLATFORM}" || -z "$(echo "${support_platform[@]}" | grep -w "${PLATFORM}")" ]]; then
|
||||
tolog "Missing [ PLATFORM ] value in ${AMLOGIC_SOC_FILE} file." "1"
|
||||
fi
|
||||
|
||||
tolog "PLATFORM: [ ${PLATFORM} ], Use in [ ${EMMC_NAME} ]"
|
||||
sleep 2
|
||||
|
||||
# Step 1. Set the kernel query api
|
||||
tolog "01. Start checking the kernel repository."
|
||||
firmware_repo="$(uci get amlogic.config.amlogic_firmware_repo 2>/dev/null)"
|
||||
[[ -n "${firmware_repo}" ]] || tolog "01.01 The custom kernel download repo is invalid." "1"
|
||||
kernel_repo="$(uci get amlogic.config.amlogic_kernel_path 2>/dev/null)"
|
||||
[[ -n "${kernel_repo}" ]] || tolog "01.02 The custom kernel download repo is invalid." "1"
|
||||
|
||||
if [[ "${kernel_repo}" == "opt/kernel" ]]; then
|
||||
uci set amlogic.config.amlogic_kernel_path="${firmware_repo}" 2>/dev/null
|
||||
uci commit amlogic 2>/dev/null
|
||||
kernel_repo="${firmware_repo}"
|
||||
fi
|
||||
|
||||
# Convert kernel repo to api format
|
||||
[[ "${kernel_repo}" =~ ^https: ]] && kernel_repo="$(echo ${kernel_repo} | awk -F'/' '{print $4"/"$5}')"
|
||||
kernel_api="https://github.com/${kernel_repo}"
|
||||
tolog "01.03 Kernel repo: ${kernel_repo}"
|
||||
# Get the current kernel uname
|
||||
kernel_uname="$(uname -r 2>/dev/null)"
|
||||
tolog "01.04 Current kernel uname: ${kernel_uname}"
|
||||
|
||||
# Get the kernel tag from uci config
|
||||
op_kernel_tags="$(uci get amlogic.config.amlogic_kernel_tags 2>/dev/null)"
|
||||
# Determine the kernel tag
|
||||
if [[ -n "${op_kernel_tags}" ]]; then
|
||||
kernel_tag="${op_kernel_tags/kernel_/}"
|
||||
else
|
||||
# Determine the kernel tag based on the current kernel uname
|
||||
if [[ "${kernel_uname}" =~ -rk3588 ]]; then
|
||||
kernel_tag="rk3588"
|
||||
elif [[ "${kernel_uname}" =~ -rk35xx ]]; then
|
||||
kernel_tag="rk35xx"
|
||||
elif [[ "${kernel_uname}" =~ -h6|-zicai ]]; then
|
||||
kernel_tag="h6"
|
||||
else
|
||||
kernel_tag="stable"
|
||||
fi
|
||||
|
||||
# Save the kernel tag to uci config
|
||||
uci set amlogic.config.amlogic_kernel_tags="kernel_${kernel_tag}" 2>/dev/null
|
||||
uci commit amlogic 2>/dev/null
|
||||
fi
|
||||
tolog "01.05 Kernel tag: kernel_${kernel_tag}"
|
||||
sleep 2
|
||||
|
||||
# Step 2: Check if there is the latest kernel version
|
||||
check_kernel() {
|
||||
# 02. Query local version information
|
||||
tolog "02. Start checking the kernel version."
|
||||
|
||||
# 02.01 Get current kernel version
|
||||
[[ ! "${kernel_tag}" =~ ^(rk3588|rk35xx)$ ]] && kernel_uname="$(echo "${kernel_uname}" | cut -d'-' -f1)"
|
||||
[[ -n "${kernel_uname}" ]] || tolog "02.01 The current kernel version is not detected." "1"
|
||||
tolog "02.01 current version: ${kernel_uname}"
|
||||
sleep 2
|
||||
|
||||
# 02.02 Version comparison
|
||||
main_line_version="$(echo ${kernel_uname} | awk -F '.' '{print $1"."$2}')"
|
||||
|
||||
# 02.03 Query the selected branch in the settings
|
||||
server_kernel_branch="$(uci get amlogic.config.amlogic_kernel_branch 2>/dev/null | grep -oE '^[1-9].[0-9]{1,3}')"
|
||||
if [[ -z "${server_kernel_branch}" ]]; then
|
||||
server_kernel_branch="${main_line_version}"
|
||||
uci set amlogic.config.amlogic_kernel_branch="${main_line_version}" 2>/dev/null
|
||||
uci commit amlogic 2>/dev/null
|
||||
fi
|
||||
|
||||
if [[ "${server_kernel_branch}" != "${main_line_version}" ]]; then
|
||||
main_line_version="${server_kernel_branch}"
|
||||
main_line_now="0"
|
||||
tolog "02.02 Select branch: ${main_line_version}"
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Check the version on the server
|
||||
latest_version="$(
|
||||
curl -fsSL -m 10 \
|
||||
${kernel_api}/releases/expanded_assets/kernel_${kernel_tag} |
|
||||
grep -oE "${main_line_version}\.[0-9]+[^\"]*\.tar\.gz" | sed 's/.tar.gz//' |
|
||||
sort -urV | head -n 1
|
||||
)"
|
||||
[[ -n "${latest_version}" ]] || tolog "02.03 No kernel available, please use another kernel branch." "1"
|
||||
|
||||
tolog "02.04 current version: ${kernel_uname}, Latest version: ${latest_version}"
|
||||
sleep 2
|
||||
|
||||
# Get the sha256 value of the latest version
|
||||
latest_kernel_sha256="$(
|
||||
curl -fsSL -m 10 \
|
||||
${kernel_api}/releases/expanded_assets/kernel_${kernel_tag} |
|
||||
awk -v pattern="${latest_version}\.tar\.gz" -v RS='</li>' '$0 ~ pattern { print $0 "</li>"; exit }' |
|
||||
grep -o 'value="sha256:[^"]*' | sed 's/value="sha256://'
|
||||
)"
|
||||
[[ -n "${latest_kernel_sha256}" ]] && tolog "02.05 Kernel sha256: ${latest_kernel_sha256}"
|
||||
|
||||
if [[ "${latest_version}" == "${kernel_uname}" ]]; then
|
||||
tolog "02.06 Already the latest version, no need to update." "1"
|
||||
sleep 2
|
||||
else
|
||||
tolog '<input type="button" class="cbi-button cbi-button-reload" value="Download" onclick="return b_check_kernel(this, '"'download_${latest_version}_${latest_kernel_sha256}'"')"/> Latest version: '${latest_version}'' "1"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Step 3: Download the latest kernel version
|
||||
download_kernel() {
|
||||
tolog "03. Start download the kernel file."
|
||||
if [[ "${download_version}" == "download_"* ]]; then
|
||||
tolog "03.01 Start downloading..."
|
||||
else
|
||||
tolog "03.01 Invalid parameter" "1"
|
||||
fi
|
||||
|
||||
# Get the kernel file name
|
||||
kernel_file_name="$(echo "${download_version}" | cut -d '_' -f2)"
|
||||
# Restore converted characters in file names(%2B to +)
|
||||
kernel_file_name="${kernel_file_name//%2B/+}"
|
||||
# Get the sha256 value
|
||||
kernel_file_sha256="$(echo "${download_version}" | cut -d '_' -f3)"
|
||||
|
||||
# Delete other residual kernel files
|
||||
rm -f ${KERNEL_DOWNLOAD_PATH}/*.tar.gz
|
||||
rm -f ${KERNEL_DOWNLOAD_PATH}/sha256sums
|
||||
rm -rf ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}*
|
||||
|
||||
kernel_down_from="https://github.com/${kernel_repo}/releases/download/kernel_${kernel_tag}/${kernel_file_name}.tar.gz"
|
||||
|
||||
curl -fsSL "${kernel_down_from}" -o ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}.tar.gz
|
||||
[[ "${?}" -ne "0" ]] && tolog "03.02 The kernel download failed." "1"
|
||||
|
||||
# Verify sha256
|
||||
if [[ -n "${kernel_file_sha256}" ]]; then
|
||||
tolog "03.03 Perform sha256 checksum verification."
|
||||
|
||||
download_kernel_sha256sums="$(sha256sum ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}.tar.gz | awk '{print $1}')"
|
||||
if [[ "${kernel_file_sha256}" != "${download_kernel_sha256sums}" ]]; then
|
||||
tolog "03.03.01 sha256sum verification mismatched." "1"
|
||||
else
|
||||
tolog "03.03.02 sha256sum verification succeeded."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Decompress the kernel package
|
||||
tolog "03.04 Start decompressing the kernel package..."
|
||||
tar -xf ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}.tar.gz -C ${KERNEL_DOWNLOAD_PATH}
|
||||
[[ "${?}" -ne "0" ]] && tolog "03.05 Kernel decompression failed." "1"
|
||||
mv -f ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}/* ${KERNEL_DOWNLOAD_PATH}/
|
||||
|
||||
sync && sleep 3
|
||||
# Delete the downloaded kernel file
|
||||
rm -f ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}.tar.gz
|
||||
rm -rf ${KERNEL_DOWNLOAD_PATH}/${kernel_file_name}
|
||||
|
||||
tolog "03.06 The kernel is ready, you can update."
|
||||
sleep 2
|
||||
|
||||
#echo '<a href="javascript:;" onclick="return amlogic_kernel(this)">Update</a>' >$START_LOG
|
||||
tolog '<input type="button" class="cbi-button cbi-button-reload" value="Update" onclick="return amlogic_kernel(this)"/>' "1"
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
getopts 'cd' opts
|
||||
case "${opts}" in
|
||||
c | check)
|
||||
check_kernel
|
||||
;;
|
||||
* | download)
|
||||
download_kernel
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,170 @@
|
||||
#!/bin/bash
|
||||
#==================================================================
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
#
|
||||
# This file is a part of the luci-app-amlogic plugin
|
||||
# https://github.com/ophub/luci-app-amlogic
|
||||
#
|
||||
# Description: Check and update luci-app-amlogic plugin
|
||||
# Copyright (C) 2021- https://github.com/unifreq/openwrt_packit
|
||||
# Copyright (C) 2021- https://github.com/ophub/luci-app-amlogic
|
||||
#==================================================================
|
||||
|
||||
# Set a fixed value
|
||||
TMP_CHECK_DIR="/tmp/amlogic"
|
||||
AMLOGIC_SOC_FILE="/etc/flippy-openwrt-release"
|
||||
START_LOG="${TMP_CHECK_DIR}/amlogic_check_plugin.log"
|
||||
RUNNING_LOG="${TMP_CHECK_DIR}/amlogic_running_script.log"
|
||||
LOG_FILE="${TMP_CHECK_DIR}/amlogic.log"
|
||||
support_platform=("allwinner" "rockchip" "amlogic" "qemu-aarch64")
|
||||
LOGTIME="$(date "+%Y-%m-%d %H:%M:%S")"
|
||||
|
||||
[[ -d ${TMP_CHECK_DIR} ]] || mkdir -p ${TMP_CHECK_DIR}
|
||||
rm -f ${TMP_CHECK_DIR}/*.ipk 2>/dev/null && sync
|
||||
rm -f ${TMP_CHECK_DIR}/sha256sums 2>/dev/null && sync
|
||||
|
||||
# Clean the running log
|
||||
clean_running() {
|
||||
echo -e '' >${RUNNING_LOG} 2>/dev/null && sync
|
||||
}
|
||||
|
||||
# Add log
|
||||
tolog() {
|
||||
echo -e "${1}" >${START_LOG}
|
||||
echo -e "${LOGTIME} ${1}" >>${LOG_FILE}
|
||||
[[ -n "${2}" && "${2}" -eq "1" ]] && clean_running && exit 1
|
||||
}
|
||||
|
||||
# Check running scripts, prohibit running concurrently
|
||||
this_running_log="1@Plugin update in progress, try again later!"
|
||||
running_script="$(cat ${RUNNING_LOG} 2>/dev/null | xargs)"
|
||||
if [[ -n "${running_script}" ]]; then
|
||||
run_num="$(echo "${running_script}" | awk -F "@" '{print $1}')"
|
||||
run_log="$(echo "${running_script}" | awk -F "@" '{print $2}')"
|
||||
fi
|
||||
if [[ -n "${run_log}" && "${run_num}" -ne "1" ]]; then
|
||||
echo -e "${run_log}" >${START_LOG} 2>/dev/null && sync && exit 1
|
||||
else
|
||||
echo -e "${this_running_log}" >${RUNNING_LOG} 2>/dev/null && sync
|
||||
fi
|
||||
|
||||
# Check release file
|
||||
if [[ -s "${AMLOGIC_SOC_FILE}" ]]; then
|
||||
source "${AMLOGIC_SOC_FILE}" 2>/dev/null
|
||||
PLATFORM="${PLATFORM}"
|
||||
else
|
||||
tolog "${AMLOGIC_SOC_FILE} file is missing!" "1"
|
||||
fi
|
||||
if [[ -z "${PLATFORM}" || -z "$(echo "${support_platform[@]}" | grep -w "${PLATFORM}")" ]]; then
|
||||
tolog "Missing [ PLATFORM ] value in ${AMLOGIC_SOC_FILE} file." "1"
|
||||
fi
|
||||
|
||||
tolog "PLATFORM: [ ${PLATFORM} ]"
|
||||
sleep 2
|
||||
|
||||
# 01. Query local version information
|
||||
tolog "01. Query current version information."
|
||||
|
||||
# If neither opkg nor apk found, set package_manager to empty
|
||||
package_manager=""
|
||||
current_plugin_v=""
|
||||
|
||||
if command -v opkg >/dev/null 2>&1; then
|
||||
# System has opkg
|
||||
package_manager="ipk"
|
||||
# Important: Add cut to handle versions like X.Y.Z-r1, ensuring consistent output
|
||||
current_plugin_v="$(opkg list-installed | grep '^luci-app-amlogic' | awk '{print $3}' | cut -d'-' -f1)"
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
# System has apk
|
||||
package_manager="apk"
|
||||
current_plugin_v="$(apk list --installed | grep '^luci-app-amlogic' | awk '{print $1}' | cut -d'-' -f4)"
|
||||
fi
|
||||
|
||||
# Check if we successfully found the plugin
|
||||
if [[ -z "${package_manager}" || -z "${current_plugin_v}" ]]; then
|
||||
tolog "01.01 Plugin 'luci-app-amlogic' not found or package manager unknown." "1"
|
||||
else
|
||||
tolog "01.01 Using [${package_manager}]. Current version: ${current_plugin_v}"
|
||||
fi
|
||||
sleep 2
|
||||
|
||||
# 02. Check the version on the server
|
||||
tolog "02. Start querying plugin version..."
|
||||
|
||||
# Get the latest version
|
||||
latest_version="$(
|
||||
curl -fsSL -m 10 \
|
||||
https://github.com/ophub/luci-app-amlogic/releases |
|
||||
grep -oE 'expanded_assets/[0-9]+.[0-9]+.[0-9]+(-[0-9]+)?' | sed 's|expanded_assets/||g' |
|
||||
sort -urV | head -n 1
|
||||
)"
|
||||
if [[ -z "${latest_version}" ]]; then
|
||||
tolog "02.01 Query failed, please try again." "1"
|
||||
else
|
||||
tolog "02.01 current version: ${current_plugin_v}, Latest version: ${latest_version}"
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Compare the version and download the latest version
|
||||
if [[ "${current_plugin_v}" == "${latest_version}" ]]; then
|
||||
tolog "02.02 Already the latest version, no need to update." "1"
|
||||
else
|
||||
tolog "02.03 New version found. Preparing to download for [${package_manager}]..."
|
||||
download_repo="https://github.com/ophub/luci-app-amlogic/releases/download"
|
||||
|
||||
# Intelligent File Discovery
|
||||
plugin_file_name=""
|
||||
lang_file_list=""
|
||||
|
||||
# Method 1: Use GitHub API if 'jq' is installed (Preferred Method)
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
tolog "Using GitHub API with jq to find package files."
|
||||
api_url="https://api.github.com/repos/ophub/luci-app-amlogic/releases/tags/${latest_version}"
|
||||
|
||||
# Fetch all asset names from the API
|
||||
asset_list="$(curl -fsSL -m 15 "${api_url}" | jq -r '.assets[].name' | xargs)"
|
||||
|
||||
if [[ -n "${asset_list}" ]]; then
|
||||
# Discover exact filenames using regular expressions from the asset list
|
||||
plugin_file_name="$(echo "${asset_list}" | tr ' ' '\n' | grep -oE "^luci-app-amlogic.*${package_manager}$" | head -n 1)"
|
||||
lang_file_list=($(echo "${asset_list}" | tr ' ' '\n' | grep -oE "^luci-i18n-amlogic.*${package_manager}$"))
|
||||
else
|
||||
tolog "Warning: Failed to fetch data from GitHub API." "1"
|
||||
fi
|
||||
else
|
||||
tolog "jq not found, Aborting." "1"
|
||||
fi
|
||||
|
||||
# Validation and Download
|
||||
if [[ -z "${plugin_file_name}" || "${#lang_file_list[@]}" -eq "0" ]]; then
|
||||
tolog "02.03.2 Could not discover plugin(.${package_manager}) in the release. Aborting." "1"
|
||||
fi
|
||||
|
||||
tolog "Found plugin file: ${plugin_file_name}"
|
||||
tolog "Found language file: $(echo ${lang_file_list[@]} | xargs)"
|
||||
|
||||
# Download the main plugin file
|
||||
plugin_full_url="${download_repo}/${latest_version}/${plugin_file_name}"
|
||||
tolog "02.04 Downloading main plugin..."
|
||||
curl -fsSL "${plugin_full_url}" -o "${TMP_CHECK_DIR}/${plugin_file_name}"
|
||||
[[ "${?}" -ne "0" ]] && tolog "02.04 Plugin [ ${plugin_file_name} ] download failed." "1"
|
||||
|
||||
# Download language packs
|
||||
for langfile in "${lang_file_list[@]}"; do
|
||||
lang_full_url="${download_repo}/${latest_version}/${langfile}"
|
||||
tolog "02.05 Downloading language pack [ ${langfile} ]..."
|
||||
curl -fsSL "${lang_full_url}" -o "${TMP_CHECK_DIR}/${langfile}"
|
||||
[[ "${?}" -ne "0" ]] && tolog "02.05 Language pack [ ${langfile} ] download failed." "1"
|
||||
done
|
||||
|
||||
sync && sleep 2
|
||||
fi
|
||||
|
||||
tolog "03. The plug is ready, you can update."
|
||||
sleep 2
|
||||
|
||||
tolog '<input type="button" class="cbi-button cbi-button-reload" value="Update" onclick="return amlogic_plugin(this)"/> Latest version: '${latest_version}'' "1"
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-amlogic": {
|
||||
"description": "Grant UCI access for luci-app-amlogic",
|
||||
"read": {
|
||||
"uci": [ "amlogic" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "amlogic" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"config": "amlogic",
|
||||
"init": "amlogic"
|
||||
}
|
||||
Reference in new issue
Block a user