From patchwork Fri Aug 5 16:23:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Wagner X-Patchwork-Id: 108698 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id C5F10B6F6F for ; Sat, 6 Aug 2011 02:21:31 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 909F4280A6; Fri, 5 Aug 2011 18:21:28 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Oby5HYfyGeS9; Fri, 5 Aug 2011 18:21:28 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D3D3C2809C; Fri, 5 Aug 2011 18:21:25 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9731A2809C for ; Fri, 5 Aug 2011 18:21:23 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 45QVU0Ribdod for ; Fri, 5 Aug 2011 18:21:22 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail.free-electrons.com (mail.free-electrons.com [88.190.12.23]) by theia.denx.de (Postfix) with ESMTP id 221322809A for ; Fri, 5 Aug 2011 18:21:20 +0200 (CEST) Received: by mail.free-electrons.com (Postfix, from userid 106) id B191D1DD; Fri, 5 Aug 2011 18:21:19 +0200 (CEST) Received: from localhost.localdomain (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id D2B3B143; Fri, 5 Aug 2011 18:21:11 +0200 (CEST) From: David Wagner To: u-boot@lists.denx.de Date: Fri, 5 Aug 2011 18:23:51 +0200 Message-Id: <1312561431-5302-1-git-send-email-david.wagner@free-electrons.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1312555798-29542-1-git-send-email-david.wagner@free-electrons.com> References: <1312555798-29542-1-git-send-email-david.wagner@free-electrons.com> Subject: [U-Boot] [PATCHv2] new tool mkenvimage: generates an env image from an arbitrary config file X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This tool takes a key=value configuration file (same as would a `printenv' show) and generates the corresponding environnment image, ready to be flashed. Signed-off-by: David Wagner --- Hi Thomas, This second version addresses all your comments except - as we discussed - the cast vs. struct part. tools/Makefile | 5 ++ tools/mkenvimage.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 0 deletions(-) create mode 100644 tools/mkenvimage.c diff --git a/tools/Makefile b/tools/Makefile index e813e1d..db8522f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -69,6 +69,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX) BIN_FILES-y += mkimage$(SFX) BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX) BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) +BIN_FILES-y += mkenvimage$(SFX) # Source files which exist outside the tools directory EXT_OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += common/env_embedded.o @@ -93,6 +94,7 @@ OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o NOPED_OBJ_FILES-y += os_support.o OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o NOPED_OBJ_FILES-y += ublimage.o +NOPED_OBJ_FILES-y += mkenvimage.o # Don't build by default #ifeq ($(ARCH),ppc) @@ -171,6 +173,9 @@ $(obj)bmp_logo$(SFX): $(obj)bmp_logo.o $(obj)envcrc$(SFX): $(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ +$(obj)mkenvimage$(SFX): $(obj)crc32.o $(obj)mkenvimage.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(obj)gen_eth_addr$(SFX): $(obj)gen_eth_addr.o $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTSTRIP) $@ diff --git a/tools/mkenvimage.c b/tools/mkenvimage.c new file mode 100644 index 0000000..175126a --- /dev/null +++ b/tools/mkenvimage.c @@ -0,0 +1,187 @@ +/* + * (C) Copyright 2011 Free Electrons + * David Wagner + * + * Inspired from envcrc.c: + * (C) Copyright 2001 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 + +extern uint32_t crc32 (uint32_t, const unsigned char *, unsigned int); + +#define CRC_SIZE sizeof(uint32_t) + +static void usage(void) +{ + printf("envcrc [-h] [-r] [-b] -s -o " + "\n" + "\n" + "\tThe input file is in format:\n" + "\t\tkey1=value1\n" + "\t\tkey2=value2\n" + "\t\t...\n" + "\t-r : the environment has two copies in flash\n" + "\t-b : the target is big endian (default is little endian)\n"); + +} + +int main(int argc, char **argv) +{ + uint32_t crc; + char *txt_filename = NULL, *bin_filename = NULL; + FILE *txt_file, *bin_file; + unsigned char *dataptr, *envptr; + unsigned int envsize, datasize = 0; + int bigendian = 0; + int redundant = 0; + + int option; + int ret = EXIT_SUCCESS; + + struct stat txt_file_stat; + + int i; + + opterr = 0; + + + /* Parse the cmdline */ + while ((option = getopt(argc, argv, "s:o:rbh")) != -1) { + switch (option) + { + case 's': + datasize = strtol(optarg, NULL, 0); + break; + case 'o': + bin_filename = strdup(optarg); + if (!bin_filename) { + fprintf(stderr, "Can't strdup() the output filename\n"); + return EXIT_FAILURE; + } + break; + case 'r': + redundant = 1; + break; + case 'b': + bigendian = 1; + break; + case 'h': + usage(); + return EXIT_SUCCESS; + default: + fprintf(stderr, "Wrong option -%c\n", option); + usage(); + return EXIT_FAILURE; + } + } + + + /* Check datasize and allocate the data */ + if (datasize == 0) { + fprintf(stderr, + "Please specify the size of the envrionnment partition.\n"); + usage(); + return EXIT_FAILURE; + } + + dataptr = calloc(datasize, 1); + if (!dataptr) { + fprintf(stderr, "Can't alloc dataptr.\n"); + return EXIT_FAILURE; + } + + /* envptr points to the beginning of the actual environment (after the + * crc and possible `redundant' bit */ + envsize = datasize - (CRC_SIZE + redundant); + envptr = dataptr + CRC_SIZE + redundant; + + + /* Check the configuration file ...*/ + txt_filename = strdup(argv[optind]); + if (!txt_filename) { + fprintf(stderr, "Can't strdup() the configuration filename\n"); + return EXIT_FAILURE; + } + ret = stat(txt_filename, &txt_file_stat); + if (ret == -1) { + fprintf(stderr, "Can't stat() on configuration file: %s", + strerror(errno)); + return EXIT_FAILURE; + } + if (txt_file_stat.st_size > envsize) { + fprintf(stderr, "The configuration file is larger than the " + "envrionnment partition size\n"); + return EXIT_FAILURE; + } + + /* ... and open it. */ + txt_file = fopen(txt_filename, "r"); + if (!txt_file) { + fprintf(stderr, "Can't open configuration file: %s", strerror(errno)); + return EXIT_FAILURE; + } + + + /* Read the raw configuration file and transform it */ + ret = fread(envptr, txt_file_stat.st_size, 1, txt_file); + if (ret != 1) { + fprintf(stderr, "Can't read the whole configuration file\n"); + return EXIT_FAILURE; + } + + for (i = 0 ; i < envsize ; i++) + if (envptr[i] == '\n') + envptr[i] = '\0'; + + ret = fclose(txt_file); + + + /* Computes the CRC and put it at the beginning of the data */ + crc = crc32(0, envptr, envsize); + + *((uint32_t*) dataptr) = bigendian ? htobe32(crc) : htole32(crc); + + bin_file = fopen(bin_filename, "w"); + if (!bin_file) { + fprintf(stderr, "Can't open output file: %s", strerror(errno)); + return EXIT_FAILURE; + } + + if (fwrite(dataptr, 1, datasize, bin_file) != datasize) { + fprintf(stderr, "fwrite() failed: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + ret = fclose(bin_file); + + + return ret; +}