From 20fac016e432cf384289b3fefadf3f4909924faf Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Wed, 19 Aug 2015 08:31:23 +0000 Subject: [PATCH] mvebu: add support for the Linksys boot counter The u-boot boot counter was never reset after a successful boot, which sometimes could make some variables become out of sync. This patch adds support for the boot counter and enables auto_recovery unconditionally. Signed-off-by: Jonas Gorski Signed-off-by: Rob Mosher Signed-off-by: Imre Kaloz SVN-Revision: 46690 --- package/system/mtd/Makefile | 2 +- package/system/mtd/src/Makefile | 1 + package/system/mtd/src/linksys_bootcount.c | 114 ++++++++++++++++++ package/system/mtd/src/mtd.c | 12 ++ package/system/mtd/src/mtd.h | 1 + .../base-files/etc/init.d/linksys_recovery | 20 +++ .../mvebu/base-files/etc/init.d/u-boot_env | 14 --- 7 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 package/system/mtd/src/linksys_bootcount.c create mode 100755 target/linux/mvebu/base-files/etc/init.d/linksys_recovery delete mode 100755 target/linux/mvebu/base-files/etc/init.d/u-boot_env diff --git a/package/system/mtd/Makefile b/package/system/mtd/Makefile index 8d7bb44aa0ae..ae1922fbd9b3 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 27ac339005fa..40a165e4e64d 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 = linksys_bootcount.o ifdef FIS_SUPPORT obj += fis.o diff --git a/package/system/mtd/src/linksys_bootcount.c b/package/system/mtd/src/linksys_bootcount.c new file mode 100644 index 000000000000..95f75fe4ba72 --- /dev/null +++ b/package/system/mtd/src/linksys_bootcount.c @@ -0,0 +1,114 @@ +/* + * Linksys boot counter reset code for mtd + * + * Copyright (C) 2013 Jonas Gorski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License v2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mtd.h" + +#define BOOTCOUNT_MAGIC 0x20110811 + +struct bootcounter { + uint32_t magic; + uint32_t count; + uint32_t checksum; +}; + +static char page[2048]; + +int mtd_resetbc(const char *mtd) +{ + 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!\n"); + 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) { + fprintf(stderr, "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) { + fprintf(stderr, "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) + fprintf(stderr, "failed to write: %i\n", ret); + sync(); +out: + close(fd); + + return 0; +} diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index 741b57b48070..02476306f65e 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -640,6 +640,10 @@ static void usage(void) " verify |- verify (use - for stdin) to device\n" " write |- write (use - for stdin) to device\n" " jffs2write append to the jffs2 partition on the device\n"); + if (mtd_resetbc) { + fprintf(stderr, + " resetbc reset the uboot boot counter\n"); + } if (mtd_fixtrx) { fprintf(stderr, " fixtrx fix the checksum in a trx header on first boot\n"); @@ -706,6 +710,7 @@ int main (int argc, char **argv) CMD_FIXSEAMA, CMD_VERIFY, CMD_DUMP, + CMD_RESETBC, } cmd = -1; erase[0] = NULL; @@ -800,6 +805,9 @@ int main (int argc, char **argv) } else if ((strcmp(argv[0], "erase") == 0) && (argc == 2)) { cmd = CMD_ERASE; device = argv[1]; + } else if (((strcmp(argv[0], "resetbc") == 0) && (argc == 2)) && mtd_resetbc) { + cmd = CMD_RESETBC; + device = argv[1]; } else if (((strcmp(argv[0], "fixtrx") == 0) && (argc == 2)) && mtd_fixtrx) { cmd = CMD_FIXTRX; device = argv[1]; @@ -891,6 +899,10 @@ int main (int argc, char **argv) case CMD_FIXTRX: if (mtd_fixtrx) { mtd_fixtrx(device, offset); + } + case CMD_RESETBC: + if (mtd_resetbc) { + mtd_resetbc(device); } case CMD_FIXSEAMA: if (mtd_fixseama) diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h index d94f394396c4..fb37b8b9fa6b 100644 --- a/package/system/mtd/src/mtd.h +++ b/package/system/mtd/src/mtd.h @@ -27,4 +27,5 @@ extern int trx_fixup(int fd, const char *name) __attribute__ ((weak)); extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak)); extern int mtd_fixtrx(const char *mtd, size_t offset) __attribute__ ((weak)); extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak)); +extern int mtd_resetbc(const char *mtd) __attribute__ ((weak)); #endif /* __mtd_h */ diff --git a/target/linux/mvebu/base-files/etc/init.d/linksys_recovery b/target/linux/mvebu/base-files/etc/init.d/linksys_recovery new file mode 100755 index 000000000000..60d7be06362a --- /dev/null +++ b/target/linux/mvebu/base-files/etc/init.d/linksys_recovery @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015 OpenWrt.org + +START=97 +boot() { +. /lib/functions.sh +. /lib/mvebu.sh + +case $(mvebu_board_name) in + armada-385-linksys-caiman|armada-385-linksys-cobra|armada-xp-linksys-mamba) + # make sure auto_recovery in uboot is always on + AUTO_RECOVERY_ENA="`fw_printenv -n auto_recovery`" + if [ "$AUTO_RECOVERY_ENA" != "yes" ] ; then + fw_setenv auto_recovery yes + fi + # reset the boot counter + mtd resetbc s_env + ;; +esac +} 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 deleted file mode 100755 index 82f36cb71fce..000000000000 --- a/target/linux/mvebu/base-files/etc/init.d/u-boot_env +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2015 OpenWrt.org - -START=97 -boot() { -. /lib/functions.sh -. /lib/mvebu.sh - -case $(mvebu_board_name) in - armada-385-linksys-caiman|armada-385-linksys-cobra|armada-xp-linksys-mamba) - fw_setenv auto_recovery off - ;; -esac -} -- 2.30.2