cns3xxx: eliminate hardcoded kernel/rootfs partition split

This changes the sysupgrade format. To support upgrades from the old
firmware to the new one, legacy images are provided. Because of the old
partition split, these have to be specific to the NOR or SPI device.

The new sysupgrade images are suitable for begin put on flash directly,
and they are independent of NOR vs SPI flash variant.

Flashing back to old firmware is supported via using the old full-flash
images instead of the old sysupgrade images.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Felix Fietkau 2016-09-15 12:51:57 +02:00
parent 58fbe07560
commit 0b3a64f862
4 changed files with 36 additions and 171 deletions

View file

@ -1,112 +1,21 @@
. /lib/cns3xxx.sh
RAMFS_COPY_DATA="/lib/cns3xxx.sh"
PART_NAME=firmware
CI_BLKSZ=65536
platform_find_partitions() {
local first dev size erasesize name
while read dev size erasesize name; do
name=${name#'"'}; name=${name%'"'}
case "$name" in
vmlinux.bin.l7|kernel|linux|rootfs)
if [ -z "$first" ]; then
first="$name"
else
echo "$erasesize:$first:$name"
break
fi
;;
esac
done < /proc/mtd
}
platform_find_kernelpart() {
local part
for part in "${1%:*}" "${1#*:}"; do
case "$part" in
vmlinux.bin.l7|kernel|linux)
echo "$part"
break
;;
esac
done
}
platform_do_upgrade_combined() {
local partitions=$(platform_find_partitions)
local kernelpart=$(platform_find_kernelpart "${partitions#*:}")
local erase_size=$((0x${partitions%%:*})); partitions="${partitions#*:}"
local kern_length=0x$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null)
local kern_blocks=$(($kern_length / $CI_BLKSZ))
local root_blocks=$((0x$(dd if="$1" bs=2 skip=5 count=4 2>/dev/null) / $CI_BLKSZ))
v "platform_do_upgrade_combined"
v "partitions=$partitions"
v "kernelpart=$kernelpart"
v "erase_size=$erase_size"
v "kern_blocks=$kern_blocks"
v "root_blocks=$root_blocks"
if [ -n "$partitions" ] && [ -n "$kernelpart" ] && \
[ ${kern_blocks:-0} -gt 0 ] && \
[ ${root_blocks:-0} -gt 0 ] && \
[ ${erase_size:-0} -gt 0 ];
then
local append=""
[ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR"
dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null | mtd write - kernel
dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null | \
mtd -r $append write - rootfs
else
echo "invalid image"
fi
}
platform_check_image() {
local board=$(cns3xxx_board_name)
local magic="$(get_magic_word "$1")"
local magic_long="$(get_magic_long "$1")"
local magic="$(get_magic_long "$1")"
[ "$#" -gt 1 ] && return 1
case "$board" in
laguna)
[ "$magic" != "4349" ] && {
echo "Invalid image. Use *-sysupgrade.bin files on this board"
[ "$magic" != "27051956" ] && {
echo "Invalid image type."
return 1
}
local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null)
local md5_chk=$(dd if="$1" bs=$CI_BLKSZ skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}"
if [ -n "$md5_img" -a -n "$md5_chk" ] && [ "$md5_img" = "$md5_chk" ]; then
return 0
else
echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)"
return 1
fi
return 0
;;
esac
echo "Sysupgrade is not yet supported on $board."
return 1
}
platform_do_upgrade() {
local board=$(cns3xxx_board_name)
v "board=$board"
case "$board" in
laguna)
platform_do_upgrade_combined "$ARGV"
;;
*)
default_do_upgrade "$ARGV"
;;
esac
}
disable_watchdog() {

View file

@ -47,6 +47,8 @@ CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_OF=y
CONFIG_CLKSRC_PROBE=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="console=ttyS0,115200"
CONFIG_CMDLINE_FORCE=y
CONFIG_CNS3XXX_ETH=y
CONFIG_COMMON_CLK=y
CONFIG_CPU_32v6=y
@ -135,11 +137,6 @@ CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
@ -190,6 +187,8 @@ CONFIG_MTD_M25P80=y
CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PHYSMAP_OF is not set
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y

View file

@ -122,13 +122,8 @@ static struct mtd_partition laguna_nor_partitions[] = {
.size = SZ_128K,
.offset = SZ_256K,
}, {
.name = "kernel",
.size = SZ_2M,
.name = "firmware",
.offset = SZ_256K + SZ_128K,
}, {
.name = "rootfs",
.size = SZ_16M - SZ_256K - SZ_128K - SZ_2M,
.offset = SZ_256K + SZ_128K + SZ_2M,
},
};
@ -168,13 +163,8 @@ static struct mtd_partition laguna_spi_partitions[] = {
.size = SZ_256K,
.offset = SZ_256K,
}, {
.name = "kernel",
.size = SZ_1M + SZ_512K,
.name = "firmware",
.offset = SZ_512K,
}, {
.name = "rootfs",
.size = SZ_16M - SZ_2M,
.offset = SZ_2M,
},
};
@ -1017,49 +1007,19 @@ static int __init laguna_model_setup(void)
platform_device_register(&laguna_uart);
if (laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) {
switch (laguna_info.nor_flash_size) {
case 1:
laguna_nor_partitions[3].size = SZ_8M - SZ_256K - SZ_128K - SZ_2M;
laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
break;
case 2:
laguna_nor_partitions[3].size = SZ_16M - SZ_256K - SZ_128K - SZ_2M;
laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
break;
case 3:
laguna_nor_partitions[3].size = SZ_32M - SZ_256K - SZ_128K - SZ_2M;
laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
break;
case 4:
laguna_nor_partitions[3].size = SZ_64M - SZ_256K - SZ_128K - SZ_2M;
laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
break;
case 5:
laguna_nor_partitions[3].size = SZ_128M - SZ_256K - SZ_128K - SZ_2M;
laguna_nor_res.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
break;
}
laguna_nor_partitions[2].size =
(SZ_4M << laguna_info.nor_flash_size) -
laguna_nor_partitions[2].offset;
laguna_nor_res.end = CNS3XXX_FLASH_BASE +
laguna_nor_partitions[2].offset +
laguna_nor_partitions[2].size - 1;
platform_device_register(&laguna_nor_pdev);
}
if (laguna_info.config2_bitmap & (SPI_FLASH_LOAD)) {
switch (laguna_info.spi_flash_size) {
case 1:
laguna_spi_partitions[3].size = SZ_4M - SZ_2M;
break;
case 2:
laguna_spi_partitions[3].size = SZ_8M - SZ_2M;
break;
case 3:
laguna_spi_partitions[3].size = SZ_16M - SZ_2M;
break;
case 4:
laguna_spi_partitions[3].size = SZ_32M - SZ_2M;
break;
case 5:
laguna_spi_partitions[3].size = SZ_64M - SZ_2M;
break;
}
laguna_spi_partitions[2].size =
(SZ_2M << laguna_info.spi_flash_size) -
laguna_spi_partitions[2].offset;
spi_register_board_info(ARRAY_AND_SIZE(laguna_spi_devices));
}

