From 94a20240f9d6776619d7652013bb10131ddad1fc Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 28 Sep 2010 10:47:06 +0300 Subject: ubi-utils: remove old ubi-utils The utilities are unmaintained for long time, and many of them do not even work, just compile, and no on complains about this. This suggests they are unused and we can now safely kill them. Signed-off-by: Artem Bityutskiy --- ubi-utils/old-utils/src/bin2nand.c | 344 -------- ubi-utils/old-utils/src/bootenv.c | 1032 ----------------------- ubi-utils/old-utils/src/bootenv.h | 434 ---------- ubi-utils/old-utils/src/config.h | 28 - ubi-utils/old-utils/src/crc32.c | 83 -- ubi-utils/old-utils/src/crc32.h | 36 - ubi-utils/old-utils/src/eb_chain.c | 281 ------- ubi-utils/old-utils/src/error.c | 240 ------ ubi-utils/old-utils/src/error.h | 84 -- ubi-utils/old-utils/src/example_ubi.h | 28 - ubi-utils/old-utils/src/hashmap.c | 412 ---------- ubi-utils/old-utils/src/hashmap.h | 49 -- ubi-utils/old-utils/src/libpfiflash.c | 1325 ------------------------------ ubi-utils/old-utils/src/libubi.c | 915 --------------------- ubi-utils/old-utils/src/libubi_int.h | 129 --- ubi-utils/old-utils/src/libubigen.c | 487 ----------- ubi-utils/old-utils/src/libubimirror.c | 237 ------ ubi-utils/old-utils/src/list.c | 149 ---- ubi-utils/old-utils/src/list.h | 56 -- ubi-utils/old-utils/src/mkbootenv.c | 168 ---- ubi-utils/old-utils/src/nand2bin.c | 493 ----------- ubi-utils/old-utils/src/nandcorr.c | 95 --- ubi-utils/old-utils/src/nandecc.c | 159 ---- ubi-utils/old-utils/src/nandecc.h | 29 - ubi-utils/old-utils/src/pddcustomize.c | 516 ------------ ubi-utils/old-utils/src/peb.c | 116 --- ubi-utils/old-utils/src/peb.h | 41 - ubi-utils/old-utils/src/pfi.c | 458 ----------- ubi-utils/old-utils/src/pfi.h | 244 ------ ubi-utils/old-utils/src/pfi2bin.c | 682 --------------- ubi-utils/old-utils/src/pfiflash.c | 264 ------ ubi-utils/old-utils/src/pfiflash.h | 76 -- ubi-utils/old-utils/src/pfiflash_error.h | 75 -- ubi-utils/old-utils/src/reader.c | 482 ----------- ubi-utils/old-utils/src/reader.h | 87 -- ubi-utils/old-utils/src/ubigen.c | 359 -------- ubi-utils/old-utils/src/ubigen.h | 149 ---- ubi-utils/old-utils/src/ubimirror.c | 213 ----- ubi-utils/old-utils/src/ubimirror.h | 66 -- ubi-utils/old-utils/src/unubi.c | 1024 ----------------------- ubi-utils/old-utils/src/unubi_analyze.c | 463 ----------- ubi-utils/old-utils/src/unubi_analyze.h | 87 -- 42 files changed, 12695 deletions(-) delete mode 100644 ubi-utils/old-utils/src/bin2nand.c delete mode 100644 ubi-utils/old-utils/src/bootenv.c delete mode 100644 ubi-utils/old-utils/src/bootenv.h delete mode 100644 ubi-utils/old-utils/src/config.h delete mode 100644 ubi-utils/old-utils/src/crc32.c delete mode 100644 ubi-utils/old-utils/src/crc32.h delete mode 100644 ubi-utils/old-utils/src/eb_chain.c delete mode 100644 ubi-utils/old-utils/src/error.c delete mode 100644 ubi-utils/old-utils/src/error.h delete mode 100644 ubi-utils/old-utils/src/example_ubi.h delete mode 100644 ubi-utils/old-utils/src/hashmap.c delete mode 100644 ubi-utils/old-utils/src/hashmap.h delete mode 100644 ubi-utils/old-utils/src/libpfiflash.c delete mode 100644 ubi-utils/old-utils/src/libubi.c delete mode 100644 ubi-utils/old-utils/src/libubi_int.h delete mode 100644 ubi-utils/old-utils/src/libubigen.c delete mode 100644 ubi-utils/old-utils/src/libubimirror.c delete mode 100644 ubi-utils/old-utils/src/list.c delete mode 100644 ubi-utils/old-utils/src/list.h delete mode 100644 ubi-utils/old-utils/src/mkbootenv.c delete mode 100644 ubi-utils/old-utils/src/nand2bin.c delete mode 100644 ubi-utils/old-utils/src/nandcorr.c delete mode 100644 ubi-utils/old-utils/src/nandecc.c delete mode 100644 ubi-utils/old-utils/src/nandecc.h delete mode 100644 ubi-utils/old-utils/src/pddcustomize.c delete mode 100644 ubi-utils/old-utils/src/peb.c delete mode 100644 ubi-utils/old-utils/src/peb.h delete mode 100644 ubi-utils/old-utils/src/pfi.c delete mode 100644 ubi-utils/old-utils/src/pfi.h delete mode 100644 ubi-utils/old-utils/src/pfi2bin.c delete mode 100644 ubi-utils/old-utils/src/pfiflash.c delete mode 100644 ubi-utils/old-utils/src/pfiflash.h delete mode 100644 ubi-utils/old-utils/src/pfiflash_error.h delete mode 100644 ubi-utils/old-utils/src/reader.c delete mode 100644 ubi-utils/old-utils/src/reader.h delete mode 100644 ubi-utils/old-utils/src/ubigen.c delete mode 100644 ubi-utils/old-utils/src/ubigen.h delete mode 100644 ubi-utils/old-utils/src/ubimirror.c delete mode 100644 ubi-utils/old-utils/src/ubimirror.h delete mode 100644 ubi-utils/old-utils/src/unubi.c delete mode 100644 ubi-utils/old-utils/src/unubi_analyze.c delete mode 100644 ubi-utils/old-utils/src/unubi_analyze.h (limited to 'ubi-utils/old-utils/src') diff --git a/ubi-utils/old-utils/src/bin2nand.c b/ubi-utils/old-utils/src/bin2nand.c deleted file mode 100644 index c7c7ccc..0000000 --- a/ubi-utils/old-utils/src/bin2nand.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2007 - * - * 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. - * - * Author: Oliver Lohmann - */ - -/* - * Create a flashable NAND image from a binary image - * - * History: - * 1.0 Initial release (tglx) - * 1.1 Understands hex and dec input parameters (tglx) - * 1.2 Generates separated OOB data, if needed. (oloh) - * 1.3 Padds data/oob to a given size. (oloh) - * 1.4 Removed argp because we want to use uClibc. - * 1.5 Minor cleanup - * 1.6 written variable not initialized (-j did not work) (haver) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "error.h" -#include "config.h" -#include "nandecc.h" - -#define PROGRAM_VERSION "1.6" - -#define CHECK_ENDP(option, endp) do { \ - if (*endp) { \ - fprintf(stderr, \ - "Parse error option \'%s\'. " \ - "No correct numeric value.\n" \ - , option); \ - exit(EXIT_FAILURE); \ - } \ -} while(0) - -typedef enum action_t { - ACT_NORMAL = 0x00000001, -} action_t; - -#define PAGESIZE 2048 -#define PADDING 0 /* 0 means, do not adjust anything */ -#define BUFSIZE 4096 - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "bin2nand - a tool for adding OOB information to a " - "binary input file.\n"; - -static const char *optionsstr = -" -c, --copyright Print copyright informatoin.\n" -" -j, --padding= Padding in Byte/Mi/ki. Default = no padding\n" -" -p, --pagesize= Pagesize in Byte/Mi/ki. Default = 2048\n" -" -o, --output= Output filename. Interleaved Data/OOB if\n" -" output-oob not specified.\n" -" -q, --output-oob= Write OOB data in separate file.\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: bin2nand [-c?V] [-j ] [-p ] [-o ] [-q ]\n" -" [--copyright] [--padding=] [--pagesize=]\n" -" [--output=] [--output-oob=] [--help] [--usage]\n" -" [--version]\n"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "padding", .has_arg = 1, .flag = NULL, .val = 'j' }, - { .name = "pagesize", .has_arg = 1, .flag = NULL, .val = 'p' }, - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "output-oob", .has_arg = 1, .flag = NULL, .val = 'q' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -static const char copyright [] __attribute__((unused)) = - "Copyright IBM Corp. 2006"; - -typedef struct myargs { - action_t action; - - size_t pagesize; - size_t padding; - - FILE* fp_in; - char *file_out_data; /* Either: Data and OOB interleaved - or plain data */ - char *file_out_oob; /* OOB Data only. */ - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -} myargs; - - -static int ustrtoull(const char *cp, char **endp, unsigned int base) -{ - unsigned long long res = strtoull(cp, endp, base); - - switch (**endp) { - case 'G': - res *= 1024; - case 'M': - res *= 1024; - case 'k': - case 'K': - res *= 1024; - /* "Ki", "ki", "Mi" or "Gi" are to be used. */ - if ((*endp)[1] == 'i') - (*endp) += 2; - } - return res; -} - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - char* endp; - - while (1) { - int key; - - key = getopt_long(argc, argv, "cj:p:o:q:?V", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'p': /* pagesize */ - args->pagesize = (size_t) - ustrtoull(optarg, &endp, 0); - CHECK_ENDP("p", endp); - break; - case 'j': /* padding */ - args->padding = (size_t) - ustrtoull(optarg, &endp, 0); - CHECK_ENDP("j", endp); - break; - case 'o': /* output */ - args->file_out_data = optarg; - break; - case 'q': /* output oob */ - args->file_out_oob = optarg; - break; - case '?': /* help */ - printf("%s", doc); - printf("%s", optionsstr); - exit(0); - break; - case 'V': - printf("%s\n", PROGRAM_VERSION); - exit(0); - break; - case 'c': - printf("%s\n", copyright); - exit(0); - default: - printf("%s", usage); - exit(-1); - } - } - - if (optind < argc) { - args->fp_in = fopen(argv[optind++], "rb"); - if ((args->fp_in) == NULL) { - err_quit("Cannot open file %s for input\n", - argv[optind++]); - } - } - - return 0; -} - -static int -process_page(uint8_t* buf, size_t pagesize, - FILE *fp_data, FILE* fp_oob, size_t* written) -{ - int eccpoi, oobsize; - size_t i; - uint8_t oobbuf[64]; - - memset(oobbuf, 0xff, sizeof(oobbuf)); - - switch(pagesize) { - case 2048: oobsize = 64; eccpoi = 64 / 2; break; - case 512: oobsize = 16; eccpoi = 16 / 2; break; - default: - err_msg("Unsupported page size: %d\n", pagesize); - return -EINVAL; - } - - for (i = 0; i < pagesize; i += 256, eccpoi += 3) { - oobbuf[eccpoi++] = 0x0; - /* Calculate ECC */ - nand_calculate_ecc(&buf[i], &oobbuf[eccpoi]); - } - - /* write data */ - *written += fwrite(buf, 1, pagesize, fp_data); - - /* either separate oob or interleave with data */ - if (fp_oob) { - i = fwrite(oobbuf, 1, oobsize, fp_oob); - if (ferror(fp_oob)) { - err_msg("IO error\n"); - return -EIO; - } - } - else { - i = fwrite(oobbuf, 1, oobsize, fp_data); - if (ferror(fp_data)) { - err_msg("IO error\n"); - return -EIO; - } - } - - return 0; -} - -int main (int argc, char** argv) -{ - int rc = -1; - int res = 0; - size_t written = 0, read; - myargs args = { - .action = ACT_NORMAL, - .pagesize = PAGESIZE, - .padding = PADDING, - .fp_in = NULL, - .file_out_data = NULL, - .file_out_oob = NULL, - }; - - FILE* fp_out_data = stdout; - FILE* fp_out_oob = NULL; - - parse_opt(argc, argv, &args); - - uint8_t* buf = calloc(1, BUFSIZE); - if (!buf) { - err_quit("Cannot allocate page buffer.\n"); - } - - if (!args.fp_in) { - err_msg("No input image specified!\n"); - goto err; - } - - if (args.file_out_data) { - fp_out_data = fopen(args.file_out_data, "wb"); - if (fp_out_data == NULL) { - err_sys("Cannot open file %s for output\n", - args.file_out_data); - goto err; - } - } - - if (args.file_out_oob) { - fp_out_oob = fopen(args.file_out_oob, "wb"); - if (fp_out_oob == NULL) { - err_sys("Cannot open file %s for output\n", - args.file_out_oob); - goto err; - } - } - - - while(1) { - read = fread(buf, 1, args.pagesize, args.fp_in); - if (feof(args.fp_in) && read == 0) - break; - - if (read < args.pagesize) { - err_msg("Image not page aligned\n"); - goto err; - } - - if (ferror(args.fp_in)) { - err_msg("Read error\n"); - goto err; - } - - res = process_page(buf, args.pagesize, fp_out_data, - fp_out_oob, &written); - if (res != 0) - goto err; - } - - while (written < args.padding) { - memset(buf, 0xff, args.pagesize); - res = process_page(buf, args.pagesize, fp_out_data, - fp_out_oob, &written); - if (res != 0) - goto err; - } - - rc = 0; -err: - free(buf); - - if (args.fp_in) - fclose(args.fp_in); - - if (fp_out_oob) - fclose(fp_out_oob); - - if (fp_out_data && fp_out_data != stdout) - fclose(fp_out_data); - - if (rc != 0) { - err_msg("Error during conversion. rc: %d\n", rc); - if (args.file_out_data) - remove(args.file_out_data); - if (args.file_out_oob) - remove(args.file_out_oob); - } - return rc; -} diff --git a/ubi-utils/old-utils/src/bootenv.c b/ubi-utils/old-utils/src/bootenv.c deleted file mode 100644 index 78198fe..0000000 --- a/ubi-utils/old-utils/src/bootenv.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2008 - * - * 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. - * - * Author: Oliver Lohmann - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hashmap.h" -#include "error.h" - -#include -#include "crc32.h" - -#define ubi_unused __attribute__((unused)) - -#define BOOTENV_MAXLINE 512 /* max line size of a bootenv.txt file */ - -/* Structures */ -struct bootenv { - hashmap_t map; ///< Pointer to hashmap which holds data structure. -}; - -struct bootenv_list { - hashmap_t head; ///< Pointer to list which holds the data structure. -}; - -/** - * @brief Remove the '\n' from a given line. - * @param line Input/Output line. - * @param size Size of the line. - * @param fp File Pointer. - * @return 0 - * @return or error - */ -static int -remove_lf(char *line, size_t size, FILE* fp) -{ - size_t i; - - for (i = 0; i < size; i++) { - if (line[i] == '\n') { - line[i] = '\0'; - return 0; - } - } - - if (!feof(fp)) { - return BOOTENV_EINVAL; - } - - return 0; -} - -/** - * @brief Determine if a line contains only WS. - * @param line The line to process. - * @param size Size of input line. - * @return 1 Yes, only WS. - * @return 0 No, contains data. - */ -static int -is_ws(const char *line, size_t size) -{ - size_t i = 0; - - while (i < size) { - switch (line[i]) { - case '\n': - return 1; - case '#': - return 1; - case ' ': - i++; - continue; - case '\t': - i++; - continue; - default: /* any other char -> no cmnt */ - return 0; - } - } - - return 0; -} - - -/* ------------------------------------------------------------------------- */ - -/** - * @brief Build a list from a comma seperated value string. - * @param list Pointer to hashmap structure which shall store - * the list. - * @param value Comma seperated value string. - * @return 0 - * @return or error. - */ -static int -build_list_definition(hashmap_t list, const char *value) -{ - int rc = 0; - char *str = NULL; - char *ptr = NULL; - size_t len, i, j; - - /* str: val1,val2 , val4,...,valN */ - len = strlen(value); - str = (char*) malloc((len+1) * sizeof(char)); - - /* 1. reformat string: remove spaces */ - for (i = 0, j = 0; i < len; i++) { - if (value[i] == ' ') - continue; - - str[j] = value[i]; - j++; - } - str[j] = '\0'; - - /* str: val1,val2,val4,...,valN\0*/ - /* 2. replace ',' seperator with '\0' */ - len = strlen(str); - for (i = 0; i < len; i++) { - if (str[i] == ',') { - str[i] = '\0'; - } - } - - /* str: val1\0val2\0val4\0...\0valN\0*/ - /* 3. insert definitions into a hash map, using it like a list */ - i = j = 0; - ptr = str; - while (((i = strlen(ptr)) > 0) && (j < len)) { - rc = hashmap_add(list, ptr, ""); - if (rc != 0) { - free(str); - return rc; - } - j += i+1; - if (j < len) - ptr += i+1; - } - - free(str); - return rc; -} - -/** - * @brief Extract a key value pair and add it to a hashmap - * @param str Input string which contains a key value pair. - * @param env The updated handle which contains the new pair. - * @return 0 - * @return or error - * @note The input string format is: "key=value" - */ -static int -extract_pair(const char *str, bootenv_t env) -{ - int rc = 0; - char *key = NULL; - char *val = NULL; - - key = strdup(str); - if (key == NULL) - return -ENOMEM; - - val = strstr(key, "="); - if (val == NULL) { - rc = BOOTENV_EBADENTRY; - goto err; - } - - *val = '\0'; /* split strings */ - val++; - - rc = bootenv_set(env, key, val); - - err: - free(key); - return rc; -} - -int -bootenv_destroy(bootenv_t* env) -{ - int rc = 0; - - if (env == NULL || *env == NULL) - return -EINVAL; - - bootenv_t tmp = *env; - - rc = hashmap_free(tmp->map); - if (rc != 0) - return rc; - - free(tmp); - return rc; -} - -int -bootenv_create(bootenv_t* env) -{ - bootenv_t res; - res = (bootenv_t) calloc(1, sizeof(struct bootenv)); - - if (res == NULL) - return -ENOMEM; - - res->map = hashmap_new(); - - if (res->map == NULL) { - free(res); - return -ENOMEM; - } - - *env = res; - - return 0; -} - - -/** - * @brief Read a formatted buffer and scan it for valid bootenv - * key/value pairs. Add those pairs into a hashmap. - * @param env Hashmap which shall be used to hold the data. - * @param buf Formatted buffer. - * @param size Size of the buffer. - * @return 0 - * @return or error - */ -static int -rd_buffer(bootenv_t env, const char *buf, size_t size) -{ - const char *curr = buf; /* ptr to current key/value pair */ - uint32_t i, j; /* current length, chars processed */ - - if (buf[size - 1] != '\0') /* must end in '\0' */ - return BOOTENV_EFMT; - - for (j = 0; j < size; j += i, curr += i) { - /* strlen returns the size of the string upto - but not including the null terminator; - adding 1 to account for '\0' */ - i = strlen(curr) + 1; - - if (i == 1) - return 0; /* no string found */ - - if (extract_pair(curr, env) != 0) - return BOOTENV_EINVAL; - } - - return 0; -} - - -int -bootenv_read_crc(FILE* fp, bootenv_t env, size_t size, uint32_t* ret_crc) -{ - int rc; - char *buf = NULL; - size_t i = 0; - uint32_t crc32_table[256]; - - if ((fp == NULL) || (env == NULL)) - return -EINVAL; - - /* allocate temp buffer */ - buf = (char*) calloc(1, size * sizeof(char)); - if (buf == NULL) - return -ENOMEM; - - /* FIXME Andreas, please review this I removed size-1 and - * replaced it by just size, I saw the kernel image starting - * with a 0x0060.... and not with the 0x60.... what it should - * be. Is this a tools problem or is it a problem here where - * fp is moved not to the right place due to the former size-1 - * here. - */ - while((i < size) && (!feof(fp))) { - int c = fgetc(fp); - if (c == EOF) { - /* FIXME isn't this dangerous, to update - the boot envs with incomplete data? */ - buf[i++] = '\0'; - break; /* we have enough */ - } - if (ferror(fp)) { - rc = -EIO; - goto err; - } - - buf[i++] = (char)c; - } - - /* calculate crc to return */ - if (ret_crc != NULL) { - init_crc32_table(crc32_table); - *ret_crc = clc_crc32(crc32_table, UBI_CRC32_INIT, buf, size); - } - - /* transfer to hashmap */ - rc = rd_buffer(env, buf, size); - -err: - free(buf); - return rc; -} - - -/** - * If we have a single file containing the boot-parameter size should - * be specified either as the size of the file or as BOOTENV_MAXSIZE. - * If the bootparameter are in the middle of a file we need the exact - * length of the data. - */ -int -bootenv_read(FILE* fp, bootenv_t env, size_t size) -{ - return bootenv_read_crc(fp, env, size, NULL); -} - - -int -bootenv_read_txt(FILE* fp, bootenv_t env) -{ - int rc = 0; - char *buf = NULL; - char *line = NULL; - char *lstart = NULL; - char *curr = NULL; - size_t len; - size_t size; - - if ((fp == NULL) || (env == NULL)) - return -EINVAL; - - size = BOOTENV_MAXSIZE; - - /* allocate temp buffers */ - buf = (char*) calloc(1, size * sizeof(char)); - lstart = line = (char*) calloc(1, size * sizeof(char)); - if ((buf == NULL) || (line == NULL)) { - rc = -ENOMEM; - goto err; - } - - curr = buf; - while ((line = fgets(line, size, fp)) != NULL) { - if (is_ws(line, size)) { - continue; - } - rc = remove_lf(line, BOOTENV_MAXSIZE, fp); - if (rc != 0) { - goto err; - } - - /* copy new line to binary buffer */ - len = strlen(line); - if (len > size) { - rc = -EFBIG; - goto err; - } - size -= len; /* track remaining space */ - - memcpy(curr, line, len); - curr += len + 1; /* for \0 seperator */ - } - - rc = rd_buffer(env, buf, BOOTENV_MAXSIZE); -err: - if (buf != NULL) - free(buf); - if (lstart != NULL) - free(lstart); - return rc; -} - -static int -fill_output_buffer(bootenv_t env, char *buf, size_t buf_size_max ubi_unused, - size_t *written) -{ - int rc = 0; - size_t keys_size, i; - size_t wr = 0; - const char **keys = NULL; - const char *val = NULL; - - rc = bootenv_get_key_vector(env, &keys_size, 1, &keys); - if (rc != 0) - goto err; - - for (i = 0; i < keys_size; i++) { - if (wr > BOOTENV_MAXSIZE) { - rc = -ENOSPC; - goto err; - } - - rc = bootenv_get(env, keys[i], &val); - if (rc != 0) - goto err; - - wr += snprintf(buf + wr, BOOTENV_MAXSIZE - wr, - "%s=%s", keys[i], val); - wr++; /* for \0 */ - } - - *written = wr; - -err: - if (keys != NULL) - free(keys); - - return rc; -} - -int -bootenv_write_crc(FILE* fp, bootenv_t env, uint32_t* ret_crc) -{ - int rc = 0; - size_t size = 0; - char *buf = NULL; - uint32_t crc32_table[256]; - - if ((fp == NULL) || (env == NULL)) - return -EINVAL; - - buf = (char*) calloc(1, BOOTENV_MAXSIZE * sizeof(char)); - if (buf == NULL) - return -ENOMEM; - - - rc = fill_output_buffer(env, buf, BOOTENV_MAXSIZE, &size); - if (rc != 0) - goto err; - - /* calculate crc to return */ - if (ret_crc != NULL) { - init_crc32_table(crc32_table); - *ret_crc = clc_crc32(crc32_table, UBI_CRC32_INIT, buf, size); - } - - if (fwrite(buf, size, 1, fp) != 1) { - rc = -EIO; - goto err; - } - -err: - if (buf != NULL) - free(buf); - return rc; -} - -int -bootenv_write(FILE* fp, bootenv_t env) -{ - return bootenv_write_crc(fp, env, NULL); -} - -int -bootenv_compare(bootenv_t first, bootenv_t second) -{ - int rc; - size_t written_first, written_second; - char *buf_first, *buf_second; - - if (first == NULL || second == NULL) - return -EINVAL; - - buf_first = malloc(BOOTENV_MAXSIZE); - if (!buf_first) - return -ENOMEM; - buf_second = malloc(BOOTENV_MAXSIZE); - if (!buf_second) { - rc = -ENOMEM; - goto err; - } - - rc = fill_output_buffer(first, buf_first, BOOTENV_MAXSIZE, - &written_first); - if (rc < 0) - goto err; - rc = fill_output_buffer(second, buf_second, BOOTENV_MAXSIZE, - &written_second); - if (rc < 0) - goto err; - - if (written_first != written_second) { - rc = 1; - goto err; - } - - rc = memcmp(buf_first, buf_second, written_first); - if (rc != 0) { - rc = 2; - goto err; - } - -err: - if (buf_first) - free(buf_first); - if (buf_second) - free(buf_second); - - return rc; -} - -int -bootenv_size(bootenv_t env, size_t *size) -{ - int rc = 0; - char *buf = NULL; - - if (env == NULL) - return -EINVAL; - - buf = (char*) calloc(1, BOOTENV_MAXSIZE * sizeof(char)); - if (buf == NULL) - return -ENOMEM; - - rc = fill_output_buffer(env, buf, BOOTENV_MAXSIZE, size); - if (rc != 0) - goto err; - -err: - if (buf != NULL) - free(buf); - return rc; -} - -int -bootenv_write_txt(FILE* fp, bootenv_t env) -{ - int rc = 0; - size_t size, wr, i; - const char **keys = NULL; - const char *key = NULL; - const char *val = NULL; - - if ((fp == NULL) || (env == NULL)) - return -EINVAL; - - rc = bootenv_get_key_vector(env, &size, 1, &keys); - if (rc != 0) - goto err; - - for (i = 0; i < size; i++) { - key = keys[i]; - rc = bootenv_get(env, key, &val); - if (rc != 0) - goto err; - - wr = fprintf(fp, "%s=%s\n", key, val); - if (wr != strlen(key) + strlen(val) + 2) { - rc = -EIO; - goto err; - } - } - -err: - if (keys != NULL) - free(keys); - return rc; -} - -int -bootenv_valid(bootenv_t env ubi_unused) -{ - /* @FIXME No sanity check implemented. */ - return 0; -} - -int -bootenv_copy_bootenv(bootenv_t in, bootenv_t *out) -{ - int rc = 0; - const char *tmp = NULL; - const char **keys = NULL; - size_t vec_size, i; - - if ((in == NULL) || (out == NULL)) - return -EINVAL; - - /* purge output var for sure... */ - rc = bootenv_destroy(out); - if (rc != 0) - return rc; - - /* create the new map */ - rc = bootenv_create(out); - if (rc != 0) - goto err; - - /* get the key list from the input map */ - rc = bootenv_get_key_vector(in, &vec_size, 0, &keys); - if (rc != 0) - goto err; - - if (vec_size != hashmap_size(in->map)) { - rc = BOOTENV_ECOPY; - goto err; - } - - /* make a deep copy of the hashmap */ - for (i = 0; i < vec_size; i++) { - rc = bootenv_get(in, keys[i], &tmp); - if (rc != 0) - goto err; - - rc = bootenv_set(*out, keys[i], tmp); - if (rc != 0) - goto err; - } - -err: - if (keys != NULL) - free(keys); - - return rc; -} - -/* ------------------------------------------------------------------------- */ - - -int -bootenv_pdd_keep(bootenv_t env_old, bootenv_t env_new, bootenv_t *env_res, - int *warnings, char *err_buf ubi_unused, - size_t err_buf_size ubi_unused) -{ - bootenv_list_t l_old = NULL; - bootenv_list_t l_new = NULL; - const char *pdd_old = NULL; - const char *pdd_new = NULL; - const char *tmp = NULL; - const char **vec_old = NULL; - const char **vec_new = NULL; - const char **pdd_up_vec = NULL; - size_t vec_old_size, vec_new_size, pdd_up_vec_size, i; - int rc = 0; - - if ((env_old == NULL) || (env_new == NULL) || (env_res == NULL)) - return -EINVAL; - - /* get the pdd strings, e.g.: - * pdd_old=a,b,c - * pdd_new=a,c,d,e */ - rc = bootenv_get(env_old, "pdd", &pdd_old); - if (rc != 0) - goto err; - rc = bootenv_get(env_new, "pdd", &pdd_new); - if (rc != 0) - goto err; - - /* put it into a list and then convert it to an vector */ - rc = bootenv_list_create(&l_old); - if (rc != 0) - goto err; - rc = bootenv_list_create(&l_new); - if (rc != 0) - goto err; - - rc = bootenv_list_import(l_old, pdd_old); - if (rc != 0) - goto err; - - rc = bootenv_list_import(l_new, pdd_new); - if (rc != 0) - goto err; - - rc = bootenv_list_to_vector(l_old, &vec_old_size, &vec_old); - if (rc != 0) - goto err; - - rc = bootenv_list_to_vector(l_new, &vec_new_size, &vec_new); - if (rc != 0) - goto err; - - rc = bootenv_copy_bootenv(env_new, env_res); - if (rc != 0) - goto err; - - /* calculate the update vector between the old and new pdd */ - pdd_up_vec = hashmap_get_update_key_vector(vec_old, vec_old_size, - vec_new, vec_new_size, &pdd_up_vec_size); - - if (pdd_up_vec == NULL) { - rc = -ENOMEM; - goto err; - } - - if (pdd_up_vec_size != 0) { - /* need to warn the user about the unset of - * some pdd/bootenv values */ - *warnings = BOOTENV_WPDD_STRING_DIFFERS; - - /* remove all entries in the new bootenv load */ - for (i = 0; i < pdd_up_vec_size; i++) { - bootenv_unset(*env_res, pdd_up_vec[i]); - } - } - - /* generate the keep array and copy old pdd values to new bootenv */ - for (i = 0; i < vec_old_size; i++) { - rc = bootenv_get(env_old, vec_old[i], &tmp); - if (rc != 0) { - rc = BOOTENV_EPDDINVAL; - goto err; - } - rc = bootenv_set(*env_res, vec_old[i], tmp); - if (rc != 0) { - goto err; - } - } - /* put the old pdd string into the result map */ - rc = bootenv_set(*env_res, "pdd", pdd_old); - if (rc != 0) { - goto err; - } - - -err: - if (vec_old != NULL) - free(vec_old); - if (vec_new != NULL) - free(vec_new); - if (pdd_up_vec != NULL) - free(pdd_up_vec); - - bootenv_list_destroy(&l_old); - bootenv_list_destroy(&l_new); - return rc; -} - - -int -bootenv_pdd_overwrite(bootenv_t env_old, bootenv_t env_new, - bootenv_t *env_res, int *warnings ubi_unused, - char *err_buf ubi_unused, size_t err_buf_size ubi_unused) -{ - if ((env_old == NULL) || (env_new == NULL) || (env_res == NULL)) - return -EINVAL; - - return bootenv_copy_bootenv(env_new, env_res); -} - -int -bootenv_pdd_merge(bootenv_t env_old, bootenv_t env_new, bootenv_t *env_res, - int *warnings ubi_unused, char *err_buf, size_t err_buf_size) -{ - if ((env_old == NULL) || (env_new == NULL) || (env_res == NULL)) - return -EINVAL; - - snprintf(err_buf, err_buf_size, "The PDD merge operation is not " - "implemented. Contact: "); - - return BOOTENV_ENOTIMPL; -} - -/* ------------------------------------------------------------------------- */ - -int -bootenv_get(bootenv_t env, const char *key, const char **value) -{ - if (env == NULL) - return -EINVAL; - - *value = hashmap_lookup(env->map, key); - if (*value == NULL) - return BOOTENV_ENOTFOUND; - - return 0; -} - -int -bootenv_get_num(bootenv_t env, const char *key, uint32_t *value) -{ - char *endptr = NULL; - const char *str; - - if (env == NULL) - return 0; - - str = hashmap_lookup(env->map, key); - if (!str) - return -EINVAL; - - *value = strtoul(str, &endptr, 0); - - if (*endptr == '\0') { - return 0; - } - - return -EINVAL; -} - -int -bootenv_set(bootenv_t env, const char *key, const char *value) -{ - if (env == NULL) - return -EINVAL; - - return hashmap_add(env->map, key, value); -} - -int -bootenv_unset(bootenv_t env, const char *key) -{ - if (env == NULL) - return -EINVAL; - - return hashmap_remove(env->map, key); -} - -int -bootenv_get_key_vector(bootenv_t env, size_t* size, int sort, - const char ***vector) -{ - if ((env == NULL) || (size == NULL)) - return -EINVAL; - - *vector = hashmap_get_key_vector(env->map, size, sort); - - if (*vector == NULL) - return -EINVAL; - - return 0; -} - -int -bootenv_dump(bootenv_t env) -{ - if (env == NULL) - return -EINVAL; - - return hashmap_dump(env->map); -} - -int -bootenv_list_create(bootenv_list_t *list) -{ - bootenv_list_t res; - res = (bootenv_list_t) calloc(1, sizeof(struct bootenv_list)); - - if (res == NULL) - return -ENOMEM; - - res->head = hashmap_new(); - - if (res->head == NULL) { - free(res); - return -ENOMEM; - } - - *list = res; - return 0; -} - -int -bootenv_list_destroy(bootenv_list_t *list) -{ - int rc = 0; - - if (list == NULL) - return -EINVAL; - - bootenv_list_t tmp = *list; - if (tmp == 0) - return 0; - - rc = hashmap_free(tmp->head); - if (rc != 0) - return rc; - - free(tmp); - *list = NULL; - return 0; -} - -int -bootenv_list_import(bootenv_list_t list, const char *str) -{ - if (list == NULL) - return -EINVAL; - - return build_list_definition(list->head, str); -} - -int -bootenv_list_export(bootenv_list_t list, char **string) -{ - size_t size, i, j, bufsize, tmp, rc = 0; - const char **items; - - if (list == NULL) - return -EINVAL; - - bufsize = BOOTENV_MAXLINE; - char *res = (char*) malloc(bufsize * sizeof(char)); - if (res == NULL) - return -ENOMEM; - - rc = bootenv_list_to_vector(list, &size, &items); - if (rc != 0) { - goto err; - } - - j = 0; - for (i = 0; i < size; i++) { - tmp = strlen(items[i]); - if (j >= bufsize) { - bufsize += BOOTENV_MAXLINE; - res = (char*) realloc(res, bufsize * sizeof(char)); - if (res == NULL) { - rc = -ENOMEM; - goto err; - } - } - memcpy(res + j, items[i], tmp); - j += tmp; - if (i < (size - 1)) { - res[j] = ','; - j++; - } - } - j++; - res[j] = '\0'; - free(items); - *string = res; - return 0; -err: - free(items); - return rc; -} - -int -bootenv_list_add(bootenv_list_t list, const char *item) -{ - if ((list == NULL) || (item == NULL)) - return -EINVAL; - - return hashmap_add(list->head, item, ""); -} - -int -bootenv_list_remove(bootenv_list_t list, const char *item) -{ - if ((list == NULL) || (item == NULL)) - return -EINVAL; - - return hashmap_remove(list->head, item); -} - -int -bootenv_list_is_in(bootenv_list_t list, const char *item) -{ - if ((list == NULL) || (item == NULL)) - return -EINVAL; - - return hashmap_lookup(list->head, item) != NULL ? 1 : 0; -} - -int -bootenv_list_to_vector(bootenv_list_t list, size_t *size, const char ***vector) -{ - if ((list == NULL) || (size == NULL)) - return -EINVAL; - - *vector = hashmap_get_key_vector(list->head, size, 1); - if (*vector == NULL) - return -ENOMEM; - - return 0; -} - -int -bootenv_list_to_num_vector(bootenv_list_t list, size_t *size, - uint32_t **vector) -{ - int rc = 0; - size_t i; - uint32_t* res = NULL; - char *endptr = NULL; - const char **a = NULL; - - rc = bootenv_list_to_vector(list, size, &a); - if (rc != 0) - goto err; - - res = (uint32_t*) malloc (*size * sizeof(uint32_t)); - if (!res) - goto err; - - for (i = 0; i < *size; i++) { - res[i] = strtoul(a[i], &endptr, 0); - if (*endptr != '\0') - goto err; - } - - if (a) - free(a); - *vector = res; - return 0; - -err: - if (a) - free(a); - if (res) - free(res); - return rc; -} diff --git a/ubi-utils/old-utils/src/bootenv.h b/ubi-utils/old-utils/src/bootenv.h deleted file mode 100644 index 8fecdbf..0000000 --- a/ubi-utils/old-utils/src/bootenv.h +++ /dev/null @@ -1,434 +0,0 @@ -#ifndef __BOOTENV_H__ -#define __BOOTENV_H__ -/* - * 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. - */ - -#include /* FILE */ -#include -#include - -/* DOXYGEN DOCUMENTATION */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file bootenv.h - * @author oliloh@de.ibm.com - * @version 1.3 - * - * 1.3 Some renaming - */ - -/** - * @mainpage Usage - * - * @section intro Introduction - * This library provides all functionality to handle with the so-called - * platform description data (PDD) and the bootparameters defined in - * U-Boot. It is able to apply the defined PDD operations in PDD update - * scenarios. For more information about the PDD and bootparameter - * environment "bootenv" confer the PDD documentation. - * - * @section ret Return codes - * This library defines some return codes which will be delivered classified - * as warnings or errors. See the "Defines" section for details and numeric - * values. - * - * @section benv Bootenv format description - * There are two different input formats: - * - text files - * - binary files - * - * @subsection txt Text Files - * Text files have to be specified like: - * @verbatim key1=value1,value2,value7\n key2=value55,value1\n key4=value1\n@endverbatim - * - * @subsection bin Binary files - * Binary files have to be specified like: - * @verbatimkey1=value1,value2,value7\0key2=value55,value1\0... @endverbatim - * You can confer the U-Boot documentation for more details. - * - * @section benvlists Bootenv lists format description. - * Values referenced in the preceeding subsection can be - * defined like lists: - * @verbatim value1,value2,value3 @endverbatim - * There are some situation where a conversion of a comma - * seperated list can be useful, e.g. to get a list - * of defined PDD entries. - */ - -#define BOOTENV_MAXSIZE (1024 * 100) /* max 100kiB space for bootenv */ - -/** - * @def BOOTENV_ECRC - * @brief Given binary file is to large. - * @def BOOTENV_EFMT - * @brief Given bootenv section has an invalid format - * @def BOOTENV_EBADENTRY - * @brief Bad entry in the bootenv section. - * @def BOOTENV_EINVAL - * @brief Invalid bootenv defintion. - * @def BOOTENV_ENOPDD - * @brief Given bootenv sectoin has no PDD defintion string (pdd=...). - * @def BOOTENV_EPDDINVAL - * @brief Given bootenv section has an invalid PDD defintion. - * @def BOOTENV_ENOTIMPL - * @brief Functionality not implemented. - * @def BOOTENV_ECOPY - * @brief Bootenv memory copy error - * @def BOOTENV_ENOTFOUND - * @brief Given key has has no value. - * @def BOOTENV_EMAX - * @brief Highest error value. - */ -#define BOOTENV_ETOOBIG 1 -#define BOOTENV_EFMT 2 -#define BOOTENV_EBADENTRY 3 -#define BOOTENV_EINVAL 4 -#define BOOTENV_ENOPDD 5 -#define BOOTENV_EPDDINVAL 6 -#define BOOTENV_ENOTIMPL 7 -#define BOOTENV_ECOPY 8 -#define BOOTENV_ENOTFOUND 9 -#define BOOTENV_EMAX 10 - -/** - * @def BOOTENV_W - * @brief A warning which is handled internally as an error - * but can be recovered by manual effort. - * @def BOOTENV_WPDD_STRING_DIFFERS - * @brief The PDD strings of old and new PDD differ and - * can cause update problems, because new PDD values - * are removed from the bootenv section completely. - */ -#define BOOTENV_W 20 -#define BOOTENV_WPDD_STRING_DIFFERS 21 -#define BOOTENV_WMAX 22 /* highest warning value */ - - -typedef struct bootenv *bootenv_t; - /**< A bootenv library handle. */ - -typedef struct bootenv_list *bootenv_list_t; - /**< A handle for a value list. */ - -typedef int(*pdd_func_t)(bootenv_t, bootenv_t, bootenv_t*, - int*, char*, size_t); - - -/** - * @brief Get a new handle. - * @return 0 - * @return or error - * */ -int bootenv_create(bootenv_t *env); - -/** - * @brief Cleanup structure. - * @param env Bootenv structure which shall be destroyed. - * @return 0 - * @return or error - */ -int bootenv_destroy(bootenv_t *env); - -/** - * @brief Copy a bootenv handle. - * @param in The input bootenv. - * @param out The copied output bootenv. Discards old data. - * @return 0 - * @return or error - */ -int bootenv_copy_bootenv(bootenv_t in, bootenv_t *out); - -/** - * @brief Looks for a value inside the bootenv data. - * @param env Handle to a bootenv structure. - * @param key The key. - * @return NULL key not found - * @return !NULL ptr to value - */ -int bootenv_get(bootenv_t env, const char *key, const char **value); - - -/** - * @brief Looks for a value inside the bootenv data and converts it to num. - * @param env Handle to a bootenv structure. - * @param key The key. - * @param value A pointer to the resulting numerical value - * @return NULL key not found - * @return !NULL ptr to value - */ -int bootenv_get_num(bootenv_t env, const char *key, uint32_t *value); - -/** - * @brief Set a bootenv value by key. - * @param env Handle to a bootenv structure. - * @param key Key. - * @param value Value to set. - * @return 0 - * @return or error - */ -int bootenv_set(bootenv_t env, const char *key, const char *value); - -/** - * @brief Remove the given key (and its value) from a bootenv structure. - * @param env Handle to a bootenv structure. - * @param key Key. - * @return 0 - * @return or error - */ -int bootenv_unset(bootenv_t env, const char *key); - - -/** - * @brief Get a vector of all keys which are currently set - * within a bootenv handle. - * @param env Handle to a bootenv structure. - * @param size The size of the allocated array structure. - * @param sort Flag, if set the vector is sorted ascending. - * @return NULL on error. - * @return !NULL a pointer to the first element the allocated vector. - * @warning Free the allocate memory yourself! - */ -int bootenv_get_key_vector(bootenv_t env, size_t *size, int sort, - const char ***vector); - -/** - * @brief Calculate the size in bytes which are necessary to write the - * current bootenv section in a *binary file. - * @param env bootenv handle. - * @param size The size in bytes of the bootenv handle. - * @return 0 - * @return or ERROR. - */ -int bootenv_size(bootenv_t env, size_t *size); - -/** - * @brief Read a binary bootenv file. - * @param fp File pointer to input stream. - * @param env bootenv handle. - * @param size maximum data size. - * @return 0 - * @return or ERROR. - */ -int bootenv_read(FILE* fp, bootenv_t env, size_t size); - -/** - * @param ret_crc return value of crc of read data - */ -int bootenv_read_crc(FILE* fp, bootenv_t env, size_t size, uint32_t *ret_crc); - -/** - * @brief Read bootenv data from an text/ascii file. - * @param fp File pointer to ascii PDD file. - * @param env bootenv handle - * @return 0 - * @return or ERROR. - */ -int bootenv_read_txt(FILE* fp, bootenv_t env); - -/** - * @brief Write a bootenv structure to the given location (binary). - * @param fp Filepointer to binary file. - * @param env Bootenv structure which shall be written. - * @return 0 - * @return or error - */ -int bootenv_write(FILE* fp, bootenv_t env); - -/** - * @param ret_crc return value of crc of read data - */ -int bootenv_write_crc(FILE* fp, bootenv_t env, uint32_t* ret_crc); - -/** - * @brief Write a bootenv structure to the given location (text). - * @param fp Filepointer to text file. - * @param env Bootenv structure which shall be written. - * @return 0 - * @return or error - */ -int bootenv_write_txt(FILE* fp, bootenv_t env); - -/** - * @brief Compare bootenvs using memcmp(). - * @param first First bootenv. - * @param second Second bootenv. - * @return 0 if bootenvs are equal - * @return < 0 if error - * @return > 0 if unequal - */ -int bootenv_compare(bootenv_t first, bootenv_t second); - -/** - * @brief Prototype for a PDD handling funtion - */ - -/** - * @brief The PDD keep operation. - * @param env_old The old bootenv structure. - * @param env_new The new bootenv structure. - * @param env_res The result of PDD keep. - * @param warnings A flag which marks any warnings. - * @return 0 - * @return or error - * @note For a complete documentation about the algorithm confer the - * PDD documentation. - */ -int bootenv_pdd_keep(bootenv_t env_old, bootenv_t env_new, - bootenv_t *env_res, int *warnings, - char *err_buf, size_t err_buf_size); - - -/** - * @brief The PDD merge operation. - * @param env_old The old bootenv structure. - * @param env_new The new bootenv structure. - * @param env_res The result of merge-pdd. - * @param warnings A flag which marks any warnings. - * @return 0 - * @return or error - * @note For a complete documentation about the algorithm confer the - * PDD documentation. - */ -int bootenv_pdd_merge(bootenv_t env_old, bootenv_t env_new, - bootenv_t *env_res, int *warnings, - char *err_buf, size_t err_buf_size); - -/** - * @brief The PDD overwrite operation. - * @param env_old The old bootenv structure. - * @param env_new The new bootenv structure. - * @param env_res The result of overwrite-pdd. - * @param warnings A flag which marks any warnings. - * @return 0 - * @return or error - * @note For a complete documentation about the algorithm confer the - * PDD documentation. - */ -int bootenv_pdd_overwrite(bootenv_t env_new, - bootenv_t env_old, bootenv_t *env_res, int *warnings, - char *err_buf, size_t err_buf_size); - -/** - * @brief Dump a bootenv structure to stdout. (Debug) - * @param env Handle to a bootenv structure. - * @return 0 - * @return or error - */ -int bootenv_dump(bootenv_t env); - -/** - * @brief Validate a bootenv structure. - * @param env Handle to a bootenv structure. - * @return 0 - * @return or error - */ -int bootenv_valid(bootenv_t env); - -/** - * @brief Create a new bootenv list structure. - * @return NULL on error - * @return or a new list handle. - * @note This structure is used to store values in a list. - * A useful addition when handling PDD strings. - */ -int bootenv_list_create(bootenv_list_t *list); - -/** - * @brief Destroy a bootenv list structure - * @param list Handle to a bootenv list structure. - * @return 0 - * @return or error - */ -int bootenv_list_destroy(bootenv_list_t *list); - -/** - * @brief Import a list from a comma seperated string - * @param list Handle to a bootenv list structure. - * @param str Comma seperated string list. - * @return 0 - * @return or error - */ -int bootenv_list_import(bootenv_list_t list, const char *str); - -/** - * @brief Export a list to a string of comma seperated values. - * @param list Handle to a bootenv list structure. - * @return NULL one error - * @return or pointer to a newly allocated string. - * @warning Free the allocated memory by yourself! - */ -int bootenv_list_export(bootenv_list_t list, char **string); - -/** - * @brief Add an item to the list. - * @param list A handle of a list structure. - * @param item An item. - * @return 0 - * @return or error - */ -int bootenv_list_add(bootenv_list_t list, const char *item); - -/** - * @brief Remove an item from the list. - * @param list A handle of a list structure. - * @param item An item. - * @return 0 - * @return or error - */ -int bootenv_list_remove(bootenv_list_t list, const char *item); - -/** - * @brief Check if a given item is in a given list. - * @param list A handle of a list structure. - * @param item An item. - * @return 1 Item is in list. - * @return 0 Item is not in list. - */ -int bootenv_list_is_in(bootenv_list_t list, const char *item); - - -/** - * @brief Convert a list into a vector of all values inside the list. - * @param list Handle to a bootenv structure. - * @param size The size of the allocated vector structure. - * @return 0 - * @return or error - * @warning Free the allocate memory yourself! - */ -int bootenv_list_to_vector(bootenv_list_t list, size_t *size, - const char ***vector); - -/** - * @brief Convert a list into a vector of all values inside the list. - * @param list Handle to a bootenv structure. - * @param size The size of the allocated vector structure. - * @return 0 - * @return or error - * @warning Free the allocate memory yourself! - */ -int bootenv_list_to_num_vector(bootenv_list_t list, size_t *size, - uint32_t **vector); - -#ifdef __cplusplus -} -#endif -#endif /*__BOOTENV_H__ */ diff --git a/ubi-utils/old-utils/src/config.h b/ubi-utils/old-utils/src/config.h deleted file mode 100644 index 55e60f3..0000000 --- a/ubi-utils/old-utils/src/config.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ -/* - * 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. - * - * Author: Frank Haverkamp - */ - -#define PACKAGE_BUGREPORT \ - "haver@vnet.ibm.com, dedekind@linutronix.de, or tglx@linutronix.de" - -#define ubi_unused __attribute__((unused)) - -#endif diff --git a/ubi-utils/old-utils/src/crc32.c b/ubi-utils/old-utils/src/crc32.c deleted file mode 100644 index 666e217..0000000 --- a/ubi-utils/old-utils/src/crc32.c +++ /dev/null @@ -1,83 +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. - * - * Author: Thomas Gleixner - */ - -/* - * CRC32 functions - * - * Can be compiled as seperate object, but is included into the ipl source - * so gcc can inline the functions. We optimize for size so the omission of - * the function frame is helpful. - * - */ - -#include -#include - -/* CRC polynomial */ -#define CRC_POLY 0xEDB88320 - -/** - * init_crc32_table - Initialize crc table - * - * @table: pointer to the CRC table which must be initialized - * - * Create CRC32 table for given polynomial. The table is created with - * the lowest order term in the highest order bit. So the x^32 term - * has to implied in the crc calculation function. - */ -void init_crc32_table(uint32_t *table) -{ - uint32_t crc; - int i, j; - - for (i = 0; i < 256; i++) { - crc = i; - for (j = 8; j > 0; j--) { - if (crc & 1) - crc = (crc >> 1) ^ CRC_POLY; - else - crc >>= 1; - } - table[i] = crc; - } -} - -/** - * clc_crc32 - Calculate CRC32 over a buffer - * - * @table: pointer to the CRC table - * @crc: initial crc value - * @buf: pointer to the buffer - * @len: number of bytes to calc - * - * Returns the updated crc value. - * - * The algorithm resembles a hardware shift register, but calculates 8 - * bit at once. - */ -uint32_t clc_crc32(uint32_t *table, uint32_t crc, void *buf, - int len) -{ - const unsigned char *p = buf; - - while(--len >= 0) - crc = table[(crc ^ *p++) & 0xff] ^ (crc >> 8); - return crc; -} diff --git a/ubi-utils/old-utils/src/crc32.h b/ubi-utils/old-utils/src/crc32.h deleted file mode 100644 index 31362b0..0000000 --- a/ubi-utils/old-utils/src/crc32.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __CRC32_H__ -#define __CRC32_H__ -/* - * 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. - */ - -/* - * Author: Thomas Gleixner - * - * CRC32 functions - * - * Can be compiled as seperate object, but is included into the ipl source - * so gcc can inline the functions. We optimize for size so the omission of - * the function frame is helpful. - * - */ -#include - -void init_crc32_table(uint32_t *table); -uint32_t clc_crc32(uint32_t *table, uint32_t crc, void *buf, int len); - -#endif /* __CRC32_H__ */ diff --git a/ubi-utils/old-utils/src/eb_chain.c b/ubi-utils/old-utils/src/eb_chain.c deleted file mode 100644 index da5c2e3..0000000 --- a/ubi-utils/old-utils/src/eb_chain.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * 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. - */ - -/* - * Author: Drake Dowsett, dowsett@de.ibm.com - * Contact: Andreas Arnez, arnez@de.ibm.com - */ - -/* see eb_chain.h */ - -#include -#include -#include -#include -#include "unubi_analyze.h" -#include "crc32.h" - -#define COPY(dst, src) \ - do { \ - dst = malloc(sizeof(*dst)); \ - if (dst == NULL) \ - return -ENOMEM; \ - memcpy(dst, src, sizeof(*dst)); \ - } while (0) - - -/** - * inserts an eb_info into the chain starting at head, then searching - * linearly for the correct position; - * new should contain valid vid and ec headers and the data_crc should - * already have been checked before insertion, otherwise the chain - * could be have un an undesired manner; - * returns -ENOMEM if alloc fails, otherwise SHOULD always return 0, - * if not, the code reached the last line and returned -EAGAIN, - * meaning there is a bug or a case not being handled here; - **/ -int -eb_chain_insert(struct eb_info **head, struct eb_info *new) -{ - uint32_t vol, num, ver; - uint32_t new_vol, new_num, new_ver; - struct eb_info *prev, *cur, *hist, *ins; - struct eb_info **prev_ptr; - - if ((head == NULL) || (new == NULL)) - return 0; - - if (*head == NULL) { - COPY(*head, new); - (*head)->next = NULL; - return 0; - } - - new_vol = be32_to_cpu(new->vid.vol_id); - new_num = be32_to_cpu(new->vid.lnum); - new_ver = be32_to_cpu(new->vid.leb_ver); - - /** TRAVERSE HORIZONTALY **/ - - cur = *head; - prev = NULL; - - /* traverse until vol_id/lnum align */ - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - while ((new_vol > vol) || ((new_vol == vol) && (new_num > num))) { - /* insert new at end of chain */ - if (cur->next == NULL) { - COPY(ins, new); - ins->next = NULL; - cur->next = ins; - return 0; - } - - prev = cur; - cur = cur->next; - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - } - - if (prev == NULL) - prev_ptr = head; - else - prev_ptr = &(prev->next); - - /* insert new into the middle of chain */ - if ((new_vol != vol) || (new_num != num)) { - COPY(ins, new); - ins->next = cur; - *prev_ptr = ins; - return 0; - } - - /** TRAVERSE VERTICALY **/ - - hist = cur; - prev = NULL; - - /* traverse until versions align */ - ver = be32_to_cpu(cur->vid.leb_ver); - while (new_ver < ver) { - /* insert new at bottom of history */ - if (hist->older == NULL) { - COPY(ins, new); - ins->next = NULL; - ins->older = NULL; - hist->older = ins; - return 0; - } - - prev = hist; - hist = hist->older; - ver = be32_to_cpu(hist->vid.leb_ver); - } - - if (prev == NULL) { - /* replace active version */ - COPY(ins, new); - ins->next = hist->next; - *prev_ptr = ins; - - /* place cur in vertical histroy */ - ins->older = hist; - hist->next = NULL; - return 0; - } - - /* insert between versions, beneath active version */ - COPY(ins, new); - ins->next = NULL; - ins->older = prev->older; - prev->older = ins; - return 0; -} - - -/** - * sets the pointer at pos to the position of the first entry in the chain - * with of vol_id and, if given, with the same lnum as *lnum; - * if there is no entry in the chain, then *pos is NULL on return; - * always returns 0; - **/ -int -eb_chain_position(struct eb_info **head, uint32_t vol_id, uint32_t *lnum, - struct eb_info **pos) -{ - uint32_t vol, num; - struct eb_info *cur; - - if ((head == NULL) || (*head == NULL) || (pos == NULL)) - return 0; - - *pos = NULL; - - cur = *head; - while (cur != NULL) { - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - - if ((vol_id == vol) && ((lnum == NULL) || (*lnum == num))) { - *pos = cur; - return 0; - } - - cur = cur->next; - } - - return 0; -} - - -/** - * prints to stream, the vol_id, lnum and leb_ver for each entry in the - * chain, starting at head; - * this is intended for debuging purposes; - * always returns 0; - * - * FIXME I do not like the double list traversion ... - **/ -int -eb_chain_print(FILE* stream, struct eb_info *head) -{ - struct eb_info *cur; - - if (stream == NULL) - stream = stdout; - - if (head == NULL) { - fprintf(stream, "EMPTY\n"); - return 0; - } - /* 012345678012345678012345678012301230123 0123 01234567 0123457 01234567*/ - fprintf(stream, "VOL_ID LNUM LEB_VER EC VID DAT PBLK PADDR DSIZE EC\n"); - cur = head; - while (cur != NULL) { - struct eb_info *hist; - - fprintf(stream, "%08x %-8u %08x %-4s%-4s", - be32_to_cpu(cur->vid.vol_id), - be32_to_cpu(cur->vid.lnum), - be32_to_cpu(cur->vid.leb_ver), - cur->ec_crc_ok ? "ok":"bad", - cur->vid_crc_ok ? "ok":"bad"); - if (cur->vid.vol_type == UBI_VID_STATIC) - fprintf(stream, "%-4s", cur->data_crc_ok ? "ok":"bad"); - else fprintf(stream, "%-4s", cur->data_crc_ok ? "ok":"ign"); - fprintf(stream, " %-4d %08x %-8u %-8llu\n", cur->phys_block, - cur->phys_addr, be32_to_cpu(cur->vid.data_size), - (unsigned long long)be64_to_cpu(cur->ec.ec)); - - hist = cur->older; - while (hist != NULL) { - fprintf(stream, "%08x %-8u %08x %-4s%-4s", - be32_to_cpu(hist->vid.vol_id), - be32_to_cpu(hist->vid.lnum), - be32_to_cpu(hist->vid.leb_ver), - hist->ec_crc_ok ? "ok":"bad", - hist->vid_crc_ok ? "ok":"bad"); - if (hist->vid.vol_type == UBI_VID_STATIC) - fprintf(stream, "%-4s", hist->data_crc_ok ? "ok":"bad"); - else fprintf(stream, "%-4s", hist->data_crc_ok ? "ok":"ign"); - fprintf(stream, " %-4d %08x %-8u %-8llu (*)\n", - hist->phys_block, hist->phys_addr, - be32_to_cpu(hist->vid.data_size), - (unsigned long long)be64_to_cpu(hist->ec.ec)); - - hist = hist->older; - } - cur = cur->next; - } - - return 0; -} - - -/** - * frees the memory of the entire chain, starting at head; - * head will be NULL on return; - * always returns 0; - **/ -int -eb_chain_destroy(struct eb_info **head) -{ - if (head == NULL) - return 0; - - while (*head != NULL) { - struct eb_info *cur; - struct eb_info *hist; - - cur = *head; - *head = (*head)->next; - - hist = cur->older; - while (hist != NULL) { - struct eb_info *temp; - - temp = hist; - hist = hist->older; - free(temp); - } - free(cur); - } - return 0; -} - diff --git a/ubi-utils/old-utils/src/error.c b/ubi-utils/old-utils/src/error.c deleted file mode 100644 index 4aaedad..0000000 --- a/ubi-utils/old-utils/src/error.c +++ /dev/null @@ -1,240 +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. - */ - -#include -#include -#include -#include -#include -#include -#include "error.h" - -#define MAXLINE 4096 -#define MAXWIDTH 80 - -static FILE *logfp = NULL; - -static void err_doit(int, int, const char *, va_list); - -int -read_procfile(FILE *fp_out, const char *procfile) -{ - FILE *fp; - - if (!fp_out) - return -ENXIO; - - fp = fopen(procfile, "r"); - if (!fp) - return -ENOENT; - - while(!feof(fp)) { - int c = fgetc(fp); - - if (c == EOF) - return 0; - - if (putc(c, fp_out) == EOF) - return -EIO; - - if (ferror(fp)) - return -EIO; - } - return fclose(fp); -} - -void -error_initlog(const char *logfile) -{ - if (!logfile) - return; - - logfp = fopen(logfile, "a+"); - read_procfile(logfp, "/proc/cpuinfo"); -} - -void -info_msg(const char *fmt, ...) -{ - FILE* fpout; - char buf[MAXLINE + 1]; - va_list ap; - int n; - - fpout = stdout; - - va_start(ap, fmt); - vsnprintf(buf, MAXLINE, fmt, ap); - n = strlen(buf); - strcat(buf, "\n"); - - fputs(buf, fpout); - fflush(fpout); - if (fpout != stdout) - fclose(fpout); - - va_end(ap); - return; -} - -void -__err_ret(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - err_doit(1, LOG_INFO, fmt, ap); - va_end(ap); - return; -} - -void -__err_sys(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - err_doit(1, LOG_ERR, fmt, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - - -void -__err_msg(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - err_doit(0, LOG_INFO, fmt, ap); - va_end(ap); - - return; -} - -void -__err_quit(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - err_doit(0, LOG_ERR, fmt, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - -void -__err_dump(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - err_doit(1, LOG_ERR, fmt, ap); - va_end(ap); - abort(); /* dump core and terminate */ - exit(EXIT_FAILURE); /* shouldn't get here */ -} - -/** - * If a logfile is used we must not print on stderr and stdout - * anymore. Since pfilfash might be used in a server context, it is - * even dangerous to write to those descriptors. - */ -static void -err_doit(int errnoflag, int level __attribute__((unused)), - const char *fmt, va_list ap) -{ - FILE* fpout; - int errno_save, n; - char buf[MAXLINE + 1]; - fpout = stderr; - - errno_save = errno; /* value caller might want printed */ - - vsnprintf(buf, MAXLINE, fmt, ap); /* safe */ - - n = strlen(buf); - - if (errnoflag) - snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save)); - strcat(buf, "\n"); - - if (logfp) { - fputs(buf, logfp); - fflush(logfp); - return; /* exit when logging completes */ - } - - if (fpout == stderr) { - /* perform line wrap when outputting to stderr */ - int word_len, post_len, chars; - char *buf_ptr; - const char *frmt = "%*s%n %n"; - - chars = 0; - buf_ptr = buf; - while (sscanf(buf_ptr, frmt, &word_len, &post_len) != EOF) { - int i; - char word[word_len + 1]; - char post[post_len + 1]; - - strncpy(word, buf_ptr, word_len); - word[word_len] = '\0'; - buf_ptr += word_len; - post_len -= word_len; - - if (chars + word_len > MAXWIDTH) { - fputc('\n', fpout); - chars = 0; - } - fputs(word, fpout); - chars += word_len; - - if (post_len > 0) { - strncpy(post, buf_ptr, post_len); - post[post_len] = '\0'; - buf_ptr += post_len; - } - for (i = 0; i < post_len; i++) { - int inc = 1, chars_new; - - if (post[i] == '\t') - inc = 8; - if (post[i] == '\n') { - inc = 0; - chars_new = 0; - } else - chars_new = chars + inc; - - if (chars_new > MAXWIDTH) { - fputc('\n', fpout); - chars_new = inc; - } - fputc(post[i], fpout); - chars = chars_new; - } - } - } - else - fputs(buf, fpout); - fflush(fpout); - if (fpout != stderr) - fclose(fpout); - - return; -} diff --git a/ubi-utils/old-utils/src/error.h b/ubi-utils/old-utils/src/error.h deleted file mode 100644 index 05d8078..0000000 --- a/ubi-utils/old-utils/src/error.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __ERROR_H__ -#define __ERROR_H__ -/* - * 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. - */ - -#include - -void error_initlog(const char *logfile); -int read_procfile(FILE *fp_out, const char *procfile); - -void __err_ret(const char *fmt, ...); -void __err_sys(const char *fmt, ...); -void __err_msg(const char *fmt, ...); -void __err_quit(const char *fmt, ...); -void __err_dump(const char *fmt, ...); - -void info_msg(const char *fmt, ...); - -#ifdef DEBUG -#define __loc_msg(str) do { \ - __err_msg("[%s. FILE: %s FUNC: %s LINE: %d]\n", \ - str, __FILE__, __FUNCTION__, __LINE__); \ -} while (0) -#else -#define __loc_msg(str) -#endif - - -#define err_dump(fmt, ...) do { \ - __loc_msg("ErrDump"); \ - __err_dump(fmt, ##__VA_ARGS__); \ -} while (0) - -#define err_quit(fmt, ...) do { \ - __loc_msg("ErrQuit"); \ - __err_quit(fmt, ##__VA_ARGS__); \ -} while (0) - - -#define err_ret(fmt, ...) do { \ - __loc_msg("ErrRet"); \ - __err_ret(fmt, ##__VA_ARGS__); \ -} while (0) - -#define err_sys(fmt, ...) do { \ - __loc_msg("ErrSys"); \ - __err_sys(fmt, ##__VA_ARGS__); \ -} while (0) - -#define err_msg(fmt, ...) do { \ - __loc_msg("ErrMsg"); \ - __err_msg(fmt, ##__VA_ARGS__); \ -} while (0) - -#define log_msg(fmt, ...) do { \ - /* __loc_msg("LogMsg"); */ \ - __err_msg(fmt, ##__VA_ARGS__); \ -} while (0) - -#ifdef DEBUG -#define dbg_msg(fmt, ...) do { \ - __loc_msg("DbgMsg"); \ - __err_msg(fmt, ##__VA_ARGS__); \ -} while (0) -#else -#define dbg_msg(fmt, ...) do {} while (0) -#endif - -#endif /* __ERROR_H__ */ diff --git a/ubi-utils/old-utils/src/example_ubi.h b/ubi-utils/old-utils/src/example_ubi.h deleted file mode 100644 index 23c7b54..0000000 --- a/ubi-utils/old-utils/src/example_ubi.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __EXAMPLE_UBI_H__ -#define __EXAMPLE_UBI_H__ -/* - * 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. - */ - -/** - * Defaults for our cards. - */ -#define EXAMPLE_UBI_DEVICE 0 -#define EXAMPLE_BOOTENV_VOL_ID_1 4 -#define EXAMPLE_BOOTENV_VOL_ID_2 5 - -#endif /* __EXAMPLE_UBI_H__ */ diff --git a/ubi-utils/old-utils/src/hashmap.c b/ubi-utils/old-utils/src/hashmap.c deleted file mode 100644 index 3511d56..0000000 --- a/ubi-utils/old-utils/src/hashmap.c +++ /dev/null @@ -1,412 +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. - * - * Author: Oliver Lohmann - */ - -#include -#include -#include -#include -#include "error.h" -#include "hashmap.h" -#define DEFAULT_BUCKETS 4096 - -#if 0 -#define INFO_MSG(fmt...) do { \ - info_msg(fmt); \ -} while (0) -#else -#define INFO_MSG(fmt...) -#endif - -struct hashentry { - char* key; /* key '0' term. str */ - char* value; /* payload '0' term. str */ - - hashentry_t next; -}; - -struct hashmap { - size_t entries; /* current #entries */ - size_t maxsize; /* no. of hash buckets */ - hashentry_t* data; /* array of buckets */ -}; - -static int -is_empty(hashentry_t l) -{ - return l == NULL ? 1 : 0; -} - -hashmap_t -hashmap_new(void) -{ - hashmap_t res; - res = (hashmap_t) calloc(1, sizeof(struct hashmap)); - - if (res == NULL) - return NULL; - - res->maxsize = DEFAULT_BUCKETS; - res->entries = 0; - - res->data = (hashentry_t*) - calloc(1, res->maxsize * sizeof(struct hashentry)); - - if (res->data == NULL) - return NULL; - - return res; -} - -static hashentry_t -new_entry(const char* key, const char* value) -{ - hashentry_t res; - - res = (hashentry_t) calloc(1, sizeof(struct hashentry)); - - if (res == NULL) - return NULL; - - /* allocate key and value and copy them */ - res->key = strdup(key); - if (res->key == NULL) { - free(res); - return NULL; - } - - res->value = strdup(value); - if (res->value == NULL) { - free(res->key); - free(res); - return NULL; - } - - res->next = NULL; - - return res; -} - -static hashentry_t -free_entry(hashentry_t e) -{ - if (!is_empty(e)) { - if(e->key != NULL) { - free(e->key); - } - if(e->value != NULL) - free(e->value); - free(e); - } - - return NULL; -} - -static hashentry_t -remove_entry(hashentry_t l, const char* key, size_t* entries) -{ - hashentry_t lnext; - if (is_empty(l)) - return NULL; - - if(strcmp(l->key,key) == 0) { - lnext = l->next; - l = free_entry(l); - (*entries)--; - return lnext; - } - - l->next = remove_entry(l->next, key, entries); - - return l; -} - -static hashentry_t -insert_entry(hashentry_t l, hashentry_t e, size_t* entries) -{ - if (is_empty(l)) { - (*entries)++; - return e; - } - - /* check for update */ - if (strcmp(l->key, e->key) == 0) { - e->next = l->next; - l = free_entry(l); - return e; - } - - l->next = insert_entry(l->next, e, entries); - return l; -} - -static hashentry_t -remove_all(hashentry_t l, size_t* entries) -{ - hashentry_t lnext; - if (is_empty(l)) - return NULL; - - lnext = l->next; - free_entry(l); - (*entries)--; - - return remove_all(lnext, entries); -} - -static const char* -value_lookup(hashentry_t l, const char* key) -{ - if (is_empty(l)) - return NULL; - - if (strcmp(l->key, key) == 0) - return l->value; - - return value_lookup(l->next, key); -} - -static void -print_all(hashentry_t l) -{ - if (is_empty(l)) { - printf("\n"); - return; - } - - printf("%s=%s", l->key, l->value); - if (!is_empty(l->next)) { - printf(","); - } - - print_all(l->next); -} - -static void -keys_to_array(hashentry_t l, const char** a, size_t* i) -{ - if (is_empty(l)) - return; - - a[*i] = l->key; - (*i)++; - - keys_to_array(l->next, a, i); -} - -uint32_t -hash_str(const char* str, uint32_t mapsize) -{ - uint32_t hash = 0; - uint32_t x = 0; - uint32_t i = 0; - size_t len = strlen(str); - - for(i = 0; i < len; str++, i++) { - hash = (hash << 4) + (*str); - if((x = hash & 0xF0000000L) != 0) { - hash ^= (x >> 24); - hash &= ~x; - } - } - - return (hash & 0x7FFFFFFF) % mapsize; -} - - -int -hashmap_is_empty(hashmap_t map) -{ - if (map == NULL) - return -EINVAL; - - return map->entries > 0 ? 1 : 0; -} - -const char* -hashmap_lookup(hashmap_t map, const char* key) -{ - uint32_t i; - - if ((map == NULL) || (key == NULL)) - return NULL; - - i = hash_str(key, map->maxsize); - - return value_lookup(map->data[i], key); -} - -int -hashmap_add(hashmap_t map, const char* key, const char* value) -{ - uint32_t i; - hashentry_t entry; - - if ((map == NULL) || (key == NULL) || (value == NULL)) - return -EINVAL; - - i = hash_str(key, map->maxsize); - entry = new_entry(key, value); - if (entry == NULL) - return -ENOMEM; - - map->data[i] = insert_entry(map->data[i], - entry, &map->entries); - - INFO_MSG("HASH_ADD: chain[%d] key:%s val:%s",i, key, value); - return 0; -} - -int -hashmap_remove(hashmap_t map, const char* key) -{ - uint32_t i; - - if ((map == NULL) || (key == NULL)) - return -EINVAL; - - i = hash_str(key, map->maxsize); - map->data[i] = remove_entry(map->data[i], key, &map->entries); - - return 0; -} - -size_t -hashmap_size(hashmap_t map) -{ - if (map != NULL) - return map->entries; - else - return 0; -} - -int -hashmap_free(hashmap_t map) -{ - size_t i; - - if (map == NULL) - return -EINVAL; - - /* "children" first */ - for(i = 0; i < map->maxsize; i++) { - map->data[i] = remove_all(map->data[i], &map->entries); - } - free(map->data); - free(map); - - return 0; -} - -int -hashmap_dump(hashmap_t map) -{ - size_t i; - if (map == NULL) - return -EINVAL; - - for(i = 0; i < map->maxsize; i++) { - if (map->data[i] != NULL) { - printf("[%zd]: ", i); - print_all(map->data[i]); - } - } - - return 0; -} - -static const char** -sort_key_vector(const char** a, size_t size) -{ - /* uses bubblesort */ - size_t i, j; - const char* tmp; - - if (size <= 0) - return a; - - for (i = size - 1; i > 0; i--) { - for (j = 0; j < i; j++) { - if (strcmp(a[j], a[j+1]) > 0) { - tmp = a[j]; - a[j] = a[j+1]; - a[j+1] = tmp; - } - } - } - return a; -} - -const char** -hashmap_get_key_vector(hashmap_t map, size_t* size, int sort) -{ - const char** res; - size_t i, j; - *size = map->entries; - - res = (const char**) malloc(*size * sizeof(char*)); - if (res == NULL) - return NULL; - - j = 0; - for(i=0; i < map->maxsize; i++) { - keys_to_array(map->data[i], res, &j); - } - - if (sort) - res = sort_key_vector(res, *size); - - return res; -} - -int -hashmap_key_is_in_vector(const char** vec, size_t size, const char* key) -{ - size_t i; - for (i = 0; i < size; i++) { - if (strcmp(vec[i], key) == 0) /* found */ - return 1; - } - - return 0; -} - -const char** -hashmap_get_update_key_vector(const char** vec1, size_t vec1_size, - const char** vec2, size_t vec2_size, size_t* res_size) -{ - const char** res; - size_t i, j; - - *res_size = vec2_size; - - res = (const char**) malloc(*res_size * sizeof(char*)); - if (res == NULL) - return NULL; - - /* get all keys from vec2 which are not set in vec1 */ - j = 0; - for (i = 0; i < vec2_size; i++) { - if (!hashmap_key_is_in_vector(vec1, vec1_size, vec2[i])) - res[j++] = vec2[i]; - } - - *res_size = j; - return res; -} diff --git a/ubi-utils/old-utils/src/hashmap.h b/ubi-utils/old-utils/src/hashmap.h deleted file mode 100644 index 1b13e95..0000000 --- a/ubi-utils/old-utils/src/hashmap.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __HASHMAP_H__ -#define __HASHMAP_H__ -/* - * 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. - * - * Author: Oliver Lohmann - */ - -#include -#include - -typedef struct hashentry *hashentry_t; -typedef struct hashmap *hashmap_t; - -hashmap_t hashmap_new(void); -int hashmap_free(hashmap_t map); - -int hashmap_add(hashmap_t map, const char* key, const char* value); -int hashmap_update(hashmap_t map, const char* key, const char* value); -int hashmap_remove(hashmap_t map, const char* key); -const char* hashmap_lookup(hashmap_t map, const char* key); - -const char** hashmap_get_key_vector(hashmap_t map, size_t* size, int sort); -int hashmap_key_is_in_vector(const char** vec, size_t size, const char* key); -const char** hashmap_get_update_key_vector(const char** vec1, size_t vec1_size, - const char** vec2, size_t vec2_size, size_t* res_size); - -int hashmap_dump(hashmap_t map); - -int hashmap_is_empty(hashmap_t map); -size_t hashmap_size(hashmap_t map); - -uint32_t hash_str(const char* str, uint32_t mapsize); - -#endif /* __HASHMAP_H__ */ diff --git a/ubi-utils/old-utils/src/libpfiflash.c b/ubi-utils/old-utils/src/libpfiflash.c deleted file mode 100644 index b0d454a..0000000 --- a/ubi-utils/old-utils/src/libpfiflash.c +++ /dev/null @@ -1,1325 +0,0 @@ -/* - * Copyright International Business Machines Corp., 2006, 2007 - * - * 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. - */ - -/* - * Authors: Oliver Lohmann - * Drake Dowsett - * Contact: Andreas Arnez - */ - -/* TODO Compare data before writing it. This implies that the volume - * parameters are compared first: size, alignment, name, type, ..., - * this is the same, compare the data. Volume deletion is deffered - * until the difference has been found out. - */ - -#include -#include -#include -#include -#define __USE_GNU -#include -#include -#include -#include - -#include -#include - -#include /* FIXME Is this ok here? */ -#include - -#include "pfiflash_error.h" -#include "ubimirror.h" -#include "error.h" -#include "reader.h" -#include "example_ubi.h" -#include "bootenv.h" - -/* ubi-header.h and crc32.h needed for CRC checking */ -#include /* FIXME Is this ok here? */ -#include "crc32.h" - -#define ubi_unused __attribute__((unused)) - -#define COMPARE_BUFFER_SIZE 2048 - -#define DEFAULT_DEV_PATTERN "/dev/ubi%d" -#define DEFAULT_VOL_PATTERN "/dev/ubi%d_%d" - -static const char copyright [] ubi_unused = - "Copyright International Business Machines Corp., 2006, 2007"; - -/* simply clear buffer, then write into front of it */ -#define EBUF(fmt...) \ - snprintf(err_buf, err_buf_size, fmt); - -/* make a history of buffer and then prepend something in front */ -#define EBUF_PREPEND(fmt) \ - do { \ - int EBUF_HISTORY_LENGTH = strlen(err_buf); \ - char EBUF_HISTORY[EBUF_HISTORY_LENGTH + 1]; \ - strncpy(EBUF_HISTORY, err_buf, EBUF_HISTORY_LENGTH + 1);\ - EBUF(fmt ": %s", EBUF_HISTORY); \ - } while (0) - -/* An array of PDD function pointers indexed by the algorithm. */ -static pdd_func_t pdd_funcs[PDD_HANDLING_NUM] = - { - &bootenv_pdd_keep, - &bootenv_pdd_merge, - &bootenv_pdd_overwrite - }; - -typedef enum ubi_update_process_t { - UBI_REMOVE = 0, - UBI_WRITE, - UBI_COMPARE, -} ubi_update_process_t; - - -/** - * skip_raw_volumes - reads data from pfi to advance fp past raw block - * @pfi: fp to pfi data - * @pfi_raws: header information - * - * Error handling): - * when early EOF in pfi data - * - returns -PFIFLASH_ERR_EOF, err_buf matches text to err - * when file I/O error - * - returns -PFIFLASH_ERR_FIO, err_buf matches text to err - **/ -static int -skip_raw_volumes(FILE* pfi, list_t pfi_raws, - char* err_buf, size_t err_buf_size) -{ - int rc; - void *i; - list_t ptr; - - if (is_empty(pfi_raws)) - return 0; - - rc = 0; - foreach(i, ptr, pfi_raws) { - size_t j; - pfi_raw_t raw; - - raw = (pfi_raw_t)i; - for(j = 0; j < raw->data_size; j++) { - int c; - - c = fgetc(pfi); - if (c == EOF) - rc = -PFIFLASH_ERR_EOF; - else if (ferror(pfi)) - rc = -PFIFLASH_ERR_FIO; - - if (rc != 0) - goto err; - } - } - - err: - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - return rc; -} - - -/** - * my_ubi_mkvol - wraps the ubi_mkvol functions and impl. bootenv update hook - * @devno: UBI device number. - * @s: Current seqnum. - * @u: Information about the UBI volume from the PFI. - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - * when UBI system couldn't create a volume - * - returns -PFIFLASH_ERR_UBI_MKVOL, err_buf matches text to err - **/ -static int -my_ubi_mkvol(int devno, int s, pfi_ubi_t u, - char *err_buf, size_t err_buf_size) -{ - int rc, type; - char path[PATH_MAX]; - libubi_t ulib; - struct ubi_mkvol_request req; - - rc = 0; - ulib = NULL; - - log_msg("[ ubimkvol id=%d, size=%d, data_size=%d, type=%d, " - "alig=%d, nlen=%d, name=%s", - u->ids[s], u->size, u->data_size, u->type, u->alignment, - strnlen(u->names[s], PFI_UBI_VOL_NAME_LEN), u->names[s]); - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - switch (u->type) { - case pfi_ubi_static: - type = UBI_STATIC_VOLUME; break; - case pfi_ubi_dynamic: - default: - type = UBI_DYNAMIC_VOLUME; - } - - snprintf(path, PATH_MAX, DEFAULT_DEV_PATTERN, devno); - - req.vol_id = u->ids[s]; - req.alignment = u->alignment; - req.bytes = u->size; - req.vol_type = type; - req.name = u->names[s]; - - rc = ubi_mkvol(ulib, path, &req); - if (rc != 0) { - rc = -PFIFLASH_ERR_UBI_MKVOL; - EBUF(PFIFLASH_ERRSTR[-rc], u->ids[s]); - goto err; - } - - err: - if (ulib != NULL) - libubi_close(ulib); - - return rc; -} - - -/** - * my_ubi_rmvol - a wrapper around the UBI library function ubi_rmvol - * @devno UBI device number - * @id UBI volume id to remove - * - * If the volume does not exist, the function will return success. - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - * when UBI system couldn't update (truncate) a volume - * - returns -PFIFLASH_ERR_UBI_VOL_UPDATE, err_buf matches text to err - * when UBI system couldn't remove a volume - * - returns -PFIFLASH_ERR_UBI_RMVOL, err_buf matches text to err - **/ -static int -my_ubi_rmvol(int devno, uint32_t id, - char *err_buf, size_t err_buf_size) -{ - int rc, fd; - char path[PATH_MAX]; - libubi_t ulib; - - rc = 0; - ulib = NULL; - - log_msg("[ ubirmvol id=%d", id); - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - /* truncate whether it exist or not */ - fd = open(path, O_RDWR); - if (fd < 0) { - libubi_close(ulib); - return 0; /* not existent, return 0 */ - } - - rc = ubi_update_start(ulib, fd, 0); - close(fd); - if (rc < 0) { - rc = -PFIFLASH_ERR_UBI_VOL_UPDATE; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; /* if EBUSY than empty device, continue */ - } - - snprintf(path, PATH_MAX, DEFAULT_DEV_PATTERN, devno); - - rc = ubi_rmvol(ulib, path, id); - if (rc != 0) { -#ifdef DEBUG - int rc_old = rc; - dbg_msg("Remove UBI volume %d returned with error: %d " - "errno=%d", id, rc_old, errno); -#endif - - rc = -PFIFLASH_ERR_UBI_RMVOL; - EBUF(PFIFLASH_ERRSTR[-rc], id); - - /* TODO Define a ubi_rmvol return value which says - * sth like EUBI_NOSUCHDEV. In this case, a failed - * operation is acceptable. Everything else has to be - * classified as real error. But talk to Andreas Arnez - * before defining something odd... - */ - /* if ((errno == EINVAL) || (errno == ENODEV)) - return 0; */ /* currently it is EINVAL or ENODEV */ - - goto err; - } - - err: - if (ulib != NULL) - libubi_close(ulib); - - return rc; -} - - -/** - * read_bootenv_volume - reads the current bootenv data from id into be_old - * @devno UBI device number - * @id UBI volume id to remove - * @bootenv_old to hold old boot_env data - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - * when UBI system couldn't open a volume to read - * - returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err - * when couldn't read bootenv data - * - returns -PFIFLASH_ERR_BOOTENV_READ, err_buf matches text to err - **/ -static int -read_bootenv_volume(int devno, uint32_t id, bootenv_t bootenv_old, - char *err_buf, size_t err_buf_size) -{ - int rc; - FILE* fp_in; - char path[PATH_MAX]; - libubi_t ulib; - - rc = 0; - fp_in = NULL; - ulib = NULL; - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - fp_in = fopen(path, "r"); - if (!fp_in) { - rc = -PFIFLASH_ERR_UBI_VOL_FOPEN; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - - log_msg("[ reading old bootenvs ..."); - - /* Save old bootenvs for reference */ - rc = bootenv_read(fp_in, bootenv_old, BOOTENV_MAXSIZE); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_READ; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - err: - if (fp_in) - fclose(fp_in); - if (ulib) - libubi_close(ulib); - - return rc; -} - - -/** - * write_bootenv_volume - writes data from PFI file int to bootenv UBI volume - * @devno UBI device number - * @id UBI volume id - * @bootend_old old PDD data from machine - * @pdd_f function to handle PDD with - * @fp_in new pdd data contained in PFI - * @fp_in_size data size of new pdd data in PFI - * @pfi_crc crc value from PFI header - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - * when bootenv can't be created - * - returns -PFIFLASH_ERR_BOOTENV_CREATE, err_buf matches text to err - * when bootenv can't be read - * - returns -PFIFLASH_ERR_BOOTENV_READ, err_buf matches text to err - * when PDD handling function returns and error - * - passes rc and err_buf data - * when CRC check fails - * - returns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err - * when bootenv can't be resized - * - returns -PFIFLASH_ERR_BOOTENV_SIZE, err_buf matches text to err - * when UBI system couldn't open a volume - * - returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err - * when couldn't write bootenv data - * - returns -PFIFLASH_ERR_BOOTENV_WRITE, err_buf matches text to err - **/ -static int -write_bootenv_volume(int devno, uint32_t id, bootenv_t bootenv_old, - pdd_func_t pdd_f, FILE* fp_in, size_t fp_in_size, - uint32_t pfi_crc, - char *err_buf, size_t err_buf_size) -{ - int rc, warnings, fd_out; - uint32_t crc; - char path[PATH_MAX]; - size_t update_size; - FILE *fp_out; - bootenv_t bootenv_new, bootenv_res; - libubi_t ulib; - - rc = 0; - warnings = 0; - crc = 0; - update_size = 0; - fp_out = NULL; - bootenv_new = NULL; - bootenv_res = NULL; - ulib = NULL; - - log_msg("[ ubiupdatevol bootenv id=%d, fp_in=%p", id, fp_in); - - /* Workflow: - * 1. Apply PDD operation and get the size of the returning - * bootenv_res section. Without the correct size it wouldn't - * be possible to call UBI update vol. - * 2. Call UBI update vol - * 3. Get FILE* to vol dev - * 4. Write to FILE* - */ - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - rc = bootenv_create(&bootenv_new); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - EBUF(PFIFLASH_ERRSTR[-rc], " 'new'"); - goto err; - } - - rc = bootenv_create(&bootenv_res); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - EBUF(PFIFLASH_ERRSTR[-rc], " 'res'"); - goto err; - } - - rc = bootenv_read_crc(fp_in, bootenv_new, fp_in_size, &crc); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_READ; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } else if (crc != pfi_crc) { - rc = -PFIFLASH_ERR_CRC_CHECK; - EBUF(PFIFLASH_ERRSTR[-rc], pfi_crc, crc); - goto err; - } - - rc = pdd_f(bootenv_old, bootenv_new, &bootenv_res, &warnings, - err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("handling PDD"); - goto err; - } - else if (warnings) - /* TODO do something with warnings */ - dbg_msg("A warning in the PDD operation occured: %d", - warnings); - - rc = bootenv_size(bootenv_res, &update_size); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_SIZE; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - fd_out = open(path, O_RDWR); - if (fd_out < 0) { - rc = -PFIFLASH_ERR_UBI_VOL_FOPEN; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - fp_out = fdopen(fd_out, "r+"); - if (!fp_out) { - rc = -PFIFLASH_ERR_UBI_VOL_FOPEN; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - rc = ubi_update_start(ulib, fd_out, update_size); - if (rc < 0) { - rc = -PFIFLASH_ERR_UBI_VOL_UPDATE; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - - rc = bootenv_write(fp_out, bootenv_res); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_WRITE; - EBUF(PFIFLASH_ERRSTR[-rc], devno, id); - goto err; - } - - err: - if (ulib != NULL) - libubi_close(ulib); - if (bootenv_new != NULL) - bootenv_destroy(&bootenv_new); - if (bootenv_res != NULL) - bootenv_destroy(&bootenv_res); - if (fp_out) - fclose(fp_out); - - return rc; -} - - -/** - * write_normal_volume - writes data from PFI file int to regular UBI volume - * @devno UBI device number - * @id UBI volume id - * @update_size size of data stream - * @fp_in PFI data file pointer - * @pfi_crc CRC data from PFI header - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - * when UBI system couldn't open a volume - * - returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err - * when unexpected EOF is encountered - * - returns -PFIFLASH_ERR_EOF, err_buf matches text to err - * when file I/O error - * - returns -PFIFLASH_ERR_FIO, err_buf matches text to err - * when CRC check fails - * - retruns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err - **/ -static int -write_normal_volume(int devno, uint32_t id, size_t update_size, FILE* fp_in, - uint32_t pfi_crc, - char *err_buf, size_t err_buf_size) -{ - int rc, fd_out; - uint32_t crc, crc32_table[256]; - char path[PATH_MAX]; - size_t bytes_left; - FILE* fp_out; - libubi_t ulib; - - rc = 0; - crc = UBI_CRC32_INIT; - bytes_left = update_size; - fp_out = NULL; - ulib = NULL; - - log_msg("[ ubiupdatevol id=%d, update_size=%d fp_in=%p", - id, update_size, fp_in); - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - fd_out = open(path, O_RDWR); - if (fd_out < 0) { - rc = -PFIFLASH_ERR_UBI_VOL_FOPEN; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - fp_out = fdopen(fd_out, "r+"); - if (!fp_out) { - rc = -PFIFLASH_ERR_UBI_VOL_FOPEN; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - rc = ubi_update_start(ulib, fd_out, update_size); - if (rc < 0) { - rc = -PFIFLASH_ERR_UBI_VOL_UPDATE; - EBUF(PFIFLASH_ERRSTR[-rc], id); - goto err; - } - - init_crc32_table(crc32_table); - while (bytes_left) { - char buf[1024]; - size_t to_rw = sizeof buf > bytes_left ? - bytes_left : sizeof buf; - if (fread(buf, 1, to_rw, fp_in) != to_rw) { - rc = -PFIFLASH_ERR_EOF; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - crc = clc_crc32(crc32_table, crc, buf, to_rw); - if (fwrite(buf, 1, to_rw, fp_out) != to_rw) { - rc = -PFIFLASH_ERR_FIO; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - bytes_left -= to_rw; - } - - if (crc != pfi_crc) { - rc = -PFIFLASH_ERR_CRC_CHECK; - EBUF(PFIFLASH_ERRSTR[-rc], pfi_crc, crc); - goto err; - } - - err: - if (fp_out) - fclose(fp_out); - if (ulib) - libubi_close(ulib); - - return rc; -} - -static int compare_bootenv(FILE *fp_pfi, FILE **fp_flash, uint32_t ids_size, - uint32_t data_size, pdd_func_t pdd_f, char *err_buf, - size_t err_buf_size) -{ - int rc, warnings = 0; - unsigned int i; - bootenv_t bootenv_pfi, bootenv_res = NULL, bootenv_flash = NULL; - - rc = bootenv_create(&bootenv_pfi); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - goto err; - } - - rc = bootenv_create(&bootenv_res); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - goto err; - } - - rc = bootenv_read(fp_pfi, bootenv_pfi, data_size); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_READ; - goto err; - } - - for (i = 0; i < ids_size; i++) { - rc = bootenv_create(&bootenv_flash); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - goto err; - } - - rc = bootenv_read(fp_flash[i], bootenv_flash, BOOTENV_MAXSIZE); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_READ; - goto err; - } - - rc = pdd_f(bootenv_flash, bootenv_pfi, &bootenv_res, - &warnings, err_buf, err_buf_size); - if (rc != 0) { - rc = -PFIFLASH_ERR_PDD_UNKNOWN; - goto err; - } - - rc = bootenv_compare(bootenv_flash, bootenv_res); - if (rc > 0) { - rc = -PFIFLASH_CMP_DIFF; - goto err; - } else if (rc < 0) { - rc = -PFIFLASH_ERR_COMPARE; - goto err; - } - - bootenv_destroy(&bootenv_flash); - bootenv_flash = NULL; - } - -err: - if (bootenv_pfi) - bootenv_destroy(&bootenv_pfi); - if (bootenv_res) - bootenv_destroy(&bootenv_res); - if (bootenv_flash) - bootenv_destroy(&bootenv_flash); - - return rc; -} - -static int compare_data(FILE *fp_pfi, FILE **fp_flash, uint32_t ids_size, - uint32_t bytes_left) -{ - unsigned int i; - size_t read_bytes, rc = 0; - char buf_pfi[COMPARE_BUFFER_SIZE]; - char *buf_flash[ids_size]; - - for (i = 0; i < ids_size; i++) { - buf_flash[i] = malloc(COMPARE_BUFFER_SIZE); - if (!buf_flash[i]) - return -PFIFLASH_ERR_COMPARE; - } - - while (bytes_left) { - if (bytes_left > COMPARE_BUFFER_SIZE) - read_bytes = COMPARE_BUFFER_SIZE; - else - read_bytes = bytes_left; - - rc = fread(buf_pfi, 1, read_bytes, fp_pfi); - if (rc != read_bytes) { - rc = -PFIFLASH_ERR_COMPARE; - goto err; - } - - for (i = 0; i < ids_size; i++) { - rc = fread(buf_flash[i], 1, read_bytes, fp_flash[i]); - if (rc != read_bytes) { - rc = -PFIFLASH_CMP_DIFF; - goto err; - } - - rc = memcmp(buf_pfi, buf_flash[i], read_bytes); - if (rc != 0) { - rc = -PFIFLASH_CMP_DIFF; - goto err; - } - } - - bytes_left -= read_bytes; - } - -err: - for (i = 0; i < ids_size; i++) - free(buf_flash[i]); - - return rc; -} - -static int compare_volumes(int devno, pfi_ubi_t u, FILE *fp_pfi, - pdd_func_t pdd_f, char *err_buf, size_t err_buf_size) -{ - int rc, is_bootenv = 0; - unsigned int i; - char path[PATH_MAX]; - libubi_t ulib = NULL; - FILE *fp_flash[u->ids_size]; - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - goto err; - } - - for (i = 0; i < u->ids_size; i++) { - if (u->ids[i] == EXAMPLE_BOOTENV_VOL_ID_1 || - u->ids[i] == EXAMPLE_BOOTENV_VOL_ID_2) - is_bootenv = 1; - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, u->ids[i]); - - fp_flash[i] = fopen(path, "r"); - if (fp_flash[i] == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - goto err; - } - } - - if (is_bootenv) - rc = compare_bootenv(fp_pfi, fp_flash, u->ids_size, - u->data_size, pdd_f, err_buf, err_buf_size); - else - rc = compare_data(fp_pfi, fp_flash, u->ids_size, u->data_size); - -err: - if (rc < 0) - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - - for (i = 0; i < u->ids_size; i++) - fclose(fp_flash[i]); - if (ulib) - libubi_close(ulib); - - return rc; -} - -static int -erase_mtd_region(FILE* file_p, int start, int length) -{ - int rc, fd; - erase_info_t erase; - mtd_info_t mtdinfo; - loff_t offset = start; - loff_t end = offset + length; - - fd = fileno(file_p); - if (fd < 0) - return -PFIFLASH_ERR_MTD_ERASE; - - rc = ioctl(fd, MEMGETINFO, &mtdinfo); - if (rc) - return -PFIFLASH_ERR_MTD_ERASE; - - /* check for bad blocks in case of NAND flash */ - if (mtdinfo.type == MTD_NANDFLASH) { - while (offset < end) { - rc = ioctl(fd, MEMGETBADBLOCK, &offset); - if (rc > 0) { - return -PFIFLASH_ERR_MTD_ERASE; - } - - offset += mtdinfo.erasesize; - } - } - - erase.start = start; - erase.length = length; - - rc = ioctl(fd, MEMERASE, &erase); - if (rc) { - return -PFIFLASH_ERR_MTD_ERASE; - } - - return rc; -} - -/** - * process_raw_volumes - writes the raw sections of the PFI data - * @pfi PFI data file pointer - * @pfi_raws list of PFI raw headers - * @rawdev device to use to write raw data - * - * Error handling: - * when early EOF in PFI data - * - returns -PFIFLASH_ERR_EOF, err_buf matches text to err - * when file I/O error - * - returns -PFIFLASH_ERR_FIO, err_buf matches text to err - * when CRC check fails - * - returns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err - * when opening MTD device fails - * - reutrns -PFIFLASH_ERR_MTD_OPEN, err_buf matches text to err - * when closing MTD device fails - * - returns -PFIFLASH_ERR_MTD_CLOSE, err_buf matches text to err - **/ -static int -process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev, - char* err_buf, size_t err_buf_size) -{ - int rc; - char *pfi_data; - void *i; - uint32_t crc, crc32_table[256]; - size_t j, k; - FILE* mtd = NULL; - list_t ptr; - - if (is_empty(pfi_raws)) - return 0; - - if (rawdev == NULL) - return 0; - - rc = 0; - - pfi_data = NULL; - - log_msg("[ rawupdate dev=%s", rawdev); - - crc = UBI_CRC32_INIT; - init_crc32_table(crc32_table); - - /* most likely only one element in list, but just in case */ - foreach(i, ptr, pfi_raws) { - pfi_raw_t r = (pfi_raw_t)i; - - /* read in pfi data */ - if (pfi_data != NULL) - free(pfi_data); - pfi_data = malloc(r->data_size * sizeof(char)); - for (j = 0; j < r->data_size; j++) { - int c = fgetc(pfi); - if (c == EOF) { - rc = -PFIFLASH_ERR_EOF; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } else if (ferror(pfi)) { - rc = -PFIFLASH_ERR_FIO; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - pfi_data[j] = (char)c; - } - crc = clc_crc32(crc32_table, crc, pfi_data, r->data_size); - - /* check crc */ - if (crc != r->crc) { - rc = -PFIFLASH_ERR_CRC_CHECK; - EBUF(PFIFLASH_ERRSTR[-rc], r->crc, crc); - goto err; - } - - /* open device */ - mtd = fopen(rawdev, "r+"); - if (mtd == NULL) { - rc = -PFIFLASH_ERR_MTD_OPEN; - EBUF(PFIFLASH_ERRSTR[-rc], rawdev); - goto err; - } - - for (j = 0; j < r->starts_size; j++) { - rc = erase_mtd_region(mtd, r->starts[j], r->data_size); - if (rc) { - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - fseek(mtd, r->starts[j], SEEK_SET); - for (k = 0; k < r->data_size; k++) { - int c = fputc((int)pfi_data[k], mtd); - if (c == EOF) { - fclose(mtd); - rc = -PFIFLASH_ERR_EOF; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - if ((char)c != pfi_data[k]) { - fclose(mtd); - rc = -1; - goto err; - } - } - } - rc = fclose(mtd); - mtd = NULL; - if (rc != 0) { - rc = -PFIFLASH_ERR_MTD_CLOSE; - EBUF(PFIFLASH_ERRSTR[-rc], rawdev); - goto err; - } - } - - err: - if (mtd != NULL) - fclose(mtd); - if (pfi_data != NULL) - free(pfi_data); - return rc; -} - - -/** - * erase_unmapped_ubi_volumes - skip volumes provided by PFI file, clear rest - * @devno UBI device number - * @pfi_ubis list of UBI header data - * - * Error handling: - * when UBI id is out of bounds - * - returns -PFIFLASH_ERR_UBI_VID_OOB, err_buf matches text to err - * when UBI volume can't be removed - * - passes rc, prepends err_buf with contextual aid - **/ -static int -erase_unmapped_ubi_volumes(int devno, list_t pfi_ubis, - char *err_buf, size_t err_buf_size) -{ - int rc; - uint8_t ubi_volumes[PFI_UBI_MAX_VOLUMES]; - size_t i; - list_t ptr; - pfi_ubi_t u; - - rc = 0; - - for (i = 0; i < PFI_UBI_MAX_VOLUMES; i++) - ubi_volumes[i] = 1; - - foreach(u, ptr, pfi_ubis) { - /* iterate over each vol_id */ - for(i = 0; i < u->ids_size; i++) { - if (u->ids[i] >= PFI_UBI_MAX_VOLUMES) { - rc = -PFIFLASH_ERR_UBI_VID_OOB; - EBUF(PFIFLASH_ERRSTR[-rc], u->ids[i]); - goto err; - } - /* remove from removal list */ - ubi_volumes[u->ids[i]] = 0; - } - } - - for (i = 0; i < PFI_UBI_MAX_VOLUMES; i++) { - if (ubi_volumes[i]) { - rc = my_ubi_rmvol(devno, i, err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("remove volume failed"); - goto err; - } - } - } - - err: - return rc; -} - - -/** - * process_ubi_volumes - delegate tasks regarding UBI volumes - * @pfi PFI data file pointer - * @seqnum sequence number - * @pfi_ubis list of UBI header data - * @bootenv_old storage for current system PDD - * @pdd_f function to handle PDD - * @ubi_update_process whether reading or writing - * - * Error handling: - * when and unknown ubi_update_process is given - * - returns -PFIFLASH_ERR_UBI_UNKNOWN, err_buf matches text to err - * otherwise - * - passes rc and err_buf - **/ -static int -process_ubi_volumes(FILE* pfi, int seqnum, list_t pfi_ubis, - bootenv_t bootenv_old, pdd_func_t pdd_f, - ubi_update_process_t ubi_update_process, - char *err_buf, size_t err_buf_size) -{ - int rc; - pfi_ubi_t u; - list_t ptr; - - rc = 0; - - foreach(u, ptr, pfi_ubis) { - int s = seqnum; - - if (s > ((int)u->ids_size - 1)) - s = 0; /* per default use the first */ - u->curr_seqnum = s; - - switch (ubi_update_process) { - case UBI_REMOVE: - /* TODO are all these "EXAMPLE" vars okay? */ - if ((u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_1) || - (u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_2)) { - rc = read_bootenv_volume(EXAMPLE_UBI_DEVICE, - u->ids[s], bootenv_old, - err_buf, err_buf_size); - /* it's okay if there is no bootenv - * we're going to write one */ - if ((rc == -PFIFLASH_ERR_UBI_VOL_FOPEN) || - (rc == -PFIFLASH_ERR_BOOTENV_READ)) - rc = 0; - if (rc != 0) - goto err; - } - - rc = my_ubi_rmvol(EXAMPLE_UBI_DEVICE, u->ids[s], - err_buf, err_buf_size); - if (rc != 0) - goto err; - - break; - case UBI_WRITE: - rc = my_ubi_mkvol(EXAMPLE_UBI_DEVICE, s, u, - err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("creating volume"); - goto err; - } - - if ((u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_1) || - (u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_2)) { - rc = write_bootenv_volume(EXAMPLE_UBI_DEVICE, - u->ids[s], - bootenv_old, pdd_f, - pfi, - u->data_size, - u->crc, - err_buf, - err_buf_size); - if (rc != 0) - EBUF_PREPEND("bootenv volume"); - } else { - rc = write_normal_volume(EXAMPLE_UBI_DEVICE, - u->ids[s], - u->data_size, pfi, - u->crc, - err_buf, - err_buf_size); - if (rc != 0) - EBUF_PREPEND("normal volume"); - } - if (rc != 0) - goto err; - - break; - case UBI_COMPARE: - rc = compare_volumes(EXAMPLE_UBI_DEVICE, u, pfi, pdd_f, - err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("compare volume"); - goto err; - } - - break; - default: - rc = -PFIFLASH_ERR_UBI_UNKNOWN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - } - - err: - return rc; -} - - -/** - * mirror_ubi_volumes - mirror redundant pairs of volumes - * @devno UBI device number - * @pfi_ubis list of PFI header data - * - * Error handling: - * when UBI system couldn't be opened - * - returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err - **/ -static int -mirror_ubi_volumes(uint32_t devno, list_t pfi_ubis, - char *err_buf, size_t err_buf_size) -{ - int rc; - uint32_t j; - list_t ptr; - pfi_ubi_t i; - libubi_t ulib; - - rc = 0; - ulib = NULL; - - log_msg("[ mirror ..."); - - ulib = libubi_open(); - if (ulib == NULL) { - rc = -PFIFLASH_ERR_UBI_OPEN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - /** - * Execute all mirror operations on redundant groups. - * Create a volume within a redundant group if it does - * not exist already (this is a precondition of - * ubimirror). - */ - foreach(i, ptr, pfi_ubis) { - for (j = 0; j < i->ids_size; j++) { - /* skip self-match */ - if (i->ids[j] == i->ids[i->curr_seqnum]) - continue; - - rc = my_ubi_rmvol(devno, i->ids[j], - err_buf, err_buf_size); - if (rc != 0) - goto err; - - rc = my_ubi_mkvol(devno, j, i, - err_buf, err_buf_size); - if (rc != 0) - goto err; - } - } - - foreach(i, ptr, pfi_ubis) { - rc = ubimirror(devno, i->curr_seqnum, i->ids, i->ids_size, - err_buf, err_buf_size); - if (rc != 0) - goto err; - } - - - err: - if (ulib != NULL) - libubi_close(ulib); - - return rc; -} - - -/** - * pfiflash_with_options - exposed func to flash memory with a PFI file - * @pfi PFI data file pointer - * @complete flag to erase unmapped volumes - * @seqnum sequence number - * @compare flag to compare - * @pdd_handling method to handle pdd (keep, merge, overwrite...) - * - * Error handling: - * when bootenv can't be created - * - returns -PFIFLASH_ERR_BOOTENV_CREATE, err_buf matches text to err - * when PFI headers can't be read, or - * when fail to skip raw sections, or - * when error occurs while processing raw volumes, or - * when fail to erase unmapped UBI vols, or - * when error occurs while processing UBI volumes, or - * when error occurs while mirroring UBI volumes - * - passes rc, prepends err_buf with contextual aid - **/ -int -pfiflash_with_options(FILE* pfi, int complete, int seqnum, int compare, - pdd_handling_t pdd_handling, const char* rawdev, - char *err_buf, size_t err_buf_size) -{ - int rc; - bootenv_t bootenv; - pdd_func_t pdd_f; - - if (pfi == NULL) - return -EINVAL; - - rc = 0; - pdd_f = NULL; - - /* If the user didnt specify a seqnum we start per default - * with the index 0 */ - int curr_seqnum = seqnum < 0 ? 0 : seqnum; - - list_t pfi_raws = mk_empty(); /* list of raw sections from a pfi */ - list_t pfi_ubis = mk_empty(); /* list of ubi sections from a pfi */ - - rc = bootenv_create(&bootenv); - if (rc != 0) { - rc = -PFIFLASH_ERR_BOOTENV_CREATE; - EBUF(PFIFLASH_ERRSTR[-rc], ""); - goto err; - } - - rc = read_pfi_headers(&pfi_raws, &pfi_ubis, pfi, err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("reading PFI header"); - goto err; - } - - if (rawdev == NULL || compare) - rc = skip_raw_volumes(pfi, pfi_raws, err_buf, err_buf_size); - else - rc = process_raw_volumes(pfi, pfi_raws, rawdev, err_buf, - err_buf_size); - if (rc != 0) { - EBUF_PREPEND("handling raw section"); - goto err; - } - - if (complete && !compare) { - rc = erase_unmapped_ubi_volumes(EXAMPLE_UBI_DEVICE, pfi_ubis, - err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("deleting unmapped UBI volumes"); - goto err; - } - } - - if (((int)pdd_handling >= 0) && - (pdd_handling < PDD_HANDLING_NUM)) - pdd_f = pdd_funcs[pdd_handling]; - else { - rc = -PFIFLASH_ERR_PDD_UNKNOWN; - EBUF("%s", PFIFLASH_ERRSTR[-rc]); - goto err; - } - - if (!compare) { - rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv, - pdd_f, UBI_REMOVE, err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("removing UBI volumes"); - goto err; - } - - rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv, - pdd_f, UBI_WRITE, err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("writing UBI volumes"); - goto err; - } - - if (seqnum < 0) { /* mirror redundant pairs */ - rc = mirror_ubi_volumes(EXAMPLE_UBI_DEVICE, pfi_ubis, - err_buf, err_buf_size); - if (rc != 0) { - EBUF_PREPEND("mirroring UBI volumes"); - goto err; - } - } - } else { - /* only compare volumes, don't alter the content */ - rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv, - pdd_f, UBI_COMPARE, err_buf, err_buf_size); - - if (rc == -PFIFLASH_CMP_DIFF) - /* update is necessary, return positive value */ - rc = 1; - - if (rc < 0) { - EBUF_PREPEND("comparing UBI volumes"); - goto err; - } - } - - err: - pfi_raws = remove_all((free_func_t)&free_pfi_raw, pfi_raws); - pfi_ubis = remove_all((free_func_t)&free_pfi_ubi, pfi_ubis); - bootenv_destroy(&bootenv); - return rc; -} - - -/** - * pfiflash - passes to pfiflash_with_options - * @pfi PFI data file pointer - * @complete flag to erase unmapped volumes - * @seqnum sequence number - * @pdd_handling method to handle pdd (keep, merge, overwrite...) - **/ -int -pfiflash(FILE* pfi, int complete, int seqnum, pdd_handling_t pdd_handling, - char *err_buf, size_t err_buf_size) -{ - return pfiflash_with_options(pfi, complete, seqnum, 0, pdd_handling, - NULL, err_buf, err_buf_size); -} diff --git a/ubi-utils/old-utils/src/libubi.c b/ubi-utils/old-utils/src/libubi.c deleted file mode 100644 index a536b47..0000000 --- a/ubi-utils/old-utils/src/libubi.c +++ /dev/null @@ -1,915 +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. - * - * Author: Artem B. Bityutskiy - * - * UBI (Unsorted Block Images) library. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "libubi.h" -#include "libubi_int.h" - -libubi_t libubi_open(void) -{ - int fd, version; - struct libubi *lib; - - lib = calloc(1, sizeof(struct libubi)); - if (!lib) - return NULL; - - /* TODO: this must be discovered instead */ - lib->sysfs = strdup("/sys"); - if (!lib->sysfs) - goto error; - - lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI); - if (!lib->sysfs_ubi) - goto error; - - /* Make sure UBI is present */ - fd = open(lib->sysfs_ubi, O_RDONLY); - if (fd == -1) - goto error; - close(fd); - - lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); - if (!lib->ubi_dev) - goto error; - - lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); - if (!lib->ubi_version) - goto error; - - lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); - if (!lib->dev_dev) - goto error; - - lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); - if (!lib->dev_avail_ebs) - goto error; - - lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); - if (!lib->dev_total_ebs) - goto error; - - lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); - if (!lib->dev_bad_count) - goto error; - - lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); - if (!lib->dev_eb_size) - goto error; - - lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); - if (!lib->dev_max_ec) - goto error; - - lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); - if (!lib->dev_bad_rsvd) - goto error; - - lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); - if (!lib->dev_max_vols) - goto error; - - lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); - if (!lib->dev_min_io_size) - goto error; - - lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); - if (!lib->ubi_vol) - goto error; - - lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); - if (!lib->vol_type) - goto error; - - lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); - if (!lib->vol_dev) - goto error; - - lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); - if (!lib->vol_alignment) - goto error; - - lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); - if (!lib->vol_data_bytes) - goto error; - - lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); - if (!lib->vol_rsvd_ebs) - goto error; - - lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); - if (!lib->vol_eb_size) - goto error; - - lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); - if (!lib->vol_corrupted) - goto error; - - lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); - if (!lib->vol_name) - goto error; - - if (read_int(lib->ubi_version, &version)) - goto error; - if (version != LIBUBI_UBI_VERSION) { - fprintf(stderr, "LIBUBI: this library was made for UBI version " - "%d, but UBI version %d is detected\n", - LIBUBI_UBI_VERSION, version); - goto error; - } - - return lib; - -error: - free(lib->vol_corrupted); - free(lib->vol_eb_size); - free(lib->vol_rsvd_ebs); - free(lib->vol_data_bytes); - free(lib->vol_alignment); - free(lib->vol_dev); - free(lib->vol_type); - free(lib->ubi_vol); - free(lib->dev_min_io_size); - free(lib->dev_max_vols); - free(lib->dev_bad_rsvd); - free(lib->dev_max_ec); - free(lib->dev_eb_size); - free(lib->dev_bad_count); - free(lib->dev_total_ebs); - free(lib->dev_avail_ebs); - free(lib->dev_dev); - free(lib->ubi_version); - free(lib->ubi_dev); - free(lib->sysfs_ubi); - free(lib->sysfs); - free(lib); - return NULL; -} - -void libubi_close(libubi_t desc) -{ - struct libubi *lib = (struct libubi *)desc; - - free(lib->vol_name); - free(lib->vol_corrupted); - free(lib->vol_eb_size); - free(lib->vol_rsvd_ebs); - free(lib->vol_data_bytes); - free(lib->vol_alignment); - free(lib->vol_dev); - free(lib->vol_type); - free(lib->ubi_vol); - free(lib->dev_min_io_size); - free(lib->dev_max_vols); - free(lib->dev_bad_rsvd); - free(lib->dev_max_ec); - free(lib->dev_eb_size); - free(lib->dev_bad_count); - free(lib->dev_total_ebs); - free(lib->dev_avail_ebs); - free(lib->dev_dev); - free(lib->ubi_version); - free(lib->ubi_dev); - free(lib->sysfs_ubi); - free(lib->sysfs); - free(lib); -} - -int ubi_get_info(libubi_t desc, struct ubi_info *info) -{ - DIR *sysfs_ubi; - struct dirent *dirent; - struct libubi *lib = (struct libubi *)desc; - - memset(info, '\0', sizeof(struct ubi_info)); - - /* - * We have to scan the UBI sysfs directory to identify how many UBI - * devices are present. - */ - sysfs_ubi = opendir(lib->sysfs_ubi); - if (!sysfs_ubi) - return -1; - - info->lowest_dev_num = INT_MAX; - while ((dirent = readdir(sysfs_ubi))) { - char *name = &dirent->d_name[0]; - int dev_num, ret; - - ret = sscanf(name, UBI_DEV_NAME_PATT, &dev_num); - if (ret == 1) { - info->dev_count += 1; - if (dev_num > info->highest_dev_num) - info->highest_dev_num = dev_num; - if (dev_num < info->lowest_dev_num) - info->lowest_dev_num = dev_num; - } - } - - if (info->lowest_dev_num == INT_MAX) - info->lowest_dev_num = 0; - - if (read_int(lib->ubi_version, &info->version)) - goto close; - - return closedir(sysfs_ubi); - -close: - closedir(sysfs_ubi); - return -1; -} - -int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) -{ - int fd, ret; - struct ubi_mkvol_req r; - size_t n; - - desc = desc; - r.vol_id = req->vol_id; - r.alignment = req->alignment; - r.bytes = req->bytes; - r.vol_type = req->vol_type; - - n = strlen(req->name); - if (n > UBI_MAX_VOLUME_NAME) - return -1; - - strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); - r.name_len = n; - - fd = open(node, O_RDONLY); - if (fd == -1) - return -1; - - ret = ioctl(fd, UBI_IOCMKVOL, &r); - if (!ret) - req->vol_id = r.vol_id; - - close(fd); - return ret; -} - -int ubi_rmvol(libubi_t desc, const char *node, int vol_id) -{ - int fd, ret; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return -1; - - ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); - close(fd); - return ret; -} - -int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) -{ - int fd, ret; - struct ubi_rsvol_req req; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return -1; - - req.bytes = bytes; - req.vol_id = vol_id; - - ret = ioctl(fd, UBI_IOCRSVOL, &req); - close(fd); - return ret; -} - -int ubi_update_start(libubi_t desc, int fd, long long bytes) -{ - desc = desc; - if (ioctl(fd, UBI_IOCVOLUP, &bytes)) - return -1; - return 0; -} - -int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) -{ - int dev_num; - struct libubi *lib = (struct libubi *)desc; - - dev_num = find_dev_num(lib, node); - if (dev_num == -1) - return -1; - - return ubi_get_dev_info1(desc, dev_num, info); -} - -int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) -{ - DIR *sysfs_ubi; - struct dirent *dirent; - struct libubi *lib = (struct libubi *)desc; - - memset(info, '\0', sizeof(struct ubi_dev_info)); - info->dev_num = dev_num; - - sysfs_ubi = opendir(lib->sysfs_ubi); - if (!sysfs_ubi) - return -1; - - info->lowest_vol_num = INT_MAX; - while ((dirent = readdir(sysfs_ubi))) { - char *name = &dirent->d_name[0]; - int vol_id, ret, devno; - - ret = sscanf(name, UBI_VOL_NAME_PATT, &devno, &vol_id); - if (ret == 2 && devno == dev_num) { - info->vol_count += 1; - if (vol_id > info->highest_vol_num) - info->highest_vol_num = vol_id; - if (vol_id < info->lowest_vol_num) - info->lowest_vol_num = vol_id; - } - } - - closedir(sysfs_ubi); - - if (info->lowest_vol_num == INT_MAX) - info->lowest_vol_num = 0; - - if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_ebs)) - return -1; - if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_ebs)) - return -1; - if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) - return -1; - if (dev_read_int(lib->dev_eb_size, dev_num, &info->eb_size)) - return -1; - if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) - return -1; - if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) - return -1; - if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) - return -1; - if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) - return -1; - - info->avail_bytes = info->avail_ebs * info->eb_size; - info->total_bytes = info->total_ebs * info->eb_size; - - return 0; -} - -int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) -{ - int vol_id, dev_num; - struct libubi *lib = (struct libubi *)desc; - - dev_num = find_dev_num_vol(lib, node); - if (dev_num == -1) - return -1; - - vol_id = find_vol_num(lib, dev_num, node); - if (vol_id == -1) - return -1; - - return ubi_get_vol_info1(desc, dev_num, vol_id, info); -} - -int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, - struct ubi_vol_info *info) -{ - int ret; - struct libubi *lib = (struct libubi *)desc; - char buf[50]; - - memset(info, '\0', sizeof(struct ubi_vol_info)); - info->dev_num = dev_num; - info->vol_id = vol_id; - - ret = vol_read_data(lib->vol_type, dev_num, vol_id, &buf[0], 50); - if (ret < 0) - return -1; - - if (strncmp(&buf[0], "static\n", ret) == 0) - info->type = UBI_STATIC_VOLUME; - else if (strncmp(&buf[0], "dynamic\n", ret) == 0) - info->type = UBI_DYNAMIC_VOLUME; - else { - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - return -1; - } - - ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, - &info->alignment); - if (ret) - return -1; - ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, - &info->data_bytes); - if (ret) - return -1; - ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_ebs); - if (ret) - return -1; - ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->eb_size); - if (ret) - return -1; - ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, - &info->corrupted); - if (ret) - return -1; - info->rsvd_bytes = info->eb_size * info->rsvd_ebs; - - ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, - UBI_VOL_NAME_MAX + 2); - if (ret < 0) - return -1; - - info->name[ret - 1] = '\0'; - return 0; -} - -/** - * read_int - read an 'int' value from a file. - * - * @file the file to read from - * @value the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int read_int(const char *file, int *value) -{ - int fd, rd; - char buf[50]; - - fd = open(file, O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 50); - if (rd == -1) - goto error; - - if (sscanf(&buf[0], "%d\n", value) != 1) { - /* This must be a UBI bug */ - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - goto error; - } - - close(fd); - return 0; - -error: - close(fd); - return -1; -} - -/** - * dev_read_int - read an 'int' value from an UBI device's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @value the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int dev_read_int(const char *patt, int dev_num, int *value) -{ - int fd, rd; - char buf[50]; - char file[strlen(patt) + 50]; - - sprintf(&file[0], patt, dev_num); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 50); - if (rd == -1) - goto error; - - if (sscanf(&buf[0], "%d\n", value) != 1) { - /* This must be a UBI bug */ - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - goto error; - } - - close(fd); - return 0; - -error: - close(fd); - return -1; -} - -/** - * dev_read_ll - read a 'long long' value from an UBI device's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @value the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int dev_read_ll(const char *patt, int dev_num, long long *value) -{ - int fd, rd; - char buf[50]; - char file[strlen(patt) + 50]; - - sprintf(&file[0], patt, dev_num); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 50); - if (rd == -1) - goto error; - - if (sscanf(&buf[0], "%lld\n", value) != 1) { - /* This must be a UBI bug */ - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - goto error; - } - - close(fd); - return 0; - -error: - close(fd); - return -1; -} - -/** - * dev_read_data - read data from an UBI device's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @buf buffer to read data to - * @buf_len buffer length - * - * This function returns number of read bytes in case of success and %-1 in - * case of failure. - */ -static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len) -{ - int fd, rd; - char file[strlen(patt) + 50]; - - sprintf(&file[0], patt, dev_num); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, buf, buf_len); - if (rd == -1) { - close(fd); - return -1; - } - - close(fd); - return rd; -} - -/** - * vol_read_int - read an 'int' value from an UBI volume's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @vol_id volume identifier - * @value the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) -{ - int fd, rd; - char buf[50]; - char file[strlen(patt) + 100]; - - sprintf(&file[0], patt, dev_num, vol_id); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 50); - if (rd == -1) - goto error; - - if (sscanf(&buf[0], "%d\n", value) != 1) { - /* This must be a UBI bug */ - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - goto error; - } - - close(fd); - return 0; - -error: - close(fd); - return -1; -} - -/** - * vol_read_ll - read a 'long long' value from an UBI volume's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @vol_id volume identifier - * @value the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int vol_read_ll(const char *patt, int dev_num, int vol_id, - long long *value) -{ - int fd, rd; - char buf[50]; - char file[strlen(patt) + 100]; - - sprintf(&file[0], patt, dev_num, vol_id); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 50); - if (rd == -1) - goto error; - - if (sscanf(&buf[0], "%lld\n", value) != 1) { - /* This must be a UBI bug */ - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - goto error; - } - - close(fd); - return 0; - -error: - close(fd); - return -1; -} - -/** - * vol_read_data - read data from an UBI volume's sysfs file. - * - * @patt the file pattern to read from - * @dev_num UBI device number - * @vol_id volume identifier - * @buf buffer to read to - * @buf_len buffer length - * - * This function returns number of read bytes in case of success and %-1 in - * case of failure. - */ -static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, - int buf_len) -{ - int fd, rd; - char file[strlen(patt) + 100]; - - sprintf(&file[0], patt, dev_num, vol_id); - fd = open(&file[0], O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, buf, buf_len); - if (rd == -1) { - close(fd); - return -1; - } - - close(fd); - return rd; -} - -/** - * mkpath - compose full path from 2 given components. - * - * @path first component - * @name second component - * - * This function returns the resulting path in case of success and %NULL in - * case of failure. - */ -static char *mkpath(const char *path, const char *name) -{ - char *n; - int len1 = strlen(path); - int len2 = strlen(name); - - n = malloc(len1 + len2 + 2); - if (!n) - return NULL; - - memcpy(n, path, len1); - if (n[len1 - 1] != '/') - n[len1++] = '/'; - - memcpy(n + len1, name, len2 + 1); - return n; -} - -/** - * find_dev_num - find UBI device number by its character device node. - * - * @lib UBI library descriptor - * @node UBI character device node name - * - * This function returns positive UBI device number in case of success and %-1 - * in case of failure. - */ -static int find_dev_num(struct libubi *lib, const char *node) -{ - struct stat st; - struct ubi_info info; - int i, major, minor; - - if (stat(node, &st)) - return -1; - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return -1; - } - - major = major(st.st_rdev); - minor = minor(st.st_rdev); - - if (minor != 0) { - errno = -EINVAL; - return -1; - } - - if (ubi_get_info((libubi_t *)lib, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - int major1, minor1, ret; - char buf[50]; - - ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); - if (ret < 0) - return -1; - - ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); - if (ret != 2) { - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - return -1; - } - - if (minor1 == minor && major1 == major) - return i; - } - - errno = ENOENT; - return -1; -} - -/** - * find_dev_num_vol - find UBI device number by volume character device node. - * - * @lib UBI library descriptor - * @node UBI character device node name - * - * This function returns positive UBI device number in case of success and %-1 - * in case of failure. - */ -static int find_dev_num_vol(struct libubi *lib, const char *node) -{ - struct stat st; - struct ubi_info info; - int i, major; - - if (stat(node, &st)) - return -1; - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return -1; - } - - major = major(st.st_rdev); - - if (minor(st.st_rdev) == 0) { - errno = -EINVAL; - return -1; - } - - if (ubi_get_info((libubi_t *)lib, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - int major1, minor1, ret; - char buf[50]; - - ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); - if (ret < 0) - return -1; - - ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); - if (ret != 2) { - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - return -1; - } - - if (major1 == major) - return i; - } - - errno = ENOENT; - return -1; -} - -/** - * find_vol_num - find UBI volume number by its character device node. - * - * @lib UBI library descriptor - * @dev_num UBI device number - * @node UBI volume character device node name - * - * This function returns positive UBI volume number in case of success and %-1 - * in case of failure. - */ -static int find_vol_num(struct libubi *lib, int dev_num, const char *node) -{ - struct stat st; - struct ubi_dev_info info; - int i, major, minor; - - if (stat(node, &st)) - return -1; - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return -1; - } - - major = major(st.st_rdev); - minor = minor(st.st_rdev); - - if (minor == 0) { - errno = -EINVAL; - return -1; - } - - if (ubi_get_dev_info1((libubi_t *)lib, dev_num, &info)) - return -1; - - for (i = info.lowest_vol_num; i <= info.highest_vol_num; i++) { - int major1, minor1, ret; - char buf[50]; - - ret = vol_read_data(lib->vol_dev, dev_num, i, &buf[0], 50); - if (ret < 0) - return -1; - - ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); - if (ret != 2) { - fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); - errno = EINVAL; - return -1; - } - - if (minor1 == minor && major1 == major) - return i; - } - - errno = ENOENT; - return -1; -} diff --git a/ubi-utils/old-utils/src/libubi_int.h b/ubi-utils/old-utils/src/libubi_int.h deleted file mode 100644 index e68b791..0000000 --- a/ubi-utils/old-utils/src/libubi_int.h +++ /dev/null @@ -1,129 +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. - * - * Author: Artem B. Bityutskiy - * - * UBI (Unsorted Block Images) library. - */ - -#ifndef __LIBUBI_INT_H__ -#define __LIBUBI_INT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * UBI heavily makes use of the sysfs file system to interact with users-pace. - * The below are pre-define UBI file and directory names. - */ - -#define SYSFS_UBI "class/ubi" -#define UBI_DEV_NAME_PATT "ubi%d" -#define UBI_VER "version" -#define DEV_DEV "dev" -#define UBI_VOL_NAME_PATT "ubi%d_%d" -#define DEV_AVAIL_EBS "avail_eraseblocks" -#define DEV_TOTAL_EBS "total_eraseblocks" -#define DEV_BAD_COUNT "bad_peb_count" -#define DEV_EB_SIZE "eraseblock_size" -#define DEV_MAX_EC "max_ec" -#define DEV_MAX_RSVD "reserved_for_bad" -#define DEV_MAX_VOLS "max_vol_count" -#define DEV_MIN_IO_SIZE "min_io_size" -#define VOL_TYPE "type" -#define VOL_DEV "dev" -#define VOL_ALIGNMENT "alignment" -#define VOL_DATA_BYTES "data_bytes" -#define VOL_RSVD_EBS "reserved_ebs" -#define VOL_EB_SIZE "usable_eb_size" -#define VOL_CORRUPTED "corrupted" -#define VOL_NAME "name" - -/** - * libubi - UBI library description data structure. - * - * @sysfs sysfs file system path - * @sysfs_ubi UBI directory in sysfs - * @ubi_dev UBI device sysfs directory pattern - * @ubi_version UBI version file sysfs path - * @dev_dev UBI device's major/minor numbers file pattern - * @dev_avail_ebs count of available eraseblocks sysfs path pattern - * @dev_total_ebs total eraseblocks count sysfs path pattern - * @dev_bad_count count of bad eraseblocks sysfs path pattern - * @dev_eb_size size of UBI device's eraseblocks sysfs path pattern - * @dev_max_ec maximum erase counter sysfs path pattern - * @dev_bad_rsvd count of physical eraseblock reserved for bad eraseblocks - * handling - * @dev_max_vols maximum volumes number count sysfs path pattern - * @dev_min_io_size minimum I/O unit size sysfs path pattern - * @ubi_vol UBI volume sysfs directory pattern - * @vol_type volume type sysfs path pattern - * @vol_dev volume's major/minor numbers file pattern - * @vol_alignment volume alignment sysfs path pattern - * @vol_data_bytes volume data size sysfs path pattern - * @vol_rsvd_ebs volume reserved size sysfs path pattern - * @vol_eb_size volume eraseblock size sysfs path pattern - * @vol_corrupted volume corruption flag sysfs path pattern - * @vol_name volume name sysfs path pattern - */ -struct libubi -{ - char *sysfs; - char *sysfs_ubi; - char *ubi_dev; - char *ubi_version; - char *dev_dev; - char *dev_avail_ebs; - char *dev_total_ebs; - char *dev_bad_count; - char *dev_eb_size; - char *dev_max_ec; - char *dev_bad_rsvd; - char *dev_max_vols; - char *dev_min_io_size; - char *ubi_vol; - char *vol_type; - char *vol_dev; - char *vol_alignment; - char *vol_data_bytes; - char *vol_rsvd_ebs; - char *vol_eb_size; - char *vol_corrupted; - char *vol_name; - char *vol_max_count; -}; - -static int read_int(const char *file, int *value); -static int dev_read_int(const char *patt, int dev_num, int *value); -static int dev_read_ll(const char *patt, int dev_num, long long *value); -static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len); -static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value); -static int vol_read_ll(const char *patt, int dev_num, int vol_id, - long long *value); -static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, - int buf_len); -static char *mkpath(const char *path, const char *name); -static int find_dev_num(struct libubi *lib, const char *node); -static int find_dev_num_vol(struct libubi *lib, const char *node); -static int find_vol_num(struct libubi *lib, int dev_num, const char *node); - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBI_INT_H__ */ diff --git a/ubi-utils/old-utils/src/libubigen.c b/ubi-utils/old-utils/src/libubigen.c deleted file mode 100644 index 1793009..0000000 --- a/ubi-utils/old-utils/src/libubigen.c +++ /dev/null @@ -1,487 +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. - * - * Author: Oliver Lohmann - * - * Add UBI headers to binary data. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "ubigen.h" -#include "crc32.h" - -#define UBI_NAME_SIZE 256 -#define DEFAULT_VID_OFFSET ((DEFAULT_PAGESIZE) - (UBI_VID_HDR_SIZE)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -static uint32_t crc32_table[256]; - -struct ubi_info { - struct ubi_vid_hdr* v; /* Volume ID header */ - struct ubi_ec_hdr* ec; /* Erase count header */ - - FILE* fp_in; /* Input Stream */ - FILE* fp_out; /* Output stream */ - - size_t eb_size; /* Physical EB size in bytes */ - size_t leb_size; /* Size of a logical EB in a physical EB */ - size_t leb_total; /* Total input size in logical EB */ - size_t alignment; /* Block alignment */ - size_t data_pad; /* Size of padding in each physical EB */ - - size_t bytes_total; /* Total input size in bytes */ - size_t bytes_read; /* Nymber of read bytes (total) */ - - uint32_t blks_written; /* Number of written logical EB */ - - uint8_t* buf; /* Allocated buffer */ - uint8_t* ptr_ec_hdr; /* Pointer to EC hdr in buf */ - uint8_t* ptr_vid_hdr; /* Pointer to VID hdr in buf */ - uint8_t* ptr_data; /* Pointer to data region in buf */ -}; - - -static uint32_t -byte_to_blk(uint64_t byte, uint32_t eb_size) -{ - return (byte % eb_size) == 0 - ? (byte / eb_size) - : (byte / eb_size) + 1; -} - -static int -validate_ubi_info(ubi_info_t u) -{ - if ((u->v->vol_type != UBI_VID_DYNAMIC) && - (u->v->vol_type != UBI_VID_STATIC)) { - return EUBIGEN_INVALID_TYPE; - } - - if (be32_to_cpu(u->ec->vid_hdr_offset) < UBI_VID_HDR_SIZE) { - return EUBIGEN_INVALID_HDR_OFFSET; - } - - return 0; -} - -static int -skip_blks(ubi_info_t u, uint32_t blks) -{ - uint32_t i; - size_t read = 0, to_read = 0; - - /* Step to a maximum of leb_total - 1 to keep the - restrictions. */ - for (i = 0; i < MIN(blks, u->leb_total-1); i++) { - /* Read in data */ - to_read = MIN(u->leb_size, - (u->bytes_total - u->bytes_read)); - read = fread(u->ptr_data, 1, to_read, u->fp_in); - if (read != to_read) { - return -EIO; - } - u->bytes_read += read; - u->blks_written++; - } - - return 0; -} - -static void -clear_buf(ubi_info_t u) -{ - memset(u->buf, 0xff, u->eb_size); -} - -static void -write_ec_hdr(ubi_info_t u) -{ - memcpy(u->ptr_ec_hdr, u->ec, UBI_EC_HDR_SIZE); -} - -static int -fill_data_buffer_from_file(ubi_info_t u, size_t* read) -{ - size_t to_read = 0; - - if (u-> fp_in == NULL) - return -EIO; - - to_read = MIN(u->leb_size, (u->bytes_total - u->bytes_read)); - *read = fread(u->ptr_data, 1, to_read, u->fp_in); - if (*read != to_read) { - return -EIO; - } - return 0; -} - -static void -add_static_info(ubi_info_t u, size_t data_size, ubigen_action_t action) -{ - uint32_t crc = clc_crc32(crc32_table, UBI_CRC32_INIT, - u->ptr_data, data_size); - - u->v->data_size = cpu_to_be32(data_size); - u->v->data_crc = cpu_to_be32(crc); - - if (action & BROKEN_DATA_CRC) { - u->v->data_crc = - cpu_to_be32(be32_to_cpu(u->v->data_crc) + 1); - } - if (action & BROKEN_DATA_SIZE) { - u->v->data_size = - cpu_to_be32(be32_to_cpu(u->v->data_size) + 1); - } -} - -static void -write_vid_hdr(ubi_info_t u, ubigen_action_t action) -{ - uint32_t crc = clc_crc32(crc32_table, UBI_CRC32_INIT, - u->v, UBI_VID_HDR_SIZE_CRC); - /* Write VID header */ - u->v->hdr_crc = cpu_to_be32(crc); - if (action & BROKEN_HDR_CRC) { - u->v->hdr_crc = cpu_to_be32(be32_to_cpu(u->v->hdr_crc) + 1); - } - memcpy(u->ptr_vid_hdr, u->v, UBI_VID_HDR_SIZE); -} - -static int -write_to_output_stream(ubi_info_t u) -{ - size_t written; - - written = fwrite(u->buf, 1, u->eb_size, u->fp_out); - if (written != u->eb_size) { - return -EIO; - } - return 0; -} - -int -ubigen_write_leb(ubi_info_t u, ubigen_action_t action) -{ - int rc = 0; - size_t read = 0; - - clear_buf(u); - write_ec_hdr(u); - - rc = fill_data_buffer_from_file(u, &read); - if (rc != 0) - return rc; - - if (u->v->vol_type == UBI_VID_STATIC) { - add_static_info(u, read, action); - } - - u->v->lnum = cpu_to_be32(u->blks_written); - - if (action & MARK_AS_UPDATE) { - u->v->copy_flag = (u->v->copy_flag)++; - } - - write_vid_hdr(u, action); - rc = write_to_output_stream(u); - if (rc != 0) - return rc; - - /* Update current handle */ - u->bytes_read += read; - u->blks_written++; - return 0; -} - -int -ubigen_write_complete(ubi_info_t u) -{ - size_t i; - int rc = 0; - - for (i = 0; i < u->leb_total; i++) { - rc = ubigen_write_leb(u, NO_ERROR); - if (rc != 0) - return rc; - } - - return 0; -} - -int -ubigen_write_broken_update(ubi_info_t u, uint32_t blk) -{ - int rc = 0; - - rc = skip_blks(u, blk); - if (rc != 0) - return rc; - - rc = ubigen_write_leb(u, MARK_AS_UPDATE | BROKEN_DATA_CRC); - if (rc != 0) - return rc; - - - return 0; -} - -void -dump_info(ubi_info_t u ubi_unused) -{ -#ifdef DEBUG - int err = 0; - if (!u) { - fprintf(stderr, ""); - return; - } - if (!u->ec) { - fprintf(stderr, ""); - err = 1; - } - if (!u->v) { - fprintf(stderr, ""); - err = 1; - } - if (err) return; - - fprintf(stderr, "ubi volume\n"); - fprintf(stderr, "version : %8d\n", u->v->version); - fprintf(stderr, "vol_id : %8d\n", be32_to_cpu(u->v->vol_id)); - fprintf(stderr, "vol_type : %8s\n", - u->v->vol_type == UBI_VID_STATIC ? - "static" : "dynamic"); - fprintf(stderr, "used_ebs : %8d\n", - be32_to_cpu(u->v->used_ebs)); - fprintf(stderr, "eb_size : 0x%08x\n", u->eb_size); - fprintf(stderr, "leb_size : 0x%08x\n", u->leb_size); - fprintf(stderr, "data_pad : 0x%08x\n", - be32_to_cpu(u->v->data_pad)); - fprintf(stderr, "leb_total : %8d\n", u->leb_total); - fprintf(stderr, "header offs : 0x%08x\n", - be32_to_cpu(u->ec->vid_hdr_offset)); - fprintf(stderr, "bytes_total : %8d\n", u->bytes_total); - fprintf(stderr, " + in MiB : %8.2f M\n", - ((float)(u->bytes_total)) / 1024 / 1024); - fprintf(stderr, "-------------------------------\n\n"); -#else - return; -#endif -} - -int -ubigen_destroy(ubi_info_t *u) -{ - if (u == NULL) - return -EINVAL; - - ubi_info_t tmp = *u; - - if (tmp) { - if (tmp->v) - free(tmp->v); - if (tmp->ec) - free(tmp->ec); - if (tmp->buf) - free(tmp->buf); - free(tmp); - } - *u = NULL; - return 0; -} - -void -ubigen_init(void) -{ - init_crc32_table(crc32_table); -} - -int -ubigen_create(ubi_info_t* u, uint32_t vol_id, uint8_t vol_type, - uint32_t eb_size, uint64_t ec, uint32_t alignment, - uint8_t version, uint32_t vid_hdr_offset, uint8_t compat_flag, - size_t data_size, FILE* fp_in, FILE* fp_out) -{ - int rc = 0; - ubi_info_t res = NULL; - uint32_t crc; - uint32_t data_offset; - - if (alignment == 0) { - rc = EUBIGEN_INVALID_ALIGNMENT; - goto ubigen_create_err; - } - if ((fp_in == NULL) || (fp_out == NULL)) { - rc = -EINVAL; - goto ubigen_create_err; - } - - res = (ubi_info_t) calloc(1, sizeof(struct ubi_info)); - if (res == NULL) { - rc = -ENOMEM; - goto ubigen_create_err; - } - - res->v = (struct ubi_vid_hdr*) calloc(1, sizeof(struct ubi_vid_hdr)); - if (res->v == NULL) { - rc = -ENOMEM; - goto ubigen_create_err; - } - - res->ec = (struct ubi_ec_hdr*) calloc(1, sizeof(struct ubi_ec_hdr)); - if (res->ec == NULL) { - rc = -ENOMEM; - goto ubigen_create_err; - } - - /* data which is needed in the general process */ - vid_hdr_offset = vid_hdr_offset ? vid_hdr_offset : DEFAULT_VID_OFFSET; - data_offset = vid_hdr_offset + UBI_VID_HDR_SIZE; - res->bytes_total = data_size; - res->eb_size = eb_size ? eb_size : DEFAULT_BLOCKSIZE; - res->data_pad = (res->eb_size - data_offset) % alignment; - res->leb_size = res->eb_size - data_offset - res->data_pad; - res->leb_total = byte_to_blk(data_size, res->leb_size); - res->alignment = alignment; - - if ((res->eb_size < (vid_hdr_offset + UBI_VID_HDR_SIZE))) { - rc = EUBIGEN_TOO_SMALL_EB; - goto ubigen_create_err; - } - res->fp_in = fp_in; - res->fp_out = fp_out; - - /* vid hdr data which doesn't change */ - res->v->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); - res->v->version = version ? version : UBI_VERSION; - res->v->vol_type = vol_type; - res->v->vol_id = cpu_to_be32(vol_id); - res->v->compat = compat_flag; - res->v->data_pad = cpu_to_be32(res->data_pad); - - /* static only: used_ebs */ - if (res->v->vol_type == UBI_VID_STATIC) { - res->v->used_ebs = cpu_to_be32(byte_to_blk - (res->bytes_total, - res->leb_size)); - } - - /* ec hdr (fixed, doesn't change) */ - res->ec->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); - res->ec->version = version ? version : UBI_VERSION; - res->ec->ec = cpu_to_be64(ec); - res->ec->vid_hdr_offset = cpu_to_be32(vid_hdr_offset); - - res->ec->data_offset = cpu_to_be32(data_offset); - - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, res->ec, - UBI_EC_HDR_SIZE_CRC); - res->ec->hdr_crc = cpu_to_be32(crc); - - /* prepare a read buffer */ - res->buf = (uint8_t*) malloc (res->eb_size * sizeof(uint8_t)); - if (res->buf == NULL) { - rc = -ENOMEM; - goto ubigen_create_err; - } - - /* point to distinct regions within the buffer */ - res->ptr_ec_hdr = res->buf; - res->ptr_vid_hdr = res->buf + be32_to_cpu(res->ec->vid_hdr_offset); - res->ptr_data = res->buf + be32_to_cpu(res->ec->vid_hdr_offset) - + UBI_VID_HDR_SIZE; - - rc = validate_ubi_info(res); - if (rc != 0) { - fprintf(stderr, "Volume validation failed: %d\n", rc); - goto ubigen_create_err; - } - - dump_info(res); - *u = res; - return rc; - - ubigen_create_err: - if (res) { - if (res->v) - free(res->v); - if (res->ec) - free(res->ec); - if (res->buf) - free(res->buf); - free(res); - } - *u = NULL; - return rc; -} - -int -ubigen_get_leb_size(ubi_info_t u, size_t* size) -{ - if (u == NULL) - return -EINVAL; - - *size = u->leb_size; - return 0; -} - - -int -ubigen_get_leb_total(ubi_info_t u, size_t* total) -{ - if (u == NULL) - return -EINVAL; - - *total = u->leb_total; - return 0; -} - -int -ubigen_set_lvol_rec(ubi_info_t u, size_t reserved_bytes, - const char* vol_name, struct ubi_vtbl_record *lvol_rec) -{ - uint32_t crc; - - if ((u == NULL) || (vol_name == NULL)) - return -EINVAL; - - memset(lvol_rec, 0x0, UBI_VTBL_RECORD_SIZE); - - lvol_rec->reserved_pebs = - cpu_to_be32(byte_to_blk(reserved_bytes, u->leb_size)); - lvol_rec->alignment = cpu_to_be32(u->alignment); - lvol_rec->data_pad = u->v->data_pad; - lvol_rec->vol_type = u->v->vol_type; - - lvol_rec->name_len = - cpu_to_be16((uint16_t)strlen((const char*)vol_name)); - - memcpy(lvol_rec->name, vol_name, UBI_VOL_NAME_MAX + 1); - - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, - lvol_rec, UBI_VTBL_RECORD_SIZE_CRC); - lvol_rec->crc = cpu_to_be32(crc); - - return 0; -} diff --git a/ubi-utils/old-utils/src/libubimirror.c b/ubi-utils/old-utils/src/libubimirror.c deleted file mode 100644 index d06770e..0000000 --- a/ubi-utils/old-utils/src/libubimirror.c +++ /dev/null @@ -1,237 +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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include "ubimirror.h" - -#define COMPARE_BUF_SIZE (128 * 1024) - -#define DEFAULT_DEV_PATTERN "/dev/ubi%d" -#define DEFAULT_VOL_PATTERN "/dev/ubi%d_%d" - -#define EBUF(fmt...) do { \ - snprintf(err_buf, err_buf_size, fmt); \ -} while (0) - -enum { - compare_error = -1, - seek_error = -2, - write_error = -3, - read_error = -4, - update_error = -5, - ubi_error = -6, - open_error = -7, - close_error = -8, - compare_equal = 0, - compare_different = 1 -}; - -/* - * Read len number of bytes from fd. - * Return 0 on EOF, -1 on error. - */ -static ssize_t fill_buffer(int fd, unsigned char *buf, ssize_t len) -{ - ssize_t got, have = 0; - - do { - got = read(fd, buf + have, len - have); - if (got == -1 && errno != EINTR) - return -1; - have += got; - } while (got > 0 && have < len); - return have; -} - -/* - * Write len number of bytes to fd. - * Return bytes written (>= 0), -1 on error. - */ -static ssize_t flush_buffer(int fd, unsigned char *buf, ssize_t len) -{ - ssize_t done, have = 0; - - do { - done = write(fd, buf + have, len - have); - if (done == -1 && errno != EINTR) - return -1; - have += done; - } while (done > 0 && have < len); - return have; -} - -/* - * Compare two files. Return 0, 1, or -1, depending on whether the - * files are equal, different, or an error occured. - * Return compare-different when target volume can not be read. Might be - * an interrupted volume update and then the target device returns -EIO but - * can be updated. - * - * fd_a is source - * fd_b is destination - */ -static int compare_files(int fd_a, int fd_b) -{ - unsigned char buf_a[COMPARE_BUF_SIZE], buf_b[COMPARE_BUF_SIZE]; - ssize_t len_a, len_b; - int rc; - - for (;;) { - len_a = fill_buffer(fd_a, buf_a, sizeof(buf_a)); - if (len_a == -1) { - rc = compare_error; - break; - } - len_b = fill_buffer(fd_b, buf_b, sizeof(buf_b)); - if (len_b == -1) { - rc = compare_different; - break; - } - if (len_a != len_b) { - rc = compare_different; - break; - } - if (len_a == 0) { /* Size on both files equal and EOF */ - rc = compare_equal; - break; - } - if (memcmp(buf_a, buf_b, len_a) != 0 ) { - rc = compare_different; - break; - } - } - /* Position both files at the beginning */ - if (lseek(fd_a, 0, SEEK_SET) == -1 || - lseek(fd_b, 0, SEEK_SET) == -1) - rc = seek_error; - return rc; -} - -int vol_get_used_bytes(int vol_fd, unsigned long long *bytes) -{ - off_t res; - - res = lseek(vol_fd, 0, SEEK_END); - if (res == (off_t)-1) - return -1; - *bytes = (unsigned long long) res; - res = lseek(vol_fd, 0, SEEK_SET); - return res == (off_t)-1 ? -1 : 0; -} - -static int copy_files(libubi_t ulib, int fd_in, int fd_out) -{ - unsigned char buf_a[COMPARE_BUF_SIZE]; - ssize_t len_a, len_b; - unsigned long long update_size, copied; - - if (vol_get_used_bytes(fd_in, &update_size) == -1 || - ubi_update_start(ulib, fd_out, update_size) == -1) - return update_error; - for (copied = 0; copied < update_size; copied += len_b ) { - len_a = fill_buffer(fd_in, buf_a, sizeof(buf_a)); - if (len_a == -1) - return read_error; - if (len_a == 0) /* Reach EOF */ - return 0; - len_b = flush_buffer(fd_out, buf_a, len_a); - if (len_b != len_a) - return write_error; - } - return 0; -} - -int ubimirror(uint32_t devno, int seqnum, uint32_t *ids, ssize_t ids_size, - char *err_buf, size_t err_buf_size) -{ - int rc = 0; - uint32_t src_id; - char path[PATH_MAX]; - libubi_t ulib; - int fd_in = -1, i = 0, fd_out = -1; - - if (ids_size == 0) - return 0; - else { - if ((seqnum < 0) || (seqnum > (ids_size - 1))) { - EBUF("volume id %d out of range", seqnum); - return EUBIMIRROR_NO_SRC; - } - src_id = ids[seqnum]; - } - - ulib = libubi_open(); - if (ulib == NULL) - return ubi_error; - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, src_id); - - fd_in = open(path, O_RDONLY); - if (fd_in == -1) { - EBUF("open error source volume %d", ids[i]); - rc = open_error; - goto err; - } - - for (i = 0; i < ids_size; i++) { - if (ids[i] == src_id) /* skip self-mirror */ - continue; - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, ids[i]); - - fd_out = open(path, O_RDWR); - if (fd_out < 0){ - EBUF("open error destination volume %d", ids[i]); - rc = open_error; - goto err; - } - rc = compare_files(fd_in, fd_out); - if (rc < 0) { - EBUF("compare error volume %d and %d", src_id, ids[i]); - goto err; - } else if (rc == compare_different) { - rc = copy_files(ulib, fd_in, fd_out); - if (rc != 0) { - EBUF("mirror error volume %d to %d", src_id, - ids[i]); - goto err; - } - } - if ((rc = close(fd_out)) == -1) { - EBUF("close error volume %d", ids[i]); - rc = close_error; - goto err; - } else - fd_out = -1; - } -err: - if (fd_out != -1) - close(fd_out); - if (fd_in != -1) - close(fd_in); - if (ulib != NULL) - libubi_close(ulib); - return rc; -} diff --git a/ubi-utils/old-utils/src/list.c b/ubi-utils/old-utils/src/list.c deleted file mode 100644 index 6eb716b..0000000 --- a/ubi-utils/old-utils/src/list.c +++ /dev/null @@ -1,149 +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. - * - * Author: Oliver Lohmann - */ - -#include -#include -#include - -#include "list.h" - -list_t -mk_empty(void) -{ - return (list_t) NULL; -} - -int -is_empty(list_t l) -{ - return l == NULL; -} - -info_t -head(list_t l) -{ - assert(!is_empty(l)); - return l->info; -} - -list_t -tail(list_t l) -{ - assert(!is_empty(l)); - return l->next; -} - -list_t -remove_head(list_t l) -{ - list_t res; - assert(!is_empty(l)); - - res = l->next; - free(l); - return res; -} - -list_t -cons(info_t e, list_t l) -{ - list_t res = malloc(sizeof(*l)); - if (!res) - return NULL; - res->info = e; - res->next = l; - - return res; -} - -list_t -prepend_elem(info_t e, list_t l) -{ - return cons(e,l); -} - -list_t -append_elem(info_t e, list_t l) -{ - if (is_empty(l)) { - return cons(e,l); - } - l->next = append_elem(e, l->next); - - return l; -} - -list_t -insert_sorted(cmp_func_t cmp, info_t e, list_t l) -{ - if (is_empty(l)) - return cons(e, l); - - switch (cmp(e, l->info)) { - case -1: - case 0: - return l; - break; - case 1: - l->next = insert_sorted(cmp, e, l); - break; - default: - break; - } - - /* never reached */ - return NULL; -} - -list_t -remove_all(free_func_t free_func, list_t l) -{ - if (is_empty(l)) - return l; - list_t lnext = l->next; - - if (free_func && l->info) { - free_func(&(l->info)); - } - free(l); - - return remove_all(free_func, lnext); -} - - -info_t -is_in(cmp_func_t cmp, info_t e, list_t l) -{ - return - (is_empty(l)) - ? NULL - : (cmp(e, l->info)) == 0 ? l->info : is_in(cmp, e, l->next); -} - - -void -apply(process_func_t process_func, list_t l) -{ - list_t ptr; - void *i; - foreach(i, ptr, l) { - process_func(i); - } -} diff --git a/ubi-utils/old-utils/src/list.h b/ubi-utils/old-utils/src/list.h deleted file mode 100644 index e8452a2..0000000 --- a/ubi-utils/old-utils/src/list.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __LIST_H__ -#define __LIST_H__ -/* - * 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. - * - * Author: Oliver Lohmann - */ - -#include - -#define foreach(elem, ptr, list) \ - for (elem = list != NULL ? (typeof(elem)) head(list) \ - : NULL, ptr = list; \ - ptr != NULL; \ - ptr = tail(ptr), \ - elem = (typeof(elem)) ptr ? head(ptr) : NULL) - -typedef struct node* list_t; -typedef void* info_t; -typedef int (*free_func_t)(info_t*); -typedef int (*cmp_func_t)(info_t, info_t); -typedef void (*process_func_t)(info_t); - -struct node { - list_t next; - info_t info; -}; - -list_t mk_empty(void); -int is_empty(list_t l); -info_t is_in(cmp_func_t cmp, info_t e, list_t l); -info_t head(list_t l); -list_t tail(list_t l); -list_t remove_head(list_t l); -list_t cons(info_t e, list_t l); -list_t prepend_elem(info_t e, list_t); -list_t append_elem(info_t e, list_t); -list_t remove_all(free_func_t free_func, list_t l); -list_t insert_sorted(cmp_func_t cmp_func, info_t e, list_t l); -void apply(process_func_t process_func, list_t l); - -#endif /* __LIST_H__ */ diff --git a/ubi-utils/old-utils/src/mkbootenv.c b/ubi-utils/old-utils/src/mkbootenv.c deleted file mode 100644 index 50fc8ac..0000000 --- a/ubi-utils/old-utils/src/mkbootenv.c +++ /dev/null @@ -1,168 +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. - * - * Author: Oliver Lohmann - * - * Create boot-parameter/pdd data from an ASCII-text input file. - * - * 1.2 Removed argp because we want to use uClibc. - * 1.3 Minor cleanup - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "bootenv.h" -#include "error.h" - -#define PROGRAM_VERSION "1.3" - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "mkbootenv - processes bootenv text files and convertes " - "them into a binary format.\n"; - -static const char copyright [] __attribute__((unused)) = - "Copyright (c) International Business Machines Corp., 2006"; - -static const char *optionsstr = -" -c, --copyright Print copyright informatoin.\n" -" -o, --output= Write the output data to instead of\n" -" stdout.\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: mkbootenv [-c?V] [-o ] [--copyright] [--output=]\n" -" [--help] [--usage] [--version] [bootenv-txt-file]\n"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -typedef struct myargs { - FILE* fp_in; - FILE* fp_out; - - char *arg1; - char **options; /* [STRING...] */ -} myargs; - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "co:?V", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'c': - fprintf(stderr, "%s\n", copyright); - exit(0); - break; - case 'o': - args->fp_out = fopen(optarg, "wb"); - if ((args->fp_out) == NULL) { - fprintf(stderr, "Cannot open file %s " - "for output\n", optarg); - exit(1); - } - break; - case '?': /* help */ - printf("%s", doc); - printf("%s", optionsstr); - printf("\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - case 'V': - printf("%s\n", PROGRAM_VERSION); - exit(0); - break; - default: - printf("%s", usage); - exit(-1); - } - } - - if (optind < argc) { - args->fp_in = fopen(argv[optind++], "rb"); - if ((args->fp_in) == NULL) { - fprintf(stderr, "Cannot open file %s for input\n", - argv[optind]); - exit(1); - } - } - - return 0; -} - -int -main(int argc, char **argv) { - int rc = 0; - bootenv_t env; - - myargs args = { - .fp_in = stdin, - .fp_out = stdout, - .arg1 = NULL, - .options = NULL, - }; - - parse_opt(argc, argv, &args); - - rc = bootenv_create(&env); - if (rc != 0) { - err_msg("Cannot create bootenv handle."); - goto err; - } - rc = bootenv_read_txt(args.fp_in, env); - if (rc != 0) { - err_msg("Cannot read bootenv from input file."); - goto err; - } - rc = bootenv_write(args.fp_out, env); - if (rc != 0) { - err_msg("Cannot write bootenv to output file."); - goto err; - } - - if (args.fp_in != stdin) { - fclose(args.fp_in); - } - if (args.fp_out != stdout) { - fclose(args.fp_out); - } - -err: - bootenv_destroy(&env); - return rc; -} diff --git a/ubi-utils/old-utils/src/nand2bin.c b/ubi-utils/old-utils/src/nand2bin.c deleted file mode 100644 index 93ba29f..0000000 --- a/ubi-utils/old-utils/src/nand2bin.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * 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. - * - * Author: Frank Haverkamp - * - * An utility to decompose NAND images and strip OOB off. Not yet finished ... - * - * 1.2 Removed argp because we want to use uClibc. - * 1.3 Minor cleanup - * 1.4 Fixed OOB output file - * 1.5 Added verbose output and option to set blocksize. - * Added split block mode for more convenient analysis. - * 1.6 Fixed ECC error detection and correction. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "nandecc.h" - -#define PROGRAM_VERSION "1.6" - -#define MAXPATH 1024 -#define MIN(x,y) ((x)<(y)?(x):(y)) - -struct args { - const char *oob_file; - const char *output_file; - size_t pagesize; - size_t blocksize; - int split_blocks; - size_t in_len; /* size of input file */ - int correct_ecc; - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -}; - -static struct args myargs = { - .output_file = "data.bin", - .oob_file = "oob.bin", - .pagesize = 2048, - .blocksize = 128 * 1024, - .in_len = 0, - .split_blocks = 0, - .correct_ecc = 0, - .arg1 = NULL, - .options = NULL, -}; - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "nand2bin - split data and OOB.\n"; - -static const char *optionsstr = -" -o, --output= Data output file\n" -" -O, --oob= OOB output file\n" -" -p, --pagesize= NAND pagesize\n" -" -b, --blocksize= NAND blocksize\n" -" -s, --split-blocks generate binaries for each block\n" -" -e, --correct-ecc Correct data according to ECC info\n" -" -v, --verbose verbose output\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n"; - -static const char *usage = -"Usage: nand2bin [-?] [-o ] [-O ] [-p ]\n" -" [--output=] [--oob=] [--pagesize=] [--help]\n" -" [--usage] input.mif\n"; - -static int verbose = 0; - -static struct option long_options[] = { - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "oob", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "pagesize", .has_arg = 1, .flag = NULL, .val = 'p' }, - { .name = "blocksize", .has_arg = 1, .flag = NULL, .val = 'b' }, - { .name = "split-blocks", .has_arg = 0, .flag = NULL, .val = 's' }, - { .name = "correct-ecc", .has_arg = 0, .flag = NULL, .val = 'e' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { NULL, 0, NULL, 0} -}; - -/* - * str_to_num - Convert string into number and cope with endings like - * k, K, kib, KiB for kilobyte - * m, M, mib, MiB for megabyte - */ -static uint32_t str_to_num(char *str) -{ - char *s = str; - ulong num = strtoul(s, &s, 0); - - if (*s != '\0') { - if (strcmp(s, "KiB") == 0) - num *= 1024; - else if (strcmp(s, "MiB") == 0) - num *= 1024*1024; - else { - fprintf(stderr, "WARNING: Wrong number format " - "\"%s\", check your paramters!\n", str); - } - } - return num; -} - -/* - * @brief Parse the arguments passed into the test case. - * - * @param argc The number of arguments - * @param argv The argument list - * @param args Pointer to program args structure - * - * @return error - * - */ -static int parse_opt(int argc, char **argv, struct args *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "b:eo:O:p:sv?", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'p': /* --pagesize */ - args->pagesize = str_to_num(optarg); - break; - - case 'b': /* --blocksize */ - args->blocksize = str_to_num(optarg); - break; - - case 'v': /* --verbose */ - verbose++; - break; - - case 's': /* --split-blocks */ - args->split_blocks = 1; - break; - - case 'e': /* --correct-ecc */ - args->correct_ecc = 1; - break; - - case 'o': /* --output= */ - args->output_file = optarg; - break; - - case 'O': /* --oob= */ - args->oob_file = optarg; - break; - - case '?': /* help */ - printf("Usage: nand2bin [OPTION...] input.mif\n"); - printf("%s", doc); - printf("%s", optionsstr); - printf("\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - - case 'V': - printf("%s\n", PROGRAM_VERSION); - exit(0); - break; - - default: - printf("%s", usage); - exit(-1); - } - } - - if (optind < argc) - args->arg1 = argv[optind++]; - - return 0; -} - -static int calc_oobsize(size_t pagesize) -{ - switch (pagesize) { - case 512: return 16; - case 2048: return 64; - default: - exit(EXIT_FAILURE); - } - return 0; -} - -static inline void hexdump(FILE *fp, const uint8_t *buf, ssize_t size) -{ - int k; - - for (k = 0; k < size; k++) { - fprintf(fp, "%02x ", buf[k]); - if ((k & 15) == 15) - fprintf(fp, "\n"); - } -} - -static int process_page(uint8_t* buf, uint8_t *oobbuf, size_t pagesize) -{ - int eccpoi, oobsize; - size_t i; - - switch (pagesize) { - case 2048: oobsize = 64; eccpoi = 64 / 2; break; - case 512: oobsize = 16; eccpoi = 16 / 2; break; - default: - fprintf(stderr, "Unsupported page size: %zd\n", pagesize); - return -EINVAL; - } - memset(oobbuf, 0xff, oobsize); - - for (i = 0; i < pagesize; i += 256, eccpoi += 3) { - oobbuf[eccpoi++] = 0x0; - /* Calculate ECC */ - nand_calculate_ecc(&buf[i], &oobbuf[eccpoi]); - } - return 0; -} - -static int bad_marker_offs_in_oob(int pagesize) -{ - switch (pagesize) { - case 2048: return 0; - case 512: return 5; - } - return -EINVAL; -} - -static int decompose_image(struct args *args, FILE *in_fp, - FILE *bin_fp, FILE *oob_fp) -{ - int read, rc, page = 0; - size_t oobsize = calc_oobsize(args->pagesize); - uint8_t *buf = malloc(args->pagesize); - uint8_t *oob = malloc(oobsize); - uint8_t *calc_oob = malloc(oobsize); - uint8_t *calc_buf = malloc(args->pagesize); - uint8_t *page_buf; - int pages_per_block = args->blocksize / args->pagesize; - int eccpoi = 0, eccpoi_start; - unsigned int i; - int badpos = bad_marker_offs_in_oob(args->pagesize); - - switch (args->pagesize) { - case 2048: eccpoi_start = 64 / 2; break; - case 512: eccpoi_start = 16 / 2; break; - default: exit(EXIT_FAILURE); - } - - if (!buf) - exit(EXIT_FAILURE); - if (!oob) - exit(EXIT_FAILURE); - if (!calc_oob) - exit(EXIT_FAILURE); - if (!calc_buf) - exit(EXIT_FAILURE); - - while (!feof(in_fp)) { - /* read page by page */ - read = fread(buf, 1, args->pagesize, in_fp); - if (ferror(in_fp)) { - fprintf(stderr, "I/O Error."); - exit(EXIT_FAILURE); - } - if (read != (ssize_t)args->pagesize) - break; - - read = fread(oob, 1, oobsize, in_fp); - if (ferror(in_fp)) { - fprintf(stderr, "I/O Error."); - exit(EXIT_FAILURE); - } - - page_buf = buf; /* default is unmodified data */ - - if ((page == 0 || page == 1) && (oob[badpos] != 0xff)) { - if (verbose) - printf("Block %d is bad\n", - page / pages_per_block); - goto write_data; - } - if (args->correct_ecc) - page_buf = calc_buf; - - process_page(buf, calc_oob, args->pagesize); - memcpy(calc_buf, buf, args->pagesize); - - /* - * Our oob format uses only the last 3 bytes out of 4. - * The first byte is 0x00 when the ECC is generated by - * our toolset and 0xff when generated by Linux. This - * is to be fixed when we want nand2bin work for other - * ECC layouts too. - */ - for (i = 0, eccpoi = eccpoi_start; i < args->pagesize; - i += 256, eccpoi += 4) - oob[eccpoi] = calc_oob[eccpoi] = 0xff; - - if (verbose && memcmp(oob, calc_oob, oobsize) != 0) { - printf("\nECC compare mismatch found at block %d page %d!\n", - page / pages_per_block, page % pages_per_block); - - printf("Read out OOB Data:\n"); - hexdump(stdout, oob, oobsize); - - printf("Calculated OOB Data:\n"); - hexdump(stdout, calc_oob, oobsize); - } - - /* Do correction on subpage base */ - for (i = 0, eccpoi = eccpoi_start; i < args->pagesize; - i += 256, eccpoi += 4) { - rc = nand_correct_data(calc_buf + i, &oob[eccpoi + 1], - &calc_oob[eccpoi + 1]); - - if (rc == -1) - fprintf(stdout, "Uncorrectable ECC error at " - "block %d page %d/%d\n", - page / pages_per_block, - page % pages_per_block, i / 256); - else if (rc > 0) - fprintf(stdout, "Correctable ECC error at " - "block %d page %d/%d\n", - page / pages_per_block, - page % pages_per_block, i / 256); - } - - write_data: - rc = fwrite(page_buf, 1, args->pagesize, bin_fp); - if (ferror(bin_fp)) { - fprintf(stderr, "I/O Error."); - exit(EXIT_FAILURE); - } - rc = fwrite(oob, 1, oobsize, oob_fp); - if (ferror(bin_fp)) { - fprintf(stderr, "I/O Error."); - exit(EXIT_FAILURE); - } - - page++; - } - free(calc_buf); - free(calc_oob); - free(oob); - free(buf); - return 0; -} - -static int split_blocks(struct args *args, FILE *in_fp) -{ - uint8_t *buf; - size_t oobsize = calc_oobsize(args->pagesize); - int pages_per_block = args->blocksize / args->pagesize; - int block_len = pages_per_block * (args->pagesize + oobsize); - int blocks = args->in_len / block_len; - char bname[256] = { 0, }; - int badpos = bad_marker_offs_in_oob(args->pagesize); - int bad_blocks = 0, i, bad_block = 0; - ssize_t rc; - FILE *b; - - buf = malloc(block_len); - if (!buf) { - perror("Not enough memory"); - exit(EXIT_FAILURE); - } - - for (i = 0; i < blocks; i++) { - rc = fread(buf, 1, block_len, in_fp); - if (rc != block_len) { - fprintf(stderr, "cannot read enough data!\n"); - exit(EXIT_FAILURE); - } - - /* do block analysis */ - bad_block = 0; - if ((buf[args->pagesize + badpos] != 0xff) || - (buf[2 * args->pagesize + oobsize + badpos] != 0xff)) { - bad_blocks++; - bad_block = 1; - } - if ((verbose && bad_block) || (verbose > 1)) { - printf("-- (block %d oob of page 0 and 1)\n", i); - hexdump(stdout, buf + args->pagesize, oobsize); - printf("--\n"); - hexdump(stdout, buf + 2 * args->pagesize + - oobsize, oobsize); - } - - /* write complete block out */ - snprintf(bname, sizeof(bname) - 1, "%s.%d", args->arg1, i); - b = fopen(bname, "w+"); - if (!b) { - perror("Cannot open file"); - exit(EXIT_FAILURE); - } - rc = fwrite(buf, 1, block_len, b); - if (rc != block_len) { - fprintf(stderr, "could not write all data!\n"); - exit(EXIT_FAILURE); - } - fclose(b); - } - - free(buf); - if (bad_blocks || verbose) - fprintf(stderr, "%d blocks, %d bad blocks\n", - blocks, bad_blocks); - return 0; -} - -int -main(int argc, char *argv[]) -{ - FILE *in, *bin = NULL, *oob = NULL; - struct stat file_info; - - parse_opt(argc, argv, &myargs); - - if (!myargs.arg1) { - fprintf(stderr, "Please specify input file!\n"); - exit(EXIT_FAILURE); - } - - if (stat(myargs.arg1, &file_info) != 0) { - perror("Cannot fetch file size from input file.\n"); - exit(EXIT_FAILURE); - } - myargs.in_len = file_info.st_size; - - in = fopen(myargs.arg1, "r"); - if (!in) { - perror("Cannot open file"); - exit(EXIT_FAILURE); - } - - if (myargs.split_blocks) { - split_blocks(&myargs, in); - goto out; - } - - bin = fopen(myargs.output_file, "w+"); - if (!bin) { - perror("Cannot open file"); - exit(EXIT_FAILURE); - } - oob = fopen(myargs.oob_file, "w+"); - if (!oob) { - perror("Cannot open file"); - exit(EXIT_FAILURE); - } - decompose_image(&myargs, in, bin, oob); - - out: - if (in) fclose(in); - if (bin) fclose(bin); - if (oob) fclose(oob); - exit(EXIT_SUCCESS); -} diff --git a/ubi-utils/old-utils/src/nandcorr.c b/ubi-utils/old-utils/src/nandcorr.c deleted file mode 100644 index caa07e2..0000000 --- a/ubi-utils/old-utils/src/nandcorr.c +++ /dev/null @@ -1,95 +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. - */ - -/* - * ECC algorithm for NAND FLASH. Detects and corrects 1 bit errors in - * a 256 bytes of data. - * - * Reimplement by Thomas Gleixner after staring long enough at the - * mess in drivers/mtd/nand/nandecc.c - * - */ - -#include "nandecc.h" - -static int countbits(uint32_t byte) -{ - int res = 0; - - for (;byte; byte >>= 1) - res += byte & 0x01; - return res; -} - -/** - * @dat: data which should be corrected - * @read_ecc: ecc information read from flash - * @calc_ecc: calculated ecc information from the data - * @return: number of corrected bytes - * or -1 when no correction is possible - */ -int nand_correct_data(uint8_t *dat, const uint8_t *read_ecc, - const uint8_t *calc_ecc) -{ - uint8_t s0, s1, s2; - - /* - * Do error detection - * - * Be careful, the index magic is due to a pointer to a - * uint32_t. - */ - s0 = calc_ecc[0] ^ read_ecc[0]; - s1 = calc_ecc[1] ^ read_ecc[1]; - s2 = calc_ecc[2] ^ read_ecc[2]; - - if ((s0 | s1 | s2) == 0) - return 0; - - /* Check for a single bit error */ - if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && - ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && - ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { - - uint32_t byteoffs, bitnum; - - byteoffs = (s1 << 0) & 0x80; - byteoffs |= (s1 << 1) & 0x40; - byteoffs |= (s1 << 2) & 0x20; - byteoffs |= (s1 << 3) & 0x10; - - byteoffs |= (s0 >> 4) & 0x08; - byteoffs |= (s0 >> 3) & 0x04; - byteoffs |= (s0 >> 2) & 0x02; - byteoffs |= (s0 >> 1) & 0x01; - - bitnum = (s2 >> 5) & 0x04; - bitnum |= (s2 >> 4) & 0x02; - bitnum |= (s2 >> 3) & 0x01; - - dat[byteoffs] ^= (1 << bitnum); - - return 1; - } - - if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) - return 1; - - return -1; -} - diff --git a/ubi-utils/old-utils/src/nandecc.c b/ubi-utils/old-utils/src/nandecc.c deleted file mode 100644 index 71660ef..0000000 --- a/ubi-utils/old-utils/src/nandecc.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file contains an ECC algorithm from Toshiba that detects and - * corrects 1 bit errors in a 256 byte block of data. - * - * drivers/mtd/nand/nand_ecc.c - * - * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) - * Toshiba America Electronics Components, Inc. - * - * This file 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 or (at your option) any - * later version. - * - * This file 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 file; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * As a special exception, if other files instantiate templates or use - * macros or inline functions from these files, or you compile these - * files and link them with other works to produce a work based on these - * files, these files do not by themselves cause the resulting work to be - * covered by the GNU General Public License. However the source code for - * these files must still be made available in accordance with section (3) - * of the GNU General Public License. - * - * This exception does not invalidate any other reasons why a work based on - * this file might be covered by the GNU General Public License. - */ - -#include "nandecc.h" - -/* - * Pre-calculated 256-way 1 byte column parity - */ -static const uint8_t nand_ecc_precalc_table[] = { - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, - 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, - 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, - 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, - 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, - 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, - 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, - 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, - 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 -}; - -/** - * nand_trans_result - [GENERIC] create non-inverted ECC - * @reg2: line parity reg 2 - * @reg3: line parity reg 3 - * @ecc_code: ecc - * - * Creates non-inverted ECC code from line parity - */ -static void nand_trans_result(uint8_t reg2, uint8_t reg3, - uint8_t *ecc_code) -{ - uint8_t a, b, i, tmp1, tmp2; - - /* Initialize variables */ - a = b = 0x80; - tmp1 = tmp2 = 0; - - /* Calculate first ECC byte */ - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ - tmp1 |= b; - b >>= 1; - a >>= 1; - } - - /* Calculate second ECC byte */ - b = 0x80; - for (i = 0; i < 4; i++) { - if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ - tmp2 |= b; - b >>= 1; - a >>= 1; - } - - /* Store two of the ECC bytes */ - ecc_code[1] = tmp1; - ecc_code[0] = tmp2; -} - -/** - * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for - * 256 byte block - * - * @dat: raw data - * @ecc_code: buffer for ECC - */ -int nand_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code) -{ - uint8_t idx, reg1, reg2, reg3; - int j; - - /* Initialize variables */ - reg1 = reg2 = reg3 = 0; - ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; - - /* Build up column parity */ - for(j = 0; j < 256; j++) { - - /* Get CP0 - CP5 from table */ - idx = nand_ecc_precalc_table[dat[j]]; - reg1 ^= (idx & 0x3f); - - /* All bit XOR = 1 ? */ - if (idx & 0x40) { - reg3 ^= (uint8_t) j; - reg2 ^= ~((uint8_t) j); - } - } - - /* Create non-inverted ECC code from line parity */ - nand_trans_result(reg2, reg3, ecc_code); - - /* Calculate final ECC code */ - ecc_code[0] = ~ecc_code[0]; - ecc_code[1] = ~ecc_code[1]; - ecc_code[2] = ((~reg1) << 2) | 0x03; - return 0; -} diff --git a/ubi-utils/old-utils/src/nandecc.h b/ubi-utils/old-utils/src/nandecc.h deleted file mode 100644 index bcf1982..0000000 --- a/ubi-utils/old-utils/src/nandecc.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _NAND_ECC_H -#define _NAND_ECC_H -/* - * 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. - * - * NAND ecc functions - */ - -#include - -int nand_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code); -int nand_correct_data(uint8_t *dat, const uint8_t *read_ecc, - const uint8_t *calc_ecc); - -#endif diff --git a/ubi-utils/old-utils/src/pddcustomize.c b/ubi-utils/old-utils/src/pddcustomize.c deleted file mode 100644 index 1eb9b9a..0000000 --- a/ubi-utils/old-utils/src/pddcustomize.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2008 - * - * 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. - * - * Author: Oliver Lohmann - * - * PDD (platform description data) contains a set of system specific - * boot-parameters. Some of those parameters need to be handled - * special on updates, e.g. the MAC addresses. They must also be kept - * if the system is updated and one must be able to modify them when - * the system has booted the first time. This tool is intended to do - * PDD modification. - * - * 1.3 Removed argp because we want to use uClibc. - * 1.4 Minor cleanups - * 1.5 Migrated to new libubi - * 1.6 Fixed broken volume update - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "bootenv.h" -#include "error.h" -#include "example_ubi.h" -#include "libubi.h" -#include "ubimirror.h" - -#define PROGRAM_VERSION "1.6" - -#define DEFAULT_DEV_PATTERN "/dev/ubi%d" -#define DEFAULT_VOL_PATTERN "/dev/ubi%d_%d" - -typedef enum action_t { - ACT_NORMAL = 0, - ACT_LIST, - ACT_ARGP_ABORT, - ACT_ARGP_ERR, -} action_t; - -#define ABORT_ARGP do { \ - args->action = ACT_ARGP_ABORT; \ -} while (0) - -#define ERR_ARGP do { \ - args->action = ACT_ARGP_ERR; \ -} while (0) - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "pddcustomize - customize bootenv and pdd values.\n"; - -static const char *optionsstr = -" -b, --both Mirror updated PDD to redundand copy.\n" -" -c, --copyright Print copyright information.\n" -" -i, --input= Binary input file. For debug purposes.\n" -" -l, --list List card bootenv/pdd values.\n" -" -o, --output= Binary output file. For debug purposes.\n" -" -s, --side= The side/seqnum to update.\n" -" -x, --host use x86 platform for debugging.\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: pddcustomize [-bclx?V] [-i ] [-o ] [-s ]\n" -" [--both] [--copyright] [--input=] [--list]\n" -" [--output=] [--side=] [--host] [--help] [--usage]\n" -" [--version] [key=value] [...]\n"; - -struct option long_options[] = { - { .name = "both", .has_arg = 0, .flag = NULL, .val = 'b' }, - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "input", .has_arg = 1, .flag = NULL, .val = 'i' }, - { .name = "list", .has_arg = 0, .flag = NULL, .val = 'l' }, - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "side", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "host", .has_arg = 0, .flag = NULL, .val = 'x' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -static const char copyright [] __attribute__((unused)) = - "Copyright IBM Corp 2006"; - -typedef struct myargs { - action_t action; - const char* file_in; - const char* file_out; - int both; - int side; - int x86; /* X86 host, use files for testing */ - bootenv_t env_in; - - char *arg1; - char **options; /* [STRING...] */ -} myargs; - -static int -get_update_side(const char* str) -{ - uint32_t i = strtoul(str, NULL, 0); - - if ((i != 0) && (i != 1)) { - return -1; - } - - return i; -} - -static int -extract_pair(bootenv_t env, const char* str) -{ - int rc = 0; - char* key; - char* val; - - key = strdup(str); - if (key == NULL) - return -ENOMEM; - - val = strstr(key, "="); - if (val == NULL) { - err_msg("Wrong argument: %s\n" - "Expecting key=value pair.\n", str); - rc = -1; - goto err; - } - - *val = '\0'; /* split strings */ - val++; - rc = bootenv_set(env, key, val); - -err: - free(key); - return rc; -} - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - int rc = 0; - - while (1) { - int key; - - key = getopt_long(argc, argv, "clbxs:i:o:?V", - long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'c': - err_msg("%s\n", copyright); - ABORT_ARGP; - break; - case 'l': - args->action = ACT_LIST; - break; - case 'b': - args->both = 1; - break; - case 'x': - args->x86 = 1; - break; - case 's': - args->side = get_update_side(optarg); - if (args->side < 0) { - err_msg("Unsupported seqnum: %d.\n" - "Supported seqnums are " - "'0' and '1'\n", - args->side, optarg); - ERR_ARGP; - } - break; - case 'i': - args->file_in = optarg; - break; - case 'o': - args->file_out = optarg; - break; - case '?': /* help */ - err_msg("Usage: pddcustomize [OPTION...] " - "[key=value] [...]"); - err_msg("%s", doc); - err_msg("%s", optionsstr); - err_msg("\nReport bugs to %s", - PACKAGE_BUGREPORT); - exit(0); - break; - case 'V': - err_msg("%s", PROGRAM_VERSION); - exit(0); - break; - default: - err_msg("%s", usage); - exit(-1); - } - } - - if (optind < argc) { - rc = extract_pair(args->env_in, argv[optind++]); - if (rc != 0) - ERR_ARGP; - } - - return 0; -} - -static int -list_bootenv(bootenv_t env) -{ - int rc = 0; - rc = bootenv_write_txt(stdout, env); - if (rc != 0) { - err_msg("Cannot list bootenv/pdd. rc: %d\n", rc); - goto err; - } -err: - return rc; -} - -static int -process_key_value(bootenv_t env_in, bootenv_t env) -{ - int rc = 0; - size_t size, i; - const char* tmp; - const char** key_vec = NULL; - - rc = bootenv_get_key_vector(env_in, &size, 0, &key_vec); - if (rc != 0) - goto err; - - for (i = 0; i < size; i++) { - rc = bootenv_get(env_in, key_vec[i], &tmp); - if (rc != 0) { - err_msg("Cannot read value to input key: %s. rc: %d\n", - key_vec[i], rc); - goto err; - } - rc = bootenv_set(env, key_vec[i], tmp); - if (rc != 0) { - err_msg("Cannot set value key: %s. rc: %d\n", - key_vec[i], rc); - goto err; - } - } - -err: - if (key_vec != NULL) - free(key_vec); - return rc; -} - -static int -read_bootenv(const char* file, bootenv_t env) -{ - int rc = 0; - FILE* fp_in = NULL; - - fp_in = fopen(file, "rb"); - if (fp_in == NULL) { - err_msg("Cannot open file: %s\n", file); - return -EIO; - } - - rc = bootenv_read(fp_in, env, BOOTENV_MAXSIZE); - if (rc != 0) { - err_msg("Cannot read bootenv from file %s. rc: %d\n", - file, rc); - goto err; - } - -err: - fclose(fp_in); - return rc; -} - -/* - * Read bootenv from ubi volume - */ -static int -ubi_read_bootenv(uint32_t devno, uint32_t id, bootenv_t env) -{ - libubi_t ulib; - int rc = 0; - char path[PATH_MAX]; - FILE* fp_in = NULL; - - ulib = libubi_open(); - if (ulib == NULL) { - err_msg("Cannot allocate ubi structure\n"); - return -1; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - fp_in = fopen(path, "r"); - if (fp_in == NULL) { - err_msg("Cannot open volume:%d number:%d\n", devno, id); - goto err; - } - - rc = bootenv_read(fp_in, env, BOOTENV_MAXSIZE); - if (rc != 0) { - err_msg("Cannot read volume:%d number:%d\n", devno, id); - goto err; - } - -err: - if (fp_in) - fclose(fp_in); - libubi_close(ulib); - return rc; -} - -static int -write_bootenv(const char* file, bootenv_t env) -{ - int rc = 0; - FILE* fp_out; - - fp_out = fopen(file, "wb"); - if (fp_out == NULL) { - err_msg("Cannot open file: %s\n", file); - return -EIO; - } - - rc = bootenv_write(fp_out, env); - if (rc != 0) { - err_msg("Cannot write bootenv to file %s. rc: %d\n", file, rc); - goto err; - } - -err: - fclose(fp_out); - return rc; -} - -/* - * Read bootenv from ubi volume - */ -static int -ubi_write_bootenv(uint32_t devno, uint32_t id, bootenv_t env) -{ - libubi_t ulib; - int rc = 0; - char path[PATH_MAX]; - FILE* fp_out = NULL; - size_t nbytes; - - rc = bootenv_size(env, &nbytes); - if (rc) { - err_msg("Cannot determine size of bootenv structure\n"); - return rc; - } - ulib = libubi_open(); - if (ulib == NULL) { - err_msg("Cannot allocate ubi structure\n"); - return rc; - } - - snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id); - - fp_out = fopen(path, "r+"); - if (fp_out == NULL) { - err_msg("Cannot fopen volume:%d number:%d\n", devno, id); - rc = -EBADF; - goto err; - } - - rc = ubi_update_start(ulib, fileno(fp_out), nbytes); - if (rc != 0) { - err_msg("Cannot start update for %s\n", path); - goto err; - } - - rc = bootenv_write(fp_out, env); - if (rc != 0) { - err_msg("Cannot write bootenv to volume %d number:%d\n", - devno, id); - goto err; - } -err: - if( fp_out ) - fclose(fp_out); - libubi_close(ulib); - return rc; -} - -static int -do_mirror(int volno) -{ - char errbuf[1024]; - uint32_t ids[2]; - int rc; - int src_volno_idx = 0; - - ids[0] = EXAMPLE_BOOTENV_VOL_ID_1; - ids[1] = EXAMPLE_BOOTENV_VOL_ID_2; - - if (volno == EXAMPLE_BOOTENV_VOL_ID_2) - src_volno_idx = 1; - - rc = ubimirror(EXAMPLE_UBI_DEVICE, src_volno_idx, ids, 2, errbuf, - sizeof errbuf); - if( rc ) - err_msg(errbuf); - return rc; -} - -int -main(int argc, char **argv) { - int rc = 0; - bootenv_t env = NULL; - uint32_t boot_volno; - myargs args = { - .action = ACT_NORMAL, - .file_in = NULL, - .file_out = NULL, - .side = -1, - .x86 = 0, - .both = 0, - .env_in = NULL, - - .arg1 = NULL, - .options = NULL, - }; - - rc = bootenv_create(&env); - if (rc != 0) { - err_msg("Cannot create bootenv handle. rc: %d", rc); - goto err; - } - - rc = bootenv_create(&(args.env_in)); - if (rc != 0) { - err_msg("Cannot create bootenv handle. rc: %d", rc); - goto err; - } - - parse_opt(argc, argv, &args); - if (args.action == ACT_ARGP_ERR) { - rc = -1; - goto err; - } - if (args.action == ACT_ARGP_ABORT) { - rc = 0; - goto out; - } - - if ((args.side == 0) || (args.side == -1)) - boot_volno = EXAMPLE_BOOTENV_VOL_ID_1; - else - boot_volno = EXAMPLE_BOOTENV_VOL_ID_2; - - if( args.x86 ) - rc = read_bootenv(args.file_in, env); - else - rc = ubi_read_bootenv(EXAMPLE_UBI_DEVICE, boot_volno, env); - if (rc != 0) { - goto err; - } - - if (args.action == ACT_LIST) { - rc = list_bootenv(env); - if (rc != 0) { - goto err; - } - goto out; - } - - rc = process_key_value(args.env_in, env); - if (rc != 0) { - goto err; - } - - if( args.x86 ) - rc = write_bootenv(args.file_in, env); - else - rc = ubi_write_bootenv(EXAMPLE_UBI_DEVICE, boot_volno, env); - if (rc != 0) - goto err; - - if( args.both ) /* No side specified, update both */ - rc = do_mirror(boot_volno); - - out: - err: - bootenv_destroy(&env); - bootenv_destroy(&(args.env_in)); - return rc; -} diff --git a/ubi-utils/old-utils/src/peb.c b/ubi-utils/old-utils/src/peb.c deleted file mode 100644 index 08b770f..0000000 --- a/ubi-utils/old-utils/src/peb.c +++ /dev/null @@ -1,116 +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. - */ - -#include -#include -#include -#include -#include -#include - -#include "peb.h" - -int -peb_cmp(peb_t eb_1, peb_t eb_2) -{ - assert(eb_1); - assert(eb_2); - - return eb_1->num == eb_2->num ? 0 - : eb_1->num > eb_2->num ? 1 : -1; -} - -int -peb_new(uint32_t eb_num, uint32_t eb_size, peb_t *peb) -{ - int rc = 0; - - peb_t res = (peb_t) malloc(sizeof(struct peb)); - if (!res) { - rc = -ENOMEM; - goto err; - } - - res->num = eb_num; - res->size = eb_size; - res->data = (uint8_t*) malloc(res->size * sizeof(uint8_t)); - if (!res->data) { - rc = -ENOMEM; - goto err; - } - memset(res->data, 0xff, res->size); - - *peb = res; - return 0; -err: - if (res) { - if (res->data) - free(res->data); - free(res); - } - *peb = NULL; - return rc; -} - -int -peb_fill(peb_t peb, uint8_t* buf, size_t buf_size) -{ - if (!peb) - return -EINVAL; - - if (buf_size > peb->size) - return -EINVAL; - - memcpy(peb->data, buf, buf_size); - return 0; -} - -int -peb_write(FILE* fp_out, peb_t peb) -{ - size_t written = 0; - - if (peb == NULL) - return -EINVAL; - - written = fwrite(peb->data, 1, peb->size, fp_out); - - if (written != peb->size) - return -EIO; - - return 0; -} - -int -peb_free(peb_t* peb) -{ - peb_t tmp = *peb; - if (tmp) { - if (tmp->data) - free(tmp->data); - free(tmp); - } - *peb = NULL; - - return 0; -} - -void peb_dump(FILE* fp_out, peb_t peb) -{ - fprintf(fp_out, "num: %08d\tsize: 0x%08x\n", peb->num, peb->size); -} diff --git a/ubi-utils/old-utils/src/peb.h b/ubi-utils/old-utils/src/peb.h deleted file mode 100644 index 246bce8..0000000 --- a/ubi-utils/old-utils/src/peb.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __RAW_BLOCK_H__ -#define __RAW_BLOCK_H__ -/* - * 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. - * - * Author: Oliver Lohmann - */ - -#include -#include - -typedef struct peb *peb_t; -struct peb { - uint32_t num; /* Physical eraseblock number - * in the RAW file. */ - uint32_t size; /* Data Size (equals physical - * erase block size) */ - uint8_t* data; /* Data buffer */ -}; - -int peb_new(uint32_t peb_num, uint32_t peb_size, peb_t* peb); -int peb_free(peb_t* peb); -int peb_cmp(peb_t peb_1, peb_t peb_2); -int peb_write(FILE* fp_out, peb_t peb); -void peb_dump(FILE* fp_out, peb_t peb); - -#endif /* __RAW_BLOCK_H__ */ diff --git a/ubi-utils/old-utils/src/pfi.c b/ubi-utils/old-utils/src/pfi.c deleted file mode 100644 index fa835e2..0000000 --- a/ubi-utils/old-utils/src/pfi.c +++ /dev/null @@ -1,458 +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. - */ - -/* - * @file pfi.c - * - * @author Oliver Lohmann - * Andreas Arnez - * Joern Engel - * Frank Haverkamp - * - * @brief libpfi holds all code to create and process pfi files. - * - * Wed Feb 8 11:38:22 CET 2006: Initial creation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pfi.h" - -#define PFI_MAGIC "PFI!\n" -#define PFI_DATA "DATA\n" /* The same size as PFI_MAGIC */ -#define PFI_MAGIC_LEN 5 - -static const char copyright [] __attribute__((unused)) = - "Copyright (c) International Business Machines Corp., 2006"; - -enum key_id { - /* version 1 */ - key_version, /* must be index position 0! */ - key_mode, - key_size, - key_crc, - key_label, - key_flags, - key_ubi_ids, - key_ubi_size, - key_ubi_type, - key_ubi_names, - key_ubi_alignment, - key_raw_starts, - key_raw_total_size, - num_keys, -}; - -struct pfi_header { - char defined[num_keys]; /* reserve all possible keys even if - version does not require this. */ - int mode_no; /* current mode no. -> can only increase */ - union { - char *str; - uint32_t num; - } value[num_keys]; -}; - - -#define PFI_MANDATORY 0x0001 -#define PFI_STRING 0x0002 -#define PFI_LISTVALUE 0x0004 /* comma seperated list of nums */ -#define PFI_MANDATORY_UBI 0x0008 -#define PFI_MANDATORY_RAW 0x0010 - -struct key_descriptor { - enum key_id id; - const char *name; - uint32_t flags; -}; - -static const struct key_descriptor key_desc_v1[] = { - { key_version, "version", PFI_MANDATORY }, - { key_mode, "mode", PFI_MANDATORY | PFI_STRING }, - { key_size, "size", PFI_MANDATORY }, - { key_crc, "crc", PFI_MANDATORY }, - { key_label, "label", PFI_MANDATORY | PFI_STRING }, - { key_flags, "flags", PFI_MANDATORY }, - { key_ubi_ids, "ubi_ids", PFI_MANDATORY_UBI | PFI_STRING }, - { key_ubi_size, "ubi_size", PFI_MANDATORY_UBI }, - { key_ubi_type, "ubi_type", PFI_MANDATORY_UBI | PFI_STRING }, - { key_ubi_names, "ubi_names", PFI_MANDATORY_UBI | PFI_STRING }, - { key_ubi_alignment, "ubi_alignment", PFI_MANDATORY_UBI }, - { key_raw_starts, "raw_starts", PFI_MANDATORY_RAW | PFI_STRING }, - { key_raw_total_size, "raw_total_size", PFI_MANDATORY_RAW }, -}; - -static const struct key_descriptor *key_descriptors[] = { - NULL, - key_desc_v1, /* version 1 */ -}; - -static const int key_descriptors_max[] = { - 0, /* version 0 */ - sizeof(key_desc_v1)/sizeof(struct key_descriptor), /* version 1 */ -}; - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -static const char* modes[] = {"raw", "ubi"}; /* order isn't arbitrary! */ - -/* latest version contains all possible keys */ -static const struct key_descriptor *key_desc = key_desc_v1; - -#define PFI_IS_UBI(mode) \ - (((mode) != NULL) && (strcmp("ubi", (mode)) == 0)) - -#define PFI_IS_RAW(mode) \ - (((mode) != NULL) && (strcmp("raw", (mode)) == 0)) - -/** - * @return <0 On Error. - * >=0 Mode no. - */ -static int -get_mode_no(const char* mode) -{ - int i; - - for (i = 0; i < (int)ARRAY_SIZE(modes); i++) - if (strcmp(mode, modes[i]) == 0) - return i; - return -1; -} - -static int -find_key_by_name (const char *name) -{ - int i; - - for (i = 0; i < num_keys; i++) { - if (strcmp(name, key_desc[i].name) == 0) - return i; - } - return -1; -} - -static int -check_valid (pfi_header head) -{ - int i; - int max_keys; - uint32_t version; - const char *mode; - const struct key_descriptor *desc; - uint32_t to_check = PFI_MANDATORY; - - /* - * For the validity check the list of possible keys depends on - * the version of the PFI file used. - */ - version = head->value[key_version].num; - if (version > PFI_HDRVERSION) - return PFI_ENOHEADER; - - max_keys = key_descriptors_max[version]; - desc = key_descriptors[version]; - - if (!desc) - return PFI_ENOVERSION; - - mode = head->value[key_mode].str; - if (PFI_IS_UBI(mode)) { - to_check |= PFI_MANDATORY_UBI; - } - else if (PFI_IS_RAW(mode)) { - to_check |= PFI_MANDATORY_RAW; - } - else { /* neither UBI nor RAW == ERR */ - return PFI_EINSUFF; - } - - for (i = 0; i < max_keys; i++) { - if ((desc[i].flags & to_check) && !head->defined[i]) { - fprintf(stderr, "libpfi: %s missing\n", desc[i].name); - return PFI_EINSUFF; - } - } - - return 0; -} - -int pfi_header_init (pfi_header *head) -{ - int i; - pfi_header self = (pfi_header) malloc(sizeof(*self)); - - *head = self; - if (self == NULL) - return PFI_ENOMEM; - - /* initialize maximum number of possible keys */ - for (i = 0; i < num_keys; i++) { - memset(self, 0, sizeof(*self)); - self->defined[i] = 0; - } - - return 0; -} - -int pfi_header_destroy (pfi_header *head) -{ - int i; - pfi_header self = *head; - - for (i = 0; i < num_keys; i++) { - if (self->defined[i] && (key_desc[i].flags & PFI_STRING) && - self->value[i].str) { - free(self->value[i].str); - } - } - free(*head); - *head = NULL; - return 0; -} - -int pfi_header_setnumber (pfi_header head, - const char *key, uint32_t value) -{ - int key_id = find_key_by_name(key); - - if (key_id < 0) - return PFI_EUNDEF; - - if (key_desc[key_id].flags & PFI_STRING) - return PFI_EBADTYPE; - - head->value[key_id].num = value; - head->defined[key_id] = 1; - return 0; -} - -int pfi_header_setvalue (pfi_header head, - const char *key, const char *value) -{ - int key_id = find_key_by_name(key); - - if (value == NULL) - return PFI_EINSUFF; - - if ((key_id < 0) || (key_id >= num_keys)) - return PFI_EUNDEF; - - if (key_desc[key_id].flags & PFI_STRING) { - /* - * The value is a string. Copy to a newly allocated - * buffer. Delete the old value, if already set. - */ - size_t len = strlen(value) + 1; - char *old_str = NULL; - char *str; - - old_str = head->value[key_id].str; - if (old_str != NULL) - free(old_str); - - str = head->value[key_id].str = (char *) malloc(len); - if (str == NULL) - return PFI_ENOMEM; - - strcpy(str, value); - } else { - int len; - int ret; - /* FIXME: here we assume that the value is always - given in hex and starts with '0x'. */ - ret = sscanf(value, "0x%x%n", &head->value[key_id].num, &len); - if (ret < 1 || value[len] != '\0') - return PFI_EBADTYPE; - } - head->defined[key_id] = 1; - return 0; -} - -int pfi_header_getnumber (pfi_header head, - const char *key, uint32_t *value) -{ - int key_id = find_key_by_name(key); - - if (key_id < 0) - return PFI_EUNDEF; - - if (key_desc[key_id].flags & PFI_STRING) - return PFI_EBADTYPE; - - if (!head->defined[key_id]) - return PFI_EUNDEF; - - *value = head->value[key_id].num; - return 0; -} - -int pfi_header_getstring (pfi_header head, - const char *key, char *value, size_t size) -{ - int key_id = find_key_by_name(key); - - if (key_id < 0) - return PFI_EUNDEF; - - if (!(key_desc[key_id].flags & PFI_STRING)) - return PFI_EBADTYPE; - - if (!head->defined[key_id]) - return PFI_EUNDEF; - - strncpy(value, head->value[key_id].str, size-1); - value[size-1] = '\0'; - return 0; -} - -int pfi_header_write (FILE *out, pfi_header head) -{ - int i; - int ret; - - pfi_header_setnumber(head, "version", PFI_HDRVERSION); - - if ((ret = check_valid(head)) != 0) - return ret; - - /* OK. Now write the header. */ - - ret = fwrite(PFI_MAGIC, 1, PFI_MAGIC_LEN, out); - if (ret < PFI_MAGIC_LEN) - return ret; - - - for (i = 0; i < num_keys; i++) { - if (!head->defined[i]) - continue; - - ret = fprintf(out, "%s=", key_desc[i].name); - if (ret < 0) - return PFI_EFILE; - - if (key_desc[i].flags & PFI_STRING) { - ret = fprintf(out, "%s", head->value[i].str); - if (ret < 0) - return PFI_EFILE; - } else { - ret = fprintf(out, "0x%8x", head->value[i].num); - if (ret < 0) - return PFI_EFILE; - - } - ret = fprintf(out, "\n"); - if (ret < 0) - return PFI_EFILE; - } - ret = fprintf(out, "\n"); - if (ret < 0) - return PFI_EFILE; - - ret = fflush(out); - if (ret != 0) - return PFI_EFILE; - - return 0; -} - -int pfi_header_read (FILE *in, pfi_header head) -{ - char magic[PFI_MAGIC_LEN]; - char mode[PFI_KEYWORD_LEN]; - char buf[256]; - - if (PFI_MAGIC_LEN != fread(magic, 1, PFI_MAGIC_LEN, in)) - return PFI_EFILE; - if (memcmp(magic, PFI_MAGIC, PFI_MAGIC_LEN) != 0) { - if (memcmp(magic, PFI_DATA, PFI_MAGIC_LEN) == 0) { - return PFI_DATA_START; - } - return PFI_ENOHEADER; - } - - while (fgets(buf, sizeof(buf), in) != NULL && buf[0] != '\n') { - char *value; - char *end; - value = strchr(buf, '='); - if (value == NULL) - return PFI_ENOHEADER; - - *value = '\0'; - value++; - end = strchr(value, '\n'); - if (end) - *end = '\0'; - - if (pfi_header_setvalue(head, buf, value)) - return PFI_ENOHEADER; - } - - if (check_valid(head) != 0) - return PFI_ENOHEADER; - - /* set current mode no. in head */ - pfi_header_getstring(head, "mode", mode, PFI_KEYWORD_LEN); - if (head->mode_no > get_mode_no(mode)) { - return PFI_EMODE; - } - head->mode_no = get_mode_no(mode); - return 0; -} - -int pfi_header_dump (FILE *out, pfi_header head __attribute__((__unused__))) -{ - fprintf(out, "Sorry not implemented yet. Write mail to " - "Andreas Arnez and complain!\n"); - return 0; -} - -int pfi_read (FILE *in, pfi_read_func func, void *priv_data) -{ - int rc; - pfi_header header; - - rc = pfi_header_init (&header); - if (0 != rc) - return rc; - if (!func) - return PFI_EINVAL; - - while ((0 == rc) && !feof(in)) { - /* - * Read header and check consistency of the fields. - */ - rc = pfi_header_read( in, header ); - if (0 != rc) - break; - if (func) { - rc = func(in, header, priv_data); - if (rc != 0) - break; - } - } - - pfi_header_destroy(&header); - return rc; -} diff --git a/ubi-utils/old-utils/src/pfi.h b/ubi-utils/old-utils/src/pfi.h deleted file mode 100644 index 8c5cc07..0000000 --- a/ubi-utils/old-utils/src/pfi.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef __pfi_h -#define __pfi_h -/* - * 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. - */ - -/** - * @file pfi.h - * - * @author Oliver Lohmann - * Andreas Arnez - * Joern Engel - * Frank Haverkamp - * - * @brief libpfi will hold all code to create and process pfi - * images. Definitions made in this file are equaly usable for the - * development host and the target system. - * - * @note This header additionally holds the official definitions for - * the pfi headers. - */ - -#include /* FILE */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Definitions. */ - -#define PFI_HDRVERSION 1 /* current header version */ - -#define PFI_ENOVERSION 1 /* unknown version */ -#define PFI_ENOHEADER 2 /* not a pfi header */ -#define PFI_EINSUFF 3 /* insufficient information */ -#define PFI_EUNDEF 4 /* key not defined */ -#define PFI_ENOMEM 5 /* out of memory */ -#define PFI_EBADTYPE 6 /* bad data type */ -#define PFI_EFILE 7 /* file I/O error: see errno */ -#define PFI_EFILEINVAL 8 /* file format not valid */ -#define PFI_EINVAL 9 /* invalid parameter */ -#define PFI_ERANGE 10 /* invalid range */ -#define PFI_EMODE 11 /* expecting other mode in this header */ -#define PFI_DATA_START 12 /* data section starts */ -#define PFI_EMAX 13 /* should be always larger as the largest - error code */ - -#define PFI_LABEL_LEN 64 /* This is the maximum length for a - PFI header label */ -#define PFI_KEYWORD_LEN 32 /* This is the maximum length for an - entry in the mode and type fields */ - -#define PFI_UBI_MAX_VOLUMES 128 -#define PFI_UBI_VOL_NAME_LEN 127 - -/** - * @brief The pfi header allows to set flags which influence the flashing - * behaviour. - */ -#define PFI_FLAG_PROTECTED 0x00000001 - - -/** - * @brief Handle to pfi header. Used in most of the functions associated - * with pfi file handling. - */ -typedef struct pfi_header *pfi_header; - - -/** - * @brief Initialize a pfi header object. - * - * @param head Pointer to handle. This function allocates memory - * for this data structure. - * @return 0 on success, otherwise: - * PFI_ENOMEM : no memory available for the handle. - */ -int pfi_header_init (pfi_header *head); - - -/** - * @brief Destroy a pfi header object. - * - * @param head handle. head is invalid after calling this function. - * @return 0 always. - */ -int pfi_header_destroy (pfi_header *head); - - -/** - * @brief Add a key/value pair to a pfi header object. - * - * @param head handle. - * @param key pointer to key string. Must be 0 terminated. - * @param value pointer to value string. Must be 0 terminated. - * @return 0 on success, otherwise: - * PFI_EUNDEF : key was not found. - * PFI_ENOMEM : no memory available for the handle. - * PFI_EBADTYPE : value is not an hex string. This happens - * when the key stores an integer and the - * new value is not convertable e.g. not in - * 0xXXXXXXXX format. - */ -int pfi_header_setvalue (pfi_header head, - const char *key, const char *value); - - -/** - * @brief Add a key/value pair to a pfi header object. Provide the - * value as a number. - * - * @param head handle. - * @param key pointer to key string. Must be 0 terminated. - * @param value value to set. - * @return 0 on success, otherwise: - * PFI_EUNDEF : key was not found. - * PFI_EBADTYPE : value is not a string. This happens - * when the key stores a string. - */ -int pfi_header_setnumber (pfi_header head, - const char *key, uint32_t value); - - -/** - * @brief For a given key, return the numerical value stored in a - * pfi header object. - * - * @param head handle. - * @param key pointer to key string. Must be 0 terminated. - * @param value pointer to value. - * @return 0 on success, otherwise: - * PFI_EUNDEF : key was not found. - * PFI_EBADTYPE : stored value is not an integer but a string. - */ -int pfi_header_getnumber (pfi_header head, - const char *key, uint32_t *value); - - -static inline uint32_t -pfi_getnumber(pfi_header head, const char *key) -{ - uint32_t value; - pfi_header_getnumber(head, key, &value); - return value; -} - -/** - * @brief For a given key, return the string value stored in a pfi - * header object. - * - * @param head handle. - * @param key pointer to key string. Must be 0 terminated. - * @param value pointer to value string. Memory must be allocated by the user. - * @return 0 on success, otherwise: - * PFI_EUNDEF : key was not found. - * PFI_EBADTYPE : stored value is not a string but an integer. - */ -int pfi_header_getstring (pfi_header head, - const char *key, char *value, size_t size); - - -/** - * @brief Write a pfi header object into a given file. - * - * @param out output stream. - * @param head handle. - * @return 0 on success, error values otherwise: - * PFI_EINSUFF : not all mandatory fields are filled. - * PFI_ENOHEADER : wrong header version or magic number. - * -E* : see . - */ -int pfi_header_write (FILE *out, pfi_header head); - - -/** - * @brief Read a pfi header object from a given file. - * - * @param in input stream. - * @param head handle. - * @return 0 on success, error values otherwise: - * PFI_ENOVERSION: unknown header version. - * PFI_EFILE : cannot read enough data. - * PFI_ENOHEADER : wrong header version or magic number. - * -E* : see . - * - * If the header verification returned success the user can assume that - * all mandatory fields for a particular version are accessible. Checking - * the return code when calling the get-function for those keys is not - * required in those cases. For optional fields the checking must still be - * done. - */ -int pfi_header_read (FILE *in, pfi_header head); - - -/** - * @brief Display a pfi header in human-readable form. - * - * @param out output stream. - * @param head handle. - * @return always 0. - * - * @note Prints out that it is not implemented and whom you should - * contact if you need it urgently!. - */ -int pfi_header_dump (FILE *out, pfi_header head); - - -/* - * @brief Iterates over a stream of pfi files. The iterator function - * must advance the file pointer in FILE *in to the next pfi - * header. Function exists on feof(in). - * - * @param in input file descriptor, must be open and valid. - * @param func iterator function called when pfi header could be - * read and was validated. The function must return 0 on - * success. - * @return See pfi_header_init and pfi_header_read. - * PFI_EINVAL : func is not valid - * 0 ok. - */ -typedef int (* pfi_read_func)(FILE *in, pfi_header hdr, void *priv_data); - -int pfi_read (FILE *in, pfi_read_func func, void *priv_data); - - -#ifdef __cplusplus -} -#endif - -#endif /* __pfi_h */ diff --git a/ubi-utils/old-utils/src/pfi2bin.c b/ubi-utils/old-utils/src/pfi2bin.c deleted file mode 100644 index 34ecc92..0000000 --- a/ubi-utils/old-utils/src/pfi2bin.c +++ /dev/null @@ -1,682 +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. - * - * Author: Oliver Lohmann - * - * Convert a PFI file (partial flash image) into a plain binary file. - * This tool can be used to prepare the data to be burned into flash - * chips in a manufacturing step where the flashes are written before - * being soldered onto the hardware. For NAND images another step is - * required to add the right OOB data to the binary image. - * - * 1.3 Removed argp because we want to use uClibc. - * 1.4 Minor cleanups - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "config.h" -#include "list.h" -#include "error.h" -#include "reader.h" -#include "peb.h" -#include "crc32.h" - -#define PROGRAM_VERSION "1.4" - -#define MAX_FNAME 255 -#define DEFAULT_ERASE_COUNT 0 /* Hmmm.... Perhaps */ -#define ERR_BUF_SIZE 1024 - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -static uint32_t crc32_table[256]; -static char err_buf[ERR_BUF_SIZE]; - -/* - * Data used to buffer raw blocks which have to be - * located at a specific point inside the generated RAW file - */ - -typedef enum action_t { - ACT_NOTHING = 0x00000000, - ACT_RAW = 0x00000001, -} action_t; - -static const char copyright [] __attribute__((unused)) = - "(c) Copyright IBM Corp 2006\n"; - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "pfi2bin - a tool to convert PFI files into binary images.\n"; - -static const char *optionsstr = -" Common settings:\n" -" -c, --copyright\n" -" -v, --verbose Print more information.\n" -"\n" -" Input:\n" -" -j, --platform=pdd-file PDD information which contains the card settings.\n" -"\n" -" Output:\n" -" -o, --output=filename Outputfile, default: stdout.\n" -"\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: pfi2bin [-cv?V] [-j pdd-file] [-o filename] [--copyright]\n" -" [--verbose] [--platform=pdd-file] [--output=filename] [--help]\n" -" [--usage] [--version] pfifile\n"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "platform", .has_arg = 1, .flag = NULL, .val = 'j' }, - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -typedef struct io { - FILE* fp_pdd; /* a FilePointer to the PDD data */ - FILE* fp_pfi; /* a FilePointer to the PFI input stream */ - FILE* fp_out; /* a FilePointer to the output stream */ -} *io_t; - -typedef struct myargs { - /* common settings */ - action_t action; - int verbose; - const char *f_in_pfi; - const char *f_in_pdd; - const char *f_out; - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -} myargs; - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "cvj:o:?V", long_options, NULL); - if (key == -1) - break; - - switch (key) { - /* common settings */ - case 'v': /* --verbose= */ - args->verbose = 1; - break; - - case 'c': /* --copyright */ - fprintf(stderr, "%s\n", copyright); - exit(0); - break; - - case 'j': /* --platform */ - args->f_in_pdd = optarg; - break; - - case 'o': /* --output */ - args->f_out = optarg; - break; - - case '?': /* help */ - printf("pfi2bin [OPTION...] pfifile\n"); - printf("%s", doc); - printf("%s", optionsstr); - printf("\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - - case 'V': - printf("%s\n", PROGRAM_VERSION); - exit(0); - break; - - default: - printf("%s", usage); - exit(-1); - } - } - - if (optind < argc) - args->f_in_pfi = argv[optind++]; - - return 0; -} - - -static size_t -byte_to_blk(size_t byte, size_t blk_size) -{ - return (byte % blk_size) == 0 - ? byte / blk_size - : byte / blk_size + 1; -} - - - - -/** - * @precondition IO: File stream points to first byte of RAW data. - * @postcondition IO: File stream points to first byte of next - * or EOF. - */ -static int -memorize_raw_eb(pfi_raw_t pfi_raw, pdd_data_t pdd, list_t *raw_pebs, - io_t io) -{ - int rc = 0; - uint32_t i; - - size_t read, to_read, eb_num; - size_t bytes_left; - list_t pebs = *raw_pebs; - peb_t peb = NULL; - - long old_file_pos = ftell(io->fp_pfi); - for (i = 0; i < pfi_raw->starts_size; i++) { - bytes_left = pfi_raw->data_size; - rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET); - if (rc != 0) - goto err; - - eb_num = byte_to_blk(pfi_raw->starts[i], pdd->eb_size); - while (bytes_left) { - to_read = MIN(bytes_left, pdd->eb_size); - rc = peb_new(eb_num++, pdd->eb_size, &peb); - if (rc != 0) - goto err; - read = fread(peb->data, 1, to_read, io->fp_pfi); - if (read != to_read) { - rc = -EIO; - goto err; - } - pebs = append_elem(peb, pebs); - bytes_left -= read; - } - - } - *raw_pebs = pebs; - return 0; -err: - pebs = remove_all((free_func_t)&peb_free, pebs); - return rc; -} - -static int -convert_ubi_volume(pfi_ubi_t ubi, pdd_data_t pdd, list_t raw_pebs, - struct ubi_vtbl_record *vol_tab, - size_t *ebs_written, io_t io) -{ - int rc = 0; - uint32_t i, j; - peb_t raw_peb; - peb_t cmp_peb; - ubi_info_t u; - size_t leb_total = 0; - uint8_t vol_type; - - switch (ubi->type) { - case pfi_ubi_static: - vol_type = UBI_VID_STATIC; break; - case pfi_ubi_dynamic: - vol_type = UBI_VID_DYNAMIC; break; - default: - vol_type = UBI_VID_DYNAMIC; - } - - rc = peb_new(0, 0, &cmp_peb); - if (rc != 0) - goto err; - - long old_file_pos = ftell(io->fp_pfi); - for (i = 0; i < ubi->ids_size; i++) { - rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET); - if (rc != 0) - goto err; - rc = ubigen_create(&u, ubi->ids[i], vol_type, - pdd->eb_size, DEFAULT_ERASE_COUNT, - ubi->alignment, UBI_VERSION, - pdd->vid_hdr_offset, 0, ubi->data_size, - io->fp_pfi, io->fp_out); - if (rc != 0) - goto err; - - rc = ubigen_get_leb_total(u, &leb_total); - if (rc != 0) - goto err; - - j = 0; - while(j < leb_total) { - cmp_peb->num = *ebs_written; - raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb, - raw_pebs); - if (raw_peb) { - rc = peb_write(io->fp_out, raw_peb); - } - else { - rc = ubigen_write_leb(u, NO_ERROR); - j++; - } - if (rc != 0) - goto err; - (*ebs_written)++; - } - /* memorize volume table entry */ - rc = ubigen_set_lvol_rec(u, ubi->size, - ubi->names[i], - (void*) &vol_tab[ubi->ids[i]]); - if (rc != 0) - goto err; - ubigen_destroy(&u); - } - - peb_free(&cmp_peb); - return 0; - -err: - peb_free(&cmp_peb); - ubigen_destroy(&u); - return rc; -} - - -static FILE* -my_fmemopen (void *buf, size_t size, const char *opentype) -{ - FILE* f; - size_t ret; - - assert(strcmp(opentype, "r") == 0); - - f = tmpfile(); - ret = fwrite(buf, 1, size, f); - rewind(f); - - return f; -} - -/** - * @brief Builds a UBI volume table from a volume entry list. - * @return 0 On success. - * else Error. - */ -static int -write_ubi_volume_table(pdd_data_t pdd, list_t raw_pebs, - struct ubi_vtbl_record *vol_tab, size_t vol_tab_size, - size_t *ebs_written, io_t io) -{ - int rc = 0; - ubi_info_t u; - peb_t raw_peb; - peb_t cmp_peb; - size_t leb_size, leb_total, j = 0; - uint8_t *ptr = NULL; - FILE* fp_leb = NULL; - int vt_slots; - size_t vol_tab_size_limit; - - rc = peb_new(0, 0, &cmp_peb); - if (rc != 0) - goto err; - - /* @FIXME: Artem creates one volume with 2 LEBs. - * IMO 2 volumes would be more convenient. In order - * to get 2 reserved LEBs from ubigen, I have to - * introduce this stupid mechanism. Until no final - * decision of the VTAB structure is made... Good enough. - */ - rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC, - pdd->eb_size, DEFAULT_ERASE_COUNT, - 1, UBI_VERSION, - pdd->vid_hdr_offset, UBI_COMPAT_REJECT, - vol_tab_size, stdin, io->fp_out); - /* @FIXME stdin for fp_in is a hack */ - if (rc != 0) - goto err; - rc = ubigen_get_leb_size(u, &leb_size); - if (rc != 0) - goto err; - ubigen_destroy(&u); - - /* - * The number of supported volumes is restricted by the eraseblock size - * and by the UBI_MAX_VOLUMES constant. - */ - vt_slots = leb_size / UBI_VTBL_RECORD_SIZE; - if (vt_slots > UBI_MAX_VOLUMES) - vt_slots = UBI_MAX_VOLUMES; - vol_tab_size_limit = vt_slots * UBI_VTBL_RECORD_SIZE; - - ptr = (uint8_t*) malloc(leb_size * sizeof(uint8_t)); - if (ptr == NULL) - goto err; - - memset(ptr, 0xff, leb_size); - memcpy(ptr, vol_tab, vol_tab_size_limit); - fp_leb = my_fmemopen(ptr, leb_size, "r"); - - rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC, - pdd->eb_size, DEFAULT_ERASE_COUNT, - 1, UBI_VERSION, pdd->vid_hdr_offset, - UBI_COMPAT_REJECT, leb_size * UBI_LAYOUT_VOLUME_EBS, - fp_leb, io->fp_out); - if (rc != 0) - goto err; - rc = ubigen_get_leb_total(u, &leb_total); - if (rc != 0) - goto err; - - long old_file_pos = ftell(fp_leb); - while(j < leb_total) { - rc = fseek(fp_leb, old_file_pos, SEEK_SET); - if (rc != 0) - goto err; - - cmp_peb->num = *ebs_written; - raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb, - raw_pebs); - if (raw_peb) { - rc = peb_write(io->fp_out, raw_peb); - } - else { - rc = ubigen_write_leb(u, NO_ERROR); - j++; - } - - if (rc != 0) - goto err; - (*ebs_written)++; - } - -err: - free(ptr); - peb_free(&cmp_peb); - ubigen_destroy(&u); - fclose(fp_leb); - return rc; -} - -static int -write_remaining_raw_ebs(pdd_data_t pdd, list_t raw_blocks, size_t *ebs_written, - FILE* fp_out) -{ - int rc = 0; - uint32_t j, delta; - list_t ptr; - peb_t empty_eb, peb; - - /* create an empty 0xff EB (for padding) */ - rc = peb_new(0, pdd->eb_size, &empty_eb); - - foreach(peb, ptr, raw_blocks) { - if (peb->num < *ebs_written) { - continue; /* omit blocks which - are already passed */ - } - - if (peb->num < *ebs_written) { - err_msg("eb_num: %d\n", peb->num); - err_msg("Bug: This should never happen. %d %s", - __LINE__, __FILE__); - goto err; - } - - delta = peb->num - *ebs_written; - if (((delta + *ebs_written) * pdd->eb_size) > pdd->flash_size) { - err_msg("RAW block outside of flash_size."); - goto err; - } - for (j = 0; j < delta; j++) { - rc = peb_write(fp_out, empty_eb); - if (rc != 0) - goto err; - (*ebs_written)++; - } - rc = peb_write(fp_out, peb); - if (rc != 0) - goto err; - (*ebs_written)++; - } - -err: - peb_free(&empty_eb); - return rc; -} - -static int -init_vol_tab(struct ubi_vtbl_record **vol_tab, size_t *vol_tab_size) -{ - uint32_t crc; - size_t i; - struct ubi_vtbl_record* res = NULL; - - *vol_tab_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE; - - res = (struct ubi_vtbl_record*) calloc(1, *vol_tab_size); - if (vol_tab == NULL) { - return -ENOMEM; - } - - for (i = 0; i < UBI_MAX_VOLUMES; i++) { - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, - &(res[i]), UBI_VTBL_RECORD_SIZE_CRC); - res[i].crc = cpu_to_be32(crc); - } - - *vol_tab = res; - return 0; -} - -static int -create_raw(io_t io) -{ - int rc = 0; - size_t ebs_written = 0; /* eraseblocks written already... */ - size_t vol_tab_size; - list_t ptr; - - list_t pfi_raws = mk_empty(); /* list of raw sections from a pfi */ - list_t pfi_ubis = mk_empty(); /* list of ubi sections from a pfi */ - list_t raw_pebs = mk_empty(); /* list of raw eraseblocks */ - - struct ubi_vtbl_record *vol_tab = NULL; - pdd_data_t pdd = NULL; - - rc = init_vol_tab (&vol_tab, &vol_tab_size); - if (rc != 0) { - err_msg("Cannot initialize volume table."); - goto err; - } - - rc = read_pdd_data(io->fp_pdd, &pdd, - err_buf, ERR_BUF_SIZE); - if (rc != 0) { - err_msg("Cannot read necessary pdd_data: %s rc: %d", - err_buf, rc); - goto err; - } - - rc = read_pfi_headers(&pfi_raws, &pfi_ubis, io->fp_pfi, - err_buf, ERR_BUF_SIZE); - if (rc != 0) { - err_msg("Cannot read pfi header: %s rc: %d", - err_buf, rc); - goto err; - } - - pfi_raw_t pfi_raw; - foreach(pfi_raw, ptr, pfi_raws) { - rc = memorize_raw_eb(pfi_raw, pdd, &raw_pebs, - io); - if (rc != 0) { - err_msg("Cannot create raw_block in mem. rc: %d\n", - rc); - goto err; - } - } - - pfi_ubi_t pfi_ubi; - foreach(pfi_ubi, ptr, pfi_ubis) { - rc = convert_ubi_volume(pfi_ubi, pdd, raw_pebs, - vol_tab, &ebs_written, io); - if (rc != 0) { - err_msg("Cannot convert UBI volume. rc: %d\n", rc); - goto err; - } - } - - rc = write_ubi_volume_table(pdd, raw_pebs, vol_tab, vol_tab_size, - &ebs_written, io); - if (rc != 0) { - err_msg("Cannot write UBI volume table. rc: %d\n", rc); - goto err; - } - - rc = write_remaining_raw_ebs(pdd, raw_pebs, &ebs_written, io->fp_out); - if (rc != 0) - goto err; - - if (io->fp_out != stdout) - info_msg("Physical eraseblocks written: %8d\n", ebs_written); -err: - free(vol_tab); - pfi_raws = remove_all((free_func_t)&free_pfi_raw, pfi_raws); - pfi_ubis = remove_all((free_func_t)&free_pfi_ubi, pfi_ubis); - raw_pebs = remove_all((free_func_t)&peb_free, raw_pebs); - free_pdd_data(&pdd); - return rc; -} - - -/* ------------------------------------------------------------------------- */ -static void -open_io_handle(myargs *args, io_t io) -{ - /* set PDD input */ - io->fp_pdd = fopen(args->f_in_pdd, "r"); - if (io->fp_pdd == NULL) { - err_sys("Cannot open: %s", args->f_in_pdd); - } - - /* set PFI input */ - io->fp_pfi = fopen(args->f_in_pfi, "r"); - if (io->fp_pfi == NULL) { - err_sys("Cannot open PFI input file: %s", args->f_in_pfi); - } - - /* set output prefix */ - if (strcmp(args->f_out,"") == 0) - io->fp_out = stdout; - else { - io->fp_out = fopen(args->f_out, "wb"); - if (io->fp_out == NULL) { - err_sys("Cannot open output file: %s", args->f_out); - } - } -} - -static void -close_io_handle(io_t io) -{ - if (fclose(io->fp_pdd) != 0) { - err_sys("Cannot close PDD file."); - } - if (fclose(io->fp_pfi) != 0) { - err_sys("Cannot close PFI file."); - } - if (io->fp_out != stdout) { - if (fclose(io->fp_out) != 0) { - err_sys("Cannot close output file."); - } - } - - io->fp_pdd = NULL; - io->fp_pfi = NULL; - io->fp_out = NULL; -} - -int -main(int argc, char *argv[]) -{ - int rc = 0; - - ubigen_init(); - init_crc32_table(crc32_table); - - struct io io = {NULL, NULL, NULL}; - myargs args = { - .action = ACT_RAW, - .verbose = 0, - - .f_in_pfi = "", - .f_in_pdd = "", - .f_out = "", - - /* arguments */ - .arg1 = NULL, - .options = NULL, - }; - - /* parse arguments */ - parse_opt(argc, argv, &args); - - if (strcmp(args.f_in_pfi, "") == 0) { - err_quit("No PFI input file specified!"); - } - - if (strcmp(args.f_in_pdd, "") == 0) { - err_quit("No PDD input file specified!"); - } - - open_io_handle(&args, &io); - - info_msg("[ Creating RAW..."); - rc = create_raw(&io); - if (rc != 0) { - err_msg("Creating RAW failed."); - goto err; - } - -err: - close_io_handle(&io); - if (rc != 0) { - remove(args.f_out); - } - - return rc; -} diff --git a/ubi-utils/old-utils/src/pfiflash.c b/ubi-utils/old-utils/src/pfiflash.c deleted file mode 100644 index 754fe33..0000000 --- a/ubi-utils/old-utils/src/pfiflash.c +++ /dev/null @@ -1,264 +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. - * - * Author: Oliver Lohmann - * Frank Haverkamp - * - * Process a PFI (partial flash image) and write the data to the - * specified UBI volumes. This tool is intended to be used for system - * update using PFI files. - * - * 1.1 fixed output to stderr and stdout in logfile mode. - * 1.2 updated. - * 1.3 removed argp parsing to be able to use uClib. - * 1.4 Minor cleanups. - * 1.5 Forgot to delete raw block before updating it. - * 1.6 Migrated to new libubi. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#undef DEBUG -#include "error.h" -#include "config.h" - -#define PROGRAM_VERSION "1.6" - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "pfiflash - a tool for updating a controller with PFI files.\n"; - -static const char *optionsstr = -" Standard options:\n" -" -c, --copyright Print copyright information.\n" -" -l, --logfile= Write a logfile to .\n" -" -v, --verbose Be verbose during program execution.\n" -"\n" -" Process options:\n" -" -C, --complete Execute a complete system update. Updates both\n" -" sides.\n" -" -p, --pdd-update= Specify the pdd-update algorithm. is either\n" -" 'keep', 'merge' or 'overwrite'.\n" -" -r, --raw-flash= Flash the raw data. Use the specified mtd device.\n" -" -s, --side= Select the side which shall be updated.\n" -" -x, --compare Only compare on-flash and pfi data, print info if\n" -" an update is neccessary and return appropriate\n" -" error code.\n" -"\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: pfiflash [-cvC?V] [-l ] [-p ] [-r ] [-s ]\n" -" [--copyright] [--logfile=] [--verbose] [--complete]\n" -" [--pdd-update=] [--raw-flash=] [--side=]\n" -" [--compare] [--help] [--usage] [--version] [pfifile]\n"; - -static const char copyright [] __attribute__((unused)) = - "Copyright IBM Corp 2006"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "logfile", .has_arg = 1, .flag = NULL, .val = 'l' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "complete", .has_arg = 0, .flag = NULL, .val = 'C' }, - { .name = "pdd-update", .has_arg = 1, .flag = NULL, .val = 'p' }, - { .name = "raw-flash", .has_arg = 1, .flag = NULL, .val = 'r' }, - { .name = "side", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "compare", .has_arg = 0, .flag = NULL, .val = 'x' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -typedef struct myargs { - int verbose; - const char *logfile; - const char *raw_dev; - - pdd_handling_t pdd_handling; - int seqnum; - int compare; - int complete; - - FILE* fp_in; - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -} myargs; - -static pdd_handling_t -get_pdd_handling(const char* str) -{ - if (strcmp(str, "keep") == 0) { - return PDD_KEEP; - } - if (strcmp(str, "merge") == 0) { - return PDD_MERGE; - } - if (strcmp(str, "overwrite") == 0) { - return PDD_OVERWRITE; - } - - return -1; -} - -static int -get_update_seqnum(const char* str) -{ - uint32_t i = strtoul(str, NULL, 0); - - if ((i != 0) && (i != 1)) { - return -1; - } - - return i; -} - - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "cl:vCp:r:s:x?V", - long_options, NULL); - if (key == -1) - break; - - switch (key) { - /* standard options */ - case 'c': - err_msg("%s\n", copyright); - exit(0); - break; - case 'v': - args->verbose = 1; - break; - case 'l': - args->logfile = optarg; - break; - /* process options */ - case 'C': - args->complete = 1; - break; - case 'p': - args->pdd_handling = get_pdd_handling(optarg); - if ((int)args->pdd_handling < 0) { - err_quit("Unknown PDD handling: %s.\n" - "Please use either " - "'keep', 'merge' or" - "'overwrite'.\n'"); - } - break; - case 's': - args->seqnum = get_update_seqnum(optarg); - if (args->seqnum < 0) { - err_quit("Unsupported side: %s.\n" - "Supported sides are '0' " - "and '1'\n", optarg); - } - break; - case 'x': - args->compare = 1; - break; - case 'r': - args->raw_dev = optarg; - break; - case '?': /* help */ - err_msg("Usage: pfiflash [OPTION...] [pfifile]"); - err_msg("%s", doc); - err_msg("%s", optionsstr); - err_msg("\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - case 'V': - err_msg("%s", PROGRAM_VERSION); - exit(0); - break; - default: - err_msg("%s", usage); - exit(-1); - - } - } - - if (optind < argc) { - args->fp_in = fopen(argv[optind++], "r"); - if ((args->fp_in) == NULL) { - err_sys("Cannot open PFI file %s for input", - argv[optind]); - } - } - - return 0; -} - -int main (int argc, char** argv) -{ - int rc = 0; - char err_buf[PFIFLASH_MAX_ERR_BUF_SIZE]; - memset(err_buf, '\0', PFIFLASH_MAX_ERR_BUF_SIZE); - - myargs args = { - .verbose = 0, - .seqnum = -1, - .compare = 0, - .complete = 0, - .logfile = NULL, /* "/tmp/pfiflash.log", */ - .pdd_handling = PDD_KEEP, - .fp_in = stdin, - .raw_dev = NULL, - }; - - parse_opt(argc, argv, &args); - error_initlog(args.logfile); - - if (!args.fp_in) { - rc = -1; - snprintf(err_buf, PFIFLASH_MAX_ERR_BUF_SIZE, - "No PFI input file specified!\n"); - goto err; - } - - rc = pfiflash_with_options(args.fp_in, args.complete, args.seqnum, - args.compare, args.pdd_handling, args.raw_dev, err_buf, - PFIFLASH_MAX_ERR_BUF_SIZE); - if (rc < 0) { - goto err_fp; - } - - err_fp: - if (args.fp_in != stdin) - fclose(args.fp_in); - err: - if (rc != 0) - err_msg("pfiflash: %s\nrc: %d\n", err_buf, rc); - return rc; -} diff --git a/ubi-utils/old-utils/src/pfiflash.h b/ubi-utils/old-utils/src/pfiflash.h deleted file mode 100644 index 039705d..0000000 --- a/ubi-utils/old-utils/src/pfiflash.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef __PFIFLASH_H__ -#define __PFIFLASH_H__ -/* - * 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. - */ - -/** - * - * @file pfi.h - * - * @author Oliver Lohmann - * - * @brief The pfiflash library offers an interface for using the - * pfiflash * utility. - */ - -#include /* FILE */ - -#define PFIFLASH_MAX_ERR_BUF_SIZE 1024 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum pdd_handling_t -{ - PDD_KEEP = 0, - PDD_MERGE, - PDD_OVERWRITE, - PDD_HANDLING_NUM, /* always the last item */ -} pdd_handling_t; /**< Possible PDD handle algorithms. */ - -/** - * @brief Flashes a PFI file to UBI Device 0. - * @param complete [0|1] Do a complete system update. - * @param seqnum Index in a redundant group. - * @param compare [0|1] Compare contents. - * @param pdd_handling The PDD handling algorithm. - * @param rawdev Device to use for raw flashing - * @param err_buf An error buffer. - * @param err_buf_size Size of the error buffer. - */ -int pfiflash_with_options(FILE* pfi, int complete, int seqnum, int compare, - pdd_handling_t pdd_handling, const char* rawdev, - char *err_buf, size_t err_buf_size); - -/** - * @brief Flashes a PFI file to UBI Device 0. - * @param complete [0|1] Do a complete system update. - * @param seqnum Index in a redundant group. - * @param pdd_handling The PDD handling algorithm. - * @param err_buf An error buffer. - * @param err_buf_size Size of the error buffer. - */ -int pfiflash(FILE* pfi, int complete, int seqnum, pdd_handling_t pdd_handling, - char *err_buf, size_t err_buf_size); - -#ifdef __cplusplus -} -#endif - -#endif /* __PFIFLASH_H__ */ diff --git a/ubi-utils/old-utils/src/pfiflash_error.h b/ubi-utils/old-utils/src/pfiflash_error.h deleted file mode 100644 index 0f27f4a..0000000 --- a/ubi-utils/old-utils/src/pfiflash_error.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __PFIFLASH_ERROR_H__ -#define __PFIFLASH_ERROR_H__ -/* - * 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. - */ - -/* - * Author: Drake Dowsett - * Contact: Andreas Arnez - */ - -enum pfiflash_err { - PFIFLASH_ERR_EOF = 1, - PFIFLASH_ERR_FIO, - PFIFLASH_ERR_UBI_OPEN, - PFIFLASH_ERR_UBI_CLOSE, - PFIFLASH_ERR_UBI_MKVOL, - PFIFLASH_ERR_UBI_RMVOL, - PFIFLASH_ERR_UBI_VOL_UPDATE, - PFIFLASH_ERR_UBI_VOL_FOPEN, - PFIFLASH_ERR_UBI_UNKNOWN, - PFIFLASH_ERR_UBI_VID_OOB, - PFIFLASH_ERR_BOOTENV_CREATE, - PFIFLASH_ERR_BOOTENV_READ, - PFIFLASH_ERR_BOOTENV_SIZE, - PFIFLASH_ERR_BOOTENV_WRITE, - PFIFLASH_ERR_PDD_UNKNOWN, - PFIFLASH_ERR_MTD_OPEN, - PFIFLASH_ERR_MTD_CLOSE, - PFIFLASH_ERR_CRC_CHECK, - PFIFLASH_ERR_MTD_ERASE, - PFIFLASH_ERR_COMPARE, - PFIFLASH_CMP_DIFF -}; - -const char *const PFIFLASH_ERRSTR[] = { - "", - "unexpected EOF", - "file I/O error", - "couldn't open UBI", - "couldn't close UBI", - "couldn't make UBI volume %d", - "couldn't remove UBI volume %d", - "couldn't update UBI volume %d", - "couldn't open UBI volume %d", - "unknown UBI operation", - "PFI data contains out of bounds UBI id %d", - "couldn't create bootenv%s", - "couldn't read bootenv", - "couldn't resize bootenv", - "couldn't write bootenv on ubi%d_%d", - "unknown PDD handling algorithm", - "couldn't open MTD device %s", - "couldn't close MTD device %s", - "CRC check failed: given=0x%08x, calculated=0x%08x", - "couldn't erase raw mtd region", - "couldn't compare volumes", - "on-flash data differ from pfi data, update is neccessary" -}; - -#endif /* __PFIFLASH_ERROR_H__ */ diff --git a/ubi-utils/old-utils/src/reader.c b/ubi-utils/old-utils/src/reader.c deleted file mode 100644 index 0ea8c6d..0000000 --- a/ubi-utils/old-utils/src/reader.c +++ /dev/null @@ -1,482 +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. - * - * Author: Oliver Lohmann - * - * Read in PFI (partial flash image) data and store it into internal - * data structures for further processing. Take also care about - * special handling if the data contains PDD (platform description - * data/boot-parameters). - */ - -#include -#include -#include -#include -#include - -#include "bootenv.h" -#include "reader.h" - -#define __unused __attribute__((unused)) - -/* @FIXME hard coded offsets right now - get them from Artem? */ -#define NAND2048_DEFAULT_VID_HDR_OFF 1984 -#define NAND512_DEFAULT_VID_HDR_OFF 448 -#define NOR_DEFAULT_VID_HDR_OFF 64 - -#define EBUF_PFI(fmt...) \ - do { int i = snprintf(err_buf, err_buf_size, "%s\n", label); \ - snprintf(err_buf + i, err_buf_size - i, fmt); \ - } while (0) - -#define EBUF(fmt...) \ - do { snprintf(err_buf, err_buf_size, fmt); } while (0) - - -int -read_pdd_data(FILE* fp_pdd, pdd_data_t* pdd_data, - char* err_buf, size_t err_buf_size) -{ - int rc = 0; - bootenv_t pdd = NULL; - pdd_data_t res = NULL; - const char* value; - - res = (pdd_data_t) malloc(sizeof(struct pdd_data)); - if (!res) { - rc = -ENOMEM; - goto err; - } - rc = bootenv_create(&pdd); - if (rc != 0) { - goto err; - } - rc = bootenv_read_txt(fp_pdd, pdd); - if (rc != 0) { - goto err; - } - rc = bootenv_get(pdd, "flash_type", &value); - if (rc != 0) { - goto err; - } - - if (strcmp(value, "NAND") == 0) { - - rc = bootenv_get_num(pdd, "flash_page_size", - &(res->flash_page_size)); - if (rc != 0) { - EBUF("Cannot read 'flash_page_size' from pdd."); - goto err; - } - res->flash_type = NAND_FLASH; - - switch (res->flash_page_size) { - case 512: - res->vid_hdr_offset = NAND512_DEFAULT_VID_HDR_OFF; - break; - case 2048: - res->vid_hdr_offset = NAND2048_DEFAULT_VID_HDR_OFF; - break; - default: - EBUF("Unsupported 'flash_page_size' %d.", - res->flash_page_size); - goto err; - } - } - else if (strcmp(value, "NOR") == 0){ - res->flash_type = NOR_FLASH; - res->vid_hdr_offset = NOR_DEFAULT_VID_HDR_OFF; - } - else { - snprintf(err_buf, err_buf_size, - "Unkown flash type: %s", value); - goto err; - } - - rc = bootenv_get_num(pdd, "flash_eraseblock_size", - &(res->eb_size)); - if (rc != 0) { - EBUF("Cannot read 'flash_eraseblock_size' from pdd."); - goto err; - } - - rc = bootenv_get_num(pdd, "flash_size", - &(res->flash_size)); - if (rc != 0) { - EBUF("Cannot read 'flash_size' from pdd."); - goto err; - } - - goto out; - err: - if (res) { - free(res); - res = NULL; - } - out: - bootenv_destroy(&pdd); - *pdd_data = res; - return rc; -} - -int -read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw, - const char* label, char* err_buf, size_t err_buf_size) -{ - int rc = 0; - char tmp_str[PFI_KEYWORD_LEN]; - bootenv_list_t raw_start_list = NULL; - pfi_raw_t res; - size_t size; - - res = (pfi_raw_t) malloc(sizeof(struct pfi_raw)); - if (!res) - return -ENOMEM; - - rc = pfi_header_getnumber(pfi_hd, "size", &(res->data_size)); - if (rc != 0) { - EBUF_PFI("Cannot read 'size' from PFI."); - goto err; - } - - rc = pfi_header_getnumber(pfi_hd, "crc", &(res->crc)); - if (rc != 0) { - EBUF_PFI("Cannot read 'crc' from PFI."); - goto err; - } - - rc = pfi_header_getstring(pfi_hd, "raw_starts", - tmp_str, PFI_KEYWORD_LEN); - if (rc != 0) { - EBUF_PFI("Cannot read 'raw_starts' from PFI."); - goto err; - } - - rc = bootenv_list_create(&raw_start_list); - if (rc != 0) { - goto err; - } - - rc = bootenv_list_import(raw_start_list, tmp_str); - if (rc != 0) { - EBUF_PFI("Cannot translate PFI value: %s", tmp_str); - goto err; - } - - rc = bootenv_list_to_num_vector(raw_start_list, - &size, &(res->starts)); - res->starts_size = size; - - if (rc != 0) { - EBUF_PFI("Cannot create numeric value array: %s", tmp_str); - goto err; - } - - goto out; - - err: - if (res) { - free(res); - res = NULL; - } - out: - bootenv_list_destroy(&raw_start_list); - *pfi_raw = res; - return rc; -} - -int -read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, - const char *label, char* err_buf, size_t err_buf_size) -{ - int rc = 0; - const char** tmp_names = NULL; - char tmp_str[PFI_KEYWORD_LEN]; - bootenv_list_t ubi_id_list = NULL; - bootenv_list_t ubi_name_list = NULL; - pfi_ubi_t res; - uint32_t i; - size_t size; - - res = (pfi_ubi_t) calloc(1, sizeof(struct pfi_ubi)); - if (!res) - return -ENOMEM; - - rc = pfi_header_getnumber(pfi_hd, "size", &(res->data_size)); - if (rc != 0) { - EBUF_PFI("Cannot read 'size' from PFI."); - goto err; - } - - rc = pfi_header_getnumber(pfi_hd, "crc", &(res->crc)); - if (rc != 0) { - EBUF_PFI("Cannot read 'crc' from PFI."); - goto err; - } - - rc = pfi_header_getstring(pfi_hd, "ubi_ids", tmp_str, PFI_KEYWORD_LEN); - if (rc != 0) { - EBUF_PFI("Cannot read 'ubi_ids' from PFI."); - goto err; - } - - rc = bootenv_list_create(&ubi_id_list); - if (rc != 0) { - goto err; - } - rc = bootenv_list_create(&ubi_name_list); - if (rc != 0) { - goto err; - } - - rc = bootenv_list_import(ubi_id_list, tmp_str); - if (rc != 0) { - EBUF_PFI("Cannot translate PFI value: %s", tmp_str); - goto err; - } - - rc = bootenv_list_to_num_vector(ubi_id_list, &size, - &(res->ids)); - res->ids_size = size; - if (rc != 0) { - EBUF_PFI("Cannot create numeric value array: %s", tmp_str); - goto err; - } - - if (res->ids_size == 0) { - rc = -1; - EBUF_PFI("Sanity check failed: No ubi_ids specified."); - goto err; - } - - rc = pfi_header_getstring(pfi_hd, "ubi_type", - tmp_str, PFI_KEYWORD_LEN); - if (rc != 0) { - EBUF_PFI("Cannot read 'ubi_type' from PFI."); - goto err; - } - if (strcmp(tmp_str, "static") == 0) - res->type = pfi_ubi_static; - else if (strcmp(tmp_str, "dynamic") == 0) - res->type = pfi_ubi_dynamic; - else { - EBUF_PFI("Unknown ubi_type in PFI."); - goto err; - } - - rc = pfi_header_getnumber(pfi_hd, "ubi_alignment", &(res->alignment)); - if (rc != 0) { - EBUF_PFI("Cannot read 'ubi_alignment' from PFI."); - goto err; - } - - rc = pfi_header_getnumber(pfi_hd, "ubi_size", &(res->size)); - if (rc != 0) { - EBUF_PFI("Cannot read 'ubi_size' from PFI."); - goto err; - } - - rc = pfi_header_getstring(pfi_hd, "ubi_names", - tmp_str, PFI_KEYWORD_LEN); - if (rc != 0) { - EBUF_PFI("Cannot read 'ubi_names' from PFI."); - goto err; - } - - rc = bootenv_list_import(ubi_name_list, tmp_str); - if (rc != 0) { - EBUF_PFI("Cannot translate PFI value: %s", tmp_str); - goto err; - } - rc = bootenv_list_to_vector(ubi_name_list, &size, - &(tmp_names)); - res->names_size = size; - if (rc != 0) { - EBUF_PFI("Cannot create string array: %s", tmp_str); - goto err; - } - - if (res->names_size != res->ids_size) { - EBUF_PFI("Sanity check failed: ubi_ids list does not match " - "sizeof ubi_names list."); - rc = -1; - } - - /* copy tmp_names to own structure */ - res->names = (char**) calloc(1, res->names_size * sizeof (char*)); - if (res->names == NULL) - goto err; - - for (i = 0; i < res->names_size; i++) { - res->names[i] = calloc(PFI_UBI_VOL_NAME_LEN + 1, sizeof(char)); - if (res->names[i] == NULL) - goto err; - strncpy(res->names[i], tmp_names[i], PFI_UBI_VOL_NAME_LEN + 1); - } - - goto out; - - err: - if (res) { - if (res->names) { - for (i = 0; i < res->names_size; i++) { - if (res->names[i]) { - free(res->names[i]); - } - } - free(res->names); - } - if (res->ids) { - free(res->ids); - } - free(res); - res = NULL; - } - - out: - bootenv_list_destroy(&ubi_id_list); - bootenv_list_destroy(&ubi_name_list); - if (tmp_names != NULL) - free(tmp_names); - *pfi_ubi = res; - return rc; -} - - -int -free_pdd_data(pdd_data_t* pdd_data) -{ - if (*pdd_data) { - free(*pdd_data); - } - *pdd_data = NULL; - - return 0; -} - -int -free_pfi_raw(pfi_raw_t* pfi_raw) -{ - pfi_raw_t tmp = *pfi_raw; - if (tmp) { - if (tmp->starts) - free(tmp->starts); - free(tmp); - } - *pfi_raw = NULL; - - return 0; -} - -int -free_pfi_ubi(pfi_ubi_t* pfi_ubi) -{ - size_t i; - pfi_ubi_t tmp = *pfi_ubi; - if (tmp) { - if (tmp->ids) - free(tmp->ids); - if (tmp->names) { - for (i = 0; i < tmp->names_size; i++) { - if (tmp->names[i]) { - free(tmp->names[i]); - } - } - free(tmp->names); - } - free(tmp); - } - *pfi_ubi = NULL; - - return 0; -} - - -int -read_pfi_headers(list_t *pfi_raws, list_t *pfi_ubis, FILE* fp_pfi, - char* err_buf, size_t err_buf_size) -{ - int rc = 0; - char mode[PFI_KEYWORD_LEN]; - char label[PFI_LABEL_LEN]; - - *pfi_raws = mk_empty(); pfi_raw_t raw = NULL; - *pfi_ubis = mk_empty(); pfi_ubi_t ubi = NULL; - pfi_header pfi_header = NULL; - - /* read all headers from PFI and store them in lists */ - rc = pfi_header_init(&pfi_header); - if (rc != 0) { - EBUF("Cannot initialize pfi header."); - goto err; - } - while ((rc == 0) && !feof(fp_pfi)) { - rc = pfi_header_read(fp_pfi, pfi_header); - if (rc != 0) { - if (rc == PFI_DATA_START) { - rc = 0; - break; /* data section starts, - all headers read */ - } - else { - goto err; - } - } - rc = pfi_header_getstring(pfi_header, "label", label, - PFI_LABEL_LEN); - if (rc != 0) { - EBUF("Cannot read 'label' from PFI."); - goto err; - } - rc = pfi_header_getstring(pfi_header, "mode", mode, - PFI_KEYWORD_LEN); - if (rc != 0) { - EBUF("Cannot read 'mode' from PFI."); - goto err; - } - if (strcmp(mode, "ubi") == 0) { - rc = read_pfi_ubi(pfi_header, fp_pfi, &ubi, label, - err_buf, err_buf_size); - if (rc != 0) { - goto err; - } - *pfi_ubis = append_elem(ubi, *pfi_ubis); - } - else if (strcmp(mode, "raw") == 0) { - rc = read_pfi_raw(pfi_header, fp_pfi, &raw, label, - err_buf, err_buf_size); - if (rc != 0) { - goto err; - } - *pfi_raws = append_elem(raw, *pfi_raws); - } - else { - EBUF("Recvieved unknown mode from PFI: %s", mode); - goto err; - } - } - goto out; - - err: - *pfi_raws = remove_all((free_func_t)&free_pfi_raw, *pfi_raws); - *pfi_ubis = remove_all((free_func_t)&free_pfi_ubi, *pfi_ubis); - out: - pfi_header_destroy(&pfi_header); - return rc; - -} diff --git a/ubi-utils/old-utils/src/reader.h b/ubi-utils/old-utils/src/reader.h deleted file mode 100644 index 715e464..0000000 --- a/ubi-utils/old-utils/src/reader.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef __READER_H__ -#define __READER_H__ -/* - * 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. - * - * Author: Oliver Lohmann - * - * Read Platform Description Data (PDD). - */ - -#include -#include - -#include "pfi.h" -#include "bootenv.h" -#include "list.h" - -typedef enum flash_type_t { - NAND_FLASH = 0, - NOR_FLASH, -} flash_type_t; - -typedef struct pdd_data *pdd_data_t; -typedef struct pfi_raw *pfi_raw_t; -typedef struct pfi_ubi *pfi_ubi_t; - -struct pdd_data { - uint32_t flash_size; - uint32_t flash_page_size; - uint32_t eb_size; - uint32_t vid_hdr_offset; - flash_type_t flash_type; -}; - -struct pfi_raw { - uint32_t data_size; - uint32_t *starts; - uint32_t starts_size; - uint32_t crc; -}; - -struct pfi_ubi { - uint32_t data_size; - uint32_t alignment; - uint32_t *ids; - uint32_t ids_size; - char **names; - uint32_t names_size; - uint32_t size; - enum { pfi_ubi_dynamic, pfi_ubi_static } type; - int curr_seqnum; /* specifies the seqnum taken in an update, - default: 0 (used by pfiflash, ubimirror) */ - uint32_t crc; -}; - -int read_pdd_data(FILE* fp_pdd, pdd_data_t *pdd_data, - char *err_buf, size_t err_buf_size); -int read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi, pfi_raw_t *pfi_raw, - const char *label, char *err_buf, size_t err_buf_size); -int read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi, pfi_ubi_t *pfi_ubi, - const char *label, char *err_buf, size_t err_buf_size); - -/** - * @brief Reads all pfi headers into list structures, separated by - * RAW and UBI sections. - */ -int read_pfi_headers(list_t *pfi_raws, list_t *pfi_ubis, FILE* fp_pfi, - char* err_buf, size_t err_buf_size); -int free_pdd_data(pdd_data_t *pdd_data); -int free_pfi_raw(pfi_raw_t *raw_pfi); -int free_pfi_ubi(pfi_ubi_t *pfi_ubi); - -#endif /* __READER_H__ */ diff --git a/ubi-utils/old-utils/src/ubigen.c b/ubi-utils/old-utils/src/ubigen.c deleted file mode 100644 index bb55fa9..0000000 --- a/ubi-utils/old-utils/src/ubigen.c +++ /dev/null @@ -1,359 +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. - * - * Author: Oliver Lohmann - * - * Tool to add UBI headers to binary images. - * - * 1.0 Initial version - * 1.1 Different CRC32 start value - * 1.2 Removed argp because we want to use uClibc. - * 1.3 Minor cleanups - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ubigen.h" -#include "config.h" - -#define PROGRAM_VERSION "1.3" - -typedef enum action_t { - ACT_NORMAL = 0x00000001, - ACT_BROKEN_UPDATE = 0x00000002, -} action_t; - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "ubigen - a tool for adding UBI information to a binary input file.\n"; - -static const char *optionsstr = -" Common settings:\n" -" -c, --copyright Print copyright information.\n" -" -d, --debug\n" -" -v, --verbose Print more progress information.\n" -"\n" -" UBI Settings:\n" -" -A, --alignment= Set the alignment size to (default 1).\n" -" Values can be specified as bytes, 'ki' or 'Mi'.\n" -" -B, --blocksize= Set the eraseblock size to (default 128\n" -" KiB).\n" -" Values can be specified as bytes, 'ki' or 'Mi'.\n" -" -E, --erasecount= Set the erase count to (default 0)\n" -" -I, --id= The UBI volume id.\n" -" -O, --offset= Offset from start of an erase block to the UBI\n" -" volume header.\n" -" -T, --type= The UBI volume type:\n" -" 1 = dynamic, 2 = static\n" -" -X, --setver= Set UBI version number to (default 1)\n" -"\n" -" Input/Output:\n" -" -i, --infile= Read input from file.\n" -" -o, --outfile= Write output to file (default is stdout).\n" -"\n" -" Special options:\n" -" -U, --broken-update= Create an ubi image which simulates a broken\n" -" update.\n" -" specifies the logical eraseblock number to\n" -" update.\n" -"\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: ubigen [-cdv?V] [-A ] [-B ] [-E ] [-I ]\n" -" [-O ] [-T ] [-X ] [-i ] [-o ]\n" -" [-U ] [--copyright] [--debug] [--verbose] [--alignment=]\n" -" [--blocksize=] [--erasecount=] [--id=]\n" -" [--offset=] [--type=] [--setver=]\n" -" [--infile=] [--outfile=]\n" -" [--broken-update=] [--help] [--usage] [--version]\n"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "debug", .has_arg = 0, .flag = NULL, .val = 'd' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "alignment", .has_arg = 1, .flag = NULL, .val = 'A' }, - { .name = "blocksize", .has_arg = 1, .flag = NULL, .val = 'B' }, - { .name = "erasecount", .has_arg = 1, .flag = NULL, .val = 'E' }, - { .name = "id", .has_arg = 1, .flag = NULL, .val = 'I' }, - { .name = "offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "type", .has_arg = 1, .flag = NULL, .val = 'T' }, - { .name = "setver", .has_arg = 1, .flag = NULL, .val = 'X' }, - { .name = "infile", .has_arg = 1, .flag = NULL, .val = 'i' }, - { .name = "outfile", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "broken-update", .has_arg = 1, .flag = NULL, .val = 'U' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -static const char copyright [] __attribute__((unused)) = - "Copyright IBM Corp 2006"; - -#define CHECK_ENDP(option, endp) do { \ - if (*endp) { \ - fprintf(stderr, \ - "Parse error option \'%s\'. " \ - "No correct numeric value.\n" \ - , option); \ - exit(EXIT_FAILURE); \ - } \ -} while(0) - -typedef struct myargs { - /* common settings */ - action_t action; - int verbose; - - int32_t id; - uint8_t type; - uint32_t eb_size; - uint64_t ec; - uint8_t version; - uint32_t hdr_offset; - uint32_t update_block; - uint32_t alignment; - - FILE* fp_in; - FILE* fp_out; - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -} myargs; - - -static int ustrtoul(const char *cp, char **endp, unsigned int base) -{ - unsigned long result = strtoul(cp, endp, base); - - switch (**endp) { - case 'G': - result *= 1024; - case 'M': - result *= 1024; - case 'k': - case 'K': - result *= 1024; - /* "Ki", "ki", "Mi" or "Gi" are to be used. */ - if ((*endp)[1] == 'i') - (*endp) += 2; - } - return result; -} - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - int err = 0; - char* endp; - - while (1) { - int key; - - key = getopt_long(argc, argv, "cdvA:B:E:I:O:T:X:i:o:U:?V", - long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'c': - fprintf(stderr, "%s\n", copyright); - exit(0); - break; - case 'o': /* output */ - args->fp_out = fopen(optarg, "wb"); - if ((args->fp_out) == NULL) { - fprintf(stderr, "Cannot open file %s " - "for output\n", optarg); - exit(1); - } - break; - case 'i': /* input */ - args->fp_in = fopen(optarg, "rb"); - if ((args->fp_in) == NULL) { - fprintf(stderr, "Cannot open file %s " - "for input\n", optarg); - exit(1); - } - break; - case 'v': /* verbose */ - args->verbose = 1; - break; - - case 'B': /* eb_size */ - args->eb_size = - (uint32_t)ustrtoul(optarg, &endp, 0); - CHECK_ENDP("B", endp); - break; - case 'E': /* erasecount */ - args->ec = (uint64_t)strtoul(optarg, &endp, 0); - CHECK_ENDP("E", endp); - break; - case 'I': /* id */ - args->id = (uint16_t)strtoul(optarg, &endp, 0); - CHECK_ENDP("I", endp); - break; - case 'T': /* type */ - args->type = - (uint16_t)strtoul(optarg, &endp, 0); - CHECK_ENDP("T", endp); - break; - case 'X': /* versionnr */ - args->version = - (uint8_t)strtoul(optarg, &endp, 0); - CHECK_ENDP("X", endp); - break; - case 'O': /* offset for volume hdr */ - args->hdr_offset = - (uint32_t) strtoul(optarg, &endp, 0); - CHECK_ENDP("O", endp); - break; - - case 'U': /* broken update */ - args->action = ACT_BROKEN_UPDATE; - args->update_block = - (uint32_t) strtoul(optarg, &endp, 0); - CHECK_ENDP("U", endp); - break; - - case '?': /* help */ - fprintf(stderr, "Usage: ubigen [OPTION...]\n"); - fprintf(stderr, "%s", doc); - fprintf(stderr, "%s", optionsstr); - fprintf(stderr, "\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(0); - break; - - default: - fprintf(stderr, "%s", usage); - exit(-1); - } - } - - if (optind < argc) { - if (!args->fp_in) { - args->fp_in = fopen(argv[optind++], "rb"); - if ((args->fp_in) == NULL) { - fprintf(stderr, "Cannot open file %s for " - "input\n", argv[optind]); - exit(1); - } - } - } - if (args->id < 0) { - err = 1; - fprintf(stderr, - "Please specify an UBI Volume ID.\n"); - } - if (args->type == 0) { - err = 1; - fprintf(stderr, - "Please specify an UBI Volume type.\n"); - } - if (err) { - fprintf(stderr, "%s", usage); - exit(1); - } - - return 0; -} - - -int -main(int argc, char **argv) -{ - int rc = 0; - ubi_info_t u; - struct stat file_info; - off_t input_len = 0; /* only used in static volumes */ - - myargs args = { - .action = ACT_NORMAL, - .verbose = 0, - - .id = -1, - .type = 0, - .eb_size = 0, - .update_block = 0, - .ec = 0, - .version = 0, - .hdr_offset = (DEFAULT_PAGESIZE) - (UBI_VID_HDR_SIZE), - .alignment = 1, - - .fp_in = NULL, - .fp_out = stdout, - /* arguments */ - .arg1 = NULL, - .options = NULL, - }; - - ubigen_init(); /* Init CRC32 table in ubigen */ - - /* parse arguments */ - parse_opt(argc, argv, &args); - - if (fstat(fileno(args.fp_in), &file_info) != 0) { - fprintf(stderr, "Cannot fetch file size " - "from input file.\n"); - } - input_len = file_info.st_size; - - rc = ubigen_create(&u, (uint32_t)args.id, args.type, - args.eb_size, args.ec, args.alignment, - args.version, args.hdr_offset, 0 ,input_len, - args.fp_in, args.fp_out); - - if (rc != 0) { - fprintf(stderr, "Cannot create UBI info handler rc: %d\n", rc); - exit(EXIT_FAILURE); - } - - if (!args.fp_in || !args.fp_out) { - fprintf(stderr, "Input/Output error.\n"); - exit(EXIT_FAILURE); - - } - - if (args.action & ACT_NORMAL) { - rc = ubigen_write_complete(u); - } - else if (args.action & ACT_BROKEN_UPDATE) { - rc = ubigen_write_broken_update(u, args.update_block); - } - if (rc != 0) { - fprintf(stderr, "Error converting input data.\n"); - exit(EXIT_FAILURE); - } - - rc = ubigen_destroy(&u); - return rc; -} diff --git a/ubi-utils/old-utils/src/ubigen.h b/ubi-utils/old-utils/src/ubigen.h deleted file mode 100644 index 8d29120..0000000 --- a/ubi-utils/old-utils/src/ubigen.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef __UBIGEN_H__ -#define __UBIGEN_H__ -/* - * 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. - * - * Author: Frank Haverkamp - * - * An utility to update UBI volumes. - */ - -#include /* FILE */ -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define DEFAULT_BLOCKSIZE (128 * 1024) -#define DEFAULT_PAGESIZE (2*1024) - -#define EUBIGEN_INVALID_TYPE 1 -#define EUBIGEN_INVALID_HDR_OFFSET 2 -#define EUBIGEN_INVALID_ALIGNMENT 3 -#define EUBIGEN_TOO_SMALL_EB 4 -#define EUBIGEN_MAX_ERROR 5 - - -typedef enum action { - NO_ERROR = 0x00000000, - BROKEN_HDR_CRC = 0x00000001, - BROKEN_DATA_CRC = 0x00000002, - BROKEN_DATA_SIZE = 0x00000004, - BROKEN_OMIT_BLK = 0x00000008, - MARK_AS_UPDATE = 0x00000010, -} ubigen_action_t; - -typedef struct ubi_info *ubi_info_t; - -/** - * @brief Initialize the internal CRC32 table. - * @note Necessary because of the used crc32 function in UBI. - * A usage of CRC32, from e.g. zlib will fail. - */ -void ubigen_init(void); - -/** - * @brief Create an ubigen handle. - * @param ... - * @return 0 On sucess. - * else Error. - * @note This parameterlist is ugly. But we have to use - * two big structs and meta information internally, - * filling them would be even uglier. - */ -int ubigen_create(ubi_info_t *u, uint32_t vol_id, uint8_t vol_type, - uint32_t eb_size, uint64_t ec, uint32_t alignment, - uint8_t version, uint32_t vid_hdr_offset, - uint8_t compat_flag, size_t data_size, - FILE* fp_in, FILE* fp_out); - -/** - * @brief Destroy an ubigen handle. - * @param u Handle to free. - * @return 0 On success. - * else Error. - */ -int ubigen_destroy(ubi_info_t *u); - -/** - * @brief Get number of total logical EBs, necessary for the - * complete storage of data in the handle. - * @param u The handle. - * @return 0 On success. - * else Error. - */ -int ubigen_get_leb_total(ubi_info_t u, size_t* total); - -/** - * @brief Get the size in bytes of one logical EB in the handle. - * @param u The handle. - * @return 0 On success. - * else Error. - */ -int ubigen_get_leb_size(ubi_info_t u, size_t* size); - - -/** - * @brief Write a logical EB (fits exactly into 1 physical EB). - * @param u Handle which holds all necessary data. - * @param action Additional operations which shall be applied on this - * logical eraseblock. Mostly injecting artifical errors. - * @return 0 On success. - * else Error. - */ -int ubigen_write_leb(ubi_info_t u, ubigen_action_t action); - -/** - * @brief Write a complete array of logical eraseblocks at once. - * @param u Handle which holds all necessary data. - * @return 0 On success. - * else Error. - */ -int ubigen_write_complete(ubi_info_t u); - -/** - * @brief Write a single block which is extracted from the - * binary input data. - * @param u Handle which holds all necessary data. - * @param blk Logical eraseblock which shall hold a inc. copy entry - * and a bad data crc. - * @return 0 On success. - * else Error. - */ -int ubigen_write_broken_update(ubi_info_t u, uint32_t blk); - -/** - * @brief Use the current ubi_info data and some additional data - * to set an UBI volume table entry from it. - * @param u Handle which holds some of the necessary data. - * @param res_bytes Number of reserved bytes which is stored in the volume - * table entry. - * @param name A string which shall be used as a volume label. - * @param lvol_r A pointer to a volume table entry. - * @return 0 On success. - * else Error. - */ -int ubigen_set_lvol_rec(ubi_info_t u, size_t reserved_bytes, - const char* name, struct ubi_vtbl_record *lvol_rec); - -#ifdef __cplusplus -} -#endif - -#endif /* __UBIGEN_H__ */ diff --git a/ubi-utils/old-utils/src/ubimirror.c b/ubi-utils/old-utils/src/ubimirror.c deleted file mode 100644 index da05a8b..0000000 --- a/ubi-utils/old-utils/src/ubimirror.c +++ /dev/null @@ -1,213 +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. - * - * Author: Oliver Lohmann - * - * 1.2 Removed argp because we want to use uClibc. - * 1.3 Minor cleanups - * 1.4 Migrated to new libubi - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "error.h" -#include "example_ubi.h" -#include "ubimirror.h" - -#define PROGRAM_VERSION "1.4" - -typedef enum action_t { - ACT_NORMAL = 0, - ACT_ARGP_ABORT, - ACT_ARGP_ERR, -} action_t; - -#define ABORT_ARGP do { \ - args->action = ACT_ARGP_ABORT; \ -} while (0) - -#define ERR_ARGP do { \ - args->action = ACT_ARGP_ERR; \ -} while (0) - -#define VOL_ARGS_MAX 2 - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "ubimirror - mirrors ubi volumes.\n"; - -static const char *optionsstr = -" -c, --copyright Print copyright information.\n" -" -s, --side= Use the side as source.\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: ubimirror [-c?V] [-s ] [--copyright] [--side=]\n" -" [--help] [--usage] [--version] \n"; - -static const char copyright [] __attribute__((unused)) = - "(C) IBM Coorporation 2007"; - -struct option long_options[] = { - { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' }, - { .name = "side", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -typedef struct myargs { - action_t action; - int side; - int vol_no; /* index of current volume */ - /* @FIXME replace by bootenv_list, makes live easier */ - /* @FIXME remove the constraint of two entries in the array */ - const char* vol[VOL_ARGS_MAX]; /* comma separated list of src/dst - volumes */ - char *arg1; - char **options; /* [STRING...] */ -} myargs; - -static int -get_update_side(const char* str) -{ - uint32_t i = strtoul(str, NULL, 0); - - if ((i != 0) && (i != 1)) { - return -1; - } - return i; -} - - -static int -parse_opt(int argc, char **argv, myargs *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "cs:?V", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'c': - err_msg("%s", copyright); - ABORT_ARGP; - break; - case 's': - args->side = get_update_side(optarg); - if (args->side < 0) { - err_msg("Unsupported seqnum: %s.\n" - "Supported seqnums are '0' " - "and '1'\n", optarg); - ERR_ARGP; - } - break; - case '?': /* help */ - err_msg("Usage: ubimirror [OPTION...] " - " \n"); - err_msg("%s", doc); - err_msg("%s", optionsstr); - err_msg("\nReport bugs to %s\n", - PACKAGE_BUGREPORT); - exit(0); - break; - case 'V': - err_msg("%s", PROGRAM_VERSION); - exit(0); - break; - default: - err_msg("%s", usage); - exit(-1); - } - } - - while (optind < argc) { - /* only two entries allowed */ - if (args->vol_no >= VOL_ARGS_MAX) { - err_msg("%s", usage); - ERR_ARGP; - } - args->vol[(args->vol_no)++] = argv[optind++]; - } - - return 0; -} - - -int -main(int argc, char **argv) { - int rc = 0; - unsigned int ids[VOL_ARGS_MAX]; - char err_buf[1024]; - - myargs args = { - .action = ACT_NORMAL, - .side = -1, - .vol_no = 0, - .vol = {"", ""}, - .options = NULL, - }; - - parse_opt(argc, argv, &args); - if (args.action == ACT_ARGP_ERR) { - rc = 127; - goto err; - } - if (args.action == ACT_ARGP_ABORT) { - rc = 126; - goto out; - } - if (args.vol_no < VOL_ARGS_MAX) { - fprintf(stderr, "missing volume number for %s\n", - args.vol_no == 0 ? "source and target" : "target"); - rc = 125; - goto out; - } - for( rc = 0; rc < args.vol_no; ++rc){ - char *endp; - ids[rc] = strtoul(args.vol[rc], &endp, 0); - if( *endp != '\0' ){ - fprintf(stderr, "invalid volume number %s\n", - args.vol[rc]); - rc = 125; - goto out; - } - } - rc = ubimirror(EXAMPLE_UBI_DEVICE, args.side, ids, args.vol_no, - err_buf, sizeof(err_buf)); - if( rc ){ - err_buf[sizeof err_buf - 1] = '\0'; - fprintf(stderr, "%s", err_buf); - if( rc < 0 ) - rc = -rc; - } - out: - err: - return rc; -} diff --git a/ubi-utils/old-utils/src/ubimirror.h b/ubi-utils/old-utils/src/ubimirror.h deleted file mode 100644 index d7ae2ad..0000000 --- a/ubi-utils/old-utils/src/ubimirror.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __UBIMIRROR_H__ -#define __UBIMIRROR_H__ -/* - * 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. - * - * Author: Oliver Lohmann - * - * An utility to mirror UBI volumes. - */ - -#include - -/** - * @def EUBIMIRROR_SRC_EQ_DST - * @brief Given source volume is also in the set of destination volumes. - */ -#define EUBIMIRROR_SRC_EQ_DST 20 - -/** - * @def EUBIMIRROR_NO_SRC - * @brief The given source volume does not exist. - */ -#define EUBIMIRROR_NO_SRC 21 - -/** - * @def EUBIMIRROR_NO_DST - * @brief One of the given destination volumes does not exist. - */ -#define EUBIMIRROR_NO_DST 22 - -/** - * @brief Mirrors UBI devices from a source device (specified by seqnum) - * to n target devices. - * @param devno Device number used by the UBI operations. - * @param seqnum An index into ids (defines the src_id). - * @param ids An array of ids. - * @param ids_size The number of entries in the ids array. - * @param err_buf A buffer to store verbose error messages. - * @param err_buf_size The size of the error buffer. - * - * @note A seqnum of value < 0 defaults to a seqnum of 0. - * @note A seqnum exceeding the range of ids_size defaults to 0. - * @note An empty ids list results in a empty stmt. - * @pre The UBI volume which shall be used as source volume exists. - * @pre The UBI volumes which are defined as destination volumes exist. - * @post The content of the UBI volume which was defined as source volume - * equals the content of the volumes which were defined as destination. - */ -int ubimirror(uint32_t devno, int seqnum, uint32_t* ids, ssize_t ids_size, - char *err_buf, size_t err_buf_size); - -#endif /* __UBIMIRROR_H__ */ diff --git a/ubi-utils/old-utils/src/unubi.c b/ubi-utils/old-utils/src/unubi.c deleted file mode 100644 index 0f72b18..0000000 --- a/ubi-utils/old-utils/src/unubi.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * 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. - */ - -/* - * Authors: Drake Dowsett, dowsett@de.ibm.com - * Frank Haverkamp, haver@vnet.ibm.com - * - * 1.2 Removed argp because we want to use uClibc. - * 1.3 Minor cleanups. - * 1.4 Meanwhile Drake had done a lot of changes, syncing those. - * 1.5 Bugfixes, simplifications - */ - -/* - * unubi reads an image file containing blocks of UBI headers and data - * (such as produced from nand2bin) and rebuilds the volumes within. The - * default operation (when no flags are given) is to rebuild all valid - * volumes found in the image. unubi can also read straight from the - * onboard MTD device (ex. /dev/mtdblock/NAND). - */ - -/* TODO: consideration for dynamic vs. static volumes */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "crc32.h" -#include "unubi_analyze.h" - -#define EXEC "unubi" -#define CONTACT "haver@vnet.ibm.com" -#define VERSION "1.5" - -static char doc[] = "\nVersion: " VERSION "\n"; -static int debug = 0; - -static const char *optionsstr = -"Extract volumes and/or analysis information from an UBI data file.\n" -"When no parameters are flagged or given, the default operation is\n" -"to rebuild all valid complete UBI volumes found within the image.\n" -"\n" -" OPERATIONS\n" -" -a, --analyze Analyze image and create gnuplot graphs\n" -" -i, --info-table Extract volume information tables\n" -" -r, --rebuild= Extract and rebuild volume\n" -"\n" -" OPTIONS\n" -" -b, --blocksize= Specify size of eraseblocks in image in bytes\n" -" (default 128KiB)\n" -" -d, --dir= Specify output directory\n" -" -D, --debug Enable debug output\n" -" -s, --headersize= Specify size reserved for metadata in eraseblock\n" - " in bytes (default 2048 Byte)\n" - /* the -s option might be insufficient when using different vid - offset than what we used when writing this tool ... Better would - probably be --vid-hdr-offset or alike */ -"\n" -" ADVANCED\n" -" -e, --eb-split Generate individual eraseblock images (all\n" -" eraseblocks)\n" -" -v, --vol-split Generate individual eraseblock images (valid\n" -" eraseblocks only)\n" -" -V, --vol-split! Raw split by eraseblock (valid eraseblocks only)\n" -"\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" --version Print program version\n" -"\n"; - -static const char *usage = -"Usage: unubi [-aievV?] [-r ] [-b ] [-d ]\n" -" [-s ] [--analyze] [--info-table]\n" -" [--rebuild=] [--blocksize=]\n" -" [--dir=] [--headersize=] [--eb-split]\n" -" [--vol-split] [--vol-split!] [--help] [--usage] [--version]\n" -" image-file\n"; - -#define ERR_MSG(fmt...) \ - fprintf(stderr, EXEC ": " fmt) - -#define SPLIT_DATA 1 -#define SPLIT_RAW 2 - -#define DIR_FMT "unubi_%s" -#define KIB 1024 -#define MIB (KIB * KIB) -#define MAXPATH KIB - -/* filenames */ -#define FN_INVAL "%s/eb%04u%s" /* invalid eraseblock */ -#define FN_NSURE "%s/eb%04u_%03u_%03u_%03x%s" /* unsure eraseblock */ -#define FN_VALID "%s/eb%04u_%03u_%03u_%03x%s" /* valid eraseblock */ -#define FN_VOLSP "%s/vol%03u_%03u_%03u_%04zu" /* split volume */ -#define FN_VOLWH "%s/volume%03u" /* whole volume */ -#define FN_VITBL "%s/vol_info_table%zu" /* vol info table */ - -static uint32_t crc32_table[256]; - -/* struct args: - * bsize int, blocksize of image blocks - * hsize int, eraseblock header size - * analyze flag, when non-zero produce analysis - * eb_split flag, when non-zero output eb#### - * note: SPLIT_DATA vs. SPLIT_RAW - * vol_split flag, when non-zero output vol###_#### - * note: SPLIT_DATA vs. SPLIT_RAW - * odir_path string, directory to place volumes in - * img_path string, file to read as ubi image - * vols int array of size UBI_MAX_VOLUMES, where a 1 can be - * written for each --rebuild flag in the index specified - * then the array can be counted and collapsed using - * count_set() and collapse() - */ -struct args { - int analyze; - int itable; - uint32_t *vols; - - size_t vid_hdr_offset; - size_t data_offset; - size_t bsize; /* FIXME replace by vid_hdr/data offs? */ - size_t hsize; - - char *odir_path; - int eb_split; - int vol_split; - char *img_path; - - char **options; -}; - -struct option long_options[] = { - { .name = "rebuild", .has_arg = 1, .flag = NULL, .val = 'r' }, - { .name = "dir", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "analyze", .has_arg = 0, .flag = NULL, .val = 'a' }, - { .name = "blocksize", .has_arg = 1, .flag = NULL, .val = 'b' }, - { .name = "eb-split", .has_arg = 0, .flag = NULL, .val = 'e' }, - { .name = "vol-split", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "vol-split!", .has_arg = 0, .flag = NULL, .val = 'e' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'J' }, - { NULL, 0, NULL, 0} -}; - -/** - * parses out a numerical value from a string of numbers followed by: - * k, K, kib, KiB for kibibyte - * m, M, mib, MiB for mebibyte - **/ -static uint32_t -str_to_num(char *str) -{ - char *s; - ulong num; - - s = str; - num = strtoul(s, &s, 0); - - if (*s != '\0') { - if ((strcmp(s, "KiB") == 0) || (strcmp(s, "K") == 0) || - (strcmp(s, "kib") == 0) || (strcmp(s, "k") == 0)) - num *= KIB; - else if ((strcmp(s, "MiB") == 0) || (strcmp(s, "M") == 0) || - (strcmp(s, "mib") == 0) || (strcmp(s, "m") == 0)) - num *= MIB; - else - ERR_MSG("couldn't parse '%s', assuming %lu\n", - s, num); - } - return num; -} - -static int -parse_opt(int argc, char **argv, struct args *args) -{ - uint32_t i; - - while (1) { - int key; - - key = getopt_long(argc, argv, "ab:s:d:Deir:vV?J", - long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'a': /* --analyze */ - args->analyze = 1; - break; - case 'b': /* --block-size= */ - args->bsize = str_to_num(optarg); - break; - case 's': /* --header-size= */ - args->hsize = str_to_num(optarg); - break; - case 'd': /* --dir= */ - args->odir_path = optarg; - break; - case 'D': /* --debug */ - /* I wanted to use -v but that was already - used ... */ - debug = 1; - break; - case 'e': /* --eb-split */ - args->eb_split = SPLIT_RAW; - break; - case 'i': /* --info-table */ - args->itable = 1; - break; - case 'r': /* --rebuild= */ - i = str_to_num(optarg); - if (i < UBI_MAX_VOLUMES) - args->vols[str_to_num(optarg)] = 1; - else { - ERR_MSG("volume-id out of bounds\n"); - return -1; - } - break; - case 'v': /* --vol-split */ - if (args->vol_split != SPLIT_RAW) - args->vol_split = SPLIT_DATA; - break; - case 'V': /* --vol-split! */ - args->vol_split = SPLIT_RAW; - break; - case '?': /* help */ - fprintf(stderr, "Usage: unubi [OPTION...] " - "image-file\n%s%s\nReport bugs to %s\n", - doc, optionsstr, CONTACT); - exit(0); - break; - case 'J': - fprintf(stderr, "%s\n", VERSION); - exit(0); - break; - default: - fprintf(stderr, "%s", usage); - exit(-1); - } - } - - /* FIXME I suppose hsize should be replaced! */ - args->vid_hdr_offset = args->hsize - UBI_VID_HDR_SIZE; - args->data_offset = args->hsize; - - if (optind < argc) - args->img_path = argv[optind++]; - return 0; -} - - -/** - * counts the number of indicies which are flagged in full_array; - * full_array is an array of flags (1/0); - **/ -static size_t -count_set(uint32_t *full_array, size_t full_len) -{ - size_t count, i; - - if (full_array == NULL) - return 0; - - for (i = 0, count = 0; i < full_len; i++) - if (full_array[i] != 0) - count++; - - return count; -} - - -/** - * generates coll_array from full_array; - * full_array is an array of flags (1/0); - * coll_array is an array of the indicies in full_array which are flagged (1); - **/ -static size_t -collapse(uint32_t *full_array, size_t full_len, - uint32_t *coll_array, size_t coll_len) -{ - size_t i, j; - - if ((full_array == NULL) || (coll_array == NULL)) - return 0; - - for (i = 0, j = 0; (i < full_len) && (j < coll_len); i++) - if (full_array[i] != 0) { - coll_array[j] = i; - j++; - } - - return j; -} - -/** - * data_crc: save the FILE* position, calculate the crc over a span, - * reset the position - * returns non-zero when EOF encountered - **/ -static int -data_crc(FILE* fpin, size_t length, uint32_t *ret_crc) -{ - int rc; - size_t i; - char buf[length]; - uint32_t crc; - fpos_t start; - - rc = fgetpos(fpin, &start); - if (rc < 0) - return -1; - - for (i = 0; i < length; i++) { - int c = fgetc(fpin); - if (c == EOF) { - ERR_MSG("unexpected EOF\n"); - return -1; - } - buf[i] = (char)c; - } - - rc = fsetpos(fpin, &start); - if (rc < 0) - return -1; - - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, buf, length); - *ret_crc = crc; - return 0; -} - - -/** - * reads data of size len from fpin and writes it to path - **/ -static int -extract_data(FILE* fpin, size_t len, const char *path) -{ - int rc; - size_t i; - FILE* fpout; - - rc = 0; - fpout = NULL; - - fpout = fopen(path, "wb"); - if (fpout == NULL) { - ERR_MSG("couldn't open file for writing: %s\n", path); - rc = -1; - goto err; - } - - for (i = 0; i < len; i++) { - int c = fgetc(fpin); - if (c == EOF) { - ERR_MSG("unexpected EOF while writing: %s\n", path); - rc = -2; - goto err; - } - c = fputc(c, fpout); - if (c == EOF) { - ERR_MSG("couldn't write: %s\n", path); - rc = -3; - goto err; - } - } - - err: - if (fpout != NULL) - fclose(fpout); - return rc; -} - - -/** - * extract volume information table from block. saves and reloads fpin - * position - * returns -1 when a fpos set or get fails, otherwise <= -2 on other - * failure and 0 on success - **/ -static int -extract_itable(FILE *fpin, struct eb_info *cur, size_t bsize, size_t num, - const char *path) -{ - char filename[MAXPATH + 1]; - int rc; - size_t i, max; - fpos_t temp; - FILE* fpout = NULL; - struct ubi_vtbl_record rec; - - if (fpin == NULL || cur == NULL || path == NULL) - return -2; - - /* remember position */ - rc = fgetpos(fpin, &temp); - if (rc < 0) - return -1; - - /* jump to top of eraseblock, skip to data section */ - fsetpos(fpin, &cur->eb_top); - if (rc < 0) - return -1; - fseek(fpin, be32_to_cpu(cur->ec.data_offset), SEEK_CUR); - - /* prepare output file */ - if (be32_to_cpu(cur->vid.vol_id) != UBI_LAYOUT_VOLUME_ID) - return -2; - memset(filename, 0, MAXPATH + 1); - snprintf(filename, MAXPATH, FN_VITBL, path, num); - fpout = fopen(filename, "w"); - if (fpout == NULL) - return -2; - - /* loop through entries */ - fprintf(fpout, - "index\trpebs\talign\ttype\tcrc\t\tname\n"); - max = bsize - be32_to_cpu(cur->ec.data_offset); - for (i = 0; i < (max / sizeof(rec)); i++) { - int blank = 1; - char *ptr, *base; - char name[UBI_VOL_NAME_MAX + 1]; - const char *type = "unknown\0"; - uint32_t crc; - - /* read record */ - rc = fread(&rec, 1, sizeof(rec), fpin); - if (rc == 0) - break; - if (rc != sizeof(rec)) { - ERR_MSG("reading volume information " - "table record failed\n"); - rc = -3; - goto exit; - } - - /* check crc */ - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, &rec, - UBI_VTBL_RECORD_SIZE_CRC); - if (crc != be32_to_cpu(rec.crc)) - continue; - - /* check for empty */ - base = (char *)&rec; - ptr = base; - while (blank && - ((unsigned)(ptr - base) < UBI_VTBL_RECORD_SIZE_CRC)) { - if (*ptr != 0) - blank = 0; - ptr++; - } - - if (blank) - continue; - - /* prep type string */ - if (rec.vol_type == UBI_VID_DYNAMIC) - type = "dynamic\0"; - else if (rec.vol_type == UBI_VID_STATIC) - type = "static\0"; - - /* prep name string */ - rec.name[be16_to_cpu(rec.name_len)] = '\0'; - sprintf(name, "%s", rec.name); - - /* print record line to fpout */ - fprintf(fpout, "%zu\t%u\t%u\t%s\t0x%08x\t%s\n", - i, - be32_to_cpu(rec.reserved_pebs), - be32_to_cpu(rec.alignment), - type, - be32_to_cpu(rec.crc), - name); - } - - exit: - /* reset position */ - if (fsetpos(fpin, &temp) < 0) - rc = -1; - - if (fpout != NULL) - fclose(fpout); - - return rc; -} - - -/** - * using eb chain, tries to rebuild the data of volume at vol_id, or for all - * the known volumes, if vol_id is NULL; - **/ -static int -rebuild_volume(FILE * fpin, uint32_t *vol_id, struct eb_info **head, - const char *path, size_t block_size, size_t header_size) -{ - char filename[MAXPATH]; - int rc; - uint32_t vol, num, data_size; - FILE* fpout; - struct eb_info *cur; - - rc = 0; - - if ((fpin == NULL) || (head == NULL) || (*head == NULL)) - return 0; - - /* when vol_id is null, then do all */ - if (vol_id == NULL) { - cur = *head; - vol = be32_to_cpu(cur->vid.vol_id); - } else { - vol = *vol_id; - eb_chain_position(head, vol, NULL, &cur); - if (cur == NULL) { - if (debug) - ERR_MSG("no valid volume %d was found\n", vol); - return -1; - } - } - - num = 0; - snprintf(filename, MAXPATH, FN_VOLWH, path, vol); - fpout = fopen(filename, "wb"); - if (fpout == NULL) { - ERR_MSG("couldn't open file for writing: %s\n", filename); - return -1; - } - - while (cur != NULL) { - size_t i; - - if (be32_to_cpu(cur->vid.vol_id) != vol) { - /* close out file */ - fclose(fpout); - - /* only stay around if that was the only volume */ - if (vol_id != NULL) - goto out; - - /* begin with next */ - vol = be32_to_cpu(cur->vid.vol_id); - num = 0; - snprintf(filename, MAXPATH, FN_VOLWH, path, vol); - fpout = fopen(filename, "wb"); - if (fpout == NULL) { - ERR_MSG("couldn't open file for writing: %s\n", - filename); - return -1; - } - } - - while (num < be32_to_cpu(cur->vid.lnum)) { - /* FIXME haver: I hope an empty block is - written out so that the binary has no holes - ... */ - if (debug) - ERR_MSG("missing valid block %d for volume %d\n", - num, vol); - num++; - } - - rc = fsetpos(fpin, &(cur->eb_top)); - if (rc < 0) - goto out; - fseek(fpin, be32_to_cpu(cur->ec.data_offset), SEEK_CUR); - - if (cur->vid.vol_type == UBI_VID_DYNAMIC) - /* FIXME It might be that alignment has influence */ - data_size = block_size - header_size; - else - data_size = be32_to_cpu(cur->vid.data_size); - - for (i = 0; i < data_size; i++) { - int c = fgetc(fpin); - if (c == EOF) { - ERR_MSG("unexpected EOF while writing: %s\n", - filename); - rc = -2; - goto out; - } - c = fputc(c, fpout); - if (c == EOF) { - ERR_MSG("couldn't write: %s\n", filename); - rc = -3; - goto out; - } - } - - cur = cur->next; - num++; - } - - out: - if (vol_id == NULL) - fclose(fpout); - return rc; -} - - -/** - * traverses FILE* trying to load complete, valid and accurate header data - * into the eb chain; - **/ -static int -unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a) -{ - char filename[MAXPATH + 1]; - char reason[MAXPATH + 1]; - int rc; - size_t i, count, itable_num; - /* relations: - * cur ~ head - * next ~ first */ - struct eb_info *head, *cur, *first, *next; - struct eb_info **next_ptr; - - rc = 0; - count = 0; - itable_num = 0; - head = NULL; - first = NULL; - next = NULL; - cur = malloc(sizeof(*cur)); - if (cur == NULL) { - ERR_MSG("out of memory\n"); - rc = -ENOMEM; - goto err; - } - memset(cur, 0, sizeof(*cur)); - - fgetpos(fpin, &(cur->eb_top)); - while (1) { - const char *raw_path; - uint32_t crc; - - cur->phys_addr = ftell(fpin); - cur->phys_block = cur->phys_addr / a->bsize; - cur->data_crc_ok = 0; - cur->ec_crc_ok = 0; - cur->vid_crc_ok = 0; - - memset(filename, 0, MAXPATH + 1); - memset(reason, 0, MAXPATH + 1); - - /* in case of an incomplete ec header */ - raw_path = FN_INVAL; - - /* read erasecounter header */ - rc = fread(&cur->ec, 1, sizeof(cur->ec), fpin); - if (rc == 0) - goto out; /* EOF */ - if (rc != sizeof(cur->ec)) { - ERR_MSG("reading ec-hdr failed\n"); - rc = -1; - goto err; - } - - /* check erasecounter header magic */ - if (be32_to_cpu(cur->ec.magic) != UBI_EC_HDR_MAGIC) { - snprintf(reason, MAXPATH, ".invalid.ec_magic"); - goto invalid; - } - - /* check erasecounter header crc */ - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, &(cur->ec), - UBI_EC_HDR_SIZE_CRC); - if (be32_to_cpu(cur->ec.hdr_crc) != crc) { - snprintf(reason, MAXPATH, ".invalid.ec_hdr_crc"); - goto invalid; - } - - /* read volume id header */ - rc = fsetpos(fpin, &(cur->eb_top)); - if (rc != 0) - goto err; - fseek(fpin, be32_to_cpu(cur->ec.vid_hdr_offset), SEEK_CUR); - rc = fread(&cur->vid, 1, sizeof(cur->vid), fpin); - if (rc == 0) - goto out; /* EOF */ - if (rc != sizeof(cur->vid)) { - ERR_MSG("reading vid-hdr failed\n"); - rc = -1; - goto err; - } - - /* if the magic number is 0xFFFFFFFF, then it's very likely - * that the volume is empty */ - if (be32_to_cpu(cur->vid.magic) == 0xffffffff) { - snprintf(reason, MAXPATH, ".empty"); - goto invalid; - } - - /* vol_id should be in bounds */ - if ((be32_to_cpu(cur->vid.vol_id) >= UBI_MAX_VOLUMES) && - (be32_to_cpu(cur->vid.vol_id) < - UBI_INTERNAL_VOL_START)) { - snprintf(reason, MAXPATH, ".invalid"); - goto invalid; - } else - raw_path = FN_NSURE; - - /* check volume id header magic */ - if (be32_to_cpu(cur->vid.magic) != UBI_VID_HDR_MAGIC) { - snprintf(reason, MAXPATH, ".invalid.vid_magic"); - goto invalid; - } - cur->ec_crc_ok = 1; - - /* check volume id header crc */ - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, &(cur->vid), - UBI_VID_HDR_SIZE_CRC); - if (be32_to_cpu(cur->vid.hdr_crc) != crc) { - snprintf(reason, MAXPATH, ".invalid.vid_hdr_crc"); - goto invalid; - } - cur->vid_crc_ok = 1; - - /* check data crc, but only for a static volume */ - if (cur->vid.vol_type == UBI_VID_STATIC) { - rc = data_crc(fpin, be32_to_cpu(cur->vid.data_size), - &crc); - if (rc < 0) - goto err; - if (be32_to_cpu(cur->vid.data_crc) != crc) { - snprintf(reason, MAXPATH, ".invalid.data_crc"); - goto invalid; - } - cur->data_crc_ok = 1; - } - - /* enlist this vol, it's valid */ - raw_path = FN_VALID; - cur->linear = count; - rc = eb_chain_insert(&head, cur); - if (rc < 0) { - if (rc == -ENOMEM) { - ERR_MSG("out of memory\n"); - goto err; - } - ERR_MSG("unknown and unexpected error, please contact " - CONTACT "\n"); - goto err; - } - - /* extract info-table */ - if (a->itable && - (be32_to_cpu(cur->vid.vol_id) == UBI_LAYOUT_VOLUME_ID)) { - extract_itable(fpin, cur, a->bsize, - itable_num, a->odir_path); - itable_num++; - } - - /* split volumes */ - if (a->vol_split) { - size_t size = 0; - - rc = fsetpos(fpin, &(cur->eb_top)); - if (rc != 0) - goto err; - - /* - * FIXME For dynamic UBI volumes we must write - * the maximum available data. The - * vid.data_size field is not used in this - * case. The dynamic volume user is - * responsible for the content. - */ - if (a->vol_split == SPLIT_DATA) { - /* Write only data section */ - if (cur->vid.vol_type == UBI_VID_DYNAMIC) { - /* FIXME Formular is not - always right ... */ - size = a->bsize - a->hsize; - } else - size = be32_to_cpu(cur->vid.data_size); - - fseek(fpin, - be32_to_cpu(cur->ec.data_offset), - SEEK_CUR); - } - else if (a->vol_split == SPLIT_RAW) - /* write entire eraseblock */ - size = a->bsize; - - snprintf(filename, MAXPATH, FN_VOLSP, - a->odir_path, - be32_to_cpu(cur->vid.vol_id), - be32_to_cpu(cur->vid.lnum), - be32_to_cpu(cur->vid.leb_ver), count); - rc = extract_data(fpin, size, filename); - if (rc < 0) - goto err; - } - - invalid: - /* split eraseblocks */ - if (a->eb_split) { - /* jump to top of block */ - rc = fsetpos(fpin, &(cur->eb_top)); - if (rc != 0) - goto err; - - if (strcmp(raw_path, FN_INVAL) == 0) - snprintf(filename, MAXPATH, raw_path, - a->odir_path, count, reason); - else - snprintf(filename, MAXPATH, raw_path, - a->odir_path, - count, - be32_to_cpu(cur->vid.vol_id), - be32_to_cpu(cur->vid.lnum), - be32_to_cpu(cur->vid.leb_ver), - reason); - - rc = extract_data(fpin, a->bsize, filename); - if (rc < 0) - goto err; - } - - /* append to simple linked list */ - if (first == NULL) - next_ptr = &first; - else - next_ptr = &next->next; - - *next_ptr = malloc(sizeof(**next_ptr)); - if (*next_ptr == NULL) { - ERR_MSG("out of memory\n"); - rc = -ENOMEM; - goto err; - } - memset(*next_ptr, 0, sizeof(**next_ptr)); - - next = *next_ptr; - memcpy(next, cur, sizeof(*next)); - next->next = NULL; - - count++; - rc = fsetpos(fpin, &(cur->eb_top)); - if (rc != 0) - goto err; - fseek(fpin, a->bsize, SEEK_CUR); - memset(cur, 0, sizeof(*cur)); - - fgetpos(fpin, &(cur->eb_top)); - } - - out: - for (i = 0; i < vc; i++) { - rc = rebuild_volume(fpin, &vols[i], &head, a->odir_path, - a->bsize, a->hsize); - if (rc < 0) - goto err; - } - - /* if there were no volumes specified, rebuild them all, - * UNLESS eb_ or vol_ split or analyze was specified */ - if ((vc == 0) && (!a->eb_split) && (!a->vol_split) && - (!a->analyze) && (!a->itable)) { - rc = rebuild_volume(fpin, NULL, &head, a->odir_path, a->bsize, - a->hsize); - if (rc < 0) - goto err; - } - - err: - free(cur); - - if (a->analyze) { - char fname[PATH_MAX + 1]; - FILE *fp; - - unubi_analyze(&head, first, a->odir_path); - - /* prepare output files */ - memset(fname, 0, PATH_MAX + 1); - snprintf(fname, PATH_MAX, "%s/%s", a->odir_path, FN_EH_STAT); - fp = fopen(fname, "w"); - if (fp != NULL) { - eb_chain_print(fp, head); - fclose(fp); - } - } - eb_chain_destroy(&head); - eb_chain_destroy(&first); - - return rc; -} - - -/** - * handles command line arguments, then calls unubi_volumes - **/ -int -main(int argc, char *argv[]) -{ - int rc, free_a_odir; - size_t vols_len; - uint32_t *vols; - FILE* fpin; - struct args a; - - rc = 0; - free_a_odir = 0; - vols_len = 0; - vols = NULL; - fpin = NULL; - init_crc32_table(crc32_table); - - /* setup struct args a */ - memset(&a, 0, sizeof(a)); - a.bsize = 128 * KIB; - a.hsize = 2 * KIB; - a.vols = malloc(sizeof(*a.vols) * UBI_MAX_VOLUMES); - if (a.vols == NULL) { - ERR_MSG("out of memory\n"); - rc = ENOMEM; - goto err; - } - memset(a.vols, 0, sizeof(*a.vols) * UBI_MAX_VOLUMES); - - /* parse args and check for validity */ - parse_opt(argc, argv, &a); - if (a.img_path == NULL) { - ERR_MSG("no image file specified\n"); - rc = EINVAL; - goto err; - } - else if (a.odir_path == NULL) { - char *ptr; - int len; - - ptr = strrchr(a.img_path, '/'); - if (ptr == NULL) - ptr = a.img_path; - else - ptr++; - - len = strlen(DIR_FMT) + strlen(ptr); - free_a_odir = 1; - a.odir_path = malloc(sizeof(*a.odir_path) * len); - if (a.odir_path == NULL) { - ERR_MSG("out of memory\n"); - rc = ENOMEM; - goto err; - } - snprintf(a.odir_path, len, DIR_FMT, ptr); - } - - fpin = fopen(a.img_path, "rb"); - if (fpin == NULL) { - ERR_MSG("couldn't open file for reading: " - "%s\n", a.img_path); - rc = EINVAL; - goto err; - } - - rc = mkdir(a.odir_path, 0777); - if ((rc < 0) && (errno != EEXIST)) { - ERR_MSG("couldn't create ouput directory: " - "%s\n", a.odir_path); - rc = -rc; - goto err; - } - - /* fill in vols array */ - vols_len = count_set(a.vols, UBI_MAX_VOLUMES); - if (vols_len > 0) { - vols = malloc(sizeof(*vols) * vols_len); - if (vols == NULL) { - ERR_MSG("out of memory\n"); - rc = ENOMEM; - goto err; - } - collapse(a.vols, UBI_MAX_VOLUMES, vols, vols_len); - } - - /* unubi volumes */ - rc = unubi_volumes(fpin, vols, vols_len, &a); - if (rc < 0) { - /* ERR_MSG("error encountered while working on image file: " - "%s\n", a.img_path); */ - rc = -rc; - goto err; - } - - err: - free(a.vols); - if (free_a_odir != 0) - free(a.odir_path); - if (fpin != NULL) - fclose(fpin); - if (vols_len > 0) - free(vols); - return rc; -} diff --git a/ubi-utils/old-utils/src/unubi_analyze.c b/ubi-utils/old-utils/src/unubi_analyze.c deleted file mode 100644 index ceaa85f..0000000 --- a/ubi-utils/old-utils/src/unubi_analyze.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * 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. - */ - -/* - * Authors: Drake Dowsett, dowsett@de.ibm.com - * Contact: Andreas Arnez, arnez@de.ibm.com - * - * unubi uses the following functions to generate analysis output based on - * the header information in a raw-UBI image - */ - -/* - * TODO: use OOB data to check for eraseblock validity in NAND images - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "unubi_analyze.h" -#include "crc32.h" - -#define EC_X_INT 50 - -/** - * intcmp - function needed by qsort to order integers - **/ -int intcmp(const void *a, const void *b) -{ - int A = *(int *)a; - int B = *(int *)b; - return A - B; -} - -int longcmp(const void *a, const void *b) -{ - long long A = *(long long *)a; - long long B = *(long long *)b; - return A - B; -} - - -/** - * unubi_analyze_group_index - finds the normalized index in an array - * item: look for this item in the array - * array: array to search through - * size: length of the array - * array should be sorted for this algorithm to perform properly; - * if the item is not found returns -1, otherwise return value is the - * index in the array (note this contricts the array size to 2^32-1); - **/ -int -norm_index(uint32_t item, uint32_t *array, size_t length) -{ - size_t i, index; - - for (index = 0, i = 0; i < length; i++) { - if ((i != 0) && (array[i] != array[i - 1])) - index++; - - if (item == array[i]) - return index; - } - - return -1; -} - - -/** - * unubi_analyze_ec_hdr - generate data table and plot script - * first: head of simple linked list - * path: folder to write into - * generates a data file containing the eraseblock index in the image - * and the erase counter found in its ec header; - * if the crc check fails, the line is commented out in the data file; - * also generates a simple gnuplot sript for quickly viewing one - * display of the data file; - **/ -int -unubi_analyze_ec_hdr(struct eb_info *first, const char *path) -{ - char filename[PATH_MAX + 1]; - size_t count, eraseblocks; - uint32_t crc, crc32_table[256]; - uint64_t *erase_counts; - FILE* fpdata; - FILE* fpplot; - struct eb_info *cur; - - if (first == NULL) - return -1; - - /* crc check still needed for `first' linked list */ - init_crc32_table(crc32_table); - - /* prepare output files */ - memset(filename, 0, PATH_MAX + 1); - snprintf(filename, PATH_MAX, "%s/%s", path, FN_EH_DATA); - fpdata = fopen(filename, "w"); - if (fpdata == NULL) - return -1; - - memset(filename, 0, PATH_MAX + 1); - snprintf(filename, PATH_MAX, "%s/%s", path, FN_EH_PLOT); - fpplot = fopen(filename, "w"); - if (fpplot == NULL) { - fclose(fpdata); - return -1; - } - - /* make executable */ - chmod(filename, 0755); - - /* first run: count elements */ - count = 0; - cur = first; - while (cur != NULL) { - cur = cur->next; - count++; - } - eraseblocks = count; - - erase_counts = malloc(eraseblocks * sizeof(*erase_counts)); - if (!erase_counts) { - perror("out of memory"); - exit(EXIT_FAILURE); - } - - memset(erase_counts, 0, eraseblocks * sizeof(*erase_counts)); - - /* second run: populate array to sort */ - count = 0; - cur = first; - while (cur != NULL) { - erase_counts[count] = be64_to_cpu(cur->ec.ec); - cur = cur->next; - count++; - } - qsort(erase_counts, eraseblocks, sizeof(*erase_counts), - (void *)longcmp); - - /* third run: generate data file */ - count = 0; - cur = first; - fprintf(fpdata, "# eraseblock_no actual_erase_count " - "sorted_erase_count\n"); - while (cur != NULL) { - crc = clc_crc32(crc32_table, UBI_CRC32_INIT, &cur->ec, - UBI_EC_HDR_SIZE_CRC); - - if ((be32_to_cpu(cur->ec.magic) != UBI_EC_HDR_MAGIC) || - (crc != be32_to_cpu(cur->ec.hdr_crc))) - fprintf(fpdata, "# "); - - fprintf(fpdata, "%zu %llu %llu", count, - (unsigned long long)be64_to_cpu(cur->ec.ec), - (unsigned long long)erase_counts[count]); - - if (be32_to_cpu(cur->ec.magic) != UBI_EC_HDR_MAGIC) - fprintf(fpdata, " ## bad magic: %08x", - be32_to_cpu(cur->ec.magic)); - - if (crc != be32_to_cpu(cur->ec.hdr_crc)) - fprintf(fpdata, " ## CRC mismatch: given=%08x, " - "calc=%08x", be32_to_cpu(cur->ec.hdr_crc), - crc); - - fprintf(fpdata, "\n"); - - cur = cur->next; - count++; - } - fclose(fpdata); - - fprintf(fpplot, "#!/usr/bin/gnuplot -persist\n"); - fprintf(fpplot, "set xlabel \"eraseblock\"\n"); - - /* fourth run: generate plot file xtics */ - count = 0; - cur = first; - fprintf(fpplot, "set xtics ("); - while (cur != NULL) { - if ((count % EC_X_INT) == 0) { - if (count > 0) - fprintf(fpplot, ", "); - fprintf(fpplot, "%zd", count); - } - - cur = cur->next; - count++; - } - fprintf(fpplot, ")\n"); - - fprintf(fpplot, "set ylabel \"erase count\"\n"); - fprintf(fpplot, "set xrange [-1:%zu]\n", eraseblocks + 1); - fprintf(fpplot, "# set yrange [-1:%llu]\n", - (unsigned long long)erase_counts[eraseblocks - 1] + 1); - fprintf(fpplot, "plot \"%s\" u 1:2 t \"unsorted: %s\" with boxes\n", - FN_EH_DATA, FN_EH_DATA); - fprintf(fpplot, "# replot \"%s\" u 1:3 t \"sorted: %s\" with lines\n", - FN_EH_DATA, FN_EH_DATA); - fprintf(fpplot, "pause -1 \"press ENTER\"\n"); - - fclose(fpplot); - - return 0; -} - - -/** - * unubi_analyze_vid_hdr - generate data table and plot script - * head: head of complex linked list (eb_chain) - * path: folder to write into - * generates a data file containing the volume id, logical number, leb version, - * and data size from the vid header; - * all eraseblocks listed in the eb_chain are valid (checked in unubi); - * also generates a simple gnuplot sript for quickly viewing one - * display of the data file; - **/ -int -unubi_analyze_vid_hdr(struct eb_info **head, const char *path) -{ - char filename[PATH_MAX + 1]; - int rc, y1, y2; - size_t count, step, breadth; - uint32_t *leb_versions, *data_sizes; - FILE* fpdata; - FILE* fpplot; - struct eb_info *cur; - - if (head == NULL || *head == NULL) - return -1; - - rc = 0; - fpdata = NULL; - fpplot = NULL; - data_sizes = NULL; - leb_versions = NULL; - - /* prepare output files */ - memset(filename, 0, PATH_MAX + 1); - snprintf(filename, PATH_MAX, "%s/%s", path, FN_VH_DATA); - fpdata = fopen(filename, "w"); - if (fpdata == NULL) { - rc = -1; - goto exit; - } - - memset(filename, 0, PATH_MAX + 1); - snprintf(filename, PATH_MAX, "%s/%s", path, FN_VH_PLOT); - fpplot = fopen(filename, "w"); - if (fpplot == NULL) { - rc = -1; - goto exit; - } - - /* make executable */ - chmod(filename, 0755); - - /* first run: count elements */ - count = 0; - cur = *head; - while (cur != NULL) { - cur = cur->next; - count++; - } - breadth = count; - - leb_versions = malloc(breadth * sizeof(uint32_t)); - if (leb_versions == NULL) { - rc = -1; - goto exit; - } - memset(leb_versions, 0, breadth * sizeof(uint32_t)); - - data_sizes = malloc(breadth * sizeof(uint32_t)); - if (data_sizes == NULL) { - rc = -1; - goto exit; - } - memset(data_sizes, 0, breadth * sizeof(*data_sizes)); - - /* second run: populate arrays to sort */ - count = 0; - cur = *head; - while (cur != NULL) { - leb_versions[count] = be32_to_cpu(cur->vid.leb_ver); - data_sizes[count] = be32_to_cpu(cur->vid.data_size); - cur = cur->next; - count++; - } - qsort(leb_versions, breadth, sizeof(*leb_versions), (void *)intcmp); - qsort(data_sizes, breadth, sizeof(*data_sizes), (void *)intcmp); - - /* third run: generate data file */ - count = 0; - cur = *head; - fprintf(fpdata, "# x_axis vol_id lnum y1_axis leb_ver " - "y2_axis data_size\n"); - while (cur != NULL) { - y1 = norm_index(be32_to_cpu(cur->vid.leb_ver), leb_versions, - breadth); - y2 = norm_index(be32_to_cpu(cur->vid.data_size), data_sizes, - breadth); - - if ((y1 == -1) || (y2 == -1)) { - rc = -1; - goto exit; - } - - fprintf(fpdata, "%zu %u %u %u %u %u %u\n", - count, - be32_to_cpu(cur->vid.vol_id), - be32_to_cpu(cur->vid.lnum), - y1, - be32_to_cpu(cur->vid.leb_ver), - y2, - be32_to_cpu(cur->vid.data_size)); - cur = cur->next; - count++; - } - - fprintf(fpplot, "#!/usr/bin/gnuplot -persist\n"); - fprintf(fpplot, "set xlabel \"volume\"\n"); - - /* fourth run: generate plot file xtics */ - count = 0; - step = 0; - cur = *head; - fprintf(fpplot, "set xtics ("); - while (cur != NULL) { - if (count > 0) - fprintf(fpplot, ", "); - if (step != be32_to_cpu(cur->vid.vol_id)) { - step = be32_to_cpu(cur->vid.vol_id); - fprintf(fpplot, "\"%zd\" %zd 0", step, count); - } - else - fprintf(fpplot, "\"%d\" %zd 1", - be32_to_cpu(cur->vid.lnum), count); - cur = cur->next; - count++; - } - fprintf(fpplot, ")\n"); - fprintf(fpplot, "set nox2tics\n"); - - /* fifth run: generate plot file ytics */ - count = 0; - cur = *head; - fprintf(fpplot, "set ylabel \"leb version\"\n"); - fprintf(fpplot, "set ytics ("); - while (cur->next != NULL) { - y1 = norm_index(be32_to_cpu(cur->vid.leb_ver), leb_versions, - breadth); - - if (y1 == -1) { - rc = -1; - goto exit; - } - - if (count > 0) - fprintf(fpplot, ", "); - - fprintf(fpplot, "\"%u\" %u", be32_to_cpu(cur->vid.leb_ver), - y1); - - cur = cur->next; - count++; - } - fprintf(fpplot, ")\n"); - - /* sixth run: generate plot file y2tics */ - count = 0; - cur = *head; - fprintf(fpplot, "set y2label \"data size\"\n"); - fprintf(fpplot, "set y2tics ("); - while (cur != NULL) { - y2 = norm_index(be32_to_cpu(cur->vid.data_size), - data_sizes, breadth); - - if (y2 == -1) { - rc = -1; - goto exit; - } - - if (count > 0) - fprintf(fpplot, ", "); - - fprintf(fpplot, "\"%u\" %u", be32_to_cpu(cur->vid.data_size), - y2); - - cur = cur->next; - count++; - } - fprintf(fpplot, ")\n"); - - y1 = norm_index(leb_versions[breadth - 1], leb_versions, breadth); - y2 = norm_index(data_sizes[breadth - 1], data_sizes, breadth); - fprintf(fpplot, "set xrange [-1:%zu]\n", count + 1); - fprintf(fpplot, "set yrange [-1:%u]\n", y1 + 1); - fprintf(fpplot, "set y2range [-1:%u]\n", y2 + 1); - fprintf(fpplot, "plot \"%s\" u 1:4 t \"leb version: %s\" " - "axes x1y1 with lp\n", FN_VH_DATA, FN_VH_DATA); - fprintf(fpplot, "replot \"%s\" u 1:6 t \"data size: %s\" " - "axes x1y2 with lp\n", FN_VH_DATA, FN_VH_DATA); - fprintf(fpplot, "pause -1 \"press ENTER\"\n"); - - exit: - if (fpdata != NULL) - fclose(fpdata); - if (fpplot != NULL) - fclose(fpplot); - if (data_sizes != NULL) - free(data_sizes); - if (leb_versions != NULL) - free(leb_versions); - - return rc; -} - - -/** - * unubi_analyze - run all analyses - * head: eb_chain head - * first: simple linked list of eraseblock headers (use .next) - * path: directory (without trailing slash) to output to - * returns 0 upon successful completion, or -1 otherwise - **/ -int -unubi_analyze(struct eb_info **head, struct eb_info *first, const char *path) -{ - int ec_rc, vid_rc; - - if (path == NULL) - return -1; - - ec_rc = unubi_analyze_ec_hdr(first, path); - vid_rc = unubi_analyze_vid_hdr(head, path); - if (ec_rc < 0 || vid_rc < 0) - return -1; - - return 0; -} diff --git a/ubi-utils/old-utils/src/unubi_analyze.h b/ubi-utils/old-utils/src/unubi_analyze.h deleted file mode 100644 index c478f53..0000000 --- a/ubi-utils/old-utils/src/unubi_analyze.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * 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. - */ - -#ifndef __UNUBI_ANALYZE_H__ -#define __UNUBI_ANALYZE_H__ - -/* - * Author: Drake Dowsett - * Contact: Andreas Arnez (arnez@de.ibm.com) - * - * Eraseblock Chain - * - * A linked list structure to order eraseblocks by volume and logical number - * and to update by version number. Doesn't contain actual eraseblock data - * but rather the erasecounter and volume id headers as well as a position - * indicator. - * - * Diagram Example: - * - * [V1.0v0]->[V1.1v2]->[V1.2v1]->[V2.0v2]->[V2.1v0]->[V2.2v1]->NULL - * | | | | | | - * NULL [V1.1v1] [V1.2v0] [V2.0v1] NULL [V2.2v0] - * | | | | - * [V1.1v0] NULL [V2.0v0] NULL - * | | - * NULL NULL - * - * [VA.BvC] represents the eb_info for the eraseblock with the vol_id A, - * lnum B and leb_ver C - * -> represents the `next' pointer - * | represents the `older' pointer - */ - -#include -#include -#include - -#define FN_EH_STAT "analysis_blocks.txt" -#define FN_EH_DATA "analysis_ec_hdr.data" -#define FN_EH_PLOT "analysis_ec_hdr.plot" -#define FN_VH_DATA "analysis_vid_hdr.data" -#define FN_VH_PLOT "analysis_vid_hdr.plot" - -struct eb_info { - struct ubi_ec_hdr ec; - struct ubi_vid_hdr vid; - - fpos_t eb_top; - uint32_t linear; - int ec_crc_ok; - int vid_crc_ok; - int data_crc_ok; - uint32_t phys_addr; - int phys_block; - - struct eb_info *next; - struct eb_info *older; -}; - -int eb_chain_insert(struct eb_info **head, struct eb_info *item); - -int eb_chain_position(struct eb_info **head, uint32_t vol_id, uint32_t *lnum, - struct eb_info **pos); - -int eb_chain_print(FILE *stream, struct eb_info *head); - -int eb_chain_destroy(struct eb_info **head); - -int unubi_analyze(struct eb_info **head, struct eb_info *first, - const char *path); - -#endif /* __UNUBI_ANALYZE_H__ */ -- cgit v1.2.3