From 56868f374f5ba88e766690236a41af36a1e51949 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 20 Feb 2008 18:00:42 +0200 Subject: ubi-tools: sanify old and new tools a bit This commit adds compatible options to new ubimkvol, ubirmvol, and ubiupdatevol and deletes corresponding old utilities. Signed-off-by: Artem Bityutskiy --- ubi-utils/new-utils/src/common.c | 18 ++ ubi-utils/new-utils/src/ubi-attach.c | 205 ------------ ubi-utils/new-utils/src/ubi-crc32.c | 125 -------- ubi-utils/new-utils/src/ubi-detach.c | 181 ----------- ubi-utils/new-utils/src/ubi-info.c | 409 ------------------------ ubi-utils/new-utils/src/ubi-mkvol.c | 288 ----------------- ubi-utils/new-utils/src/ubi-nize.c | 550 --------------------------------- ubi-utils/new-utils/src/ubi-rmvol.c | 170 ---------- ubi-utils/new-utils/src/ubi-update.c | 295 ------------------ ubi-utils/new-utils/src/ubiattach.c | 205 ++++++++++++ ubi-utils/new-utils/src/ubicrc32.c | 125 ++++++++ ubi-utils/new-utils/src/ubidetach.c | 181 +++++++++++ ubi-utils/new-utils/src/ubimkvol.c | 310 +++++++++++++++++++ ubi-utils/new-utils/src/ubinfo.c | 409 ++++++++++++++++++++++++ ubi-utils/new-utils/src/ubinize.c | 550 +++++++++++++++++++++++++++++++++ ubi-utils/new-utils/src/ubirmvol.c | 195 ++++++++++++ ubi-utils/new-utils/src/ubiupdatevol.c | 334 ++++++++++++++++++++ 17 files changed, 2327 insertions(+), 2223 deletions(-) delete mode 100644 ubi-utils/new-utils/src/ubi-attach.c delete mode 100644 ubi-utils/new-utils/src/ubi-crc32.c delete mode 100644 ubi-utils/new-utils/src/ubi-detach.c delete mode 100644 ubi-utils/new-utils/src/ubi-info.c delete mode 100644 ubi-utils/new-utils/src/ubi-mkvol.c delete mode 100644 ubi-utils/new-utils/src/ubi-nize.c delete mode 100644 ubi-utils/new-utils/src/ubi-rmvol.c delete mode 100644 ubi-utils/new-utils/src/ubi-update.c create mode 100644 ubi-utils/new-utils/src/ubiattach.c create mode 100644 ubi-utils/new-utils/src/ubicrc32.c create mode 100644 ubi-utils/new-utils/src/ubidetach.c create mode 100644 ubi-utils/new-utils/src/ubimkvol.c create mode 100644 ubi-utils/new-utils/src/ubinfo.c create mode 100644 ubi-utils/new-utils/src/ubinize.c create mode 100644 ubi-utils/new-utils/src/ubirmvol.c create mode 100644 ubi-utils/new-utils/src/ubiupdatevol.c (limited to 'ubi-utils/new-utils/src') diff --git a/ubi-utils/new-utils/src/common.c b/ubi-utils/new-utils/src/common.c index fec640d..50859dc 100644 --- a/ubi-utils/new-utils/src/common.c +++ b/ubi-utils/new-utils/src/common.c @@ -52,6 +52,24 @@ static int get_multiplier(const char *str) if (!strcmp(str, "GiB")) return 1024 * 1024 * 1024; + /* Handle deprecated stuff */ + if (!strcmp(str, "KB") || !strcmp(str, "Kib") || !strcmp(str, "kib") || + !strcmp(str, "kiB")) { + fprintf(stderr, "Warning: use \"KiB\" instead of \"%s\" to " + "specify Kilobytes - support will be removed\n", str); + return 1024; + } + if (!strcmp(str, "MB") || !strcmp(str, "Mib") || !strcmp(str, "mb")) { + fprintf(stderr, "Warning: use \"MiB\" instead of \"%s\", " + "this support will be removed\n", str); + return 1024*1024; + } + if (!strcmp(str, "GB") || !strcmp(str, "Gib") || !strcmp(str, "gb")) { + fprintf(stderr, "Warning: use \"GiB\" instead of \"%s\", " + "this support will be removed\n", str); + return 1024*1024*1024; + } + return -1; } diff --git a/ubi-utils/new-utils/src/ubi-attach.c b/ubi-utils/new-utils/src/ubi-attach.c deleted file mode 100644 index 7b231a6..0000000 --- a/ubi-utils/new-utils/src/ubi-attach.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2007 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to attach MTD devices to UBI. - * - * Author: Artem Bityutskiy - */ - -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-attach" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int mtdn; - int vidoffs; - const char *node; -}; - -static struct args args = { - .devn = UBI_DEV_NUM_AUTO, - .mtdn = -1, - .vidoffs = 0, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to attach MTD device to UBI."; - -static const char *optionsstr = -"-d, --devn= the number to assign to the newly created UBI device\n" -" (the number is assigned automatically if this is not\n" -" specified\n" -"-m, --mtdn= MTD device number to attach\n" -"-O, --vid-hdr-offset VID header offset (do not specify this unless you\n" -" really know what you do and the optimal defaults will\n" -" be used)\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-m ] [-d ]\n" -"\t\t[--mtdn=] [--devn ]\n" -"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n" -"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI and\n" -" and create UBI device number 3 (ubi3)"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "m:d:OhV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'm': - args.mtdn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.mtdn < 0) - return errmsg("bad MTD device number: \"%s\"", optarg); - - break; - - case 'o': - args.vidoffs = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vidoffs <= 0) - return errmsg("bad VID header offset: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI control device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI control device specified (use -h for help)"); - - if (args.mtdn == -1) - return errmsg("MTD device number was not specified (use -h for help)"); - - args.node = argv[optind]; - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_info ubi_info; - struct ubi_dev_info dev_info; - struct ubi_attach_request req; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - /* - * Make sure the kernel is fresh enough and this feature is supported. - */ - err = ubi_get_info(libubi, &ubi_info); - if (err) { - sys_errmsg("cannot get UBI information"); - goto out_libubi; - } - - if (ubi_info.ctrl_major == -1) { - errmsg("MTD attach/detach feature is not supported by your kernel"); - goto out_libubi; - } - - req.dev_num = args.devn; - req.mtd_num = args.mtdn; - req.vid_hdr_offset = args.vidoffs; - - err = ubi_attach_mtd(libubi, args.node, &req); - if (err) { - sys_errmsg("cannot attach mtd%d", args.mtdn); - goto out_libubi; - } - - /* Print some information about the new UBI device */ - err = ubi_get_dev_info1(libubi, req.dev_num, &dev_info); - if (err) { - sys_errmsg("cannot get information about newly created UBI device"); - goto out_libubi; - } - - printf("UBI device number %d, total %d LEBs (", dev_info.dev_num, dev_info.total_lebs); - ubiutils_print_bytes(dev_info.total_bytes, 0); - printf("), available %d LEBs (", dev_info.avail_lebs); - ubiutils_print_bytes(dev_info.avail_bytes, 0); - printf("), LEB size "); - ubiutils_print_bytes(dev_info.leb_size, 1); - printf("\n"); - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubi-crc32.c b/ubi-utils/new-utils/src/ubi-crc32.c deleted file mode 100644 index d3d3136..0000000 --- a/ubi-utils/new-utils/src/ubi-crc32.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Calculate CRC32 with UBI start value (0xFFFFFFFF) for a given binary image. - * - * Author: Oliver Lohmann - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "crc32.h" -#include "common.h" - -#define BUFSIZE 4096 - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-crc32" - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)"; - -static const char *optionsstr = -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-h] [--help]"; - -static const struct option long_options[] = { - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err = 0; - uint32_t crc = UBI_CRC32_INIT; - char buf[BUFSIZE]; - FILE *fp; - - if (argc > 1) { - fp = fopen(argv[1], "r"); - if (!fp) - return sys_errmsg("cannot open \"%s\"", argv[1]); - } else - fp = stdin; - - err = parse_opt(argc, argv); - if (err) - return err; - - while (!feof(fp)) { - size_t read; - - read = fread(buf, 1, BUFSIZE, fp); - if (ferror(fp)) { - sys_errmsg("cannot read input file"); - err = -1; - goto out_close; - } - crc = crc32(crc, buf, read); - } - - printf("0x%08x\n", crc); - -out_close: - if (fp != stdin) - fclose(fp); - return err; -} diff --git a/ubi-utils/new-utils/src/ubi-detach.c b/ubi-utils/new-utils/src/ubi-detach.c deleted file mode 100644 index 0ee7954..0000000 --- a/ubi-utils/new-utils/src/ubi-detach.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to delete UBI devices (detach MTD devices from UBI). - * - * Author: Artem Bityutskiy - */ - -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-detach" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int mtdn; - const char *node; -}; - -static struct args args = { - .devn = UBI_DEV_NUM_AUTO, - .mtdn = -1, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION -" - a tool to remove UBI devices (detach MTD devices from UBI)"; - -static const char *optionsstr = -"-d, --devn= UBI device number to delete\n" -"-m, --mtdn= or altrnatively, MTD device number to detach -\n" -" this will delete corresponding UBI device\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-d ] [-m ]\n" -"\t\t[--devn ] [--mtdn=]\n" -"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n" -"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - detach MTD device 0 (mtd0)"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "m:d:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'm': - args.mtdn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.mtdn < 0) - return errmsg("bad MTD device number: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI control device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI control device specified (use -h for help)"); - - if (args.mtdn == -1 && args.devn == -1) - return errmsg("neither MTD nor UBI devices were specified (use -h for help)"); - - if (args.mtdn != -1 && args.devn != -1) - return errmsg("specify either MTD or UBI device (use -h for help)"); - - args.node = argv[optind]; - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_info ubi_info; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - /* - * Make sure the kernel is fresh enough and this feature is supported. - */ - err = ubi_get_info(libubi, &ubi_info); - if (err) { - sys_errmsg("cannot get UBI information"); - goto out_libubi; - } - - if (ubi_info.ctrl_major == -1) { - errmsg("MTD detach/detach feature is not supported by your kernel"); - goto out_libubi; - } - - if (args.devn != -1) { - err = ubi_remove_dev(libubi, args.node, args.devn); - if (err) { - sys_errmsg("cannot remove ubi%d", args.devn); - goto out_libubi; - } - } else { - err = ubi_detach_mtd(libubi, args.node, args.mtdn); - if (err) { - sys_errmsg("cannot detach mtd%d", args.mtdn); - goto out_libubi; - } - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} - diff --git a/ubi-utils/new-utils/src/ubi-info.c b/ubi-utils/new-utils/src/ubi-info.c deleted file mode 100644 index d469a1a..0000000 --- a/ubi-utils/new-utils/src/ubi-info.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) 2007 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to get UBI information. - * - * Author: Artem Bityutskiy - */ - -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-nfo" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int vol_id; - int all; - const char *node; -}; - -static struct args args = { - .vol_id = -1, - .devn = -1, - .all = 0, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to print UBI information."; - -static const char *optionsstr = -"-d, --devn= UBI device number to get information about\n" -"-n, --vol_id= ID of UBI volume to print information about\n" -"-a, --all print information about all devices and volumes,\n" -" or about all volumes if the UBI device was\n" -" specified\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage 1: " PROGRAM_NAME " [-d ] [-n ] [-a] [-h] [-V] [--vol_id=]\n" -"\t\t[--devn ] [--all] [--help] [--version]\n" -"Usage 2: " PROGRAM_NAME " [-a] [-h] [-V] [--all] [--help] [--version]\n" -"Usage 3: " PROGRAM_NAME " [-h] [-V] [--help] [--version]\n\n" -"Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n" -"Example 2: " PROGRAM_NAME " -d 1 - print information about UBI device number 1\n" -"Example 3: " PROGRAM_NAME " /dev/ubi0 -a - print information about all volumes of UBI\n" -" device /dev/ubi0\n" -"Example 4: " PROGRAM_NAME " /dev/ubi1_0 - print information about UBI volume /dev/ubi1_0\n" -"Example 5: " PROGRAM_NAME " -a - print all information\n"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "all", .has_arg = 0, .flag = NULL, .val = 'a' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "an:d:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'a': - args.all = 1; - break; - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) - return errmsg("bad volume ID: " "\"%s\"", optarg); - break; - - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc - 1) - args.node = argv[optind]; - else if (optind < argc) - return errmsg("more then one UBI devices specified (use -h for help)"); - - return 0; -} - -static int translate_dev(libubi_t libubi, const char *node) -{ - int err; - - err = ubi_node_type(libubi, node); - if (err == -1) { - if (errno) - return errmsg("unrecognized device node \"%s\"", node); - return errmsg("\"%s\" does not correspond to any UBI device or volume", node); - } - - if (err == 1) { - struct ubi_dev_info dev_info; - - err = ubi_get_dev_info(libubi, node, &dev_info); - if (err) - return sys_errmsg("cannot get information about UBI device \"%s\"", node); - - args.devn = dev_info.dev_num; - } else { - struct ubi_vol_info vol_info; - - err = ubi_get_vol_info(libubi, node, &vol_info); - if (err) - return sys_errmsg("cannot get information about UBI volume \"%s\"", node); - - if (args.vol_id != -1) - return errmsg("both volume character device node (\"%s\") and " - "volume ID (%d) are specify, use only one of them" - "(use -h for help)", node, args.vol_id); - - args.devn = vol_info.dev_num; - args.vol_id = vol_info.vol_id; - } - - return 0; -} - -static int print_vol_info(libubi_t libubi, int dev_num, int vol_id) -{ - int err; - struct ubi_vol_info vol_info; - - err = ubi_get_vol_info1(libubi, dev_num, vol_id, &vol_info); - if (err) - return sys_errmsg("cannot get information about UBI volume %d on ubi%d", - vol_id, dev_num); - - printf("Volume ID: %d (on ubi%d)\n", vol_info.vol_id, vol_info.dev_num); - printf("Type: %s\n", - vol_info.type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"); - printf("Alignment: %d\n", vol_info.alignment); - - printf("Size: %d LEBs (", vol_info.rsvd_lebs); - ubiutils_print_bytes(vol_info.rsvd_bytes, 0); - printf(")\n"); - - if (vol_info.type == UBI_STATIC_VOLUME) { - printf("Data bytes: "); - ubiutils_print_bytes(vol_info.data_bytes, 1); - } - printf("State: %s\n", vol_info.corrupted ? "corrupted" : "OK"); - printf("Name: %s\n", vol_info.name); - printf("Character device major/minor: %d:%d\n", - vol_info.major, vol_info.minor); - - return 0; -} - -static int print_dev_info(libubi_t libubi, int dev_num, int all) -{ - int i, err, first = 1; - struct ubi_dev_info dev_info; - struct ubi_vol_info vol_info; - - err = ubi_get_dev_info1(libubi, dev_num, &dev_info); - if (err) - return sys_errmsg("cannot get information about UBI device %d", dev_num); - - printf("ubi%d:\n", dev_info.dev_num); - printf("Volumes count: %d\n", dev_info.vol_count); - printf("Logical eraseblock size: %d\n", dev_info.leb_size); - - printf("Total amount of logical eraseblocks: %d (", dev_info.total_lebs); - ubiutils_print_bytes(dev_info.total_bytes, 0); - printf(")\n"); - - printf("Amount of available logical eraseblocks: %d (", dev_info.avail_lebs); - ubiutils_print_bytes(dev_info.avail_bytes, 0); - printf(")\n"); - - printf("Maximum count of volumes %d\n", dev_info.max_vol_count); - printf("Count of bad physical eraseblocks: %d\n", dev_info.bad_count); - printf("Count of reserved physical eraseblocks: %d\n", dev_info.bad_rsvd); - printf("Current maximum erase counter value: %lld\n", dev_info.max_ec); - printf("Minimum input/output unit size: %d bytes\n", dev_info.min_io_size); - printf("Character device major/minor: %d:%d\n", - dev_info.major, dev_info.minor); - - if (dev_info.vol_count == 0) - return 0; - - printf("Present volumes: "); - for (i = dev_info.lowest_vol_num; - i <= dev_info.highest_vol_num; i++) { - err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe volume %d on ubi%d", - i, dev_info.dev_num); - } - - if (!first) - printf(", %d", i); - else { - printf("%d", i); - first = 0; - } - } - printf("\n"); - - if (!all) - return 0; - - first = 1; - printf("\n"); - - for (i = dev_info.lowest_vol_num; - i <= dev_info.highest_vol_num; i++) { - if(!first) - printf("-----------------------------------\n"); - err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe volume %d on ubi%d", - i, dev_info.dev_num); - } - first = 0; - - err = print_vol_info(libubi, dev_info.dev_num, i); - if (err) - return err; - } - - return 0; -} - -static int print_general_info(libubi_t libubi, int all) -{ - int i, err, first = 1; - struct ubi_info ubi_info; - struct ubi_dev_info dev_info; - - err = ubi_get_info(libubi, &ubi_info); - if (err) - return sys_errmsg("cannot get UBI information"); - - printf("UBI version: %d\n", ubi_info.version); - printf("Count of UBI devices: %d\n", ubi_info.dev_count); - if (ubi_info.ctrl_major != -1) - printf("UBI control device major/minor: %d:%d\n", - ubi_info.ctrl_major, ubi_info.ctrl_minor); - else - printf("UBI control device is not supported by this kernel\n"); - - if (ubi_info.dev_count == 0) - return 0; - - printf("Present UBI devices: "); - for (i = ubi_info.lowest_dev_num; - i <= ubi_info.highest_dev_num; i++) { - err = ubi_get_dev_info1(libubi, i, &dev_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe UBI device %d", i); - } - - if (!first) - printf(", ubi%d", i); - else { - printf("ubi%d", i); - first = 0; - } - } - printf("\n"); - - if (!all) - return 0; - - first = 1; - printf("\n"); - - for (i = ubi_info.lowest_dev_num; - i <= ubi_info.highest_dev_num; i++) { - if(!first) - printf("\n===================================\n\n"); - err = ubi_get_dev_info1(libubi, i, &dev_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe UBI device %d", i); - } - first = 0; - - err = print_dev_info(libubi, i, all); - if (err) - return err; - } - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - - err = parse_opt(argc, argv); - if (err) - return -1; - - if (!args.node && args.devn != -1) - return errmsg("specify either device number or node file (use -h for help)"); - - libubi = libubi_open(); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - if (args.node) { - /* - * A character device was specified, translate this into UBI - * device number and volume ID. - */ - err = translate_dev(libubi, args.node); - if (err) - goto out_libubi; - } - - if (args.vol_id != -1 && args.devn == -1) { - errmsg("volume ID is specified, but UBI device number is not " - "(use -h for help)\n"); - goto out_libubi; - } - - if (args.devn != -1 && args.vol_id != -1) { - print_vol_info(libubi, args.devn, args.vol_id); - goto out; - } - - if (args.devn == -1 && args.vol_id == -1) - err = print_general_info(libubi, args.all); - else if (args.devn != -1 && args.vol_id == -1) - err = print_dev_info(libubi, args.devn, args.all); - - if (err) - goto out_libubi; - -out: - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubi-mkvol.c b/ubi-utils/new-utils/src/ubi-mkvol.c deleted file mode 100644 index 49d1905..0000000 --- a/ubi-utils/new-utils/src/ubi-mkvol.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * An utility to create UBI volumes. - * - * Authors: Artem Bityutskiy - * Frank Haverkamp - */ - -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-mkvol" - -/* The variables below are set by command line arguments */ -struct args { - int vol_id; - int vol_type; - long long bytes; - int lebs; - int alignment; - const char *name; - int nlen; - const char *node; - int maxavs; -}; - -static struct args args = { - .vol_type = UBI_DYNAMIC_VOLUME, - .bytes = -1, - .lebs = -1, - .alignment = 1, - .vol_id = UBI_VOL_NUM_AUTO, - .name = NULL, - .nlen = 0, - .node = NULL, - .maxavs = 0, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to create UBI volumes."; - -static const char *optionsstr = -"-a, --alignment= volume alignment (default is 1)\n" -"-n, --vol_id= UBI volume ID, if not specified, the volume ID\n" -" will be assigned automatically\n" -"-N, --name= volume name\n" -"-s, --size= volume size volume size in bytes, kilobytes (KiB)\n" -" or megabytes (MiB)\n" -"-S, --lebs= alternative way to give volume size in logical\n" -" eraseblocks\n" -"-m, --maxavsize set volume size to maximum available size\n" -"-t, --type= volume type (dynamic, static), default is dynamic\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-h] [-a ] [-n ] [-N ]\n" -"\t\t\t[-s ] [-S ] [-t ] [-V] [-m]\n" -"\t\t\t[--alignment=][--vol_id=] [--name=]\n" -"\t\t\t[--size=] [--lebs=] [--type=] [--help]\n" -"\t\t\t[--version] [--maxavsize]\n\n" -"Example: " PROGRAM_NAME "/dev/ubi0 -s 20MiB -N config_data - create a 20 Megabytes volume\n" -" named \"config_data\" on UBI device /dev/ubi0."; - -static const struct option long_options[] = { - { .name = "alignment", .has_arg = 1, .flag = NULL, .val = 'a' }, - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, - { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "lebs", .has_arg = 1, .flag = NULL, .val = 'S' }, - { .name = "type", .has_arg = 1, .flag = NULL, .val = 't' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { .name = "maxavsize", .has_arg = 0, .flag = NULL, .val = 'm' }, - { NULL, 0, NULL, 0}, -}; - -static int param_sanity_check(void) -{ - int len; - - if (args.bytes == -1 && !args.maxavs && args.lebs == -1) - return errmsg("volume size was not specified (use -h for help)"); - - if ((args.bytes != -1 && (args.maxavs || args.lebs != -1)) || - (args.lebs != -1 && (args.maxavs || args.bytes != -1)) || - (args.maxavs && (args.bytes != -1 || args.lebs != -1))) - return errmsg("size specified with more then one option"); - - if (args.name == NULL) - return errmsg("volume name was not specified (use -h for help)"); - - len = strlen(args.name); - if (len > UBI_MAX_VOLUME_NAME) - return errmsg("too long name (%d symbols), max is %d", len, UBI_MAX_VOLUME_NAME); - - return 0; -} - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "a:n:N:s:S:t:hVm", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 't': - if (!strcmp(optarg, "dynamic")) - args.vol_type = UBI_DYNAMIC_VOLUME; - else if (!strcmp(optarg, "static")) - args.vol_type = UBI_STATIC_VOLUME; - else - return errmsg("bad volume type: \"%s\"", optarg); - break; - - case 's': - args.bytes = ubiutils_get_bytes(optarg); - if (args.bytes <= 0) - return errmsg("bad volume size: \"%s\"", optarg); - break; - - case 'S': - args.lebs = strtoull(optarg, &endp, 0); - if (endp == optarg || args.lebs <= 0 || *endp != '\0') - return errmsg("bad LEB count: \"%s\"", optarg); - break; - - case 'a': - args.alignment = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.alignment <= 0) - return errmsg("bad volume alignment: \"%s\"", optarg); - break; - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) - return errmsg("bad volume ID: " "\"%s\"", optarg); - break; - - case 'N': - args.name = optarg; - args.nlen = strlen(args.name); - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case 'm': - args.maxavs = 1; - break; - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI device specified (use -h for help)"); - - args.node = argv[optind]; - - if (param_sanity_check()) - return -1; - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_dev_info dev_info; - struct ubi_vol_info vol_info; - struct ubi_mkvol_request req; - - err = parse_opt(argc, argv); - if (err) - return err; - - libubi = libubi_open(); - if (!libubi) - return sys_errmsg("cannot open libubi"); - - err = ubi_node_type(libubi, args.node); - if (err == 2) { - errmsg("\"%s\" is an UBI volume node, not an UBI device node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI device node", args.node); - goto out_libubi; - } - - err = ubi_get_dev_info(libubi, args.node, &dev_info); - if (err) { - sys_errmsg("cannot get information about UBI device \"%s\"", - args.node); - goto out_libubi; - } - - if (args.maxavs) { - args.bytes = dev_info.avail_bytes; - printf("Set volume size to %lld\n", req.bytes); - } - - if (args.lebs != -1) { - args.bytes = dev_info.leb_size; - args.bytes -= dev_info.leb_size % args.alignment; - args.bytes *= args.lebs; - } - - req.vol_id = args.vol_id; - req.alignment = args.alignment; - req.bytes = args.bytes; - req.vol_type = args.vol_type; - req.name = args.name; - - err = ubi_mkvol(libubi, args.node, &req); - if (err < 0) { - sys_errmsg("cannot UBI create volume"); - goto out_libubi; - } - - args.vol_id = req.vol_id; - - /* Print information about the created device */ - err = ubi_get_vol_info1(libubi, dev_info.dev_num, args.vol_id, &vol_info); - if (err) { - sys_errmsg("cannot get information about newly created UBI volume"); - goto out_libubi; - } - - printf("Volume ID %d, size %d LEBs (", vol_info.vol_id, vol_info.rsvd_lebs); - ubiutils_print_bytes(vol_info.rsvd_bytes, 0); - printf("), LEB size "); - ubiutils_print_bytes(vol_info.leb_size, 1); - printf(", %s, name \"%s\", alignment %d\n", - req.vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static", - vol_info.name, vol_info.alignment); - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubi-nize.c b/ubi-utils/new-utils/src/ubi-nize.c deleted file mode 100644 index 532b193..0000000 --- a/ubi-utils/new-utils/src/ubi-nize.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Generate UBI images. - * - * Authors: Artem Bityutskiy - * Oliver Lohmann - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-nize" - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION -" - a tool to generate UBI images. An UBI image may contain one or more UBI " -"volumes which have to be defined in the input configuration ini-file. The " -"ini file defines all the UBI volumes - their characteristics and the and the " -"contents, but it does not define the characteristics of the flash the UBI " -"image is generated for. Instead, the flash characteristics are defined via " -"the command-line options. Note, if not sure about some of the command-line " -"parameters, do not specify them and let the utility to use default values."; - -static const char *optionsstr = -"-o, --output= output file name (default is stdout)\n" -"-p, --peb-size= size of the physical eraseblock of the flash\n" -" this UBI image is created for in bytes,\n" -" kilobytes (KiB), or megabytes (MiB)\n" -" (mandatory parameter)\n" -"-m, --min-io-size= minimum input/output unit size of the flash\n" -" in bytes\n" -"-s, --sub-page-size= minimum input/output unit used for UBI\n" -" headers, e.g. sub-page size in case of NAND\n" -" flash (equivalent to the minimum input/output\n" -" unit size by default)\n" -"-O, --vid-hdr-offset= offset if the VID header from start of the\n" -" physical eraseblock (default is the second\n" -" minimum I/O unit or sub-page, if it was\n" -" specified)\n" -"-e, --erase-counter= the erase counter value to put to EC headers\n" -" (default is 0)\n" -"-x, --ubi-ver= UBI version number to put to EC headers\n" -" (default is 1)\n" -"-v --verbose be verbose\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-o filename] [-h] [-V] [--output=] [--help]\n" -"\t\t[--version] ini-file\n" -"Example: " PROGRAM_NAME " -o ubi.img cfg.ini - create UBI image 'ubi.img' as\n" -" described by configuration file 'cfg.ini'"; - -static const char *ini_doc = "INI-file format.\n" -"The input configuration ini-file describes all the volumes which have to\n" -"be included to the output UBI image. Each volume is described in its own\n" -"section which may be named arbitrarily. The section consists on\n" -"\"key=value\" pairs, for example:\n\n" -"[jffs2-volume]\n" -"mode=ubi\n" -"image=../jffs2.img\n" -"vol_id=1\n" -"vol_size=30MiB\n" -"vol_type=dynamic\n" -"vol_name=jffs2_volume\n" -"vol_flags=autoresize\n" -"vol_alignment=1\n\n" -"This example configuration file tells the utility to create an UBI image\n" -"with one volume with ID 1, volume size 30MiB, the volume is dynamic, has\n" -"name \"jffs2_volume\", \"autoresize\" volume flag, and alignment 1. The\n" -"\"image=../jffs2.img\" line tells the utility to take the contents of the\n" -"volume from the \"../jffs2.img\" file. The size of the image file has to be\n" -"less or equivalent to the volume size (30MiB). The \"mode=ubi\" line is\n" -"mandatory and just tells that the section describes an UBI volume - other\n" -"section modes may be added in the future.\n" -"Notes:\n" -" * size in vol_size might be specified kilobytes (KiB), megabytes (MiB),\n" -" gigabytes (GiB) or bytes (no modifier);\n" -" * if \"vol_size\" key is absent, the volume size is assumed to be\n" -" equivalent to the size of the image file (defined by \"image\" key);\n" -" * if the \"image\" is absent, the volume is assumed to be empty;\n" -" * volume alignment must not be greater than the logical eraseblock size;\n" -" * one ini file may contain arbitrary number of sections, the utility will\n" -" put all the volumes which are described by these section to the output\n" -" UBI image file."; - -struct option long_options[] = { - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "peb-size", .has_arg = 1, .flag = NULL, .val = 'p' }, - { .name = "min-io-size", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, - { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, - { .name = "verbose", .has_arg = 1, .flag = NULL, .val = 'v' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -struct args { - const char *f_in; - const char *f_out; - FILE *fp_out; - int peb_size; - int min_io_size; - int subpage_size; - int vid_hdr_offs; - int ec; - int ubi_ver; - int verbose; - dictionary *dict; -}; - -static struct args args = { - .f_out = NULL, - .peb_size = -1, - .min_io_size = -1, - .subpage_size = -1, - .vid_hdr_offs = 0, - .ec = 0, - .ubi_ver = 1, - .verbose = 0, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "o:p:m:s:O:e:x:vhV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'o': - args.fp_out = fopen(optarg, "wb"); - if (!args.fp_out) - return errmsg("cannot open file \"%s\"", optarg); - args.f_out = optarg; - break; - - case 'p': - args.peb_size = ubiutils_get_bytes(optarg); - if (args.peb_size <= 0) - return errmsg("bad physical eraseblock size: \"%s\"", optarg); - break; - - case 'm': - args.min_io_size = ubiutils_get_bytes(optarg); - if (args.min_io_size <= 0) - return errmsg("bad min. I/O unit size: \"%s\"", optarg); - break; - - case 's': - args.subpage_size = ubiutils_get_bytes(optarg); - if (args.subpage_size <= 0) - return errmsg("bad sub-page size: \"%s\"", optarg); - break; - - case 'O': - args.vid_hdr_offs = strtoul(optarg, &endp, 0); - if (endp == optarg || args.vid_hdr_offs < 0) - return errmsg("bad VID header offset: \"%s\"", optarg); - break; - - case 'e': - args.ec = strtoul(optarg, &endp, 0); - if (endp == optarg || args.ec < 0) - return errmsg("bad erase counter value: \"%s\"", optarg); - break; - - case 'x': - args.ubi_ver = strtoul(optarg, &endp, 0); - if (endp == optarg || args.ubi_ver < 0) - return errmsg("bad UBI version: \"%s\"", optarg); - break; - - case 'v': - args.verbose = 1; - break; - - case 'h': - ubiutils_print_text(stderr, doc, 80); - fprintf(stderr, "\n%s\n\n", ini_doc); - fprintf(stderr, "%s\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("input configuration file was not specified (use -h for help)"); - - if (optind != argc - 1) - return errmsg("more then one configuration file was specified (use -h for help)"); - - args.f_in = argv[optind]; - - if (args.peb_size < 0) - return errmsg("physical eraseblock size was not specified (use -h for help)"); - - if (args.min_io_size < 0) - return errmsg("min. I/O unit size was not specified (use -h for help)"); - - if (args.subpage_size < 0) - args.subpage_size = args.min_io_size; - - if (!args.f_out) { - args.f_out = "stdout"; - args.fp_out = stdout; - } - - return 0; -} - -int read_section(const char *sname, struct ubigen_vol_info *vi, - const char **img) -{ - char buf[256]; - const char *p; - - *img = NULL; - - if (strlen(sname) > 128) - return errmsg("too long section name \"%s\"", sname); - - /* Make sure mode is UBI, otherwise ignore this section */ - sprintf(buf, "%s:mode", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) { - errmsg("\"mode\" key not found in section \"%s\"", sname); - errmsg("the \"mode\" key is mandatory and has to be " - "\"mode=ubi\" if the section describes an UBI volume"); - return -1; - } - - /* If mode is not UBI, skip this section */ - if (strcmp(p, "ubi")) { - verbose(args.verbose, "skip non-ubi section \"%s\"", sname); - return 1; - } - - verbose(args.verbose, "mode=ubi, keep parsing"); - - /* Fetch the name of the volume image file */ - sprintf(buf, "%s:image", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) - *img = p; - - /* Fetch volume id */ - sprintf(buf, "%s:vol_id", sname); - vi->id = iniparser_getint(args.dict, buf, -1); - if (vi->id == -1) - return errmsg("\"vol_id\" key not found in section \"%s\"", sname); - - if (vi->id < 0) - return errmsg("negative volume ID %d", vi->id); - - if (vi->id >= UBI_MAX_VOLUMES) - return errmsg("too high volume ID %d, max. is %d", vi->id, UBI_MAX_VOLUMES); - - verbose(args.verbose, "volume ID: %d", vi->id); - - /* Fetch volume size */ - sprintf(buf, "%s:vol_size", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) { - vi->bytes = ubiutils_get_bytes(p); - if (vi->bytes <= 0) - return errmsg("bad \"vol_size\" key: \"%s\"", p); - - verbose(args.verbose, "volume size: %lld bytes", vi->bytes); - } else { - struct stat st; - - if (!*img) - return errmsg("neither image file (\"image=\") nor volume size (\"vol_size=\") specified"); - - if (stat(*img, &st)) - return sys_errmsg("cannot stat \"%s\"", *img); - - vi->bytes = st.st_size; - - if (vi->bytes == 0) - return errmsg("file \"%s\" referred from section \"%s\" is empty", *img, sname); - - printf(PROGRAM_NAME ": volume size was not specified in" - "section \"%s\", assume ", sname); - ubiutils_print_bytes(vi->bytes, 1); - printf("\n"); - } - - /* Fetch volume type */ - sprintf(buf, "%s:vol_type", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) { - normsg(": volume type was not specified in " - "section \"%s\", assume \"dynamic\"\n", sname); - vi->type = UBI_VID_DYNAMIC; - } else { - if (!strcmp(p, "static")) - vi->type = UBI_VID_STATIC; - else if (!strcmp(p, "dynamic")) - vi->type = UBI_VID_DYNAMIC; - else - return errmsg("invalid volume type \"%s\"", p); - } - - verbose(args.verbose, "volume type: %s", - vi->type == UBI_VID_DYNAMIC ? "dynamic" : "static"); - - /* Fetch volume name */ - sprintf(buf, "%s:vol_name", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) - return errmsg("\"vol_name\" key not found in section \"%s\"", sname); - - vi->name = p; - vi->name_len = strlen(p); - if (vi->name_len > UBI_VOL_NAME_MAX) - return errmsg("too long volume name in section \"%s\", max. is %d characters", - vi->name, UBI_VOL_NAME_MAX); - - verbose(args.verbose, "volume name: %s", p); - - /* Fetch volume alignment */ - sprintf(buf, "%s:vol_alignment", sname); - vi->alignment = iniparser_getint(args.dict, buf, -1); - if (vi->alignment == -1) { - normsg("volume alignment was not specified in section " - "\"%s\", assume 1", sname); - vi->alignment = 1; - } else if (vi->id < 0) - return errmsg("negative volume alignement %d", vi->alignment); - - verbose(args.verbose, "volume alignment: %d", vi->alignment); - - /* Fetch volume flags */ - sprintf(buf, "%s:vol_flags", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) { - if (!strcmp(p, "autoresize")) { - verbose(args.verbose, "autoresize flags found"); - vi->flags |= UBI_VTBL_AUTORESIZE_FLG; - } else { - return errmsg("unknown flags \"%s\" in section \"%s\"", p, sname); - } - } - - return 0; -} - -static void init_vol_info(const struct ubigen_info *ui, - struct ubigen_vol_info *vi) -{ - vi->data_pad = ui->leb_size % vi->alignment; - vi->usable_leb_size = ui->leb_size - vi->data_pad; - vi->used_ebs = (vi->bytes + vi->usable_leb_size - 1) / vi->usable_leb_size; - vi->compat = 0; -} - -int main(int argc, char * const argv[]) -{ - int err = -1, sects, i, volumes; - struct ubigen_info ui; - struct ubi_vtbl_record *vtbl; - - err = parse_opt(argc, argv); - if (err) - return -1; - - ubigen_info_init(&ui, args.peb_size, args.min_io_size, - args.subpage_size, args.vid_hdr_offs, - args.ubi_ver, args.ec); - - verbose(args.verbose, "LEB size: %d", ui.leb_size); - verbose(args.verbose, "PEB size: %d", ui.peb_size); - verbose(args.verbose, "min_io_size: %d", ui.min_io_size); - verbose(args.verbose, "VID offset: %d", ui.vid_hdr_offs); - - vtbl = ubigen_create_empty_vtbl(&ui); - if (!vtbl) - goto out; - - args.dict = iniparser_load(args.f_in); - if (!args.dict) { - errmsg("cannot load the input ini file \"%s\"", args.f_in); - goto out_vtbl; - } - - verbose(args.verbose, "loaded the ini-file \"%s\"", args.f_in); - - /* Each section describes one volume */ - sects = iniparser_getnsec(args.dict); - if (sects == -1) { - errmsg("ini-file parsing error (iniparser_getnsec)"); - goto out_dict; - } - - verbose(args.verbose, "count of sections: %d", sects); - if (sects == 0) { - errmsg("no sections found the ini-file \"%s\"", args.f_in); - goto out_dict; - } - - /* - * Skip 2 PEBs at the beginning of the file for the volume table which - * will be written later. - */ - if (fseek(args.fp_out, ui.peb_size * 2, SEEK_SET) == -1) { - errmsg("cannot seek file \"%s\"", args.f_out); - goto out_dict; - } - - for (i = 0; i < sects; i++) { - const char *sname = iniparser_getsecname(args.dict, i); - struct ubigen_vol_info vi; - const char *img = NULL; - struct stat st; - FILE *f; - - if (!sname) { - errmsg("ini-file parsing error (iniparser_getsecname)"); - goto out_dict; - } - - if (args.verbose) - printf("\n"); - verbose(args.verbose, "parsing section \"%s\"", sname); - - err = read_section(sname, &vi, &img); - if (err == -1) - goto out_dict; - if (!err) - volumes += 1; - init_vol_info(&ui, &vi); - - verbose(args.verbose, "adding volume %d", vi.id); - - err = ubigen_add_volume(&ui, &vi, vtbl); - if (err) { - errmsg("cannot add volume for section \"%s\"", sname); - goto out_dict; - } - - if (!img) - continue; - - if (stat(img, &st)) { - sys_errmsg("cannot stat \"%s\"", img); - goto out_dict; - } - - /* - * Make sure the image size is not larger then the volume size. - */ - if (st.st_size > vi.bytes) { - errmsg("error in section \"%s\": size of the image file \"%s\" " - "is %lld, which is larger then the volume size %lld", - sname, img, (long long)st.st_size, vi.bytes); - goto out_dict; - } - - f = fopen(img, "r"); - if (!f) { - sys_errmsg("cannot open \"%s\"", img); - goto out_dict; - } - - verbose(args.verbose, "writing volume %d", vi.id); - verbose(args.verbose, "image file: %s", img); - - err = ubigen_write_volume(&ui, &vi, st.st_size, f, args.fp_out); - fclose(f); - if (err) { - errmsg("cannot write volume for section \"%s\"", sname); - goto out_dict; - } - - if (args.verbose) - printf("\n"); - } - - verbose(args.verbose, "writing layout volume"); - - if (fseek(args.fp_out, 0, SEEK_SET) == -1) { - errmsg("cannot seek file \"%s\"", args.f_out); - goto out_dict; - } - - err = ubigen_write_layout_vol(&ui, vtbl, args.fp_out); - if (err) { - errmsg("cannot write layout volume"); - goto out_dict; - } - - verbose(args.verbose, "done"); - - iniparser_freedict(args.dict); - free(vtbl); - fclose(args.fp_out); - return 0; - -out_dict: - iniparser_freedict(args.dict); -out_vtbl: - free(vtbl); -out: - fclose(args.fp_out); - remove(args.f_out); - return err; -} diff --git a/ubi-utils/new-utils/src/ubi-rmvol.c b/ubi-utils/new-utils/src/ubi-rmvol.c deleted file mode 100644 index 72bf069..0000000 --- a/ubi-utils/new-utils/src/ubi-rmvol.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * An utility to remove UBI volumes. - * - * Authors: Artem Bityutskiy - * Frank Haverkamp - */ - -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-rmvol" - -/* The variables below are set by command line arguments */ -struct args { - int vol_id; - const char *node; -}; - -static struct args args = { - .vol_id = -1, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to remove UBI volumes."; - -static const char *optionsstr = -" -n, --vol_id= volume ID to remove\n" -" -h, --help print help message\n" -" -V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-n ] [--vol_id=] [-h] [--help]\n\n" -"Example: " PROGRAM_NAME "/dev/ubi0 -n 1 - remove UBI volume 1 from UBI device corresponding\n" -" to the node file /dev/ubi0."; - -static const struct option long_options[] = { - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int param_sanity_check(void) -{ - if (args.vol_id == -1) { - errmsg("volume ID is was not specified"); - return -1; - } - - return 0; -} - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "n:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) { - errmsg("bad volume ID: " "\"%s\"", optarg); - return -1; - } - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - errmsg("parameter is missing"); - return -1; - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) { - errmsg("UBI device name was not specified (use -h for help)"); - return -1; - } else if (optind != argc - 1) { - errmsg("more then one UBI device specified (use -h for help)"); - return -1; - } - - args.node = argv[optind]; - - if (param_sanity_check()) - return -1; - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - err = ubi_node_type(libubi, args.node); - if (err == 2) { - errmsg("\"%s\" is an UBI volume node, not an UBI device node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI device node", args.node); - goto out_libubi; - } - - err = ubi_rmvol(libubi, args.node, args.vol_id); - if (err) { - sys_errmsg("cannot UBI remove volume"); - goto out_libubi; - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubi-update.c b/ubi-utils/new-utils/src/ubi-update.c deleted file mode 100644 index bf548a9..0000000 --- a/ubi-utils/new-utils/src/ubi-update.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * An utility to update UBI volumes. - * - * Authors: Frank Haverkamp - * Joshua W. Boyer - * Artem Bityutskiy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubi-update" - -struct args { - int truncate; - const char *node; - const char *img; -}; - -static struct args args = { - .truncate = 0, - .node = NULL, - .img = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to write data to UBI volumes."; - -static const char *optionsstr = -"-n, --vol_id= ID of UBI volume to update\n" -"-t, --truncate truncate volume (wipe it out)\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-t] [-h] [-V] [--truncate] [--help]\n" -"\t\t[--version] \n\n" -"Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - write file \"fs.img\" to UBI volume /dev/ubi0_1\n" -"Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1"; - -struct option long_options[] = { - { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "n:thV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 't': - args.truncate = 1; - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI device name was not specified (use -h for help)"); - else if (optind != argc - 2) - return errmsg("specify UBI device name and image file name as first 2 " - "parameters (use -h for help)"); - - args.node = argv[optind]; - args.img = argv[optind + 1]; - - return 0; -} - -static int truncate_volume(libubi_t libubi) -{ - int err, fd; - - fd = open(args.node, O_RDWR); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", args.node); - - err = ubi_update_start(libubi, fd, 0); - if (err) { - sys_errmsg("cannot truncate volume \"%s\"", args.node); - close(fd); - return -1; - } - - close(fd); - return 0; -} - -static int ubi_write(int fd, const void *buf, int len) -{ - int ret; - - while (len) { - ret = write(fd, buf, len); - if (ret < 0) { - if (errno == EINTR) { - warnmsg("do not interrupt me!"); - continue; - } - return sys_errmsg("cannot write %d bytes to volume \"%s\"", - len, args.node); - } - - if (ret == 0) - return errmsg("cannot write %d bytes to volume \"%s\"", len, args.node); - - len -= ret; - buf += ret; - } - - return 0; -} - -static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) -{ - int err, fd, ifd; - long long bytes; - struct stat st; - char *buf; - - buf = malloc(vol_info->leb_size); - if (!buf) - return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); - - err = stat(args.img, &st); - if (err < 0) { - errmsg("stat failed on \"%s\"", args.node); - goto out_free; - } - - bytes = st.st_size; - if (bytes > vol_info->rsvd_bytes) { - errmsg("\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)", - args.img, bytes, args.node, vol_info->rsvd_bytes); - goto out_free; - } - - fd = open(args.node, O_RDWR); - if (fd == -1) { - sys_errmsg("cannot open UBI volume \"%s\"", args.node); - goto out_free; - } - - ifd = open(args.img, O_RDONLY); - if (ifd == -1) { - sys_errmsg("cannot open \"%s\"", args.img); - goto out_close1; - } - - err = ubi_update_start(libubi, fd, bytes); - if (err) { - sys_errmsg("cannot start volume \"%s\" update", args.node); - goto out_close; - } - - while (bytes) { - int tocopy = vol_info->leb_size; - - if (tocopy > bytes) - tocopy = bytes; - - err = read(ifd, buf, tocopy); - if (err != tocopy) { - if (errno == EINTR) { - warnmsg("do not interrupt me!"); - continue; - } else { - sys_errmsg("cannot read %d bytes from \"%s\"", - tocopy, args.img); - goto out_close; - } - } - - err = ubi_write(fd, buf, tocopy); - if (err) - goto out_close; - bytes -= tocopy; - } - - close(ifd); - close(fd); - free(buf); - return 0; - -out_close: - close(ifd); -out_close1: - close(fd); -out_free: - free(buf); - return -1; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_vol_info vol_info; - - err = parse_opt(argc, argv); - if (err) - return -1; - - if (!args.img && !args.truncate) - return errmsg("incorrect arguments, use -h for help"); - - libubi = libubi_open(); - if (libubi == NULL) { - sys_errmsg("cannot open libubi"); - goto out_libubi; - } - - err = ubi_node_type(libubi, args.node); - if (err == 1) { - errmsg("\"%s\" is an UBI device node, not an UBI volume node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI volume node", args.node); - goto out_libubi; - } - - err = ubi_get_vol_info(libubi, args.node, &vol_info); - if (err) { - sys_errmsg("cannot get information about UBI volume \"%s\"", - args.node); - goto out_libubi; - } - - if (args.truncate) - err = truncate_volume(libubi); - else - err = update_volume(libubi, &vol_info); - if (err) - goto out_libubi; - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubiattach.c b/ubi-utils/new-utils/src/ubiattach.c new file mode 100644 index 0000000..b3d768a --- /dev/null +++ b/ubi-utils/new-utils/src/ubiattach.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to attach MTD devices to UBI. + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubiattach" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int mtdn; + int vidoffs; + const char *node; +}; + +static struct args args = { + .devn = UBI_DEV_NUM_AUTO, + .mtdn = -1, + .vidoffs = 0, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to attach MTD device to UBI."; + +static const char *optionsstr = +"-d, --devn= the number to assign to the newly created UBI device\n" +" (the number is assigned automatically if this is not\n" +" specified\n" +"-m, --mtdn= MTD device number to attach\n" +"-O, --vid-hdr-offset VID header offset (do not specify this unless you\n" +" really know what you do and the optimal defaults will\n" +" be used)\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-m ] [-d ]\n" +"\t\t[--mtdn=] [--devn ]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI and\n" +" and create UBI device number 3 (ubi3)"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "m:d:OhV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'm': + args.mtdn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.mtdn < 0) + return errmsg("bad MTD device number: \"%s\"", optarg); + + break; + + case 'o': + args.vidoffs = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vidoffs <= 0) + return errmsg("bad VID header offset: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc) + return errmsg("UBI control device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI control device specified (use -h for help)"); + + if (args.mtdn == -1) + return errmsg("MTD device number was not specified (use -h for help)"); + + args.node = argv[optind]; + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_info ubi_info; + struct ubi_dev_info dev_info; + struct ubi_attach_request req; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + /* + * Make sure the kernel is fresh enough and this feature is supported. + */ + err = ubi_get_info(libubi, &ubi_info); + if (err) { + sys_errmsg("cannot get UBI information"); + goto out_libubi; + } + + if (ubi_info.ctrl_major == -1) { + errmsg("MTD attach/detach feature is not supported by your kernel"); + goto out_libubi; + } + + req.dev_num = args.devn; + req.mtd_num = args.mtdn; + req.vid_hdr_offset = args.vidoffs; + + err = ubi_attach_mtd(libubi, args.node, &req); + if (err) { + sys_errmsg("cannot attach mtd%d", args.mtdn); + goto out_libubi; + } + + /* Print some information about the new UBI device */ + err = ubi_get_dev_info1(libubi, req.dev_num, &dev_info); + if (err) { + sys_errmsg("cannot get information about newly created UBI device"); + goto out_libubi; + } + + printf("UBI device number %d, total %d LEBs (", dev_info.dev_num, dev_info.total_lebs); + ubiutils_print_bytes(dev_info.total_bytes, 0); + printf("), available %d LEBs (", dev_info.avail_lebs); + ubiutils_print_bytes(dev_info.avail_bytes, 0); + printf("), LEB size "); + ubiutils_print_bytes(dev_info.leb_size, 1); + printf("\n"); + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff --git a/ubi-utils/new-utils/src/ubicrc32.c b/ubi-utils/new-utils/src/ubicrc32.c new file mode 100644 index 0000000..100b3cd --- /dev/null +++ b/ubi-utils/new-utils/src/ubicrc32.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Calculate CRC32 with UBI start value (0xFFFFFFFF) for a given binary image. + * + * Author: Oliver Lohmann + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "crc32.h" +#include "common.h" + +#define BUFSIZE 4096 + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubicrc32" + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)"; + +static const char *optionsstr = +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-h] [--help]"; + +static const struct option long_options[] = { + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err = 0; + uint32_t crc = UBI_CRC32_INIT; + char buf[BUFSIZE]; + FILE *fp; + + if (argc > 1) { + fp = fopen(argv[1], "r"); + if (!fp) + return sys_errmsg("cannot open \"%s\"", argv[1]); + } else + fp = stdin; + + err = parse_opt(argc, argv); + if (err) + return err; + + while (!feof(fp)) { + size_t read; + + read = fread(buf, 1, BUFSIZE, fp); + if (ferror(fp)) { + sys_errmsg("cannot read input file"); + err = -1; + goto out_close; + } + crc = crc32(crc, buf, read); + } + + printf("0x%08x\n", crc); + +out_close: + if (fp != stdin) + fclose(fp); + return err; +} diff --git a/ubi-utils/new-utils/src/ubidetach.c b/ubi-utils/new-utils/src/ubidetach.c new file mode 100644 index 0000000..cd48368 --- /dev/null +++ b/ubi-utils/new-utils/src/ubidetach.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to delete UBI devices (detach MTD devices from UBI). + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubidetach" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int mtdn; + const char *node; +}; + +static struct args args = { + .devn = UBI_DEV_NUM_AUTO, + .mtdn = -1, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION +" - a tool to remove UBI devices (detach MTD devices from UBI)"; + +static const char *optionsstr = +"-d, --devn= UBI device number to delete\n" +"-m, --mtdn= or altrnatively, MTD device number to detach -\n" +" this will delete corresponding UBI device\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-d ] [-m ]\n" +"\t\t[--devn ] [--mtdn=]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - detach MTD device 0 (mtd0)"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "m:d:hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'm': + args.mtdn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.mtdn < 0) + return errmsg("bad MTD device number: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc) + return errmsg("UBI control device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI control device specified (use -h for help)"); + + if (args.mtdn == -1 && args.devn == -1) + return errmsg("neither MTD nor UBI devices were specified (use -h for help)"); + + if (args.mtdn != -1 && args.devn != -1) + return errmsg("specify either MTD or UBI device (use -h for help)"); + + args.node = argv[optind]; + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_info ubi_info; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + /* + * Make sure the kernel is fresh enough and this feature is supported. + */ + err = ubi_get_info(libubi, &ubi_info); + if (err) { + sys_errmsg("cannot get UBI information"); + goto out_libubi; + } + + if (ubi_info.ctrl_major == -1) { + errmsg("MTD detach/detach feature is not supported by your kernel"); + goto out_libubi; + } + + if (args.devn != -1) { + err = ubi_remove_dev(libubi, args.node, args.devn); + if (err) { + sys_errmsg("cannot remove ubi%d", args.devn); + goto out_libubi; + } + } else { + err = ubi_detach_mtd(libubi, args.node, args.mtdn); + if (err) { + sys_errmsg("cannot detach mtd%d", args.mtdn); + goto out_libubi; + } + } + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} + diff --git a/ubi-utils/new-utils/src/ubimkvol.c b/ubi-utils/new-utils/src/ubimkvol.c new file mode 100644 index 0000000..7da788b --- /dev/null +++ b/ubi-utils/new-utils/src/ubimkvol.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to create UBI volumes. + * + * Authors: Artem Bityutskiy + * Frank Haverkamp + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubimkvol" + +/* The variables below are set by command line arguments */ +struct args { + int vol_id; + int vol_type; + long long bytes; + int lebs; + int alignment; + const char *name; + int nlen; + const char *node; + int maxavs; + /* For deprecated -d option handling */ + int devn; + char dev_name[256]; +}; + +static struct args args = { + .vol_type = UBI_DYNAMIC_VOLUME, + .bytes = -1, + .lebs = -1, + .alignment = 1, + .vol_id = UBI_VOL_NUM_AUTO, + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to create UBI volumes."; + +static const char *optionsstr = +"-a, --alignment= volume alignment (default is 1)\n" +"-n, --vol_id= UBI volume ID, if not specified, the volume ID\n" +" will be assigned automatically\n" +"-N, --name= volume name\n" +"-s, --size= volume size volume size in bytes, kilobytes (KiB)\n" +" or megabytes (MiB)\n" +"-S, --lebs= alternative way to give volume size in logical\n" +" eraseblocks\n" +"-m, --maxavsize set volume size to maximum available size\n" +"-t, --type= volume type (dynamic, static), default is dynamic\n" +"-h, -?, --help print help message\n" +"-V, --version print program version\n\n" +"The following is a compatibility option which is deprecated, do not use it\n" +"-d, --devn= UBI device number - may be used instead of the UBI\n" +" device node name in which case the utility assumes\n" +" that the device node is \"/dev/ubi\""; + + +static const char *usage = +"Usage: " PROGRAM_NAME " [-h] [-a ] [-n ] [-N ]\n" +"\t\t\t[-s ] [-S ] [-t ] [-V] [-m]\n" +"\t\t\t[--alignment=][--vol_id=] [--name=]\n" +"\t\t\t[--size=] [--lebs=] [--type=] [--help]\n" +"\t\t\t[--version] [--maxavsize]\n\n" +"Example: " PROGRAM_NAME "/dev/ubi0 -s 20MiB -N config_data - create a 20 Megabytes volume\n" +" named \"config_data\" on UBI device /dev/ubi0."; + +static const struct option long_options[] = { + { .name = "alignment", .has_arg = 1, .flag = NULL, .val = 'a' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, + { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, + { .name = "lebs", .has_arg = 1, .flag = NULL, .val = 'S' }, + { .name = "type", .has_arg = 1, .flag = NULL, .val = 't' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { .name = "maxavsize", .has_arg = 0, .flag = NULL, .val = 'm' }, + /* Deprecated -d option */ + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { NULL, 0, NULL, 0}, +}; + +static int param_sanity_check(void) +{ + int len; + + if (args.bytes == -1 && !args.maxavs && args.lebs == -1) + return errmsg("volume size was not specified (use -h for help)"); + + if ((args.bytes != -1 && (args.maxavs || args.lebs != -1)) || + (args.lebs != -1 && (args.maxavs || args.bytes != -1)) || + (args.maxavs && (args.bytes != -1 || args.lebs != -1))) + return errmsg("size specified with more then one option"); + + if (args.name == NULL) + return errmsg("volume name was not specified (use -h for help)"); + + len = strlen(args.name); + if (len > UBI_MAX_VOLUME_NAME) + return errmsg("too long name (%d symbols), max is %d", len, UBI_MAX_VOLUME_NAME); + + return 0; +} + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "a:n:N:s:S:t:h?Vmd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 't': + if (!strcmp(optarg, "dynamic")) + args.vol_type = UBI_DYNAMIC_VOLUME; + else if (!strcmp(optarg, "static")) + args.vol_type = UBI_STATIC_VOLUME; + else + return errmsg("bad volume type: \"%s\"", optarg); + break; + + case 's': + args.bytes = ubiutils_get_bytes(optarg); + if (args.bytes <= 0) + return errmsg("bad volume size: \"%s\"", optarg); + break; + + case 'S': + args.lebs = strtoull(optarg, &endp, 0); + if (endp == optarg || args.lebs <= 0 || *endp != '\0') + return errmsg("bad LEB count: \"%s\"", optarg); + break; + + case 'a': + args.alignment = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.alignment <= 0) + return errmsg("bad volume alignment: \"%s\"", optarg); + break; + + case 'n': + args.vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vol_id < 0) + return errmsg("bad volume ID: " "\"%s\"", optarg); + break; + + case 'd': + /* Handle deprecated -d option */ + warnmsg("-d is depricated and will be removed, do not use it"); + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: " "\"%s\"", optarg); + break; + + case 'N': + args.name = optarg; + args.nlen = strlen(args.name); + break; + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case 'm': + args.maxavs = 1; + break; + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) + return errmsg("UBI device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI device specified (use -h for help)"); + + args.node = argv[optind]; + } + + if (param_sanity_check()) + return -1; + + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_dev_info dev_info; + struct ubi_vol_info vol_info; + struct ubi_mkvol_request req; + + err = parse_opt(argc, argv); + if (err) + return err; + + libubi = libubi_open(); + if (!libubi) + return sys_errmsg("cannot open libubi"); + + err = ubi_node_type(libubi, args.node); + if (err == 2) { + errmsg("\"%s\" is an UBI volume node, not an UBI device node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI device node", args.node); + goto out_libubi; + } + + err = ubi_get_dev_info(libubi, args.node, &dev_info); + if (err) { + sys_errmsg("cannot get information about UBI device \"%s\"", + args.node); + goto out_libubi; + } + + if (args.maxavs) { + args.bytes = dev_info.avail_bytes; + printf("Set volume size to %lld\n", req.bytes); + } + + if (args.lebs != -1) { + args.bytes = dev_info.leb_size; + args.bytes -= dev_info.leb_size % args.alignment; + args.bytes *= args.lebs; + } + + req.vol_id = args.vol_id; + req.alignment = args.alignment; + req.bytes = args.bytes; + req.vol_type = args.vol_type; + req.name = args.name; + + err = ubi_mkvol(libubi, args.node, &req); + if (err < 0) { + sys_errmsg("cannot UBI create volume"); + goto out_libubi; + } + + args.vol_id = req.vol_id; + + /* Print information about the created device */ + err = ubi_get_vol_info1(libubi, dev_info.dev_num, args.vol_id, &vol_info); + if (err) { + sys_errmsg("cannot get information about newly created UBI volume"); + goto out_libubi; + } + + printf("Volume ID %d, size %d LEBs (", vol_info.vol_id, vol_info.rsvd_lebs); + ubiutils_print_bytes(vol_info.rsvd_bytes, 0); + printf("), LEB size "); + ubiutils_print_bytes(vol_info.leb_size, 1); + printf(", %s, name \"%s\", alignment %d\n", + req.vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static", + vol_info.name, vol_info.alignment); + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff --git a/ubi-utils/new-utils/src/ubinfo.c b/ubi-utils/new-utils/src/ubinfo.c new file mode 100644 index 0000000..185caae --- /dev/null +++ b/ubi-utils/new-utils/src/ubinfo.c @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to get UBI information. + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubinfo" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int vol_id; + int all; + const char *node; +}; + +static struct args args = { + .vol_id = -1, + .devn = -1, + .all = 0, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to print UBI information."; + +static const char *optionsstr = +"-d, --devn= UBI device number to get information about\n" +"-n, --vol_id= ID of UBI volume to print information about\n" +"-a, --all print information about all devices and volumes,\n" +" or about all volumes if the UBI device was\n" +" specified\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage 1: " PROGRAM_NAME " [-d ] [-n ] [-a] [-h] [-V] [--vol_id=]\n" +"\t\t[--devn ] [--all] [--help] [--version]\n" +"Usage 2: " PROGRAM_NAME " [-a] [-h] [-V] [--all] [--help] [--version]\n" +"Usage 3: " PROGRAM_NAME " [-h] [-V] [--help] [--version]\n\n" +"Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n" +"Example 2: " PROGRAM_NAME " -d 1 - print information about UBI device number 1\n" +"Example 3: " PROGRAM_NAME " /dev/ubi0 -a - print information about all volumes of UBI\n" +" device /dev/ubi0\n" +"Example 4: " PROGRAM_NAME " /dev/ubi1_0 - print information about UBI volume /dev/ubi1_0\n" +"Example 5: " PROGRAM_NAME " -a - print all information\n"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "all", .has_arg = 0, .flag = NULL, .val = 'a' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "an:d:hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'a': + args.all = 1; + break; + + case 'n': + args.vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vol_id < 0) + return errmsg("bad volume ID: " "\"%s\"", optarg); + break; + + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc - 1) + args.node = argv[optind]; + else if (optind < argc) + return errmsg("more then one UBI devices specified (use -h for help)"); + + return 0; +} + +static int translate_dev(libubi_t libubi, const char *node) +{ + int err; + + err = ubi_node_type(libubi, node); + if (err == -1) { + if (errno) + return errmsg("unrecognized device node \"%s\"", node); + return errmsg("\"%s\" does not correspond to any UBI device or volume", node); + } + + if (err == 1) { + struct ubi_dev_info dev_info; + + err = ubi_get_dev_info(libubi, node, &dev_info); + if (err) + return sys_errmsg("cannot get information about UBI device \"%s\"", node); + + args.devn = dev_info.dev_num; + } else { + struct ubi_vol_info vol_info; + + err = ubi_get_vol_info(libubi, node, &vol_info); + if (err) + return sys_errmsg("cannot get information about UBI volume \"%s\"", node); + + if (args.vol_id != -1) + return errmsg("both volume character device node (\"%s\") and " + "volume ID (%d) are specify, use only one of them" + "(use -h for help)", node, args.vol_id); + + args.devn = vol_info.dev_num; + args.vol_id = vol_info.vol_id; + } + + return 0; +} + +static int print_vol_info(libubi_t libubi, int dev_num, int vol_id) +{ + int err; + struct ubi_vol_info vol_info; + + err = ubi_get_vol_info1(libubi, dev_num, vol_id, &vol_info); + if (err) + return sys_errmsg("cannot get information about UBI volume %d on ubi%d", + vol_id, dev_num); + + printf("Volume ID: %d (on ubi%d)\n", vol_info.vol_id, vol_info.dev_num); + printf("Type: %s\n", + vol_info.type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"); + printf("Alignment: %d\n", vol_info.alignment); + + printf("Size: %d LEBs (", vol_info.rsvd_lebs); + ubiutils_print_bytes(vol_info.rsvd_bytes, 0); + printf(")\n"); + + if (vol_info.type == UBI_STATIC_VOLUME) { + printf("Data bytes: "); + ubiutils_print_bytes(vol_info.data_bytes, 1); + } + printf("State: %s\n", vol_info.corrupted ? "corrupted" : "OK"); + printf("Name: %s\n", vol_info.name); + printf("Character device major/minor: %d:%d\n", + vol_info.major, vol_info.minor); + + return 0; +} + +static int print_dev_info(libubi_t libubi, int dev_num, int all) +{ + int i, err, first = 1; + struct ubi_dev_info dev_info; + struct ubi_vol_info vol_info; + + err = ubi_get_dev_info1(libubi, dev_num, &dev_info); + if (err) + return sys_errmsg("cannot get information about UBI device %d", dev_num); + + printf("ubi%d:\n", dev_info.dev_num); + printf("Volumes count: %d\n", dev_info.vol_count); + printf("Logical eraseblock size: %d\n", dev_info.leb_size); + + printf("Total amount of logical eraseblocks: %d (", dev_info.total_lebs); + ubiutils_print_bytes(dev_info.total_bytes, 0); + printf(")\n"); + + printf("Amount of available logical eraseblocks: %d (", dev_info.avail_lebs); + ubiutils_print_bytes(dev_info.avail_bytes, 0); + printf(")\n"); + + printf("Maximum count of volumes %d\n", dev_info.max_vol_count); + printf("Count of bad physical eraseblocks: %d\n", dev_info.bad_count); + printf("Count of reserved physical eraseblocks: %d\n", dev_info.bad_rsvd); + printf("Current maximum erase counter value: %lld\n", dev_info.max_ec); + printf("Minimum input/output unit size: %d bytes\n", dev_info.min_io_size); + printf("Character device major/minor: %d:%d\n", + dev_info.major, dev_info.minor); + + if (dev_info.vol_count == 0) + return 0; + + printf("Present volumes: "); + for (i = dev_info.lowest_vol_num; + i <= dev_info.highest_vol_num; i++) { + err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe volume %d on ubi%d", + i, dev_info.dev_num); + } + + if (!first) + printf(", %d", i); + else { + printf("%d", i); + first = 0; + } + } + printf("\n"); + + if (!all) + return 0; + + first = 1; + printf("\n"); + + for (i = dev_info.lowest_vol_num; + i <= dev_info.highest_vol_num; i++) { + if(!first) + printf("-----------------------------------\n"); + err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe volume %d on ubi%d", + i, dev_info.dev_num); + } + first = 0; + + err = print_vol_info(libubi, dev_info.dev_num, i); + if (err) + return err; + } + + return 0; +} + +static int print_general_info(libubi_t libubi, int all) +{ + int i, err, first = 1; + struct ubi_info ubi_info; + struct ubi_dev_info dev_info; + + err = ubi_get_info(libubi, &ubi_info); + if (err) + return sys_errmsg("cannot get UBI information"); + + printf("UBI version: %d\n", ubi_info.version); + printf("Count of UBI devices: %d\n", ubi_info.dev_count); + if (ubi_info.ctrl_major != -1) + printf("UBI control device major/minor: %d:%d\n", + ubi_info.ctrl_major, ubi_info.ctrl_minor); + else + printf("UBI control device is not supported by this kernel\n"); + + if (ubi_info.dev_count == 0) + return 0; + + printf("Present UBI devices: "); + for (i = ubi_info.lowest_dev_num; + i <= ubi_info.highest_dev_num; i++) { + err = ubi_get_dev_info1(libubi, i, &dev_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe UBI device %d", i); + } + + if (!first) + printf(", ubi%d", i); + else { + printf("ubi%d", i); + first = 0; + } + } + printf("\n"); + + if (!all) + return 0; + + first = 1; + printf("\n"); + + for (i = ubi_info.lowest_dev_num; + i <= ubi_info.highest_dev_num; i++) { + if(!first) + printf("\n===================================\n\n"); + err = ubi_get_dev_info1(libubi, i, &dev_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe UBI device %d", i); + } + first = 0; + + err = print_dev_info(libubi, i, all); + if (err) + return err; + } + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + + err = parse_opt(argc, argv); + if (err) + return -1; + + if (!args.node && args.devn != -1) + return errmsg("specify either device number or node file (use -h for help)"); + + libubi = libubi_open(); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + if (args.node) { + /* + * A character device was specified, translate this into UBI + * device number and volume ID. + */ + err = translate_dev(libubi, args.node); + if (err) + goto out_libubi; + } + + if (args.vol_id != -1 && args.devn == -1) { + errmsg("volume ID is specified, but UBI device number is not " + "(use -h for help)\n"); + goto out_libubi; + } + + if (args.devn != -1 && args.vol_id != -1) { + print_vol_info(libubi, args.devn, args.vol_id); + goto out; + } + + if (args.devn == -1 && args.vol_id == -1) + err = print_general_info(libubi, args.all); + else if (args.devn != -1 && args.vol_id == -1) + err = print_dev_info(libubi, args.devn, args.all); + + if (err) + goto out_libubi; + +out: + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff --git a/ubi-utils/new-utils/src/ubinize.c b/ubi-utils/new-utils/src/ubinize.c new file mode 100644 index 0000000..a78199e --- /dev/null +++ b/ubi-utils/new-utils/src/ubinize.c @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Generate UBI images. + * + * Authors: Artem Bityutskiy + * Oliver Lohmann + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubinize" + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION +" - a tool to generate UBI images. An UBI image may contain one or more UBI " +"volumes which have to be defined in the input configuration ini-file. The " +"ini file defines all the UBI volumes - their characteristics and the and the " +"contents, but it does not define the characteristics of the flash the UBI " +"image is generated for. Instead, the flash characteristics are defined via " +"the command-line options. Note, if not sure about some of the command-line " +"parameters, do not specify them and let the utility to use default values."; + +static const char *optionsstr = +"-o, --output= output file name (default is stdout)\n" +"-p, --peb-size= size of the physical eraseblock of the flash\n" +" this UBI image is created for in bytes,\n" +" kilobytes (KiB), or megabytes (MiB)\n" +" (mandatory parameter)\n" +"-m, --min-io-size= minimum input/output unit size of the flash\n" +" in bytes\n" +"-s, --sub-page-size= minimum input/output unit used for UBI\n" +" headers, e.g. sub-page size in case of NAND\n" +" flash (equivalent to the minimum input/output\n" +" unit size by default)\n" +"-O, --vid-hdr-offset= offset if the VID header from start of the\n" +" physical eraseblock (default is the second\n" +" minimum I/O unit or sub-page, if it was\n" +" specified)\n" +"-e, --erase-counter= the erase counter value to put to EC headers\n" +" (default is 0)\n" +"-x, --ubi-ver= UBI version number to put to EC headers\n" +" (default is 1)\n" +"-v --verbose be verbose\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-o filename] [-h] [-V] [--output=] [--help]\n" +"\t\t[--version] ini-file\n" +"Example: " PROGRAM_NAME " -o ubi.img cfg.ini - create UBI image 'ubi.img' as\n" +" described by configuration file 'cfg.ini'"; + +static const char *ini_doc = "INI-file format.\n" +"The input configuration ini-file describes all the volumes which have to\n" +"be included to the output UBI image. Each volume is described in its own\n" +"section which may be named arbitrarily. The section consists on\n" +"\"key=value\" pairs, for example:\n\n" +"[jffs2-volume]\n" +"mode=ubi\n" +"image=../jffs2.img\n" +"vol_id=1\n" +"vol_size=30MiB\n" +"vol_type=dynamic\n" +"vol_name=jffs2_volume\n" +"vol_flags=autoresize\n" +"vol_alignment=1\n\n" +"This example configuration file tells the utility to create an UBI image\n" +"with one volume with ID 1, volume size 30MiB, the volume is dynamic, has\n" +"name \"jffs2_volume\", \"autoresize\" volume flag, and alignment 1. The\n" +"\"image=../jffs2.img\" line tells the utility to take the contents of the\n" +"volume from the \"../jffs2.img\" file. The size of the image file has to be\n" +"less or equivalent to the volume size (30MiB). The \"mode=ubi\" line is\n" +"mandatory and just tells that the section describes an UBI volume - other\n" +"section modes may be added in the future.\n" +"Notes:\n" +" * size in vol_size might be specified kilobytes (KiB), megabytes (MiB),\n" +" gigabytes (GiB) or bytes (no modifier);\n" +" * if \"vol_size\" key is absent, the volume size is assumed to be\n" +" equivalent to the size of the image file (defined by \"image\" key);\n" +" * if the \"image\" is absent, the volume is assumed to be empty;\n" +" * volume alignment must not be greater than the logical eraseblock size;\n" +" * one ini file may contain arbitrary number of sections, the utility will\n" +" put all the volumes which are described by these section to the output\n" +" UBI image file."; + +struct option long_options[] = { + { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, + { .name = "peb-size", .has_arg = 1, .flag = NULL, .val = 'p' }, + { .name = "min-io-size", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, + { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, + { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, + { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, + { .name = "verbose", .has_arg = 1, .flag = NULL, .val = 'v' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0} +}; + +struct args { + const char *f_in; + const char *f_out; + FILE *fp_out; + int peb_size; + int min_io_size; + int subpage_size; + int vid_hdr_offs; + int ec; + int ubi_ver; + int verbose; + dictionary *dict; +}; + +static struct args args = { + .f_out = NULL, + .peb_size = -1, + .min_io_size = -1, + .subpage_size = -1, + .vid_hdr_offs = 0, + .ec = 0, + .ubi_ver = 1, + .verbose = 0, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "o:p:m:s:O:e:x:vhV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'o': + args.fp_out = fopen(optarg, "wb"); + if (!args.fp_out) + return errmsg("cannot open file \"%s\"", optarg); + args.f_out = optarg; + break; + + case 'p': + args.peb_size = ubiutils_get_bytes(optarg); + if (args.peb_size <= 0) + return errmsg("bad physical eraseblock size: \"%s\"", optarg); + break; + + case 'm': + args.min_io_size = ubiutils_get_bytes(optarg); + if (args.min_io_size <= 0) + return errmsg("bad min. I/O unit size: \"%s\"", optarg); + break; + + case 's': + args.subpage_size = ubiutils_get_bytes(optarg); + if (args.subpage_size <= 0) + return errmsg("bad sub-page size: \"%s\"", optarg); + break; + + case 'O': + args.vid_hdr_offs = strtoul(optarg, &endp, 0); + if (endp == optarg || args.vid_hdr_offs < 0) + return errmsg("bad VID header offset: \"%s\"", optarg); + break; + + case 'e': + args.ec = strtoul(optarg, &endp, 0); + if (endp == optarg || args.ec < 0) + return errmsg("bad erase counter value: \"%s\"", optarg); + break; + + case 'x': + args.ubi_ver = strtoul(optarg, &endp, 0); + if (endp == optarg || args.ubi_ver < 0) + return errmsg("bad UBI version: \"%s\"", optarg); + break; + + case 'v': + args.verbose = 1; + break; + + case 'h': + ubiutils_print_text(stderr, doc, 80); + fprintf(stderr, "\n%s\n\n", ini_doc); + fprintf(stderr, "%s\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc) + return errmsg("input configuration file was not specified (use -h for help)"); + + if (optind != argc - 1) + return errmsg("more then one configuration file was specified (use -h for help)"); + + args.f_in = argv[optind]; + + if (args.peb_size < 0) + return errmsg("physical eraseblock size was not specified (use -h for help)"); + + if (args.min_io_size < 0) + return errmsg("min. I/O unit size was not specified (use -h for help)"); + + if (args.subpage_size < 0) + args.subpage_size = args.min_io_size; + + if (!args.f_out) { + args.f_out = "stdout"; + args.fp_out = stdout; + } + + return 0; +} + +int read_section(const char *sname, struct ubigen_vol_info *vi, + const char **img) +{ + char buf[256]; + const char *p; + + *img = NULL; + + if (strlen(sname) > 128) + return errmsg("too long section name \"%s\"", sname); + + /* Make sure mode is UBI, otherwise ignore this section */ + sprintf(buf, "%s:mode", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (!p) { + errmsg("\"mode\" key not found in section \"%s\"", sname); + errmsg("the \"mode\" key is mandatory and has to be " + "\"mode=ubi\" if the section describes an UBI volume"); + return -1; + } + + /* If mode is not UBI, skip this section */ + if (strcmp(p, "ubi")) { + verbose(args.verbose, "skip non-ubi section \"%s\"", sname); + return 1; + } + + verbose(args.verbose, "mode=ubi, keep parsing"); + + /* Fetch the name of the volume image file */ + sprintf(buf, "%s:image", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (p) + *img = p; + + /* Fetch volume id */ + sprintf(buf, "%s:vol_id", sname); + vi->id = iniparser_getint(args.dict, buf, -1); + if (vi->id == -1) + return errmsg("\"vol_id\" key not found in section \"%s\"", sname); + + if (vi->id < 0) + return errmsg("negative volume ID %d", vi->id); + + if (vi->id >= UBI_MAX_VOLUMES) + return errmsg("too high volume ID %d, max. is %d", vi->id, UBI_MAX_VOLUMES); + + verbose(args.verbose, "volume ID: %d", vi->id); + + /* Fetch volume size */ + sprintf(buf, "%s:vol_size", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (p) { + vi->bytes = ubiutils_get_bytes(p); + if (vi->bytes <= 0) + return errmsg("bad \"vol_size\" key: \"%s\"", p); + + verbose(args.verbose, "volume size: %lld bytes", vi->bytes); + } else { + struct stat st; + + if (!*img) + return errmsg("neither image file (\"image=\") nor volume size (\"vol_size=\") specified"); + + if (stat(*img, &st)) + return sys_errmsg("cannot stat \"%s\"", *img); + + vi->bytes = st.st_size; + + if (vi->bytes == 0) + return errmsg("file \"%s\" referred from section \"%s\" is empty", *img, sname); + + printf(PROGRAM_NAME ": volume size was not specified in" + "section \"%s\", assume ", sname); + ubiutils_print_bytes(vi->bytes, 1); + printf("\n"); + } + + /* Fetch volume type */ + sprintf(buf, "%s:vol_type", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (!p) { + normsg(": volume type was not specified in " + "section \"%s\", assume \"dynamic\"\n", sname); + vi->type = UBI_VID_DYNAMIC; + } else { + if (!strcmp(p, "static")) + vi->type = UBI_VID_STATIC; + else if (!strcmp(p, "dynamic")) + vi->type = UBI_VID_DYNAMIC; + else + return errmsg("invalid volume type \"%s\"", p); + } + + verbose(args.verbose, "volume type: %s", + vi->type == UBI_VID_DYNAMIC ? "dynamic" : "static"); + + /* Fetch volume name */ + sprintf(buf, "%s:vol_name", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (!p) + return errmsg("\"vol_name\" key not found in section \"%s\"", sname); + + vi->name = p; + vi->name_len = strlen(p); + if (vi->name_len > UBI_VOL_NAME_MAX) + return errmsg("too long volume name in section \"%s\", max. is %d characters", + vi->name, UBI_VOL_NAME_MAX); + + verbose(args.verbose, "volume name: %s", p); + + /* Fetch volume alignment */ + sprintf(buf, "%s:vol_alignment", sname); + vi->alignment = iniparser_getint(args.dict, buf, -1); + if (vi->alignment == -1) { + normsg("volume alignment was not specified in section " + "\"%s\", assume 1", sname); + vi->alignment = 1; + } else if (vi->id < 0) + return errmsg("negative volume alignement %d", vi->alignment); + + verbose(args.verbose, "volume alignment: %d", vi->alignment); + + /* Fetch volume flags */ + sprintf(buf, "%s:vol_flags", sname); + p = iniparser_getstring(args.dict, buf, NULL); + if (p) { + if (!strcmp(p, "autoresize")) { + verbose(args.verbose, "autoresize flags found"); + vi->flags |= UBI_VTBL_AUTORESIZE_FLG; + } else { + return errmsg("unknown flags \"%s\" in section \"%s\"", p, sname); + } + } + + return 0; +} + +static void init_vol_info(const struct ubigen_info *ui, + struct ubigen_vol_info *vi) +{ + vi->data_pad = ui->leb_size % vi->alignment; + vi->usable_leb_size = ui->leb_size - vi->data_pad; + vi->used_ebs = (vi->bytes + vi->usable_leb_size - 1) / vi->usable_leb_size; + vi->compat = 0; +} + +int main(int argc, char * const argv[]) +{ + int err = -1, sects, i, volumes; + struct ubigen_info ui; + struct ubi_vtbl_record *vtbl; + + err = parse_opt(argc, argv); + if (err) + return -1; + + ubigen_info_init(&ui, args.peb_size, args.min_io_size, + args.subpage_size, args.vid_hdr_offs, + args.ubi_ver, args.ec); + + verbose(args.verbose, "LEB size: %d", ui.leb_size); + verbose(args.verbose, "PEB size: %d", ui.peb_size); + verbose(args.verbose, "min_io_size: %d", ui.min_io_size); + verbose(args.verbose, "VID offset: %d", ui.vid_hdr_offs); + + vtbl = ubigen_create_empty_vtbl(&ui); + if (!vtbl) + goto out; + + args.dict = iniparser_load(args.f_in); + if (!args.dict) { + errmsg("cannot load the input ini file \"%s\"", args.f_in); + goto out_vtbl; + } + + verbose(args.verbose, "loaded the ini-file \"%s\"", args.f_in); + + /* Each section describes one volume */ + sects = iniparser_getnsec(args.dict); + if (sects == -1) { + errmsg("ini-file parsing error (iniparser_getnsec)"); + goto out_dict; + } + + verbose(args.verbose, "count of sections: %d", sects); + if (sects == 0) { + errmsg("no sections found the ini-file \"%s\"", args.f_in); + goto out_dict; + } + + /* + * Skip 2 PEBs at the beginning of the file for the volume table which + * will be written later. + */ + if (fseek(args.fp_out, ui.peb_size * 2, SEEK_SET) == -1) { + errmsg("cannot seek file \"%s\"", args.f_out); + goto out_dict; + } + + for (i = 0; i < sects; i++) { + const char *sname = iniparser_getsecname(args.dict, i); + struct ubigen_vol_info vi; + const char *img = NULL; + struct stat st; + FILE *f; + + if (!sname) { + errmsg("ini-file parsing error (iniparser_getsecname)"); + goto out_dict; + } + + if (args.verbose) + printf("\n"); + verbose(args.verbose, "parsing section \"%s\"", sname); + + err = read_section(sname, &vi, &img); + if (err == -1) + goto out_dict; + if (!err) + volumes += 1; + init_vol_info(&ui, &vi); + + verbose(args.verbose, "adding volume %d", vi.id); + + err = ubigen_add_volume(&ui, &vi, vtbl); + if (err) { + errmsg("cannot add volume for section \"%s\"", sname); + goto out_dict; + } + + if (!img) + continue; + + if (stat(img, &st)) { + sys_errmsg("cannot stat \"%s\"", img); + goto out_dict; + } + + /* + * Make sure the image size is not larger then the volume size. + */ + if (st.st_size > vi.bytes) { + errmsg("error in section \"%s\": size of the image file \"%s\" " + "is %lld, which is larger then the volume size %lld", + sname, img, (long long)st.st_size, vi.bytes); + goto out_dict; + } + + f = fopen(img, "r"); + if (!f) { + sys_errmsg("cannot open \"%s\"", img); + goto out_dict; + } + + verbose(args.verbose, "writing volume %d", vi.id); + verbose(args.verbose, "image file: %s", img); + + err = ubigen_write_volume(&ui, &vi, st.st_size, f, args.fp_out); + fclose(f); + if (err) { + errmsg("cannot write volume for section \"%s\"", sname); + goto out_dict; + } + + if (args.verbose) + printf("\n"); + } + + verbose(args.verbose, "writing layout volume"); + + if (fseek(args.fp_out, 0, SEEK_SET) == -1) { + errmsg("cannot seek file \"%s\"", args.f_out); + goto out_dict; + } + + err = ubigen_write_layout_vol(&ui, vtbl, args.fp_out); + if (err) { + errmsg("cannot write layout volume"); + goto out_dict; + } + + verbose(args.verbose, "done"); + + iniparser_freedict(args.dict); + free(vtbl); + fclose(args.fp_out); + return 0; + +out_dict: + iniparser_freedict(args.dict); +out_vtbl: + free(vtbl); +out: + fclose(args.fp_out); + remove(args.f_out); + return err; +} diff --git a/ubi-utils/new-utils/src/ubirmvol.c b/ubi-utils/new-utils/src/ubirmvol.c new file mode 100644 index 0000000..5822aa0 --- /dev/null +++ b/ubi-utils/new-utils/src/ubirmvol.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to remove UBI volumes. + * + * Authors: Artem Bityutskiy + * Frank Haverkamp + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubirmvol" + +/* The variables below are set by command line arguments */ +struct args { + int vol_id; + const char *node; + /* For deprecated -d option handling */ + int devn; + char dev_name[256]; +}; + +static struct args args = { + .vol_id = -1, + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to remove UBI volumes."; + +static const char *optionsstr = +"-n, --vol_id= volume ID to remove\n" +"-h, -?, --help print help message\n" +"-V, --version print program version\n\n" +"The following is a compatibility option which is deprecated, do not use it\n" +"-d, --devn= UBI device number - may be used instead of the UBI\n" +" device node name in which case the utility assumes\n" +" that the device node is \"/dev/ubi\""; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-n ] [--vol_id=] [-h] [--help]\n\n" +"Example: " PROGRAM_NAME "/dev/ubi0 -n 1 - remove UBI volume 1 from UBI device corresponding\n" +" to the node file /dev/ubi0."; + +static const struct option long_options[] = { + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + /* Deprecated -d option */ + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { NULL, 0, NULL, 0}, +}; + +static int param_sanity_check(void) +{ + if (args.vol_id == -1) { + errmsg("volume ID is was not specified"); + return -1; + } + + return 0; +} + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "n:h?Vd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + + case 'n': + args.vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vol_id < 0) { + errmsg("bad volume ID: " "\"%s\"", optarg); + return -1; + } + break; + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'd': + /* Handle deprecated -d option */ + warnmsg("-d is depricated and will be removed, do not use it"); + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: " "\"%s\"", optarg); + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + errmsg("parameter is missing"); + return -1; + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) { + errmsg("UBI device name was not specified (use -h for help)"); + return -1; + } else if (optind != argc - 1) { + errmsg("more then one UBI device specified (use -h for help)"); + return -1; + } + + args.node = argv[optind]; + } + + + if (param_sanity_check()) + return -1; + + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + err = ubi_node_type(libubi, args.node); + if (err == 2) { + errmsg("\"%s\" is an UBI volume node, not an UBI device node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI device node", args.node); + goto out_libubi; + } + + err = ubi_rmvol(libubi, args.node, args.vol_id); + if (err) { + sys_errmsg("cannot UBI remove volume"); + goto out_libubi; + } + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff --git a/ubi-utils/new-utils/src/ubiupdatevol.c b/ubi-utils/new-utils/src/ubiupdatevol.c new file mode 100644 index 0000000..76d9f4e --- /dev/null +++ b/ubi-utils/new-utils/src/ubiupdatevol.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to update UBI volumes. + * + * Authors: Frank Haverkamp + * Joshua W. Boyer + * Artem Bityutskiy + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.1" +#define PROGRAM_NAME "ubiupdatevol" + +struct args { + int truncate; + const char *node; + const char *img; + /* For deprecated -d and -B options handling */ + int devn; + char dev_name[256]; + int broken_update; +}; + +static struct args args = { + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to write data to UBI volumes."; + +static const char *optionsstr = +"-n, --vol_id= ID of UBI volume to update\n" +"-t, --truncate truncate volume (wipe it out)\n" +"-h, --help print help message\n" +"-V, --version print program version\n\n" +"The following are compatibility options which are deprecated, do not use them\n" +"-d, --devn= UBI device number - may be used instead of the UBI\n" +" device node name in which case the utility assumes\n" +" that the device node is \"/dev/ubi\"\n" +"-B, --broken-update broken update, this is for testing"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-t] [-h] [-V] [--truncate] [--help]\n" +"\t\t\t[--version] \n\n" +"Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - write file \"fs.img\" to UBI volume /dev/ubi0_1\n" +"Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1"; + +struct option long_options[] = { + { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + /* Deprecated -d and -B options */ + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "broken-update", .has_arg = 1, .flag = NULL, .val = 'B' }, + { NULL, 0, NULL, 0} +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "n:th?Vd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 't': + args.truncate = 1; + break; + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'd': + { + char *endp; + + /* Handle deprecated -d option */ + warnmsg("-d is depricated and will be removed, do not use it"); + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: " "\"%s\"", optarg); + break; + } + + case 'B': + /* Handle deprecated -B option */ + warnmsg("-B is depricated and will be removed, do not use it"); + args.broken_update = 1; + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) + return errmsg("UBI device name was not specified (use -h for help)"); + else if (optind != argc - 2) + return errmsg("specify UBI device name and image file name as first 2 " + "parameters (use -h for help)"); + } + + args.node = argv[optind]; + args.img = argv[optind + 1]; + + return 0; +} + +static int truncate_volume(libubi_t libubi) +{ + int err, fd; + + fd = open(args.node, O_RDWR); + if (fd == -1) + return sys_errmsg("cannot open \"%s\"", args.node); + + err = ubi_update_start(libubi, fd, 0); + if (err) { + sys_errmsg("cannot truncate volume \"%s\"", args.node); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int ubi_write(int fd, const void *buf, int len) +{ + int ret; + + while (len) { + ret = write(fd, buf, len); + if (ret < 0) { + if (errno == EINTR) { + warnmsg("do not interrupt me!"); + continue; + } + return sys_errmsg("cannot write %d bytes to volume \"%s\"", + len, args.node); + } + + if (ret == 0) + return errmsg("cannot write %d bytes to volume \"%s\"", len, args.node); + + len -= ret; + buf += ret; + } + + return 0; +} + +static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) +{ + int err, fd, ifd; + long long bytes; + struct stat st; + char *buf; + + buf = malloc(vol_info->leb_size); + if (!buf) + return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); + + err = stat(args.img, &st); + if (err < 0) { + errmsg("stat failed on \"%s\"", args.node); + goto out_free; + } + + bytes = st.st_size; + if (bytes > vol_info->rsvd_bytes) { + errmsg("\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)", + args.img, bytes, args.node, vol_info->rsvd_bytes); + goto out_free; + } + + /* A hack to handle deprecated -B option */ + if (args.broken_update) + bytes = 1; + + fd = open(args.node, O_RDWR); + if (fd == -1) { + sys_errmsg("cannot open UBI volume \"%s\"", args.node); + goto out_free; + } + + ifd = open(args.img, O_RDONLY); + if (ifd == -1) { + sys_errmsg("cannot open \"%s\"", args.img); + goto out_close1; + } + + err = ubi_update_start(libubi, fd, bytes); + if (err) { + sys_errmsg("cannot start volume \"%s\" update", args.node); + goto out_close; + } + + while (bytes) { + int tocopy = vol_info->leb_size; + + if (tocopy > bytes) + tocopy = bytes; + + err = read(ifd, buf, tocopy); + if (err != tocopy) { + if (errno == EINTR) { + warnmsg("do not interrupt me!"); + continue; + } else { + sys_errmsg("cannot read %d bytes from \"%s\"", + tocopy, args.img); + goto out_close; + } + } + + err = ubi_write(fd, buf, tocopy); + if (err) + goto out_close; + bytes -= tocopy; + } + + close(ifd); + close(fd); + free(buf); + return 0; + +out_close: + close(ifd); +out_close1: + close(fd); +out_free: + free(buf); + return -1; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_vol_info vol_info; + + err = parse_opt(argc, argv); + if (err) + return -1; + + if (!args.img && !args.truncate) + return errmsg("incorrect arguments, use -h for help"); + + libubi = libubi_open(); + if (libubi == NULL) { + sys_errmsg("cannot open libubi"); + goto out_libubi; + } + + err = ubi_node_type(libubi, args.node); + if (err == 1) { + errmsg("\"%s\" is an UBI device node, not an UBI volume node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI volume node", args.node); + goto out_libubi; + } + + err = ubi_get_vol_info(libubi, args.node, &vol_info); + if (err) { + sys_errmsg("cannot get information about UBI volume \"%s\"", + args.node); + goto out_libubi; + } + + if (args.truncate) + err = truncate_volume(libubi); + else + err = update_volume(libubi, &vol_info); + if (err) + goto out_libubi; + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} -- cgit v1.2.3