From patchwork Tue Aug 18 22:56:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: nyt-openwrt@countercultured.net X-Patchwork-Id: 508518 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 58E711404A8 for ; Wed, 19 Aug 2015 08:57:54 +1000 (AEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 8DB0D28BC25; Wed, 19 Aug 2015 00:56:05 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 4CDF528BCD2 for ; Wed, 19 Aug 2015 00:55:32 +0200 (CEST) X-policyd-weight: using cached result; rate: -7.6 Received: from countercultured.net (countercultured.net [209.51.175.25]) by arrakis.dune.hu (Postfix) with SMTP for ; Wed, 19 Aug 2015 00:55:31 +0200 (CEST) Received: (qmail 26857 invoked by uid 1000); 18 Aug 2015 22:56:14 -0000 From: Rob Mosher To: kaloz@openwrt.org Date: Tue, 18 Aug 2015 18:56:14 -0400 Message-Id: <1439938574-26818-1-git-send-email-nyt-openwrt@countercultured.net> X-Mailer: git-send-email 2.1.4 Cc: Rob Mosher , Jonas Gorski , openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] [PATCH V2] Fix for mvebu (WRT1900AC/WRT1200AC/etc) boot counter X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" 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: Jonas Gorski Signed-off-by: Rob Mosher --- 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 + .../linux/mvebu/base-files/etc/init.d/u-boot_env | 1 + 6 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 package/system/mtd/src/linksys_bootcount.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..40a165e 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 0000000..95f75fe --- /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 741b57b..0247630 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]; @@ -892,6 +900,10 @@ int main (int argc, char **argv) if (mtd_fixtrx) { mtd_fixtrx(device, offset); } + case CMD_RESETBC: + if (mtd_resetbc) { + mtd_resetbc(device); + } case CMD_FIXSEAMA: if (mtd_fixseama) mtd_fixseama(device, 0); diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h index d94f394..fb37b8b 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/u-boot_env b/target/linux/mvebu/base-files/etc/init.d/u-boot_env index 82f36cb..bf038b2 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 resetbc s_env ;; esac }