Skip to content

Instantly share code, notes, and snippets.

@luaraneda
Created December 20, 2022 17:47
Show Gist options
  • Save luaraneda/480c2395710b3a1d7027b6d586443d5b to your computer and use it in GitHub Desktop.
Save luaraneda/480c2395710b3a1d7027b6d586443d5b to your computer and use it in GitHub Desktop.
OpenWrt: Implement dual-partition support for Dynalink DL-WRX36: 2 boot slots + recovery by loading initramfs image from USB
#!/bin/sh /etc/rc.common
START=99
boot() {
case $(board_name) in
dynalink,dl-wrx36)
# Note: It might be a good idea to not touch this when running from initramfs even if it's 1
local owrt_upgrade_available=$(fw_printenv -n owrt_upgrade_available 2>/dev/null)
if [ "$owrt_upgrade_available" = "1" ]; then
fw_setenv owrt_upgrade_available 0
fi
;;
edgecore,eap102)
fw_setenv upgrade_available 0
# Unset changed flag after sysupgrade complete
fw_setenv changed
;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
# OTA handling should not be used. Reset it just in case.
fw_setenv flag_ota_reboot 0
# Not strictly needed but useful to handle partition crash condition
fw_setenv flag_boot_success 1
;;
esac
}
PART_NAME=firmware
REQUIRE_IMAGE_METADATA=1
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
return 0;
}
dynalink_dl_wrx36_init_uboot_env() {
fw_setenv mtdids 'nand0=nand0'
# Set mtdparts env var depending on current OEM partition slot
# Use offset of mtd18 (rootfs)
local mtd18_offset=$(cat /sys/class/mtd/mtd18/offset 2>/dev/null)
if [ "$mtd18_offset" -eq $((0x1000000)) ]; then
fw_setenv mtdparts 'mtdparts=nand0:0x6100000@0x1000000(fs),0x6100000@0x7a00000(fs_1)'
elif [ "$mtd18_offset" -eq $((0x7a00000)) ]; then
fw_setenv mtdparts 'mtdparts=nand0:0x6100000@0x7a00000(fs),0x6100000@0x1000000(fs_1)'
else
echo "could not determine current OEM partition slot for rootfs. Got offset '$mtd18_offset'"
return
fi
#
fw_setenv owrt_boot 'if test $owrt_upgrade_available != 0; then run owrt_bootcount_test_0; fi; run owrt_boot_selected'
fw_setenv owrt_bootcount_test_0 'if test $owrt_bootcount = 0; then setenv owrt_bootcount 1 && saveenv; else run owrt_bootcount_test_1; fi'
fw_setenv owrt_bootcount_test_1 'if test $owrt_bootcount = 1; then setenv owrt_bootcount 2 && run owrt_boot_change_slot && saveenv; else run owrt_bootcount_test_2; fi'
fw_setenv owrt_bootcount_test_2 'if test $owrt_bootcount = 2; then setenv owrt_bootcount 3 && setenv owrt_active 0 && saveenv; fi'
fw_setenv owrt_boot_change_slot 'if test $owrt_active = 1; then setenv owrt_active 2; elif test $owrt_active = 2; then setenv owrt_active 1; fi'
fw_setenv owrt_boot_selected 'if test $owrt_active = 1; then run owrt_boot_slot1; elif test $owrt_active = 2; then run owrt_boot_slot2; else run owrt_boot_usbinitramfs; fi'
fw_setenv owrt_boot_slot1 'setenv bootargs console=ttyMSM0,115200n8 ubi.mtd=rootfs rootfstype=squashfs rootwait; ubi part fs; ubi read 0x44000000 kernel; bootm 0x44000000#config@rt5010w-d350-rev0'
fw_setenv owrt_boot_slot2 'setenv bootargs console=ttyMSM0,115200n8 ubi.mtd=rootfs_1 rootfstype=squashfs rootwait; ubi part fs_1; ubi read 0x44000000 kernel; bootm 0x44000000#config@rt5010w-d350-rev0'
fw_setenv owrt_boot_usbinitramfs 'usb start && fatload usb 0:1 0x44000000 openwrt-ipq807x-generic-dynalink_dl-wrx36-initramfs-uImage.itb && bootm 0x44000000'
# Set initial status to: initramfs from USB
fw_setenv owrt_active 0
fw_setenv owrt_upgrade_available 0
fw_setenv owrt_bootcount 0
#
# Finish setup: set version variable at the end to signal the process completed successfully
fw_setenv bootcmd 'run owrt_boot'
fw_setenv owrt_env_ver 1
}
platform_do_upgrade() {
case "$(board_name)" in
dynalink,dl-wrx36)
local env_version_owrt='1'
local env_version_device=$(fw_printenv -n owrt_env_ver 2>/dev/null)
if [ "$env_version_device" != "$env_version_owrt" ]; then
echo "Initializing uboot env as version mismatch was detected. Current is '$env_version_owrt' and device has '$env_version_device'"
dynalink_dl_wrx36_init_uboot_env
fi
#
local active_slot_cur=$(fw_printenv -n owrt_active 2>/dev/null)
local active_slot_new;
if [ "$active_slot_cur" = "1" ]; then
CI_UBIPART="rootfs_1"
active_slot_new="2"
else
CI_UBIPART="rootfs"
active_slot_new="1"
fi
fw_setenv owrt_upgrade_available 1
fw_setenv owrt_bootcount 0
fw_setenv owrt_active $active_slot_new
#
nand_do_upgrade "$1"
;;
edgecore,eap102)
active="$(fw_printenv -n active)"
if [ "$active" -eq "1" ]; then
CI_UBIPART="rootfs2"
else
CI_UBIPART="rootfs1"
fi
# force altbootcmd which handles partition change in u-boot
fw_setenv bootcount 3
fw_setenv upgrade_available 1
nand_do_upgrade "$1"
;;
edimax,cax1800)
nand_do_upgrade "$1"
;;
qnap,301w)
kernelname="0:HLOS"
rootfsname="rootfs"
mmc_do_upgrade "$1"
;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
part_num="$(fw_printenv -n flag_boot_rootfs)"
if [ "$part_num" -eq "0" ]; then
CI_UBIPART="rootfs_1"
target_num=1
# Reset fail flag for the current partition
# With both partition set to fail, the partition 2 (bit 1)
# is loaded
fw_setenv flag_try_sys2_failed 0
else
CI_UBIPART="rootfs"
target_num=0
# Reset fail flag for the current partition
# or uboot will skip the loading of this partition
fw_setenv flag_try_sys1_failed 0
fi
# Tell uboot to switch partition
fw_setenv flag_boot_rootfs $target_num
fw_setenv flag_last_success $target_num
# Reset success flag
fw_setenv flag_boot_success 0
nand_do_upgrade "$1"
;;
*)
default_do_upgrade "$1"
;;
esac
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment