octeon: n821: sysupgrade for Cisco vEdge 1000

This commit adds the logic required to install OpenWrt on a
Cisco/Viptela vEdge 1000 while nicely integrating with the already
present bootloader and making it possible to roll back to stock OS.

The vEdge 1000 has a built-in SSD with a ext2 partition from which
the stock u-boot boots the Linux kernel from.

In order for Linux not to be confused about which partition the root
file system is on, there are some tricks needed to ensure the partition
is identifiable at boot time. For this we use blkid as part of the
scripts, and sfdisk as part of the manual installation process
documented on the wiki. Thus, those packages have been added as a
platform dependency. Finally, the u-boot environment is updated which
requires the use of uboot-envtools.

Tested on a Cisco vEdge 1000.

Signed-off-by: Christian Svensson <blue@cmd.nu>
Link: https://github.com/openwrt/openwrt/pull/16140
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Christian Svensson 2024-08-11 13:27:49 +02:00 committed by Robert Marko
parent 64dae1052b
commit 9bc782dfd8
3 changed files with 77 additions and 14 deletions

View file

@ -4,29 +4,46 @@ move_config() {
. /lib/upgrade/common.sh . /lib/upgrade/common.sh
local device="$1" local device="$1"
local fstype="$2"
[ -n "$device" ] && [ -b "$device" ] && { [ -n "$device" ] && [ -b "$device" ] && {
mount -t vfat "$device" /mnt mount -t "${fstype}" "$device" /mnt
[ -f "/mnt/$BACKUP_FILE" ] && mv -f "/mnt/$BACKUP_FILE" / [ -f "/mnt/$BACKUP_FILE" ] && mv -f "/mnt/$BACKUP_FILE" /
umount /mnt umount /mnt
} }
} }
octeon_get_n821_disk() {
local partnum=$1
local MAJOR MINOR DEVNAME DEVTYPE
while read line; do
export -n "${line}"
done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
echo "/dev/${DEVNAME}${partnum}"
}
octeon_move_config() { octeon_move_config() {
. /lib/functions.sh . /lib/functions.sh
case "$(board_name)" in case "$(board_name)" in
erlite|\ erlite|\
ubnt,usg) ubnt,usg)
move_config "/dev/sda1" move_config "/dev/sda1" "vfat"
;; ;;
itus,shield-router) itus,shield-router)
move_config "/dev/mmcblk1p1" move_config "/dev/mmcblk1p1" "vfat"
;; ;;
er|\ er|\
ubnt,edgerouter-4|\ ubnt,edgerouter-4|\
ubnt,edgerouter-6p) ubnt,edgerouter-6p)
move_config "/dev/mmcblk0p1" move_config "/dev/mmcblk0p1" "vfat"
;; ;;
cisco,vedge1000)
# Copy from the internal USB disk's first partition.
# It is resolved from the device path to not be dependent on which
# /dev/sd? path it is at, nor which UUID it happens to have.
move_config "$(octeon_get_n821_disk 1)" "ext2"
;;
esac esac
} }

View file

