The uboot boot counter was never reset after a successful boot. This patch prevents bootcmd and boot_part from becoming out of sync after a sysupgrade and ensures the proper partition is booted.
Signed-off-by: Rob Mosher <[email protected]> --- package/system/mtd/Makefile | 2 +- package/system/mtd/src/Makefile | 1 + package/system/mtd/src/mvebu.c | 100 +++++++++++++++++++++ .../linux/mvebu/base-files/etc/init.d/u-boot_env | 1 + 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 package/system/mtd/src/mvebu.c diff --git a/package/system/mtd/Makefile b/package/system/mtd/Makefile index 8d7bb44..ae1922f 100644 --- a/package/system/mtd/Makefile +++ b/package/system/mtd/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mtd -PKG_RELEASE:=20 +PKG_RELEASE:=21 PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME) STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS) diff --git a/package/system/mtd/src/Makefile b/package/system/mtd/src/Makefile index 27ac339..3424dd2 100644 --- a/package/system/mtd/src/Makefile +++ b/package/system/mtd/src/Makefile @@ -10,6 +10,7 @@ obj.brcm47xx = $(obj.brcm) obj.bcm53xx = $(obj.brcm) obj.brcm63xx = imagetag.o obj.ramips = $(obj.seama) +obj.mvebu = mvebu.c ifdef FIS_SUPPORT obj += fis.o diff --git a/package/system/mtd/src/mvebu.c b/package/system/mtd/src/mvebu.c new file mode 100644 index 0000000..0929a97 --- /dev/null +++ b/package/system/mtd/src/mvebu.c @@ -0,0 +1,100 @@ +/* + * GPL Header ... + */ + + + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <endian.h> +#include <string.h> +#include <errno.h> + +#include <sys/ioctl.h> +#include <mtd/mtd-user.h> + +#include "mtd.h" + +#define BOOTCOUNT_MAGIC 0x20110811 + +struct bootcounter { + uint32_t magic; + uint32_t count; + uint32_t checksum; +}; + +static char page[2048]; + +int mtd_fixtrx(const char *mtd, size_t offset) +{ + struct mtd_info_user mtd_info; + struct bootcounter *curr = (struct bootcounter *)page; + unsigned int i; + int last_count = 0; + int num_bc; + int fd; + int ret; + + fd = mtd_check_open(mtd); + + if (ioctl(fd, MEMGETINFO, &mtd_info) < 0) { + fprintf(stderr, "failed to get mtd info!"); + return -1; + } + + num_bc = mtd_info.size / mtd_info.writesize; + + for (i = 0; i < num_bc; i++) { + pread(fd, curr, sizeof(*curr), i * mtd_info.writesize); + + if (curr->magic != BOOTCOUNT_MAGIC && curr->magic != 0xffffffff) { + printf("unexpected magic %08x, bailing out\n", curr->magic); + goto out; + } + + if (curr->magic == 0xffffffff) + break; + + last_count = curr->count; + } + + /* no need to do writes when last boot count is already 0 */ + if (last_count == 0) + goto out; + + + if (i == num_bc) { + struct erase_info_user erase_info; + erase_info.start = 0; + erase_info.length = mtd_info.size; + + /* erase block */ + ret = ioctl(fd, MEMERASE, &erase_info); + if (ret < 0) { + printf("failed to erase block: %i\n", ret); + return -1; + } + + i = 0; + } + + memset(curr, 0xff, mtd_info.writesize); + + curr->magic = BOOTCOUNT_MAGIC; + curr->count = 0; + curr->checksum = BOOTCOUNT_MAGIC; + + ret = pwrite(fd, curr, mtd_info.writesize, i * mtd_info.writesize); + if (ret < 0) + printf("failed to write: %i\n", ret); + sync(); +out: + close(fd); + + return 0; +} diff --git a/target/linux/mvebu/base-files/etc/init.d/u-boot_env b/target/linux/mvebu/base-files/etc/init.d/u-boot_env index 82f36cb..2869dd6 100755 --- a/target/linux/mvebu/base-files/etc/init.d/u-boot_env +++ b/target/linux/mvebu/base-files/etc/init.d/u-boot_env @@ -9,6 +9,7 @@ boot() { case $(mvebu_board_name) in armada-385-linksys-caiman|armada-385-linksys-cobra|armada-xp-linksys-mamba) fw_setenv auto_recovery off + mtd fixtrx s_env ;; esac } -- 2.1.4 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