View file

@ -11,14 +11,19 @@ define Image/Prepare
mkimage -A arm -O linux -T kernel -C none -a 0x20008000 -e 0x20008000 -n 'OpenWrt Linux-$(LINUX_VERSION)' -d $(KDIR)/zImage $(KDIR)/uImage
endef
LEGACY_NOR_KERNEL_SIZE = 2048k
LEGACY_SPI_KERNEL_SIZE = 1536k
# Build sysupgrade image
define BuildFirmware/Generic
dd if=$(KDIR)/uImage of=$(KDIR)/uImage.pad bs=64k conv=sync; \
dd if=$(KDIR)/root.$(1) of=$(KDIR)/root.$(1).pad bs=128k conv=sync; \
define BuildFirmware/Legacy
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(1)-sysupgrade.bin \
of=$(KDIR)/uImage.pad bs=$(3) count=1
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(1)-sysupgrade.bin \
of=$(KDIR)/root.$(1).pad bs=$(3) skip=1
sh $(TOPDIR)/scripts/combined-image.sh \
$(KDIR)/uImage.pad \
$(KDIR)/root.$(1).pad \
$(BIN_DIR)/$(IMG_PREFIX)-$(patsubst jffs2-%,jffs2,$(patsubst squashfs-%,squashfs,$(1)))-sysupgrade.bin
$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-legacy-sysupgrade.bin
endef
define Image/BuildKernel/Initramfs
@ -26,22 +31,14 @@ define Image/BuildKernel/Initramfs
endef
define Image/Build
cat $(KDIR)/uImage $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(1)-sysupgrade.bin
$(call Image/Build/$(1),$(1))
$(call BuildFirmware/Generic,$(1))
cp $(KDIR)/uImage $(BIN_DIR)/$(IMG_PREFIX)-uImage
$(call BuildFirmware/Legacy,$(1),laguna_spi,$(LEGACY_SPI_KERNEL_SIZE))
$(call BuildFirmware/Legacy,$(1),laguna_nor,$(LEGACY_NOR_KERNEL_SIZE))
endef
define Image/Build/squashfs
$(call prepare_generic_squashfs,$(KDIR)/root.$(1))
dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img bs=128k conv=sync
( \
dd if=$(KDIR)/uImage bs=2048k conv=sync; \
dd if=$(KDIR)/root.$(1) bs=128k conv=sync; \
) > $(BIN_DIR)/$(IMG_PREFIX)-$(1)_laguna_nor.bin
( \
dd if=$(KDIR)/uImage bs=1536k conv=sync; \
dd if=$(KDIR)/root.$(1) bs=256k conv=sync; \
) > $(BIN_DIR)/$(IMG_PREFIX)-$(1)_laguna_spi.bin
$(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(1)-sysupgrade.bin)
endef
$(eval $(call BuildImage))