@ -2,11 +2,21 @@
# Copyright (C) 2021 OpenWrt.org # Copyright (C) 2021 OpenWrt.org
# #
if [ -x /usr/sbin/blkid ]; then
RAMFS_COPY_BIN="/usr/sbin/blkid"
fi
platform_get_rootfs() { platform_get_rootfs() {
local rootfsdev local rootfsdev
local rootpartuuid
if read cmdline < /proc/cmdline; then if read cmdline < /proc/cmdline; then
case "$cmdline" in case "$cmdline" in
*root=PARTUUID=*)
rootpartuuid="${cmdline##*root=PARTUUID=}"
rootpartuuid="${rootpartuuid%% *}"
rootfsdev="$(blkid -o device -t PARTUUID="${rootpartuuid}")"
;;
*root=*) *root=*)
rootfsdev="${cmdline##*root=}" rootfsdev="${cmdline##*root=}"
rootfsdev="${rootfsdev%% *}" rootfsdev="${rootfsdev%% *}"
@ -17,10 +27,20 @@ platform_get_rootfs() {
fi fi
} }
platform_get_n821_disk() {
local partnum=$1
local DEVNAME
while read line; do
export -n "${line}"
done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
echo "/dev/${DEVNAME}${partnum}"
}
platform_copy_config_helper() { platform_copy_config_helper() {
local device=$1 local device=$1
local fstype=$2
mount -t vfat "$device" /mnt mount -t "${fstype}" "$device" /mnt
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE" cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
umount /mnt umount /mnt
} }
@ -29,15 +49,18 @@ platform_copy_config() {
case "$(board_name)" in case "$(board_name)" in
erlite|\ erlite|\
ubnt,usg) ubnt,usg)
platform_copy_config_helper /dev/sda1 platform_copy_config_helper /dev/sda1 vfat
;; ;;
itus,shield-router) itus,shield-router)
platform_copy_config_helper /dev/mmcblk1p1 platform_copy_config_helper /dev/mmcblk1p1 vfat
;; ;;
er|\ er|\
ubnt,edgerouter-4|\ ubnt,edgerouter-4|\
ubnt,edgerouter-6p) ubnt,edgerouter-6p)
platform_copy_config_helper /dev/mmcblk0p1 platform_copy_config_helper /dev/mmcblk0p1 vfat
;;
cisco,vedge1000)
platform_copy_config_helper "$(platform_get_n821_disk 1)" ext2
;; ;;
esac esac
} }
@ -61,14 +84,26 @@ platform_do_flash() {
echo "flashing Itus Kernel to /boot/$kernel (/dev/mmblk1p1)" echo "flashing Itus Kernel to /boot/$kernel (/dev/mmblk1p1)"
tar -Oxf $tar_file "$board_dir/kernel" > /boot/$kernel tar -Oxf $tar_file "$board_dir/kernel" > /boot/$kernel
else else
mount -t vfat /dev/$kernel /boot if [ "${board}" = "cisco,vedge1000" ]; then
local rootpartuuid
rootpartuuid="$(/usr/sbin/blkid -o value -s PARTUUID "${rootfs}")"
if [ -n "${rootpartuuid}" ]; then
echo "setting root partition to PARTUUID=${rootpartuuid}"
fw_setenv bootcmd 'usb start; ext2load usb 0:1 $loadaddr vmlinux.64; bootoctlinux $loadaddr coremask=f endbootargs rootfstype=squashfs rootwait root=PARTUUID='"${rootpartuuid}"
else
echo "WARNING: unable to figure out root partition UUID, leaving bootcmd unchanged"
fi
mount -t ext2 "${kernel}" /boot
else
mount -t vfat "${kernel}" /boot
fi
[ -f /boot/vmlinux.64 -a ! -L /boot/vmlinux.64 ] && { [ -f /boot/vmlinux.64 -a ! -L /boot/vmlinux.64 ] && {
mv /boot/vmlinux.64 /boot/vmlinux.64.previous mv /boot/vmlinux.64 /boot/vmlinux.64.previous
mv /boot/vmlinux.64.md5 /boot/vmlinux.64.md5.previous mv /boot/vmlinux.64.md5 /boot/vmlinux.64.md5.previous
} }
echo "flashing kernel to /dev/$kernel" echo "flashing kernel to $(awk '/\/boot/ {print $1}' /proc/mounts)"
tar xf $tar_file $board_dir/kernel -O > /boot/vmlinux.64 tar xf $tar_file $board_dir/kernel -O > /boot/vmlinux.64
md5sum /boot/vmlinux.64 | cut -f1 -d " " > /boot/vmlinux.64.md5 md5sum /boot/vmlinux.64 | cut -f1 -d " " > /boot/vmlinux.64.md5
fi fi
@ -86,20 +121,27 @@ platform_do_upgrade() {
local rootfs="$(platform_get_rootfs)" local rootfs="$(platform_get_rootfs)"
local kernel= local kernel=
if [ ! -b "${rootfs}" ] && [ "${board}" = "cisco,vedge1000" ]; then
# Default to the built-in USB disk for N821
rootfs="$(platform_get_n821_disk 2)"
fi
[ -b "${rootfs}" ] || return 1 [ -b "${rootfs}" ] || return 1
case "$board" in case "$board" in
er | \ er | \
ubnt,edgerouter-4 | \ ubnt,edgerouter-4 | \
ubnt,edgerouter-6p) ubnt,edgerouter-6p)
kernel=mmcblk0p1 kernel=/dev/mmcblk0p1
;; ;;
erlite|\ erlite|\
ubnt,usg) ubnt,usg)
kernel=sda1 kernel=/dev/sda1
;; ;;
itus,shield-router) itus,shield-router)
kernel=ItusrouterImage kernel=ItusrouterImage
;; ;;
cisco,vedge1000)
kernel="$(platform_get_n821_disk 1)"
;;
*) *)
return 1 return 1
esac esac
@ -123,7 +165,8 @@ platform_check_image() {
itus,shield-router | \ itus,shield-router | \
ubnt,edgerouter-4 | \ ubnt,edgerouter-4 | \
ubnt,edgerouter-6p | \ ubnt,edgerouter-6p | \
ubnt,usg) ubnt,usg | \
cisco,vedge1000)
local kernel_length=$(tar xf $tar_file $board_dir/kernel -O | wc -c 2> /dev/null) local kernel_length=$(tar xf $tar_file $board_dir/kernel -O | wc -c 2> /dev/null)
local rootfs_length=$(tar xf $tar_file $board_dir/root -O | wc -c 2> /dev/null) local rootfs_length=$(tar xf $tar_file $board_dir/root -O | wc -c 2> /dev/null)
[ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && { [ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && {

View file

@ -100,13 +100,16 @@ define Device/cisco_vedge1000
DEVICE_MODEL := vEdge 1000 DEVICE_MODEL := vEdge 1000
BOARD_NAME := cisco,vedge1000 BOARD_NAME := cisco,vedge1000
DEVICE_PACKAGES += \ DEVICE_PACKAGES += \
blkid \
kmod-hwmon-jc42 \ kmod-hwmon-jc42 \
kmod-hwmon-max6697 \ kmod-hwmon-max6697 \
kmod-of-mdio \ kmod-of-mdio \
kmod-rtc-ds1307 \ kmod-rtc-ds1307 \
kmod-usb-dwc3 \ kmod-usb-dwc3 \
kmod-usb-storage-uas \ kmod-usb-storage-uas \
kmod-usb3 kmod-usb3 \
sfdisk \
uboot-envtools
KERNEL := kernel-bin | append-dtb-elf KERNEL := kernel-bin | append-dtb-elf
KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts) KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts)
DEVICE_DTS := cn6130_cisco_vedge1000 DEVICE_DTS := cn6130_cisco_vedge1000