diff options
Diffstat (limited to 'ubi-utils/old-tools')
65 files changed, 0 insertions, 16318 deletions
| diff --git a/ubi-utils/old-tools/Makefile b/ubi-utils/old-tools/Makefile deleted file mode 100644 index d4c908b..0000000 --- a/ubi-utils/old-tools/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -# -# Makefile for ubi-utils -# - -OPTFLAGS := -O2 -Wall -KERNELHDR := ../../include -DESTDIR := /usr/local -SBINDIR=/usr/sbin -MANDIR=/usr/man -INCLUDEDIR=/usr/include - -CC := $(CROSS)gcc -CFLAGS := -I./inc -I./src -I$(KERNELHDR) $(OPTFLAGS) -Werror \ -	-Wwrite-strings -W -std=gnu99 -DPACKAGE_VERSION=\"1.0\" - -PERLPROGS = mkpfi ubicrc32.pl -TARGETS = pfiflash pddcustomize ubimirror \ -	bin2nand nand2bin ubigen mkbootenv unubi pfi2bin - -vpath   %.c ./src - -%: %.o -	$(CC) $(LDFLAGS) -g -o $@ $^ - -%.o: %.c -	$(CC) $(CFLAGS) -g -c -o $@ $< -g -Wp,-MD,.$(shell basename $<).dep - -all: $(TARGETS) libubi.a - -IGNORE=${wildcard .*.c.dep} --include ${IGNORE} - -clean: -	rm -rf *.o $(TARGETS) .*.c.dep libubi.a - -libubi.a: libubi.o -	ar cr $@ $^ - -ubidetach: ubidetach.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubiattach: ubiattach.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubinfo: ubinfo.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubiupdate: ubiupdate.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubimkvol: ubimkvol.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubirmvol: ubirmvol.o common.o libubi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -pddcustomize: pddcustomize.o error.o libubimirror.o bootenv.o hashmap.o \ -		libubi.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -pfiflash: pfiflash.o libpfiflash.o list.o reader.o error.o libubimirror.o \ -		bootenv.o hashmap.o pfi.o libubi.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubimirror: ubimirror.o error.o libubimirror.o bootenv.o hashmap.o \ -		libubi.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -nand2bin: nand2bin.o nandecc.o nandcorr.o -	$(CC) $(LDFLAGS) -o $@ $^ - -bin2nand: bin2nand.o error.o nandecc.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubigen: ubigen.o libubigen.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -mkbootenv: mkbootenv.o bootenv.o hashmap.o error.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -unubi: unubi.o crc32.o unubi_analyze.o eb_chain.o -	$(CC) $(LDFLAGS) -o $@ $^ - -pfi2bin: pfi2bin.o peb.o error.o list.o crc32.o libubigen.o bootenv.o \ -		hashmap.o reader.o pfi.o -	$(CC) $(LDFLAGS) -o $@ $^ - -ubicrc32: ubicrc32.o crc32.o -	$(CC) $(LDFLAGS) -o $@ $^ - -install: ${TARGETS} -	mkdir -p ${DESTDIR}/${SBINDIR} -	install -m0755 ${TARGETS} ${DESTDIR}/${SBINDIR}/ -	(cd perl && install ${PERLPROGS} ${DESTDIR}/${SBINDIR}/) - -uninstall: -	for file in ${TARGETS} ${PERLPROGS}; do \ -		$(RM) ${DESTDIR}/${SBINDIR}/$$file; \ -	done diff --git a/ubi-utils/old-tools/README b/ubi-utils/old-tools/README deleted file mode 100644 index 39ed0e9..0000000 --- a/ubi-utils/old-tools/README +++ /dev/null @@ -1,155 +0,0 @@ -This directory contains old UBI tools which I cannot maintain -because they are too messy and vague for me and the original authors -do not seem to have much time for them. Some of the utilities are -just not of general interest because they are oriented to specific -tasks of the guys from IBM. - -But the "unubi" utility must be very useful but it fails when I -try to feed an image to it, so it should be looked at and fixed, -then moved to the main "main" place. - -Artem Bityutskiy - -README -====== - -The programs and libraries in this directory provide a tool-chain to -generate binary data for embedded systems which can be flashed either -by a hardware flash programmer, e.g. JTAG debugger, or on the target -system directly using pfiflash, or ubimkvol, ubirmvol, ubiupdatevol. - -The latter is the case when there is already Linux running which has -build in UBI support. - -Authors: Oliver Lohmann -         Frank Haverkamp -	 Andreas Arnez -	 Artem Bityutskiy - -mkpfi           - tool for flash content generation in PFI -                  format -pfi2bin         - conversion tool to transfer a PFI file into a -                  binary image -pfiflash        - tool to update the embedded systems flash using -                  pfi files created by mkpfi -libbootenv      - library for boot-parameter processing -libpfi          - library for partial flash image (PFI) creation -                  and handling -ubigen          - tool to create binary UBI images e.g. for a -                  jtag flashing tool -nandimg         - tool to add OOB data to binary images intended -                  for NAND flash systems -ubilib          - UBI library - - -The following text is from original UBI announcement -==================================================== - -UBI - Unsorted Block Images - -UBI (Latin: "where?") manages multiple logical volumes on a single -flash device, specifically supporting NAND flash devices. UBI provides -a flexible partitioning concept which still allows for wear-levelling -across the whole flash device. - -In a sense, UBI may be compared to the Logical Volume Manager -(LVM). Whereas LVM maps logical sector numbers to physical HDD sector -numbers, UBI maps logical eraseblocks to physical eraseblocks. - -More information may be found in the UBI design documentation: -ubidesign.pdf. Which can be found here: -http://www.linux-mtd.infradead.org/doc/ubi.html - -Partitioning/Re-partitioning - -  An UBI volume occupies a certain number of erase blocks. This is -  limited by a configured maximum volume size, which could also be -  viewed as the partition size. Each individual UBI volume's size can -  be changed independently of the other UBI volumes, provided that the -  sum of all volume sizes doesn't exceed a certain limit. - -  UBI supports dynamic volumes and static volumes. Static volumes are -  read-only and their contents are protected by CRC check sums. - -Bad eraseblocks handling - -  UBI transparently handles bad eraseblocks. When a physical -  eraseblock becomes bad, it is substituted by a good physical -  eraseblock, and the user does not even notice this. - -Scrubbing - -  On a NAND flash bit flips can occur on any write operation, -  sometimes also on read. If bit flips persist on the device, at first -  they can still be corrected by ECC, but once they accumulate, -  correction will become impossible. Thus it is best to actively scrub -  the affected eraseblock, by first copying it to a free eraseblock -  and then erasing the original. The UBI layer performs this type of -  scrubbing under the covers, transparently to the UBI volume users. - -Erase Counts - -  UBI maintains an erase count header per eraseblock. This frees -  higher-level layers (like file systems) from doing this and allows -  for centralized erase count management instead. The erase counts are -  used by the wear-levelling algorithm in the UBI layer. The algorithm -  itself is exchangeable. - -Booting from NAND - -  For booting directly from NAND flash the hardware must at least be -  capable of fetching and executing a small portion of the NAND -  flash. Some NAND flash controllers have this kind of support. They -  usually limit the window to a few kilobytes in erase block 0. This -  "initial program loader" (IPL) must then contain sufficient logic to -  load and execute the next boot phase. - -  Due to bad eraseblocks, which may be randomly scattered over the -  flash device, it is problematic to store the "secondary program -  loader" (SPL) statically. Also, due to bit-flips it may become -  corrupted over time. UBI allows to solve this problem gracefully by -  storing the SPL in a small static UBI volume. - -UBI volumes vs. static partitions - -  UBI volumes are still very similar to static MTD partitions: - -    * both consist of eraseblocks (logical eraseblocks in case of UBI -      volumes, and physical eraseblocks in case of static partitions; -    * both support three basic operations - read, write, erase. - -  But UBI volumes have the following advantages over traditional -  static MTD partitions: - -    * there are no eraseblock wear-leveling constraints in case of UBI -      volumes, so the user should not care about this; -    * there are no bit-flips and bad eraseblocks in case of UBI volumes. - -  So, UBI volumes may be considered as flash devices with relaxed -  restrictions. - -Where can it be found? - -  Documentation, kernel code and applications can be found in the MTD -  gits. - -What are the applications for? - -  The applications help to create binary flash images for two -  purposes: pfi files (partial flash images) for in-system update of -  UBI volumes, and plain binary images, with or without OOB data in -  case of NAND, for a manufacturing step. Furthermore some tools -  are/and will be created that allow flash content analysis after a -  system has crashed. - -Who did UBI? - -  The original ideas, where UBI is based on, were developed by Andreas -  Arnez, Frank Haverkamp and Thomas Gleixner. Josh W. Boyer and -  some others were involved too. The implementation of the kernel -  layer was done by Artem B. Bityutskiy. The user-space applications -  and tools were written by Oliver Lohmann with contributions from -  Frank Haverkamp, Andreas Arnez, and Artem. Joern Engel contributed a -  patch which modifies JFFS2 so that it can be run on a UBI -  volume. Thomas Gleixner did modifications to the NAND layer and also -  some to JFFS2 to make it work. diff --git a/ubi-utils/old-tools/inc/libubi.h b/ubi-utils/old-tools/inc/libubi.h deleted file mode 100644 index 0cdb67c..0000000 --- a/ubi-utils/old-tools/inc/libubi.h +++ /dev/null @@ -1,340 +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_H__ -#define __LIBUBI_H__ - -#include <stdint.h> -#include <mtd/ubi-user.h> -#include <ctype.h> -#include <mtd/ubi-header.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* UBI version libubi is made for */ -#define LIBUBI_UBI_VERSION 1 - -/* UBI library descriptor */ -typedef void * libubi_t; - -/** - * struct ubi_attach_request - MTD device attachement request. - * @dev_num: number to assigne to the newly created UBI device - *           (%UBI_DEV_NUM_AUTO should be used to automatically assign the - *           number) - * @mtd_num: MTD device number to attach - * @vid_hdr_offset: VID header offset (%0 means default offset and this is what - *                  most of the users want) - */ -struct ubi_attach_request -{ -	int dev_num; -	int mtd_num; -	int vid_hdr_offset; -}; - -/** - * struct ubi_mkvol_request - volume creation request. - * @vol_id: ID to assign to the new volume (%UBI_VOL_NUM_AUTO should be used to - *          automatically assign ID) - * @alignment: volume alignment - * @bytes: volume size in bytes - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @name: volume name - */ -struct ubi_mkvol_request -{ -	int vol_id; -	int alignment; -	long long bytes; -	int vol_type; -	const char *name; -}; - -/** - * struct ubi_info - general UBI information. - * @dev_count: count of UBI devices in system - * @lowest_dev_num: lowest UBI device number - * @highest_dev_num: highest UBI device number - * @version: UBI version - * @ctrl_major: major number of the UBI control device - * @ctrl_minor: minor number of the UBI control device - */ -struct ubi_info -{ -	int dev_count; -	int lowest_dev_num; -	int highest_dev_num; -	int version; -	int ctrl_major; -	int ctrl_minor; -}; - -/** - * struct ubi_dev_info - UBI device information. - * @vol_count: count of volumes on this UBI device - * @lowest_vol_num: lowest volume number - * @highest_vol_num: highest volume number - * @major: major number of corresponding character device - * @minor: minor number of corresponding character device - * @total_lebs: total number of logical eraseblocks on this UBI device - * @avail_lebs: how many logical eraseblocks are not used and available for new - *             volumes - * @total_bytes: @total_lebs * @leb_size - * @avail_bytes: @avail_lebs * @leb_size - * @bad_count: count of bad physical eraseblocks - * @leb_size: logical eraseblock size - * @max_ec: current highest erase counter value - * @bad_rsvd: how many physical eraseblocks of the underlying flash device are - *            reserved for bad eraseblocks handling - * @max_vol_count: maximum possible number of volumes on this UBI device - * @min_io_size: minimum input/output unit size of the UBI device - */ -struct ubi_dev_info -{ -	int dev_num; -	int vol_count; -	int lowest_vol_num; -	int highest_vol_num; -	int major; -	int minor; -	int total_lebs; -	int avail_lebs; -	long long total_bytes; -	long long avail_bytes; -	int bad_count; -	int leb_size; -	long long max_ec; -	int bad_rsvd; -	int max_vol_count; -	int min_io_size; -}; - -/** - * struct ubi_vol_info - UBI volume information. - * @dev_num: UBI device number the volume resides on - * @vol_id: ID of this volume - * @major: major number of corresponding volume character device - * @minor: minor number of corresponding volume character device - * @dev_major: major number of corresponding UBI device character device - * @dev_minor: minor number of corresponding UBI device character device - * @type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @alignment: alignemnt of this volume - * @data_bytes: how many data bytes are stored on this volume (equivalent to - *              @rsvd_bytes for dynamic volumes) - * @rsvd_bytes: how many bytes are reserved for this volume - * @rsvd_lebs: how many logical eraseblocks are reserved for this volume - * @leb_size: logical eraseblock size of this volume (may be less then - *           device's logical eraseblock size due to alignment) - * @corrupted: non-zero if the volume is corrupted - * @name: volume name (null-terminated) - */ -struct ubi_vol_info -{ -	int dev_num; -	int vol_id; -	int major; -	int minor; -	int dev_major; -	int dev_minor; -	int type; -	int alignment; -	long long data_bytes; -	long long rsvd_bytes; -	int rsvd_lebs; -	int leb_size; -	int corrupted; -	char name[UBI_VOL_NAME_MAX + 1]; -}; - -/** - * libubi_open - open UBI library. - * This function initializes and opens the UBI library and returns UBI library - * descriptor in case of success and %NULL in case of failure. - */ -libubi_t libubi_open(void); - -/** - * libubi_close - close UBI library. - * @desc UBI library descriptor - */ -void libubi_close(libubi_t desc); - -/** - * ubi_get_info - get general UBI information. - * @desc: UBI library descriptor - * @info: pointer to the &struct ubi_info object to fill - * - * This function fills the passed @info object with general UBI information and - * returns %0 in case of success and %-1 in case of failure. - */ -int ubi_get_info(libubi_t desc, struct ubi_info *info); - -/** - * ubi_attach_mtd - attach MTD device to UBI. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @req: MTD attach request. - * - * This function creates a new UBI device by attaching an MTD device as - * described by @req. Returns %0 in case of success and %-1 in case of failure. - * The newly created UBI device number is returned in @req->dev_num. - */ -int ubi_attach_mtd(libubi_t desc, const char *node, -		   struct ubi_attach_request *req); - -/** - * ubi_detach_mtd - detach an MTD device. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @mtd_num: MTD device number to detach - * - * This function detaches MTD device number @mtd_num from UBI, which means the - * corresponding UBI device is removed. Returns zero in case of success and %-1 - * in case of failure. - */ -int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num); - -/** - * ubi_remove_dev - remove an UBI device. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @ubi_dev: UBI device number to remove - * - * This function removes UBI device number @ubi_dev and returns zero in case of - * success and %-1 in case of failure. - */ -int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev); - -/** - * ubi_mkvol - create an UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device to create a volume at - * @req: UBI volume creation request - * - * This function creates a UBI volume as described at @req and returns %0 in - * case of success and %-1 in case of failure. The assigned volume ID is - * returned in @req->vol_id. - */ -int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); - -/** - * ubi_rmvol - remove a UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device to remove a volume from - * @vol_id: ID of the volume to remove - * - * This function removes volume @vol_id from UBI device @node and returns %0 in - * case of success and %-1 in case of failure. - */ -int ubi_rmvol(libubi_t desc, const char *node, int vol_id); - -/** - * ubi_rsvol - re-size UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device owning the volume which should be - *        re-sized - * @vol_id: volume ID to re-size - * @bytes: new volume size in bytes - * - * This function returns %0 in case of success and %-1 in case of error. - */ -int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); - -/** - * ubi_node_type - test UBI node type. - * @desc: UBI library descriptor - * @node: the node to test - * - * This function tests whether @node is a UBI device or volume node and returns - * %1 if this is an UBI device node, %2 if this is a volume node, and %-1 if - * this is not an UBI node or if an error occurred (the latter is indicated by - * a non-zero errno). - */ -int ubi_node_type(libubi_t desc, const char *node); - -/** - * ubi_get_dev_info - get UBI device information. - * @desc: UBI library descriptor - * @node: name of the UBI character device to fetch information about - * @info: pointer to the &struct ubi_dev_info object to fill - * - * This function fills the passed @info object with UBI device information and - * returns %0 in case of success and %-1 in case of failure. - */ -int ubi_get_dev_info(libubi_t desc, const char *node, -		     struct ubi_dev_info *info); - -/** - * ubi_get_dev_info1 - get UBI device information. - * @desc: UBI library descriptor - * @dev_num: UBI device number to fetch information about - * @info: pointer to the &struct ubi_dev_info object to fill - * - * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI - * device number, not UBI character device. - */ -int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); - -/** - * ubi_get_vol_info - get UBI volume information. - * @desc: UBI library descriptor - * @node: name of the UBI volume character device to fetch information about - * @info: pointer to the &struct ubi_vol_info object to fill - * - * This function fills the passed @info object with UBI volume information and - * returns %0 in case of success and %-1 in case of failure. - */ -int ubi_get_vol_info(libubi_t desc, const char *node, -		     struct ubi_vol_info *info); - -/** - * ubi_get_vol_info1 - get UBI volume information. - * @desc: UBI library descriptor - * @dev_num: UBI device number - * @vol_id: ID of the UBI volume to fetch information about - * @info: pointer to the &struct ubi_vol_info object to fill - * - * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI - * volume number, not UBI volume character device. - */ -int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, -		      struct ubi_vol_info *info); - -/** - * ubi_update_start - start UBI volume update. - * @desc: UBI library descriptor - * @fd: volume character devie file descriptor - * @bytes: how many bytes will be written to the volume - * - * This function initiates UBI volume update and returns %0 in case of success - * and %-1 in case of error. - */ -int ubi_update_start(libubi_t desc, int fd, long long bytes); - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBI_H__ */ diff --git a/ubi-utils/old-tools/scripts/Makefile b/ubi-utils/old-tools/scripts/Makefile deleted file mode 100644 index b8e3c96..0000000 --- a/ubi-utils/old-tools/scripts/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# -# Makefile -# -# Testcase for UBI pfi update. -# -# Author:	Frank Haverkamp <haverkam@de.ibm.com> -# - -card		= test -mkpfi_cfg	= test.cfg - -# -# Some default values you might want to overwrite. Try it if you need -# it and add more if needed. Note that no real sanity checking is done -# on those values. If you do it wrong your card has no valid PDD data. -# - -PATH := $(PATH):/opt/ppc/usr/bin:../perl:.. - -dd		= dd -sed		= sed -bin2nand	= bin2nand -ubigen		= ubigen -mkpfi		= mkpfi -v -pfi2bin		= pfi2bin -v - -vmlinux_bin	?= test_vmlinux.bin -rootfs_bin	?= test_rootfs.bin -spl_bin		?= test_u-boot.bin -pdd_txt		?= pdd.txt - -flashtype	?= nand -pagesize	?= 2048 - -compl		?= $(card)_complete -compl_pfi	?= $(compl).pfi -compl_img	?= $(compl).img - -compl_nand2048_mif=$(compl).$(flashtype)$(pagesize).mif -compl_nand2048_img=$(compl).$(flashtype)$(pagesize).img - -all: help - -help: -	@echo "Testcases for the UBI/NAND manufacturing tool-chain" -	@echo "---------------------------------------------------------------" -	@echo "  make mif_test          - Generate a mif (manufacturing " -	@echo "                           image file)." -	@echo "  make bin2nand2bin_test - Create binary with ECC information" -	@echo "                           in the OOB area. Test ECC generation" -	@echo "                           and correction." - -mif_test: $(compl_pfi) $(compl_nand2048_mif) - -bin2nand2bin_test: -	chmod a+x ./bin2nand2bin_test.sh -	chmod a+x ./inject_biterror.pl -	./bin2nand2bin_test.sh - -$(compl_pfi): $(vmlinux_bin) $(rootfs_bin) $(spl_bin) -	$(mkpfi) -c $(mkpfi_cfg) - -# Binary data and out of band data (OOB) -# -$(compl_nand2048_mif): $(compl_img) -	$(bin2nand) -p $(pagesize) -o $(compl_nand2048_mif) $< - -# Binary data only -# -$(compl_img): $(compl_pfi) -	$(pfi2bin) -j $(pdd_txt) -o $@ $< - -# -# Default data -# -# If the binary data is not available in the current working directory -# we try to create symlinks to our test data. -# -$(vmlinux_bin) $(rootfs_bin) $(spl_bin): -	@echo -	@echo "No $@ found, will use defaults !" -	@echo -	@echo "OR press CTRL-C to provide your own $@" && 	\ -	sleep 1 &&						\ -	$(dd) if=/dev/urandom of=$@ bs=1M count=1 - -clean: -	$(RM) *.pfi *~ testblock* oob.bin - -distclean: clean -	$(RM) *.bin *.mif *.oob *.img diff --git a/ubi-utils/old-tools/scripts/README b/ubi-utils/old-tools/scripts/README deleted file mode 100644 index 01c7453..0000000 --- a/ubi-utils/old-tools/scripts/README +++ /dev/null @@ -1,14 +0,0 @@ -README -====== - -This procedure creates a test pfi which should be flashed to our -system with pfiflash. The testcase should read the data back and  -compare with the original. - -We should try not forget to run these tests before we release  -a new version of UBI. - -Frank - -Please guys, clean up this and move the tests to mtd-utils/tests/ -Artem. diff --git a/ubi-utils/old-tools/scripts/bin2nand2bin_test.sh b/ubi-utils/old-tools/scripts/bin2nand2bin_test.sh deleted file mode 100644 index 51f048c..0000000 --- a/ubi-utils/old-tools/scripts/bin2nand2bin_test.sh +++ /dev/null @@ -1,216 +0,0 @@ -#!/bin/sh -# -# Version: 1.1 -# Author:  Frank Haverkamp <haver@vnet.ibm.com> -# -# Testcase for nand2bin and bin2nand. Generate testdata and inject -# biterrors. Convert data back and compare with original data. -# -# Conversion: -#    bin -> bin2nand -> mif -> nand2bin -> img -# - -inject_biterror=./inject_biterror.pl -pagesize=2048 -oobsize=64 - -# Create test data -dd if=/dev/urandom of=testblock.bin bs=131072 count=1 - -for layout in IBM MTD ; do -    echo "*** Simple test with $layout layout ..." - -    echo -n "Convert bin to mif ... " -    bin2nand -l$layout --pagesize=${pagesize} -o testblock.mif testblock.bin -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo -n "Convert mif to bin ... " -    nand2bin -l$layout --pagesize=${pagesize} -o testblock.img testblock.mif -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo -n "Comparing data ... " -    diff testblock.bin testblock.img -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi -done - -echo "*** Test conversion without bitflips ..." - -echo -n "Convert bin to mif ... " -bin2nand --pagesize=${pagesize} -o testblock.mif testblock.bin -if [ $? -ne "0" ]; then -    echo "failed!" -    exit 1 -else -    echo "ok" -fi - -echo -n "Convert mif to bin ... " -nand2bin --pagesize=${pagesize} -o testblock.img testblock.mif -if [ $? -ne "0" ]; then -    echo "failed!" -    exit 1 -else -    echo "ok" -fi - -echo -n "Comparing data ... " -diff testblock.bin testblock.img -if [ $? -ne "0" ]; then -    echo "failed!" -    exit 1 -else -    echo "ok" -fi - -echo "*** Test conversion with uncorrectable ECC erors ..." -echo -n "Inject biterror at offset $ioffs ... " -${inject_biterror} --offset=0 --bitmask=0x81 \ -    --input=testblock.mif \ -    --output=testblock_bitflip.mif -if [ $? -ne "0" ]; then -    echo "failed!" -    exit 1 -else -    echo "ok" -fi - -echo "Convert mif to bin ... " -rm testblock.img -nand2bin --correct-ecc --pagesize=${pagesize} -o testblock.img \ -    testblock_bitflip.mif -if [ $? -ne "0" ]; then -    echo "failed!" -    exit 1 -else -    echo "ok" -fi - -echo -n "Comparing data, must fail due to uncorrectable ECC ... " -diff testblock.bin testblock.img -if [ $? -ne "0" ]; then -    echo "ok" # Must fail! -else -    echo "failed!" -    exit 1 -fi - -echo "*** Test bitflips in data ... " -for offs in `seq 0 255` ; do - -    cp testblock.mif testblock_bitflip.mif - -    for xoffs in 0 256 512 768 ; do -	let ioffs=$offs+$xoffs - -	cp testblock_bitflip.mif testblock_bitflip_tmp.mif -	echo -n "Inject biterror at offset $ioffs ... " -	${inject_biterror} --offset=${ioffs} --bitmask=0x01 \ -	    --input=testblock_bitflip_tmp.mif \ -	    --output=testblock_bitflip.mif -	if [ $? -ne "0" ]; then -	    echo "failed!" -	    exit 1 -	else -	    echo "ok" -	fi -    done - -    echo "Convert mif to bin ... " -    rm testblock.img -    nand2bin --correct-ecc --pagesize=${pagesize} -o testblock.img \ -	testblock_bitflip.mif -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo -n "Comparing data ... " -    diff testblock.bin testblock.img -    if [ $? -ne "0" ]; then -	hexdump testblock.bin > testblock.bin.txt -	hexdump testblock.img > testblock.img.txt -	echo "Use tkdiff testblock.bin.txt testblock.img.txt to compare" -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    # Without correction -    echo "Convert mif to bin ... " -    rm testblock.img -    nand2bin --pagesize=${pagesize} -o testblock.img \ -	testblock_bitflip.mif -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo -n "Comparing data must differ, correction is disabled ... " -    diff testblock.bin testblock.img -    if [ $? -ne "0" ]; then -	echo "ok" # must fail -    else -	echo "failed!" -	exit 1 -    fi -done - -echo "*** Test bitflips in OOB data ... " -for offs in `seq 0 $oobsize` ; do - -    let ioffs=$pagesize+$offs - -    echo -n "Inject biterror at offset $ioffs ... " -    ${inject_biterror} --offset=${ioffs} --bitmask=0x01 \ -	--input=testblock.mif \ -	--output=testblock_bitflip.mif -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo "Convert mif to bin ... " -    rm testblock.img -    nand2bin --correct-ecc --pagesize=${pagesize} -o testblock.img \ -	testblock_bitflip.mif -    if [ $? -ne "0" ]; then -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi - -    echo -n "Comparing data ... " -    diff testblock.bin testblock.img -    if [ $? -ne "0" ]; then -	hexdump testblock.bin > testblock.bin.txt -	hexdump testblock.img > testblock.img.txt -	echo "Use tkdiff testblock.bin.txt testblock.img.txt to compare" -	echo "failed!" -	exit 1 -    else -	echo "ok" -    fi -done diff --git a/ubi-utils/old-tools/scripts/f128_nand_sample.cfg b/ubi-utils/old-tools/scripts/f128_nand_sample.cfg deleted file mode 100644 index bb62600..0000000 --- a/ubi-utils/old-tools/scripts/f128_nand_sample.cfg +++ /dev/null @@ -1,38 +0,0 @@ -[targets] -complete=ipl,spl,bootenv,kernel,rootfs -bootcode=spl,bootenv - -# Build sections -[ipl] -image=ipl.bin -raw_starts=0x00000000 -raw_total_size=128kiB - -[spl] -image=u-boot.bin -ubi_ids=2,3 -ubi_size=2MiB -ubi_type=static -ubi_names=spl_0,spl_1 - -[bootenv] -bootenv_file=bootenv_complete.txt -ubi_ids=4,5 -ubi_size=128kiB -ubi_type=static -ubi_names=bootenv_0,bootenv_1 - -[kernel] -image=vmlinux.bin -ubi_ids=6,7 -ubi_size=6MiB -ubi_type=static -ubi_names=kernel_0,kernel_1 - -[rootfs] -image=rootfs.bin -ubi_ids=8,9 -ubi_alignment=2kiB -ubi_size=16MiB -ubi_type=dynamic -ubi_names=rootfs_0,rootfs_1 diff --git a/ubi-utils/old-tools/scripts/f64_nor_sample.cfg b/ubi-utils/old-tools/scripts/f64_nor_sample.cfg deleted file mode 100644 index 889d4c2..0000000 --- a/ubi-utils/old-tools/scripts/f64_nor_sample.cfg +++ /dev/null @@ -1,39 +0,0 @@ -[targets] -complete=ipl,spl,bootenv,kernel,rootfs -bootcode=spl,bootenv -rootfs=rootfs - -# Build sections -[ipl] -image=ipl.bin -raw_starts=0x02FE0000, 0x03FE0000 -raw_total_size=128kiB - -[spl] -image=u-boot.bin -ubi_ids=2,3 -ubi_size=2MiB -ubi_type=static -ubi_names=spl_0,spl_1 - -[bootenv] -bootenv_file=bootenv_complete.txt -ubi_ids=4,5 -ubi_size=128kiB -ubi_type=static -ubi_names=bootenv_0,bootenv_1 - -[kernel] -image=vmlinux.bin -ubi_ids=6,7 -ubi_size=6MiB -ubi_type=static -ubi_names=kernel_0,kernel_1 - -[rootfs] -image=rootfs.bin -ubi_ids=8,9 -ubi_alignment=2kiB -ubi_size=16128kiB -ubi_type=dynamic -ubi_names=rootfs_0,rootfs_1 diff --git a/ubi-utils/old-tools/scripts/inject_biterror.pl b/ubi-utils/old-tools/scripts/inject_biterror.pl deleted file mode 100644 index b4a862a..0000000 --- a/ubi-utils/old-tools/scripts/inject_biterror.pl +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/perl -w -# -# 2007 Frank Haverkamp <haver@vnet.ibm.com> -# -# Program for bit-error injection. I am sure that perl experts do it -# in 1 line. Please let me know how it is done right ;-). -# - -use strict; -use warnings; -use Getopt::Long; -use Pod::Usage; - -my $i; -my $help; -my $result; -my $offset = 0; -my $bitmask = 0x01; -my $in = "input.mif"; -my $out = "output.mif"; - -$result = GetOptions ("offset=i"  => \$offset,    # numeric -		      "bitmask=o" => \$bitmask,   # numeric -		      "input=s"	  => \$in,	  # string -		      "output=s"  => \$out,       # string -		      "help|?"    => \$help) or pod2usage(2); - -pod2usage(1) if $help; - -my $buf; - -open(my $in_fh, "<", $in) -  or die "Cannot open file $in: $!"; -binmode $in_fh; - -open(my $out_fh, ">", $out) or -  die "Cannot open file $out: $!"; -binmode $out_fh; - -$i = 0; -while (sysread($in_fh, $buf, 1)) { - -	$buf = pack('C', unpack('C', $buf) ^ $bitmask) if ($i == $offset); -	syswrite($out_fh, $buf, 1) or -	  die "Cannot write to offset $offset: $!"; -	$i++; -} - -close $in_fh; -close $out_fh; - -__END__ - -=head1 NAME - -inject_biterrors.pl - -=head1 SYNOPSIS - -inject_biterror.pl [options] - -=head1 OPTIONS - -=over 8 - -=item B<--help> - -Print a brief help message and exits. - -=item B<--offset>=I<offset> - -Byte-offset where bit-error should be injected. - -=item B<--bitmask>=I<bitmask> - -Bit-mask where to inject errors in the byte. - -=item B<--input>=I<input-file> - -Input file. - -=item B<--output>=I<output-file> - -Output file. - -=back - -=head1 DESCRIPTION - -B<inject_biterrors.pl> will read the given input file and inject -biterrors at the I<offset> specified. The location of the biterrors -are defined by the I<bitmask> parameter. - -=cut diff --git a/ubi-utils/old-tools/scripts/jffs2_test.sh b/ubi-utils/old-tools/scripts/jffs2_test.sh deleted file mode 100755 index 0cc9f0c..0000000 --- a/ubi-utils/old-tools/scripts/jffs2_test.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh -# -# Testcase for JFFS2 verification. We do not want to see any -# kernel errors occuring when this is executed. -# -# -# To have a standardized output I define the following function to be -# used when a test was ok or when it failed. -# -failed () -{ -    echo "FAILED" -} - -passed () -{ -    echo "PASSED" -} - -# -# Print sucess message. Consider to exit with zero as return code. -# -exit_success () -{ -    echo "SUCCESS" -    exit 0 -} - -# -# Print failure message. Consider to exit with non zero return code. -# -exit_failure () -{ -    echo "FAILED" -    exit 1 -} - -echo "***********************************************************************" -echo "*        jffs2 testing ...                                            *" -echo "***********************************************************************" - -ulimit -c unlimited - -for i in `seq 5000`; do -    echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " -    dd if=/dev/urandom of=test.bin bs=$i count=1; -    if [ $? -ne "0" ] ; then -        exit_failure -    fi -    passed - -    echo "Copy to different file ... " -    dd if=test.bin of=new.bin bs=$i count=1; -    if [ $? -ne "0" ] ; then -        exit_failure -    fi -    passed - -    echo "Comparing files ... " -    cmp test.bin new.bin -    dd if=test.bin of=new.bin bs=$i count=1; -    if [ $? -ne "0" ] ; then -        exit_failure -    fi -    passed -done - -for i in `seq 5000`; do -    echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " -    dd if=/dev/urandom of=foo bs=$i count=1; -    if [ $? -ne "0" ] ; then -        exit_failure -    fi -    passed -done - -for i in `seq 5000`; do  -    echo "Testing $i byte (dd if=/dev/zero of=foo bs=$i count=1) ... " -    dd if=/dev/zero of=foo bs=$i count=1; -    if [ $? -ne "0" ] ; then -        exit_failure -    fi -    passed -done - -echo "***********************************************************************" -echo "*               Congratulations, no errors found!                     *" -echo "*              Have fun with your cool JFFS2 using system!            *" -echo "***********************************************************************" - -exit_success diff --git a/ubi-utils/old-tools/scripts/mkdevs.pl b/ubi-utils/old-tools/scripts/mkdevs.pl deleted file mode 100755 index f0fd464..0000000 --- a/ubi-utils/old-tools/scripts/mkdevs.pl +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl -w - -# -# Author: Artem B. Bityutskiy <dedekind@oktetlabs.ru> -# -# A small scrip which creates UBI device nodes in /dev. UBI allocates -# major number dynamically, so the script looks at /proc/devices to find -# out UBI's major number. -# - - -my $proc = '/proc/devices'; -my $regexp = '(\d+) (ubi\d+)$'; - - -open FILE, "<", $proc or die "Cannot open $proc file: $!\n"; -my @file = <FILE>; -close FILE; - -foreach (@file) { -	next if not m/$regexp/g; -	print "found $2\n"; - -	system("rm -rf /dev/$2"); -	system("mknod /dev/$2 c $1 0"); - -	for (my $i = 0; $i < 128; $i += 1) { -		system("rm -rf /dev/$2_$i"); -		my $j = $i + 1; -		system("mknod /dev/$2_$i c $1 $j"); -	} -} diff --git a/ubi-utils/old-tools/scripts/mkpfi b/ubi-utils/old-tools/scripts/mkpfi deleted file mode 100644 index 2cce587..0000000 --- a/ubi-utils/old-tools/scripts/mkpfi +++ /dev/null @@ -1,723 +0,0 @@ -#!/usr/bin/perl -# -# 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. -# - -# -# mkpfi -# -# This perl program is assembles PFI files from a config file. -# -# Author: Oliver Lohmann (oliloh@de.ibm.com) -# -use warnings; -use strict; -use lib "/usr/lib/perl5"; # Please change this path as you need it, or -			  # make a proposal how this could be done -			  # nicer. -use Getopt::Long; -use Pod::Usage; -use Config::IniFiles; -use File::Temp; - -# ---------------------------------------------------------------------------- -# Versions -our $version : unique = "0.1"; -our $pfi_version : unique = "0x1"; - -# ---------------------------------------------------------------------------- -# Globals -my $verbose = 0; -my $cfg; - -my %opts = (); -my %files = (config => ""); -my @tmp_files; - -my %tools = (ubicrc32 => "ubicrc32"); - -# ---------------------------------------------------------------------------- -# Processing the input sections -# -# The idea is to combine each section entry with a function -# in order to allow some kind of preprocessing for the values -# before they are written into the PFI file. -# This is especially useful to be more verbose and -# user-friendly in the layout file. -# -# All key-function hashes are applied after the general -# validation of the configuration file. -# If any mandatory key is missing in a section the user -# will be informed and the PFI creation process is aborted. -# -# Default keys will be checked for their presence inside the config -# file. If they are missing, they will be generated with appr. values. - -# Mandatory keys for UBI volumes. -my %ubi_keys = ("ubi_ids"       => \&check_id_list, -		"ubi_size"      => \&replace_num, -		"ubi_type"      => \&replace_type, -		"ubi_names"     => \&remove_spaces, -		"ubi_alignment" => \&replace_num); - -# Mandatory keys for RAW sections. -my %raw_keys = ("raw_starts"     => \&expand_starts, -		"raw_total_size" => \&replace_num); - -# Common default keys for documentation and control purposes. -my %common_keys = ("flags" => \&replace_num, -		   "label" => \&do_nothing); - -# Define any defaults here. Values which maintained in this default -# region need not to be specified by the user explicitly. -my %def_ubi_keys      = ("ubi_alignment" => [\&set_default, "0x1"]); -my %def_raw_keys      = (); -my %def_common_keys   = ("flags"	 => [\&set_default, "0x0"], -			 "label"	 => [\&generate_label, ""]); - -# ---------------------------------------------------------------------------- -# Input keys, actually the path to the input data. - -my %input_keys = ("image" => \&do_nothing); - -# Placeholder keys allow the replacement via a special -# purpose function. E.g. the bootenv_file key will be used -# to generate bootenv binary data from an text file and -# replace the bootenv_file key with an image key to handle it -# in the same way in the further creation process. -my %input_placeholder_keys = ("bootenv_file" => \&create_bootenv_image); - -# ---------------------------------------------------------------------------- -# Helper - -# @brief Get current time string. -sub get_date { -	my $tmp = scalar localtime; -	$tmp =~ s/ /_/g; -	return $tmp; -} - -# @brief Print an info message to stdout. -sub INFO($) { -	my $str = shift; - -	if (!$verbose) { -		return; -	} - -	print STDOUT $str; -} - -# @brief Print an error message to stderr. -sub ERR($) { -	my $str = shift; -	print STDERR $str; -} - -# @brief Print a warning message to stderr. -sub WARN($) { -	my $str = shift; -	print STDERR $str; -} - -sub parse_command_line($) { -	my $opt = shift; -	my $result = GetOptions( "help"	     => \$$opt{'help'}, -				 "man"	     => \$$opt{'man'}, -				 "config=s"  => \$$opt{'config'}, -				 "verbose"   => \$$opt{'verbose'}, -			       ) or pod2usage(2); -	pod2usage(1) if defined ($$opt{help}); -	pod2usage(-verbose => 2) if defined ($$opt{man}); - -	$verbose = $$opt{verbose} if defined $$opt{verbose}; - -	if (!defined $$opt{config}) { -		ERR("[ ERROR: No config file specified. Aborting...\n"); -		exit 1; -	} - -} - -# @brief Check if all needed tools are in PATH. -sub check_tools { -	my $err = 0; -	my $key; - -	foreach $key (keys %tools) { -		if (`which $tools{$key}` eq "") { -			ERR("\n") if ($err == 0); -			ERR("! Please add the tool \'$tools{$key}\' " . -				"to your path!\n"); -			$err = 1; -		} -	} -	die "[ ERROR: Did not find all needed tools!\n" if $err; -} - -sub open_cfg_file($) { -	my $fname = shift; -	my $res = new Config::IniFiles( -file => $fname ); - -	die "[ ERROR: Cannot load your config file!\n" if (!defined $res); -	return $res; -} - -sub set_default($$$$) { -	my ($cfg, $section, $parameter, $def_value) = @_; -	$cfg->newval($section, $parameter, $def_value); -	return; -} - -sub generate_label($$$$) { -	my ($cfg, $section, $parameter, $def_value) = @_; -	my $new_label = $def_value . $section; -	$new_label .= "_" . get_date; -	$cfg->newval($section, $parameter, $new_label); -	return; -} - -# @brief   Converts any num to a unified hex string, i.e the resulting value -#	   always starts with "0x" and is aligned to 8 hexdigits. -# @return  Returns 0 on success, otherwise an error occured. -# -sub any_num_to_hex($$) { -	my $val = shift; -	my $res = shift; - -	# M(iB) -	if ($val =~ m/([0-9]+)[Mm][i]?[Bb]?/g) { -		$$res = sprintf("0x%08x", $1 * 1024 * 1024); -	} -	# k(iB) -	elsif ($val =~ m/([0-9]+)[kK][i]?[Bb]?/g) { -		$$res = sprintf("0x%08x", $1 * 1024); -	} -	# hex -	elsif ($val =~ m/0x?([0-9a-fA-F]+)/g) { -		$$res = sprintf("0x%08x", hex $1); -	} -	# decimal -	elsif ($val =~ m/^([0-9]+)$/g) { -		$$res = sprintf("0x%08x", $1); -	} -	else { -		$$res = ""; -		return -1; -	} - -	return 0; -} - -sub remove_spaces($$$) { -	my ($cfg, $section, $parameter) = @_; -	my ($start, @starts, @new_starts); -	my $val = $cfg->val($section, $parameter); -	my $res; - -	$val =~ s/ //g; # spaces -	$cfg->newval($section, $parameter, $val); -} - -sub expand_starts($$$) { -	my ($cfg, $section, $parameter) = @_; -	my ($start, @starts, @new_starts); -	my $val = $cfg->val($section, $parameter); -	my $res; - -	$val =~ s/ //g; # spaces -	@starts = split(/,/, $val); - -	foreach $start (@starts) { -		if (any_num_to_hex($start, \$res) != 0) { -			ERR("[ ERROR: [$section]\n"); -			ERR("[        Expecting a list of numeric " . -			    "values for parameter: $parameter\n"); -			exit 1; -		} -		push (@new_starts, $res); -	} -	$res = join(',', @starts); - -	$cfg->newval($section, $parameter, $res); -} - -sub check_id_list($$$) { -	my ($cfg, $section, $parameter) = @_; -	my $val = $cfg->val($section, $parameter); -	my $res; - -	if (!($val =~ m/^[0-9]+[,0-9]*/)) { -		ERR("[ ERROR: Syntax error in 'ubi_ids' in " . -		    "section '$section': $val\n"); -			ERR("[ Aborting... "); -			exit 1; -	} -} - -sub replace_type($$$) { -	my ($cfg, $section, $parameter) = @_; -	my $val = $cfg->val($section, $parameter); -	my $res; - -	$res = lc($val); -	grep {$res eq $_} ('static', 'dynamic') -	    or die "[ ERROR: Unknown UBI Volume Type in " . -	    "section '$section': $val\n"; - -	$cfg->newval($section, $parameter, $res); -} - - -sub replace_num($$$) { -	my ($cfg, $section, $parameter) = @_; -	my $val = $cfg->val($section, $parameter); -	my $res = ""; - -	if (any_num_to_hex($val, \$res) != 0) { -		ERR("[ ERROR: [$section]\n"); -		ERR("[        Expecting a numeric value " . -		    "for parameter: $parameter\n"); -		exit 1; -	} -	$cfg->newval($section, $parameter, $res); -} - -sub do_nothing($$$) { -	my ($cfg, $section, $parameter) = @_; -	return; -} - -sub bootenv_sanity_check($) { -	my $env = shift;	# hash array containing bootenv -	my %pdd = (); - -	defined($$env{'pdd'}) or return "'pdd' not defined"; -	foreach (split /,/, $$env{'pdd'}) { -		defined($$env{$_}) or return "undefined '$_' in pdd"; -		$pdd{$_} = 1; -	} - -	defined $$env{'pdd_preserve'} or -		return ""; -	foreach (split /,/, $$env{'pdd_preserve'}) { -		defined($pdd{$_}) -			or return "pdd_preserve field '$_' not in pdd"; -	} -	return ""; -} - -sub create_bootenv_image($$$) { -	my ($cfg, $section, $parameter) = @_; -	my $txt_fn = $cfg->val($section, "bootenv_file"); -	my $in; - -	my %value = (); -	my @key = (); - -	open $in, "<", $txt_fn -		or die "[ ERROR: can't open bootenv file '$txt_fn'.\n"; -	while (<$in>) { -		next if (/^\s*(\#.*)?$/); # Skip comments/whitespace. - -		if (/^(\S+?)\+\=(.*)$/) { -			defined($value{$1}) or -				die "$txt_fn:$.: error: appending to" . -					" non-existent '$1'\n"; -			$value{$1} .= $2; -		} elsif (/^(\S+?)\=(.*)$/) { -			not defined($value{$1}) or -				die "$txt_fn:$.: error: trying to" . -					" redefine '$1'\n"; -			push @key, $1; -			$value{$1} = $2; -		} else { -			die "$txt_fn:$.: error: unrecognized syntax\n"; -		} -	} -	close $in; - -	$_ = &bootenv_sanity_check(\%value) -		and die "$txt_fn: error: $_\n"; - -	my $tmp_file = new File::Temp(); -	push (@tmp_files, $tmp_file); - -	foreach (@key) { -		print $tmp_file "$_=", $value{$_}, "\0"; -	} -	close $tmp_file; - -	$cfg->newval($section, "image", $tmp_file-> filename); -} - -sub process_keys($$$) { -	my ($cfg, $section, $keys) = @_; -	my @parameters = $cfg->Parameters($section); -	my $i; - -	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) { -		if (defined($$keys{$parameters[$i]})) { -			$$keys{$parameters[$i]}->($cfg, $section, -					$parameters[$i]); -		} -	} - -} - -sub is_in_keylist($$) { -	my ($key, $keys) = @_; -	my $i; - -	for ($i = 0; $i < scalar(@$keys); $i++) { -		if ($$keys[$i] eq $key) { -			return 1; -		} -	} - -	return 0; -} - -sub check_default_keys($$$) { -	my ($cfg, $section, $keys) = @_; -	my @parameters = $cfg->Parameters($section); -	my $key; - -	foreach $key (keys %$keys) { -		if (!is_in_keylist($key, \@parameters)) { -			$$keys{$key}[0]-> -				($cfg, $section, $key, $$keys{$key}[1]); -		} -	} - -} - - - -sub check_keys($$$) { -	my ($cfg, $section, $keys) = @_; -	my @parameters = $cfg->Parameters($section); -	my ($i, $key, $err); - -	$err = 0; -	for ($i = 0 ; $i < scalar(@$keys) ; $i++ ) { -		if (!is_in_keylist($$keys[$i], \@parameters)) { -			ERR("[ ERROR: [$section]\n") if $err == 0; -			$err = 1; -			ERR("[        Missing key '$$keys[$i]'\n"); -		} -	} - -	if ($err) { -		ERR("[ Aborting...\n"); -		exit 1; -	} -} - -sub push_pfi_data($$$$$) { -	my ($cfg, $section, $pfi_infos, $keys, $mode) = @_; -	my ($tmp, $i, $hdr); - -	my %pfi_info = (); -	$pfi_info{'mode'} = $mode; -	$pfi_info{'image'} = $cfg->val($section, "image"); - -	# Build the PFI header -	$hdr  = sprintf("PFI!\n"); -	$hdr .= sprintf("version=0x%08x\n", hex $pfi_version); -	$hdr .= sprintf("mode=$mode\n"); - -	# calculate the size of the binary data part -	$tmp = -s $cfg->val($section, "image"); -	if (!defined $tmp) { -		ERR("[ ERROR: [$section]\n"); -		ERR("[        Missing input image: " -				. $cfg->val($section, "image") . "\n"); -		exit 1; -	} -	# Check for the image to fit into the given space -	my $quota; -	if ($mode eq 'raw') { -		$quota = oct $cfg->val($section, "raw_total_size"); -	} elsif ($mode eq 'ubi') { -		$quota = oct $cfg->val($section, "ubi_size"); -	} -	$tmp <= $quota -		or die "[ERROR: image file too big: " . -		$cfg->val($section, "image") . "\n"; -	$pfi_info{'size'} = $tmp; - -	$hdr .= sprintf("size=0x%08x\n", $tmp); - -	my $img_file = $cfg->val($section, "image"); -	my $crc32 = `$tools{'ubicrc32'} $img_file 2>&1`; -	if (any_num_to_hex($crc32, \$tmp) != 0) { -		die "[ ERROR: $tools{'ubicrc32'} returned with errors"; -	} -	$hdr .= sprintf("crc=$tmp\n"); - - -	# Process all remaining keys -	for ($i = 0; $i < scalar (@$keys); $i++) { -		if ($$keys[$i] eq "image") { # special case image input file -			if (! -e ($tmp = $cfg->val($section, "image"))) { -				ERR("[ ERROR: [$section]\n"); -				ERR("[        Cannot find input file $tmp\n"); -				exit 1; -			} -			next; -		} -		$hdr .= sprintf("%s=%s\n", $$keys[$i], -				$cfg->val($section, $$keys[$i])); -	} - -	$hdr .= sprintf("\n"); # end marker for PFI-header - -	$pfi_info{'header'} = $hdr; - -	# store in the header list -	push @$pfi_infos, \%pfi_info; -} - -sub process_section($$$$$$) { -	my ($cfg, $section, $pfi_infos, $custom_keys, -			$def_custom_keys, $mode) = @_; -	my @keys = (keys %common_keys, keys %$custom_keys); -	my @complete_keys = (@keys, keys %input_keys); - -	# set defaults if necessary -	check_default_keys($cfg, $section, $def_custom_keys); -	check_default_keys($cfg, $section, \%def_common_keys); - -	# check for placeholders... -	process_keys($cfg, $section, \%input_placeholder_keys); - -	# VALIDATE layout.cfg entries -	check_keys($cfg, $section, \@complete_keys); - -	# execute linked functions (if any) -	process_keys($cfg, $section, \%common_keys); -	process_keys($cfg, $section, $custom_keys); - -	push_pfi_data($cfg, $section, $pfi_infos, \@keys, $mode); -} - -sub get_section_info($$) { -	my ($cfg, $section) = @_; -	my @parameters = $cfg->Parameters($section); -	my ($ubi, $raw, $i, @res); - -	$ubi = $raw = 0; -	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) { -		if ($parameters[$i] =~ m/ubi_/gi) { -			$ubi = 1; -			@res = (\%ubi_keys, \%def_ubi_keys, "ubi"); -		} -		if ($parameters[$i] =~ m/raw_/gi) { -			$raw = 1; -			@res = (\%raw_keys, \%def_raw_keys, "raw"); -		} -	} - -	if (($ubi + $raw) != 1)	{ # double definition in section -		ERR("[ ERROR: Layout error in section '$section'\n"); -		exit 1; -	} - -	return @res; -} - -sub mk_target_list($$) { -	my $val = shift; -	my $tmp = shift; -	my $complete = 0; - -	if ($val =~ m/\((.*)\)/g) { -		$val = $1; -		$complete = 1; -	} -	$val =~ s/ //g; # spaces - -	@$tmp = split(/,/, $val); - -	return $complete; -} - -sub copy_bytes($$$) { -	my ($in, $out, $to_copy) = @_; - -	while ($to_copy) { -		my $buf; -		my $bufsize = 1024*1024; - -		$bufsize < $to_copy or $bufsize = $to_copy; -		read($in, $buf, $bufsize) == $bufsize -			or die "[ ERROR: Image file shrunk during operation\n"; -		print $out $buf; -		$to_copy -= $bufsize; -	} -} - -sub write_target($$) { -	my ($pfi_infos, $target) = @_; -	my ($pfi_info); - -	INFO("[ Writting target pfi file: '$target.pfi'...\n"); -	if (-e "$target.pfi") { -		WARN("! Replaced old pfi...\n"); -		`rm -f $target.pfi`; -	} -	open(FILE, ">", "$target.pfi") -		or die "[ ERROR: Cannot create output file: $target.pfi\n"; -	binmode(FILE); - -	# @FIXME sort by mode (first raw, then ubi) -	# Currently this ordering is based on a string comparism. :-) -	@$pfi_infos = sort {(lc $$a{'mode'}) cmp (lc $$b{'mode'})} @$pfi_infos; - -	# Print all headers first -	foreach $pfi_info (@$pfi_infos) { -		print FILE $$pfi_info{'header'}; - -	} -	# Print the linked data sections -	print FILE "DATA\n"; -	foreach $pfi_info (@$pfi_infos) { -		open(IMAGE, "<", $$pfi_info{'image'}) -				or die "[ ERROR: Cannot open input image: " . -				"$$pfi_info{'image'}" . "\n"; -		binmode(IMAGE); -		©_bytes(\*IMAGE, \*FILE, $$pfi_info{'size'}); -		close(IMAGE) or die "[ ERROR: Cannot close input image: " . -				"$$pfi_info{'image'}" . "\n"; -	} -	close(FILE) or die "[ ERROR: Cannot close output file: $target.pfi\n"; -} - -sub process_config($) { -	my $cfg = shift; -	my @sections = $cfg->Sections; -	my ($i, $j, $keylist, $def_keylist, $mode, $tmp, -			@tlist, $complete,@pfi_infos); - -	my @parameters = $cfg->Parameters("targets") or -		die "[ ERROR: Config file has no 'targets' section!\n"; - -	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) { -		INFO("[ Processing target '$parameters[$i]'...\n"); -		@pfi_infos = (); - -		# get a list of subtargets -		$complete = mk_target_list($cfg->val("targets", -					$parameters[$i]), \@tlist); -		# build all subtargets -		for ($j = 0 ; $j < scalar(@tlist) ; $j++ ) { -			($keylist, $def_keylist, $mode) -				= get_section_info($cfg, $tlist[$j]); -			process_section($cfg, $tlist[$j], -					\@pfi_infos, -					$keylist, $def_keylist, $mode); -		} - -		write_target(\@pfi_infos, $parameters[$i]); -	} - -	INFO("[ Success.\n"); - - -} - -sub clear_files() { -	# @FIXME: -	# Works implicitly and Fedora seems to have removed -	# the cleanup call. Thus for now, inactive. -	# File::Temp::cleanup(); -} - -require 5.008_000;		# Tested with version 5.8.0. -select STDOUT; $| = 1;		# make STDOUT output unbuffered -select STDERR; $| = 1;		# make STDERR output unbuffered - -parse_command_line(\%opts); -check_tools; -$cfg = open_cfg_file($opts{config}); -process_config($cfg); -clear_files; - -__END__ - - -=head1 NAME - -mkpfi - Using GetOpt::Long, Pod::Usage, Config::IniFiles - - -=head1 SYNOPSIS - -mkpfi  [OPTIONS ...] - - -	OPTION - -	[--config] [--help] [--man] - - -=head1 ABSTRACT - -Perl script for generating pdd pfi files from given config files. - -=head1 OPTIONS - -=over - -=item B<--help> - -Print out brief help message. - -=item B<--usage> - -Print usage. - -=item B<--config> - -Config input file. - -=item B<--man> - -Print manual page, same as 'perldoc mkpfi'. - -=item B<--verbose> - -Be verbose! - -=back - -=head1 BUGS - -Report via MTD mailing list - - -=head1 SEE ALSO - -http://www.linux-mtd.infradead.org/ - - -=head1 AUTHOR - -Oliver Lohmann (oliloh@de.ibm.com) - -=cut diff --git a/ubi-utils/old-tools/scripts/pdd.txt b/ubi-utils/old-tools/scripts/pdd.txt deleted file mode 100644 index a3ad915..0000000 --- a/ubi-utils/old-tools/scripts/pdd.txt +++ /dev/null @@ -1,16 +0,0 @@ -pdd=flash_type,flash_size,flash_eraseblock_size,flash_page_size,card_serialnumber,card_type,ethaddr,eth1addr,eth0,eth1,total,card_hardwarelevel -pdd_preserve=ethaddr,eth1addr,card_serialnumber -# To be personalized -ethaddr=00:04:34:56:78:9A -eth1addr=00:04:34:56:78:9B -card_serialnumber=SN0 -# Static for this card type -total=102M -card_type=nand_driven_testcard -card_hardwarelevel=0 -eth0=bcm5222,eth0,0 -eth1=bcm5222,eth0,1 -flash_type=NAND -flash_size=0x08000000 -flash_eraseblock_size=0x00020000 -flash_page_size=0x00000800 diff --git a/ubi-utils/old-tools/scripts/run_all.sh b/ubi-utils/old-tools/scripts/run_all.sh deleted file mode 100755 index 040bcbd..0000000 --- a/ubi-utils/old-tools/scripts/run_all.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh - -exit_success () -{ -	echo "UBI Utils Test Scripts - SUCCESS!" -	exit 0 -} - -exit_failure () -{ -	echo $1 -	echo "UBI Utils Test Scripts - FAILED!" -	exit 1 -} - -echo UBI Utils Test Scripts - -devno=$1 -logfile=temp-test-log.txt - -if test -z "$devno"; -then -	echo "Usage is $0 <mtd device number>" -	exit 1 -fi - -cwd=`pwd` || exit_failure "pwd failed" - -log="${cwd}/${logfile}" - -PATH=$PATH:$cwd:.. - -cat /dev/null > $log || exit_failure "Failed to create $log" - -echo "Setting up for jffs2_test.sh" | tee -a $log - -avail=`cat /sys/class/ubi/ubi${devno}/avail_eraseblocks` -size=`cat /sys/class/ubi/ubi${devno}/eraseblock_size` - -bytes=`expr $avail \* $size` - -ubimkvol -d$devno -s$bytes -n0 -Njtstvol || exit_failure "ubimkvol failed" - -mkdir -p /mnt/test_file_system || exit_failure "mkdir failed" - -mtd=`cat /proc/mtd | grep jtstvol | cut -d: -f1` - -if test -z "$mtd"; -then -	exit_failure "mtd device not found" -fi - -mount -t jffs2 $mtd /mnt/test_file_system || exit_failure "mount failed" - -cd /mnt/test_file_system || exit_failure "cd failed" - -echo Running jffs2_test.sh | tee -a $log - -jffs2_test.sh >> $log 2>&1 || exit_failure "jffs2_test.sh failed" - -rm -f * - -cd $cwd || exit_failure "cd failed" - -umount /mnt/test_file_system || exit_failure "umount failed" - -ubirmvol -d$devno -n0 || exit_failure "ubirmvol failed" - -major=`cat /sys/class/ubi/ubi${devno}/dev | cut -d: -f1` - -for minor in `seq 0 32`; do -	if test ! -e /dev/ubi${devno}_$minor ; -	then -		mknod /dev/ubi${devno}_$minor c $major $(($minor + 1)) -	fi -done - -rm -f testdata.bin readdata.bin - -echo Running ubi_jffs2_test.sh | tee -a $log - -ubi_jffs2_test.sh >> $log 2>&1 || exit_failure "ubi_jffs2_test.sh failed" - -echo Running ubi_test.sh | tee -a $log - -ubi_test.sh >> $log 2>&1 || exit_failure "ubi_test.sh failed" - -for minor in `seq 0 32`; do -	if test -e /sys/class/ubi/ubi${devno}/$minor; -	then -		ubirmvol -d$devno -n$minor || exit_failure "ubirmvol failed" -	fi -done - -echo Running ubi_tools_test.sh | tee -a $log - -ubi_tools_test.sh >> $log 2>&1 || exit_failure "ubi_tools_test failed" - -rm -f $log - -exit_success diff --git a/ubi-utils/old-tools/scripts/test.cfg b/ubi-utils/old-tools/scripts/test.cfg deleted file mode 100644 index 0b5ec48..0000000 --- a/ubi-utils/old-tools/scripts/test.cfg +++ /dev/null @@ -1,23 +0,0 @@ -[targets] -test_complete=spl,kernel,rootfs - -[spl] -image=test_u-boot.bin -ubi_ids=10,11 -ubi_size=1MiB  -ubi_type=static -ubi_names=test_spl_0,test_spl_1 - -[kernel] -image=test_vmlinux.bin -ubi_ids=12,13 -ubi_size=2MiB  -ubi_type=static -ubi_names=test_kernel_0,test_kernel_1 - -[rootfs] -image=test_rootfs.bin -ubi_ids=14,15 -ubi_size=2MiB  -ubi_type=dynamic -ubi_names=test_rootfs_0,test_rootfs_1 diff --git a/ubi-utils/old-tools/scripts/ubi_test.sh b/ubi-utils/old-tools/scripts/ubi_test.sh deleted file mode 100755 index 73e4b19..0000000 --- a/ubi-utils/old-tools/scripts/ubi_test.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/bin/sh -# -# UBI Volume creation/deletion/write/read test script -# -# Written in shell language to reduce dependencies to more sophisticated  -# interpreters, which may not be available on some stupid platforms. -# -# Author: Frank Haverkamp <haver@vnet.ibm.com> -# -# 1.0 Initial version -# 1.1 Use ubiupdatevol instead of ubiwritevol -# - -VERSION="1.1" - -export PATH=$PATH:~/bin:/usr/local/bin:/home/dedekind/work/prj/ubi/tools/flashutils/bin/ - -UBIMKVOL=ubimkvol -UBIRMVOL=ubirmvol -UBIUPDATEVOL=ubiupdatevol - -# 128 KiB 131072 -# 256 KiB 262144 -# 512 KiB 524288 - -SIZE_512K=524288 -SIZE_1M=1310720 - -SELF=$0 -MINVOL=10 -MAXVOL=12 - -# -# To have a standardized output I define the following function to be -# used when a test was ok or when it failed. -# -failed ()  -{ -    echo "FAILED" -} - -passed () -{ -    echo "PASSED" -} - -# -# Print sucess message. Consider to exit with zero as return code. -# -exit_success () -{ -    echo "SUCCESS" -    exit 0 -} - -# -# Print failure message. Consider to exit with non zero return code. -# -exit_failure () -{ -    echo "FAILED" -    exit 1 -} - -############################################################################### -# -# START -# -############################################################################### - -fix_sysfs_issue () -{ -    echo -n "*** Fixing the sysfs issue with the /dev nodes ... " - -    minor=0 -    major=`grep ubi0 /proc/devices | sed -e 's/\(.*\) ubi0/\1/'` - -    rm -rf /dev/ubi0 -    mknod /dev/ubi0 c $major 0 - -    for minor in `seq 0 $MAXVOL`; do -	### echo " mknod /dev/ubi0_$minor c $major $(($minor + 1))" -        rm -rf /dev/ubi0_$minor -        mknod /dev/ubi0_$minor c $major $(($minor + 1)) -    done -    passed -} - -# delete_volume - Delete a volume. If it does not exist, do not try -#                 to delete it. -# @id:     volume id -# -delete_volume () -{ -    volume=$1 - -    ### FIXME broken sysfs!!!! -    if [ -e /sys/class/ubi/$volume -o -e /sys/class/ubi/ubi0/$volume -o -e /sys/class/ubi/ubi0_$volume ]; then - -	echo -n "*** Truncate volume if it exists ... " -	$UBIUPDATEVOL -d0 -n$volume -t -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed - -	echo -n "*** Delete volume if it exists ... " -	$UBIRMVOL -d0 -n$volume -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed -    fi -} - -mkvol_rmvol_test () -{ -    type=$1 - -### Test if volume delete on non-existing volumes fails nicely - -    for i in `seq $MINVOL $MAXVOL`; do -	echo "*** Delete if exist or not $i ... " - -	delete_volume $i -	passed -    done - -### Now deleting volumes must fail - -    for i in `seq $MINVOL $MAXVOL`; do -	echo "*** Trying to delete non existing UBI Volume $i ... " - -	$UBIRMVOL -d0 -n$i -	if [ $? -eq "0" ] ; then -	    exit_failure -	fi -	passed -    done - -### Test if volume creation works ok - -    for i in `seq $MINVOL $MAXVOL`; do -	echo "*** Creating UBI Volume $i ... " -	echo "    $UBIMKVOL -d0 -n$i -t$type -NNEW$i -s $SIZE_512K" - -	$UBIMKVOL -d0 -n$i -t$type -N"NEW$i" -s $SIZE_512K -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed -    done - -### Now deleting volumes must be ok - -    for i in `seq $MINVOL $MAXVOL`; do -	echo "*** Trying to delete UBI Volume $i ... " - -	$UBIRMVOL -d0 -n$i -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed -    done - -### Now allocate too large volume - -    echo -n "*** Try to create too large volume" -    $UBIMKVOL -d0 -n$MINVOL -t$type -N"NEW$MINVOL" -s 800000000 -    if [ $? -eq "0" ] ; then -	exit_failure -    fi -    passed -} - -# writevol_test - Tests volume creation and writing data to it. -# -# @size:    Size of random data to write -# @type:    Volume type static or dynamic -# -writevol_test () -{ -    size=$1 -    type=$2 - -    echo "*** Write volume test with size $size" - -### Make sure that volume exist, delete existing volume, create new - -    delete_volume $MINVOL - -    echo -n "*** Try to create volume ... " -    $UBIMKVOL -d0 -n$MINVOL -t$type -N"NEW$MINVOL" -s $SIZE_1M -    if [ $? -ne "0" ] ; then -	exit_failure -    fi -    passed -     -### Try to create same volume again -    echo -n "*** Try to create some volume again, this must fail ... " -    $UBIMKVOL -d0 -n$MINVOL -t$type -N"NEW$MINVOL" -s $SIZE_1M -    if [ $? -eq "0" ] ; then -	exit_failure -    fi -    passed -     -### Now create test data, write it, read it, compare it -    echo -n "*** Create test data ... " -    dd if=/dev/urandom of=testdata.bin bs=$size count=1 -    if [ $? -ne "0" ] ; then -	exit_failure -    fi -    passed - -    echo "*** Now writing data to volume ... " -    # sleep 5 -    ls -l testdata.bin -    echo "    $UBIUPDATEVOL -d0 -n$MINVOL testdata.bin" -    $UBIUPDATEVOL -d0 -n$MINVOL testdata.bin -    if [ $? -ne "0" ] ; then -	exit_failure -    fi -    passed - -    if [ $type = "static" ] ; then -	echo "*** Download data with cat ... " -	cat /dev/ubi0_$MINVOL > readdata.bin -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed -    else -	echo "*** Download data with dd bs=1 ... " -	dd if=/dev/ubi0_$MINVOL of=readdata.bin bs=$size count=1 -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed - -	# Size 1 does not work with this test ... -	# -	#echo "*** Download data with dd bs=$size ... " -	#dd if=/dev/ubi0_$MINVOL of=readdata2.bin bs=$size count=1 -	#if [ $? -ne "0" ] ; then -	#    exit_failure -	#fi -	#passed - -	#echo -n "*** Comparing data (1) ... " -	#cmp readdata.bin readdata2.bin -	#if [ $? -ne "0" ] ; then -	#    exit_failure -	#fi -	#passed -    fi - -    echo -n "*** Comparing data ... " -    cmp readdata.bin testdata.bin -    if [ $? -ne "0" ] ; then -	exit_failure -    fi -    passed -} - -echo "***********************************************************************" -echo "*           UBI Testing starts now ...                                *" -echo "*                                 Good luck!                          *" -echo "***********************************************************************" - -# Set to zero if not running on example hardware -grep ubi /proc/devices > /dev/null -if [ $? -ne "0" ]; then -    echo "No UBI found in /proc/devices! I am broken!" -    exit_failure -fi - -# Set to zero if not running on example hardware -grep 1142 /proc/cpuinfo > /dev/null -if [ $? -eq "0" ]; then -    echo "Running on example hardware" -    mount -o remount,rw / / -    sleep 1 -    fix_sysfs_issue -else -    echo "Running on Artems hardware" -fi - -echo "***********************************************************************" -echo "*        mkvol/rmvol testing for static volumes ...                   *" -echo "***********************************************************************" - -mkvol_rmvol_test static - -echo "***********************************************************************" -echo "*        mkvol/rmvol testing for dynamic volumes ...                  *" -echo "***********************************************************************" - -mkvol_rmvol_test dynamic - -echo "***********************************************************************" -echo "*                write to static volumes ...                          *" -echo "***********************************************************************" - -# 10 Erase blocks = (128 KiB - 64 * 2) * 10 -#                 = 1309440 bytes -# 128 KiB 131072 -# 256 KiB 262144 -# 512 KiB 524288 - -for size in 262144 131073 131072 2048 1 4096 12800 31313  ; do -    writevol_test $size static -done - -echo "***********************************************************************" -echo "*                write to dynamic volumes ...                         *" -echo "***********************************************************************" -echo "VERSION: $VERSION" - -for size in 131073 131072 2048 1 4096 12800 31313 262144 ; do -    writevol_test $size dynamic -done - -echo "***********************************************************************" -echo "*               Congratulations, no errors found!                     *" -echo "*              Have fun with your cool UBI system!                    *" -echo "***********************************************************************" - -exit_success diff --git a/ubi-utils/old-tools/scripts/ubi_tools_test.sh b/ubi-utils/old-tools/scripts/ubi_tools_test.sh deleted file mode 100755 index 7f121f1..0000000 --- a/ubi-utils/old-tools/scripts/ubi_tools_test.sh +++ /dev/null @@ -1,252 +0,0 @@ -#!/bin/sh -# -# UBI Volume creation/deletion/write/read test script. -# Uses our flash update tools and the associated toolchain for flash -# image creation. -# -# Written in shell language to reduce dependencies to more sophisticated  -# interpreters, which may not be available on some stupid platforms. -# -# Author: Frank Haverkamp <haver@vnet.ibm.com> -# -# 1.0 Initial version -# - -VERSION="1.0" - -export PATH=$PATH:~/bin:/usr/local/bin:/home/dedekind/work/prj/ubi/tools/flashutils/bin/ - -UBIMKVOL=ubimkvol -UBIRMVOL=ubirmvol -UBIWRITEVOL=ubiupdatevol -PFIFLASH=pfiflash -CMP=cmp - -MAXVOL=32 - -test_pfi=test_complete.pfi -real_pfi=example_complete.pfi - -# 128 KiB 131072 -# 256 KiB 262144 -# 512 KiB 524288 - -# -# To have a standardized output I define the following function to be -# used when a test was ok or when it failed. -# -failed ()  -{ -    echo "FAILED" -} - -passed () -{ -    echo "PASSED" -} - -# -# Print sucess message. Consider to exit with zero as return code. -# -exit_success () -{ -    echo "SUCCESS" -    exit 0 -} - -# -# Print failure message. Consider to exit with non zero return code. -# -exit_failure () -{ -    echo "FAILED" -    exit 1 -} - -############################################################################### -# -# START -# -############################################################################### - -fix_sysfs_issue () -{ -    echo -n "*** Fixing the sysfs issue with the /dev nodes ... " - -    minor=0 -    major=`grep ubi0 /proc/devices | sed -e 's/\(.*\) ubi0/\1/'` - -    rm -rf /dev/ubi0 -    mknod /dev/ubi0 c $major 0 - -    for minor in `seq 0 $MAXVOL`; do -	### echo " mknod /dev/ubi0_$minor c $major $(($minor + 1))" -        rm -rf /dev/ubi0_$minor -        mknod /dev/ubi0_$minor c $major $(($minor + 1)) -    done -    passed -} - -# delete_volume - Delete a volume. If it does not exist, do not try -#                 to delete it. -# @id:     volume id -# -delete_volume () -{ -    volume=$1 - -    ### FIXME broken sysfs!!!! -    if [ -e /sys/class/ubi/$volume -o -e /sys/class/ubi/ubi0/$volume -o -e /sys/class/ubi/ubi0_$volume ]; then - -	echo -n "*** Truncate volume if it exists ... " -	$UBIWRITEVOL -d0 -n$volume -t -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed - -	echo -n "*** Delete volume if it exists ... " -	$UBIRMVOL -d0 -n$volume -	if [ $? -ne "0" ] ; then -	    exit_failure -	fi -	passed -    fi -} - -echo "***********************************************************************" -echo "*           UBI Tools Testing starts now ...                          *" -echo "*                                 Good luck!                          *" -echo "***********************************************************************" - -# Set to zero if not running on example hardware -grep ubi /proc/devices > /dev/null -if [ $? -ne "0" ]; then -    echo "No UBI found in /proc/devices! I am broken!" -    exit_failure -fi - -# Set to zero if not running on example hardware -grep 1142 /proc/cpuinfo > /dev/null -if [ $? -eq "0" ]; then -    echo "Running on example hardware" -    mount -o remount,rw / / -    sleep 1 -    fix_sysfs_issue -else -    echo "Running on other hardware" -fi - -### Test basic stuff -pfiflash_basic () -{ -    echo "Calling pfiflash with test-data ... " -    echo "    $PFIFLASH $test_pfi" -    $PFIFLASH $test_pfi -    if [ $? -ne "0" ]; then -	echo "Uhhh something went wrong!" -	exit_failure -    fi -    passed -     -    echo "Testing if data is correct 10 and 11 ... " -    $CMP /dev/ubi0_10 /dev/ubi0_11 -    if [ $? -ne "0" ]; then -	echo "Mirrored volumes not equal!" -	exit_failure -    fi -    passed -     -    echo "Comparing against original data ... " -    $CMP /dev/ubi0_10 test_u-boot.bin -    if [ $? -ne "0" ]; then -	echo "Compared volume not equal!" -	exit_failure -    fi -    passed -     -    echo "Testing if data is correct 12 and 13 ... " -    $CMP /dev/ubi0_12 /dev/ubi0_13 -    if [ $? -ne "0" ]; then -	echo "Mirrored volumes not equal!" -	exit_failure -    fi -    passed -     -    echo "Comparing against original data ... " -    $CMP /dev/ubi0_12 test_vmlinux.bin -    if [ $? -ne "0" ]; then -	echo "Compared volume not equal!" -	exit_failure -    fi -    passed -     -    echo "Testing if data is correct 14 and 15 ... " -    $CMP /dev/ubi0_14 /dev/ubi0_15 -    if [ $? -ne "0" ]; then -	echo "Mirrored volumes not equal!" -	exit_failure -    fi -    passed -} - -### Test each and everything -pfiflash_advanced () -{ -    if [ -e  example_complete.pfi ]; then -	echo "Calling pfiflash with real data ... " -	$PFIFLASH -p overwrite --complete example_complete.pfi -	if [ $? -ne "0" ]; then -	    echo "Uhhh something went wrong!" -	    exit_failure -	fi -	passed -	 -	echo "Testing if data is correct 2 and 3 ... " -	$CMP /dev/ubi0_2 /dev/ubi0_3 -	if [ $? -ne "0" ]; then -	    echo "Mirrored volumes not equal!" -	    exit_failure -	fi -	passed -	 -	echo "Comparing against original data ... " -	$CMP /dev/ubi0_2 u-boot.bin -	if [ $? -ne "0" ]; then -	    echo "Compared volume not equal!" -	    exit_failure -	fi -	passed -	 -	echo "Testing if data is correct 6 and 7 ... " -	$CMP /dev/ubi0_6 /dev/ubi0_7 -	if [ $? -ne "0" ]; then -	    echo "Mirrored volumes not equal!" -	    exit_failure -	fi -	passed -	 -	echo "Comparing against original data ... " -	$CMP /dev/ubi0_6 vmlinux.bin -	if [ $? -ne "0" ]; then -	    echo "Compared volume not equal!" -	    exit_failure -	fi -	passed -    fi -} - -echo "***********************************************************************" -echo "*                Testing pfiflash ...                                 *" -echo "***********************************************************************" -echo "VERSION: $VERSION" - -pfiflash_basic -pfiflash_advanced -     -echo "***********************************************************************" -echo "*               Congratulations, no errors found!                     *" -echo "*              Have fun with your cool UBI system!                    *" -echo "***********************************************************************" - -exit_success diff --git a/ubi-utils/old-tools/scripts/ubicrc32.pl b/ubi-utils/old-tools/scripts/ubicrc32.pl deleted file mode 100644 index 92711cb..0000000 --- a/ubi-utils/old-tools/scripts/ubicrc32.pl +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/perl -w - -# Subroutine crc32(): Calculates the CRC on a given string. - -{ -    my @table = (); - -    # @brief Calculate CRC32 for a given string. -    sub crc32 -    { -	unless (@table) { -	    # Initialize the CRC table -	    my $poly = 0xEDB88320; -	    @table = (); - -	    for my $i (0..255) { -		my $c = $i; - -		for my $j (0..7) { -		    $c = ($c & 1) ? (($c >> 1) ^ $poly) : ($c >> 1); -		} -		$table[$i] = $c; -	    } -	} -	my $s = shift;		# string to calculate the CRC for -	my $crc = shift;	# CRC start value - -	defined($crc) -	    or $crc = 0xffffffff; # Default CRC start value - -	for (my $i = 0; $i < length($s); $i++) { -	    $crc = $table[($crc ^ ord(substr($s, $i, 1))) & 0xff] -		^ ($crc >> 8); -	} -	return $crc; -    } -} - -sub crc32_on_file -{ -    my $file = shift; - -    my $crc32 = crc32(''); -    my $buf = ''; -    my $ret = 0; - -    while ($ret = read($file, $buf, 8192)) { -	$crc32 = crc32($buf, $crc32); -    } -    defined($ret) -	or return undef; -    printf("0x%x\n", $crc32); -} - - -# Main routine: Calculate the CRCs on the given files and print the -# results. - -{ -    if (@ARGV) { -	while (my $path = shift) { -	    my $file; -	    open $file, "<", $path -		or die "Error opening '$path'.\n"; - -	    &crc32_on_file($file) -		or die "Error reading from '$path'.\n"; -	    close $file; -	} -    } else { -	&crc32_on_file(\*STDIN) -	    or die "Error reading from stdin.\n"; -    } -} diff --git a/ubi-utils/old-tools/scripts/unubi_test.sh b/ubi-utils/old-tools/scripts/unubi_test.sh deleted file mode 100644 index 40dc2e2..0000000 --- a/ubi-utils/old-tools/scripts/unubi_test.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh -# -# Use raw NAND data, extract UBI image and apply tool to it. -# Test basic functionality. -# -# 2007 Frank Haverkamp <haver@vnet.ibm.com> -# - -version=1.1 - -image=data.mif -oob=oob.bin -data=data.bin -pagesize=2048 -volmax=31 -datadir=unubi_data - -# general arguments e.g. debug enablement -# unubi_args="-D" - -echo "------------------------------------------------------------------------" -echo "Testcase: ${0} Version: ${version}" -echo "------------------------------------------------------------------------" -echo "Testing nand2bin ..." -echo "  Input:    ${image}" -echo "  Data:     ${data}" -echo "  OOB:      ${oob}" -echo "  Pagesize: ${pagesize}" -nand2bin --pagesize ${pagesize} -o ${data} -O ${oob} ${image} -echo - -echo "------------------------------------------------------------------------" -echo "Testing unubi ..." -echo "------------------------------------------------------------------------" -unubi --version -echo - -echo "------------------------------------------------------------------------" -echo "Trying to extract first ${volmax} volumes ..." -echo "------------------------------------------------------------------------" -mkdir -p ${datadir}/volumes -for v in `seq 0 ${volmax}` ; do -    unubi ${unubi_args} -r${v} -d${datadir}/volumes ${data} -    echo -n "." -done -echo "ok" -ls -l ${datadir}/volumes -echo - -echo "------------------------------------------------------------------------" -echo "Extracting graphics ..." -echo "------------------------------------------------------------------------" -unubi -a  -d${datadir} ${data} -echo "Use gnuplot to display:" -ls ${datadir}/*.plot -ls ${datadir}/*.data -echo - -echo "------------------------------------------------------------------------" -echo "eb-split" -echo "------------------------------------------------------------------------" -unubi -e -d${datadir}/eb-split ${data} -ls -l ${datadir}/eb-split -echo - -echo "------------------------------------------------------------------------" -echo "vol-split" -echo "------------------------------------------------------------------------" -unubi -v -d${datadir}/vol-split ${data} -ls  -l ${datadir}/vol-split -echo -echo "The generated images contain only the data (126KiB in our   " -echo "case) not including the UBI erase count and volume info     " -echo "header. For dynamic volumes the data should be the full     " -echo "126KiB. Unubi cannot know how much of the data is valid.    " -echo - -echo "------------------------------------------------------------------------" -echo "!vol-split" -echo "------------------------------------------------------------------------" -unubi -V -d${datadir}/vol-split! ${data} -ls -l ${datadir}/vol-split\! -echo -echo "The generated images contain the full block data of 128KiB  " -echo "including the UBI erase count and volume information header." -echo - -echo "------------------------------------------------------------------------" -echo "Extracting volume info table ..." -echo "------------------------------------------------------------------------" -unubi -i -d${datadir} ${data} -echo "I strongly hope that empty ubi blocks are filled with 0xff! " -echo - -echo "------------------------------------------------------------------------" -echo "Table 0" -echo "------------------------------------------------------------------------" -cat ${datadir}/vol_info_table0 -echo - -echo "------------------------------------------------------------------------" -echo "Table 1" -echo "------------------------------------------------------------------------" -cat ${datadir}/vol_info_table1 -echo diff --git a/ubi-utils/old-tools/src/bin2nand.c b/ubi-utils/old-tools/src/bin2nand.c deleted file mode 100644 index 83f50cc..0000000 --- a/ubi-utils/old-tools/src/bin2nand.c +++ /dev/null @@ -1,366 +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) - * 1.7 Made NAND ECC layout configurable (haver) - */ - -#include <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <getopt.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> - -#include "error.h" -#include "config.h" -#include "nandecc.h" -#include "ecclayouts.h" - -#define PROGRAM_VERSION "1.7" - -#define ARRAY_SIZE(a)    (sizeof(a) / sizeof((a)[0])) - -#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=<num>      Padding in Byte/Mi/ki. Default = no padding\n" -"  -l, --ecc-placement=<MTD,IBM> OOB placement scheme (default is IBM).\n" -"  -p, --pagesize=<num>     Pagesize in Byte/Mi/ki. Default = 2048\n" -"  -o, --output=<fname>     Output filename. Interleaved Data/OOB if\n" -"                           output-oob not specified.\n" -"  -q, --output-oob=<fname> 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 <num>] [-p <num>] [-o <fname>] [-q <fname>]\n" -"            [--copyright] [--padding=<num>] [--pagesize=<num>]\n" -"            [--output=<fname>] [--output-oob=<fname>] [--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 = "ecc-layout", .has_arg = 1, .flag = NULL, .val = 'l' }, -	{ .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} -}; - -#define __unused __attribute__((unused)) -static const char copyright [] __unused = "Copyright IBM Corp. 2007"; - -struct args { -	action_t action; - -	size_t pagesize; -	size_t oobsize; -	size_t padding; - -	FILE* fp_in; -	const char *file_out_data; /* Either: Data and OOB interleaved -				      or plain data */ -	const char *file_out_oob; /* OOB Data only. */ -	struct nand_ecclayout *nand_oob; - -	/* special stuff needed to get additional arguments */ -	char *arg1; -	char **options;			/* [STRING...] */ -}; - - -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, struct args *args) -{ -	const char *ecc_layout = NULL; -	unsigned int i, oob_idx = 0; -	char* endp; - -	while (1) { -		int key; - -		key = getopt_long(argc, argv, "cj:l: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 'l': /* --ecc-layout=<...> */ -			ecc_layout = optarg; -			break; -		case '?': /* help */ -			printf("%s%s", doc, 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++]); -		} -	} - -	switch (args->pagesize) { -	case 512:  args->oobsize = 16; oob_idx = 0; break; -	case 2048: args->oobsize = 64; oob_idx = 1; break; -	default: -		err_msg("Unsupported page size: %d\n", args->pagesize); -		return -EINVAL; -	} - -	/* Figure out correct oob layout if it differs from default */ -	if (ecc_layout) { -		for (i = 0; i < ARRAY_SIZE(oob_placement); i++) -			if (strcmp(ecc_layout, oob_placement[i].name) == 0) -				args->nand_oob = -					oob_placement[i].nand_oob[oob_idx]; -	} -	return 0; -} - -static int -process_page(struct args *args, uint8_t *buf, FILE *fp_data, FILE *fp_oob, -	     size_t *written) -{ -	int eccpoi; -	size_t i; -	uint8_t oobbuf[64]; -	uint8_t ecc_code[3] = { 0, }; /* temp */ - -	/* Calculate ECC for each subpage of 256 bytes */ -	memset(oobbuf, 0xff, sizeof(oobbuf)); -	for (eccpoi = 0, i = 0; i < args->pagesize; i += 256, eccpoi += 3) { -		int j; -		nand_calculate_ecc(&buf[i], ecc_code); -		for (j = 0; j < 3; j++) -			oobbuf[args->nand_oob->eccpos[eccpoi + j]] = ecc_code[j]; -	} - -	/* write data */ -	*written += fwrite(buf, 1, args->pagesize, fp_data); - -	/* either separate oob or interleave with data */ -	if (fp_oob) { -		i = fwrite(oobbuf, 1, args->oobsize, fp_oob); -		if (ferror(fp_oob)) { -			err_msg("IO error\n"); -			return -EIO; -		} -	} -	else { -		i = fwrite(oobbuf, 1, args->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; -	struct args args = { -		.action	  = ACT_NORMAL, -		.pagesize = PAGESIZE, -		.padding  = PADDING, -		.fp_in	  = NULL, -		.file_out_data = NULL, -		.file_out_oob = NULL, -		.nand_oob = &ibm_nand_oob_64, -	}; - -	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(&args, buf, fp_out_data, fp_out_oob, -				   &written); -		if (res != 0) -			goto err; -	} - -	while (written < args.padding) { -		memset(buf, 0xff, args.pagesize); -		res = process_page(&args, buf, 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-tools/src/bootenv.c b/ubi-utils/old-tools/src/bootenv.c deleted file mode 100644 index a6dd4de..0000000 --- a/ubi-utils/old-tools/src/bootenv.c +++ /dev/null @@ -1,1032 +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 <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <netinet/in.h> -#include <sys/stat.h> -#include <bootenv.h> - -#include "hashmap.h" -#include "error.h" - -#include <mtd/ubi-header.h> -#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: <oliloh@de.ibm.com>"); - -	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-tools/src/bootenv.h b/ubi-utils/old-tools/src/bootenv.h deleted file mode 100644 index 8fecdbf..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> /* FILE */ -#include <stdint.h> -#include <pfiflash.h> - -/* 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: - * @verbatim<CRC32-bit>key1=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-tools/src/common.c b/ubi-utils/old-tools/src/common.c deleted file mode 100644 index 7ed1ade..0000000 --- a/ubi-utils/old-tools/src/common.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) Artem Bityutskiy, 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. - */ - -/* - * This file contains various common stuff used by UBI utilities. - * - * Author: Artem Bityutskiy - */ - -#include <stdio.h> -#include <string.h> - -/** - * ubiutils_bytes_multiplier - convert size specifier to an integer - *                             multiplier. - * - * @str: the size specifier string - * - * This function parses the @str size specifier, which may be one of - * 'KiB', 'MiB', or 'GiB' into an integer multiplier. Returns positive - * size multiplier in case of success and %-1 in case of failure. - */ -int ubiutils_get_multiplier(const char *str) -{ -	if (!str) -		return 1; - -	/* Remove spaces before the specifier */ -	while (*str == ' ' || *str == '\t') -		str += 1; - -	if (!strcmp(str, "KiB")) -		return 1024; -	if (!strcmp(str, "MiB")) -		return 1024 * 1024; -	if (!strcmp(str, "GiB")) -		return 1024 * 1024 * 1024; - -	return -1; -} - -/** - * ubiutils_print_bytes - print bytes. - * @bytes: variable to print - * @bracket: whether brackets have to be put or not - * - * This is a helper function which prints amount of bytes in a human-readable - * form, i.e., it prints the exact amount of bytes following by the approximate - * amount of Kilobytes, Megabytes, or Gigabytes, depending on how big @bytes - * is. - */ -void ubiutils_print_bytes(long long bytes, int bracket) -{ -	const char *p; - -	if (bracket) -		p = " ("; -	else -		p = ", "; - -	printf("%lld bytes", bytes); - -	if (bytes > 1024 * 1024 * 1024) -		printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024)); -	else if (bytes > 1024 * 1024) -		printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024)); -	else if (bytes > 1024) -		printf("%s%.1f KiB", p, (double)bytes / 1024); -	else -		return; - -	if (bracket) -		printf(")"); -} diff --git a/ubi-utils/old-tools/src/common.h b/ubi-utils/old-tools/src/common.h deleted file mode 100644 index 06ae623..0000000 --- a/ubi-utils/old-tools/src/common.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Artem Bityutskiy, 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 __UBI_UTILS_COMMON_H__ -#define __UBI_UTILS_COMMON_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Error messages */ -#define errmsg(fmt, ...) do {                                             \ -        fprintf(stderr, PROGRAM_NAME " error: " fmt "\n", ##__VA_ARGS__); \ -} while(0) - -/* Warnings */ -#define warnmsg(fmt, ...) do {                                              \ -        fprintf(stderr, PROGRAM_NAME " warning: " fmt "\n", ##__VA_ARGS__); \ -} while(0) - -int ubiutils_get_multiplier(const char *str); -void ubiutils_print_bytes(long long bytes, int bracket); - -#ifdef __cplusplus -} -#endif - -#endif /* !__UBI_UTILS_COMMON_H__ */ diff --git a/ubi-utils/old-tools/src/config.h b/ubi-utils/old-tools/src/config.h deleted file mode 100644 index 55e60f3..0000000 --- a/ubi-utils/old-tools/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-tools/src/crc32.c b/ubi-utils/old-tools/src/crc32.c deleted file mode 100644 index 666e217..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> -#include <crc32.h> - -/* 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-tools/src/crc32.h b/ubi-utils/old-tools/src/crc32.h deleted file mode 100644 index 31362b0..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> - -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-tools/src/eb_chain.c b/ubi-utils/old-tools/src/eb_chain.c deleted file mode 100644 index 4647cf4..0000000 --- a/ubi-utils/old-tools/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 <errno.h> -#include <stdlib.h> -#include <string.h> -#include <mtd_swab.h> -#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), -			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), -				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-tools/src/ecclayouts.h b/ubi-utils/old-tools/src/ecclayouts.h deleted file mode 100644 index a1c7823..0000000 --- a/ubi-utils/old-tools/src/ecclayouts.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __ECCLAYOUTS_H__ -#define __ECCLAYOUTS_H__ -/* - * 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. - */ - -#include <stdint.h> -#include <mtd/mtd-abi.h> - -/* Define default oob placement schemes for large and small page devices */ -static struct nand_ecclayout mtd_nand_oob_16 = { -	.eccbytes = 6, -	.eccpos = { 0, 1, 2, 3, 6, 7 }, -	.oobfree = {{ .offset = 8, .length = 8 }} -}; - -static struct nand_ecclayout mtd_nand_oob_64 = { -	.eccbytes = 24, -	.eccpos = { 40, 41, 42, 43, 44, 45, 46, 47, -		    48, 49, 50, 51, 52, 53, 54, 55, -		    56, 57, 58, 59, 60, 61, 62, 63 }, -	.oobfree = {{ .offset = 2, .length = 38 }} -}; - -/* Define IBM oob placement schemes */ -static struct nand_ecclayout ibm_nand_oob_16 = { -	.eccbytes = 6, -	.eccpos = { 9, 10, 11, 13, 14, 15 }, -	.oobfree = {{ .offset = 8, .length = 8 }} -}; - -static struct nand_ecclayout ibm_nand_oob_64 = { -	.eccbytes = 24, -	.eccpos = { 33, 34, 35, 37, 38, 39, 41, 42, -		    43, 45, 46, 47, 49, 50, 51, 53, -		    54, 55, 57, 58, 59, 61, 62, 63 }, -	.oobfree = {{ .offset = 2, .length = 30 }} -}; - -struct oob_placement { -	const char *name; -	struct nand_ecclayout *nand_oob[2]; -}; - -static struct oob_placement oob_placement[] = { -	{ .name = "IBM", -	  .nand_oob = { &ibm_nand_oob_16, &ibm_nand_oob_64 }}, -	{ .name = "MTD", -	  .nand_oob = { &mtd_nand_oob_16, &mtd_nand_oob_64 }}, -}; - -#endif diff --git a/ubi-utils/old-tools/src/error.c b/ubi-utils/old-tools/src/error.c deleted file mode 100644 index 4aaedad..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> -#include <stdarg.h> -#include <syslog.h> -#include <stdlib.h> -#include <sys/errno.h> -#include <string.h> -#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-tools/src/error.h b/ubi-utils/old-tools/src/error.h deleted file mode 100644 index 05d8078..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> - -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-tools/src/example_ubi.h b/ubi-utils/old-tools/src/example_ubi.h deleted file mode 100644 index 23c7b54..0000000 --- a/ubi-utils/old-tools/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-tools/src/hashmap.c b/ubi-utils/old-tools/src/hashmap.c deleted file mode 100644 index 3511d56..0000000 --- a/ubi-utils/old-tools/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 <errno.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#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-tools/src/hashmap.h b/ubi-utils/old-tools/src/hashmap.h deleted file mode 100644 index 1b13e95..0000000 --- a/ubi-utils/old-tools/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 <stdlib.h> -#include <stdint.h> - -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-tools/src/libpfiflash.c b/ubi-utils/old-tools/src/libpfiflash.c deleted file mode 100644 index 7e3d3b3..0000000 --- a/ubi-utils/old-tools/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 <oliloh@de.ibm.com> - *	    Drake Dowsett <dowsett@de.ibm.com> - * Contact: Andreas Arnez <anrez@de.ibm.com> - */ - -/* 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 <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#define __USE_GNU -#include <string.h> -#include <stdlib.h> -#include <limits.h> -#include <sys/ioctl.h> - -#include <libubi.h> -#include <pfiflash.h> - -#include <mtd/ubi-user.h>	/* FIXME Is this ok here? */ -#include <mtd/mtd-user.h> - -#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 <mtd/ubi-header.h>	/* 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(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(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(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(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(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(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(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(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(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(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(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(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(PFIFLASH_ERRSTR[-rc]); -				goto err; -			} else if (ferror(pfi)) { -				rc = -PFIFLASH_ERR_FIO; -				EBUF(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(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(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(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(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(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-tools/src/libubi.c b/ubi-utils/old-tools/src/libubi.c deleted file mode 100644 index be06f70..0000000 --- a/ubi-utils/old-tools/src/libubi.c +++ /dev/null @@ -1,1171 +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 <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include "libubi.h" -#include "libubi_int.h" - -/** - * mkpath - compose full path from 2 given components. - * @path: the first component - * @name: the 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) { -		errmsg("cannot allocate %d bytes", len1 + len2 + 2); -		perror("malloc"); -		return NULL; -	} - -	memcpy(n, path, len1); -	if (n[len1 - 1] != '/') -		n[len1++] = '/'; - -	memcpy(n + len1, name, len2 + 1); -	return n; -} - -/** - * read_positive_ll - read a positive 'long long' value from a file. - * @file: the file to read from - * @value: the result is stored here - * - * This function reads file @file and interprets its contents as a positive - * 'long long' integer. If this is not true, it fails with %EINVAL error code. - * Returns %0 in case of success and %-1 in case of failure. - */ -static int read_positive_ll(const char *file, long long *value) -{ -	int fd, rd; -	char buf[50]; - -	fd = open(file, O_RDONLY); -	if (fd == -1) -		return -1; - -	rd = read(fd, buf, 50); -	if (rd == -1) { -		errmsg("cannot read \"%s\"", file); -		perror("read"); -		goto out_error; -	} -	if (rd == 50) { -		errmsg("contents of \"%s\" is too long", file); -		errno = EINVAL; -		goto out_error; -	} - -	if (sscanf(buf, "%lld\n", value) != 1) { -		/* This must be a UBI bug */ -		errmsg("cannot read integer from \"%s\"\n", file); -		errno = EINVAL; -		goto out_error; -	} - -	if (*value < 0) { -		errmsg("negative value %lld in \"%s\"", *value, file); -		errno = EINVAL; -		goto out_error; -	} - -	if (close(fd)) { -		errmsg("close failed on \"%s\"", file); -		perror("close"); -		return -1; -	} - -	return 0; - -out_error: -	close(fd); -	return -1; -} - -/** - * read_positive_int - read a positive 'int' value from a file. - * @file: the file to read from - * @value: the result is stored here - * - * This function is the same as 'read_positive_ll()', but it reads an 'int' - * value, not 'long long'. - */ -static int read_positive_int(const char *file, int *value) -{ -	long long res; - -	if (read_positive_ll(file, &res)) -		return -1; - -	/* Make sure the value is not too big */ -	if (res > INT_MAX) { -		errmsg("value %lld read from file \"%s\" is out of range", -		       res, file); -		errno = EINVAL; -		return -1; -	} - -	*value = res; -	return 0; -} - -/** - * read_data - read data from a file. - * @file: the file to read from - * @buf: the 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. Note, if the file contains more then @buf_len bytes of - * date, this function fails with %EINVAL error code. - */ -static int read_data(const char *file, void *buf, int buf_len) -{ -	int fd, rd, tmp, tmp1; - -	fd = open(file, O_RDONLY); -	if (fd == -1) -		return -1; - -	rd = read(fd, buf, buf_len); -	if (rd == -1) { -		errmsg("cannot read \"%s\"", file); -		perror("read"); -		goto out_error; -	} - -	/* Make sure all data is read */ -	tmp1 = read(fd, &tmp, 1); -	if (tmp1 == 1) { -		errmsg("cannot read \"%s\"", file); -		perror("read"); -		goto out_error; -	} -	if (tmp1) { -		errmsg("file \"%s\" contains too much data (> %d bytes)", -		       file, buf_len); -		errno = EINVAL; -		goto out_error; -	} - -	if (close(fd)) { -		errmsg("close failed on \"%s\"", file); -		perror("close"); -		return -1; -	} - -	return rd; - -out_error: -	close(fd); -	return -1; -} - -/** - * read_major - read major and minor numbers from a file. - * @file: name of the file to read from - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns % in case of succes, and %-1 in case of failure. - */ -static int read_major(const char *file, int *major, int *minor) -{ -	int ret; -	char buf[50]; - -	ret = read_data(file, buf, 50); -	if (ret < 0) -		return ret; - -	ret = sscanf(buf, "%d:%d\n", major, minor); -	if (ret != 2) { -		errmsg("\"%s\" does not have major:minor format", file); -		errno = EINVAL; -		return -1; -	} - -	if (*major < 0 || *minor < 0) { -		errmsg("bad major:minor %d:%d in \"%s\"", -		       *major, *minor, file); -		errno = EINVAL; -		return -1; -	} - -	return 0; -} - -/** - * dev_read_int - read a positive 'int' value from an UBI device sysfs file. - * @patt: 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) -{ -	char file[strlen(patt) + 50]; - -	sprintf(file, patt, dev_num); -	return read_positive_int(file, value); -} - -/** - * vol_read_int - read a positive 'int' value from an UBI volume sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @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) -{ -	char file[strlen(patt) + 100]; - -	sprintf(file, patt, dev_num, vol_id); -	return read_positive_int(file, value); -} - -/** - * dev_read_ll - read a positive 'long long' value from an UBI device sysfs file. - * @patt: 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) -{ -	char file[strlen(patt) + 50]; - -	sprintf(file, patt, dev_num); -	return read_positive_ll(file, value); -} - -/** - * vol_read_ll - read a positive 'long long' value from an UBI volume sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @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) -{ -	char file[strlen(patt) + 100]; - -	sprintf(file, patt, dev_num, vol_id); -	return read_positive_ll(file, value); -} - -/** - * vol_read_data - read data from an UBI volume's sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @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) -{ -	char file[strlen(patt) + 100]; - -	sprintf(file, patt, dev_num, vol_id); -	return read_data(file, buf, buf_len); -} - -/** - * dent_is_dir - check if a file is a directory. - * @dir: the base directory path of the file - * @name: file name - * - * This function returns %1 if file @name in directory @dir is a directoru, and - * %0 if not. - */ -static int dent_is_dir(const char *dir, const char *name) -{ -	int ret; -	struct stat st; -	char full_path[strlen(dir) + strlen(name) + 2]; - -	sprintf(full_path, "%s/%s", dir, name); -	ret = lstat(full_path, &st); -	if (ret) { -		errmsg("lstat failed on \"%s\"", full_path); -		perror("lstat"); -		return -1; -	} - -	return !!S_ISDIR(st.st_mode); -} - -/** - * dev_get_major - get major and minor numbers of an UBI device. - * @lib: libubi descriptor - * @dev_num: UBI device number - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int dev_get_major(struct libubi *lib, int dev_num, int *major, int *minor) -{ -	char file[strlen(lib->dev_dev) + 50]; - -	sprintf(file, lib->dev_dev, dev_num); -	return read_major(file, major, minor); -} - -/** - * vol_get_major - get major and minor numbers of an UBI volume. - * @lib: libubi descriptor - * @dev_num: UBI device number - * @vol_id: volume ID - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int vol_get_major(struct libubi *lib, int dev_num, int vol_id, -			 int *major, int *minor) -{ -	char file[strlen(lib->vol_dev) + 100]; - -	sprintf(file, lib->vol_dev, dev_num, vol_id); -	return read_major(file, major, minor); -} - -/** - * vol_node2nums - find UBI device number and volume ID by volume device node - *                 file. - * @lib: UBI library descriptor - * @node: UBI character device node name - * @dev_num: UBI device number is returned here - * @vol_id: volume ID is returned hers - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num, -			 int *vol_id) -{ -	struct stat st; -	struct ubi_info info; -	int i, fd, major, minor; -	char file[strlen(lib->ubi_vol) + 100]; - -	if (lstat(node, &st)) -		return -1; - -	if (!S_ISCHR(st.st_mode)) { -		errmsg("\"%s\" is not a character device", node); -		errno = EINVAL; -		return -1; -	} - -	major = major(st.st_rdev); -	minor = minor(st.st_rdev); - -	if (minor == 0) { -		errmsg("\"%s\" is not a volume character device", node); -		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; - -		ret = dev_get_major(lib, i, &major1, &minor1); -		if (ret) { -			if (errno == ENOENT) -				continue; -			return -1; -		} - -		if (major1 == major) -			break; -	} - -	if (i > info.highest_dev_num) { -		errno = ENODEV; -		return -1; -	} - -	/* Make sure this UBI volume exists */ -	sprintf(file, lib->ubi_vol, i, minor - 1); -	fd = open(file, O_RDONLY); -	if (fd == -1) { -		errno = ENODEV; -		return -1; -	} - -	*dev_num = i; -	*vol_id = minor - 1; -	errno = 0; -	return 0; -} - -/** - * dev_node2num - 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 dev_node2num(struct libubi *lib, const char *node, int *dev_num) -{ -	struct stat stat; -	struct ubi_info info; -	int i, major, minor; - -	if (lstat(node, &stat)) -		return -1; - -	if (!S_ISCHR(stat.st_mode)) { -		errmsg("\"%s\" is not a character device", node); -		errno = EINVAL; -		return -1; -	} - -	major = major(stat.st_rdev); -	minor = minor(stat.st_rdev); - -	if (minor != 0) { -		errmsg("\"%s\" is not an UBI character device", node); -		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; - -		ret = dev_get_major(lib, i, &major1, &minor1); -		if (ret) { -			if (errno == ENOENT) -				continue; -			return -1; -		} - -		if (major1 == major) { -			if (minor1 != 0) { -				errmsg("UBI character device minor number is " -				       "%d, but must be 0", minor1); -				errno = EINVAL; -				return -1; -			} -			errno = 0; -			*dev_num = i; -			return 0; -		} -	} - -	errno = ENODEV; -	return -1; -} - -static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num) -{ -	struct ubi_info info; -	int i, ret, mtd_num1; - -	if (ubi_get_info((libubi_t *)lib, &info)) -		return -1; - -	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { -		ret = dev_read_int(lib->dev_mtd_num, i, &mtd_num1); -		if (ret) { -			if (errno == ENOENT) -				continue; -			return -1; -		} - -		if (mtd_num1 == mtd_num) { -			errno = 0; -			*dev_num = i; -			return 0; -		} -	} - -	errno = ENODEV; -	return -1; -} - -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 out_error; - -	lib->sysfs_ctrl = mkpath(lib->sysfs, SYSFS_CTRL); -	if (!lib->sysfs_ctrl) -		goto out_error; - -	lib->ctrl_dev = mkpath(lib->sysfs_ctrl, CTRL_DEV); -	if (!lib->ctrl_dev) -		goto out_error; - -	lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI); -	if (!lib->sysfs_ubi) -		goto out_error; - -	/* Make sure UBI is present */ -	fd = open(lib->sysfs_ubi, O_RDONLY); -	if (fd == -1) { -		errmsg("cannot open \"%s\", UBI does not seem to exist in system", -		       lib->sysfs_ubi); -		goto out_error; -	} - -	if (close(fd)) { -		errmsg("close failed on \"%s\"", lib->sysfs_ubi); -		perror("close"); -		goto out_error; -	} - -	lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); -	if (!lib->ubi_dev) -		goto out_error; - -	lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); -	if (!lib->ubi_version) -		goto out_error; - -	lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); -	if (!lib->dev_dev) -		goto out_error; - -	lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); -	if (!lib->dev_avail_ebs) -		goto out_error; - -	lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); -	if (!lib->dev_total_ebs) -		goto out_error; - -	lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); -	if (!lib->dev_bad_count) -		goto out_error; - -	lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); -	if (!lib->dev_eb_size) -		goto out_error; - -	lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); -	if (!lib->dev_max_ec) -		goto out_error; - -	lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); -	if (!lib->dev_bad_rsvd) -		goto out_error; - -	lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); -	if (!lib->dev_max_vols) -		goto out_error; - -	lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); -	if (!lib->dev_min_io_size) -		goto out_error; - -	lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM); -	if (!lib->dev_mtd_num) -		goto out_error; - -	lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); -	if (!lib->ubi_vol) -		goto out_error; - -	lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); -	if (!lib->vol_type) -		goto out_error; - -	lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); -	if (!lib->vol_dev) -		goto out_error; - -	lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); -	if (!lib->vol_alignment) -		goto out_error; - -	lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); -	if (!lib->vol_data_bytes) -		goto out_error; - -	lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); -	if (!lib->vol_rsvd_ebs) -		goto out_error; - -	lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); -	if (!lib->vol_eb_size) -		goto out_error; - -	lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); -	if (!lib->vol_corrupted) -		goto out_error; - -	lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); -	if (!lib->vol_name) -		goto out_error; - -	if (read_positive_int(lib->ubi_version, &version)) -		goto out_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 out_error; -	} - -	return lib; - -out_error: -	libubi_close((libubi_t)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_mtd_num); -	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->ctrl_dev); -	free(lib->sysfs_ctrl); -	free(lib->sysfs); -	free(lib); -} - -int ubi_attach_mtd(libubi_t desc, const char *node, -		   struct ubi_attach_request *req) -{ -	int fd, ret; -	struct ubi_attach_req r; - -	memset(&r, sizeof(struct ubi_attach_req), '\0'); - -	desc = desc; -	r.ubi_num = req->dev_num; -	r.mtd_num = req->mtd_num; -	r.vid_hdr_offset = req->vid_hdr_offset; - -	fd = open(node, O_RDONLY); -	if (fd == -1) -		return -1; - -	ret = ioctl(fd, UBI_IOCATT, &r); -	close(fd); -	if (ret == -1) -		return -1; - -	req->dev_num = r.ubi_num; - -#ifdef UDEV_SETTLE_HACK -	if (system("udevsettle") == -1) -		return -1; -	if (system("udevsettle") == -1) -		return -1; -#endif - -	return ret; -} - -int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num) -{ -	int ret, ubi_dev; - -	ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev); -	if (ret == -1) -		return ret; - -	return ubi_remove_dev(desc, node, ubi_dev); -} - -int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev) -{ -	int fd, ret; - -	desc = desc; - -	fd = open(node, O_RDONLY); -	if (fd == -1) -		return -1; -	ret = ioctl(fd, UBI_IOCDET, &ubi_dev); -	if (ret == -1) -		goto out_close; - -#ifdef UDEV_SETTLE_HACK -	if (system("udevsettle") == -1) -		return -1; -#endif - -out_close: -	close(fd); -	return ret; -} - -int ubi_node_type(libubi_t desc, const char *node) -{ -	struct stat st; -	struct ubi_info info; -	int i, fd, major, minor; -	struct libubi *lib = (struct libubi *)desc; -	char file[strlen(lib->ubi_vol) + 100]; - -	if (lstat(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 (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; - -		ret = dev_get_major(lib, i, &major1, &minor1); -		if (ret) { -			if (errno == ENOENT) -				continue; -			return -1; -		} - -		if (major1 == major) -			break; -	} - -	if (i > info.highest_dev_num) { -		/* -		 * The character device node does not correspond to any -		 * existing UBI device or volume, but we do not want to return -		 * any error number in this case, to indicate the fact that it -		 * could be a UBI device/volume, but it doesn't. -		 */ -		errno = 0; -		return -1; -	} - -	if (minor == 0) -		return 1; - -	/* This is supposdely an UBI volume device node */ -	sprintf(file, lib->ubi_vol, i, minor - 1); -	fd = open(file, O_RDONLY); -	if (fd == -1) { -		errno = 0; -		return -1; -	} - -	return 2; -} - -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)); - -	if (read_major(lib->ctrl_dev, &info->ctrl_major, &info->ctrl_minor)) { -		/* -		 * Older UBI versions did not have control device, so we do not -		 * panic here for compatibility reasons. May be few years later -		 * we could return -1 here, but for now just set major:minor to -		 * -1. -		 */ -		info->ctrl_major = info->ctrl_minor = -1; -	} - -	/* -	 * 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) { -		errmsg("cannot open %s", lib->sysfs_ubi); -		perror("opendir"); -		return -1; -	} - -	info->lowest_dev_num = INT_MAX; -	while (1) { -		int dev_num, ret; - -		errno = 0; -		dirent = readdir(sysfs_ubi); -		if (!dirent) -			break; -		/* -		 * Make sure this direntry is a directory and not a symlink - -		 * Linux puts symlinks to UBI volumes on this UBI device to the -		 * same sysfs directory. -		 */ -		if (!dent_is_dir(lib->sysfs_ubi, dirent->d_name)) -			continue; - -		ret = sscanf(dirent->d_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 (!dirent && errno) { -		errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); -		perror("readdir"); -		goto out_close; -	} - -	if (closedir(sysfs_ubi)) { -		errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); -		perror("closedir"); -		return -1; -	} - -	if (info->lowest_dev_num == INT_MAX) -		info->lowest_dev_num = 0; - -	if (read_positive_int(lib->ubi_version, &info->version)) -		return -1; - -	return 0; - -out_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; - -	memset(&r, sizeof(struct ubi_mkvol_req), '\0'); - -	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 == -1) -		goto out_close; - -	req->vol_id = r.vol_id; - -#ifdef UDEV_SETTLE_HACK -	if (system("udevsettle") == -1) -		return -1; -#endif - -out_close: -	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); -	if (ret == -1) -		goto out_close; - -#ifdef UDEV_SETTLE_HACK -	if (system("udevsettle") == -1) -		return -1; -#endif - -out_close: -	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_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 (1) { -		int vol_id, ret, devno; - -		errno = 0; -		dirent = readdir(sysfs_ubi); -		if (!dirent) -			break; -		ret = sscanf(dirent->d_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; -		} -	} - -	if (!dirent && errno) { -		errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); -		perror("readdir"); -		goto out_close; -	} - -	if (closedir(sysfs_ubi)) { -		errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); -		perror("closedir"); -		return -1; -	} - -	if (info->lowest_vol_num == INT_MAX) -		info->lowest_vol_num = 0; - -	if (dev_get_major(lib, dev_num, &info->major, &info->minor)) -		return -1; - -	if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_lebs)) -		return -1; -	if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_lebs)) -		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->leb_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_lebs * info->leb_size; -	info->total_bytes = info->total_lebs * info->leb_size; - -	return 0; - -out_close: -	closedir(sysfs_ubi); -	return -1; -} - -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; - -	if (dev_node2num(lib, node, &dev_num)) -		return -1; - -	return ubi_get_dev_info1(desc, dev_num, 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; - -	if (dev_get_major(lib, dev_num, &info->dev_major, &info->dev_minor)) -		return -1; -	if (vol_get_major(lib, dev_num, vol_id, &info->major, &info->minor)) -		return -1; - -	ret = vol_read_data(lib->vol_type, dev_num, vol_id, buf, 50); -	if (ret < 0) -		return -1; - -	if (strncmp(buf, "static\n", ret) == 0) -		info->type = UBI_STATIC_VOLUME; -	else if (strncmp(buf, "dynamic\n", ret) == 0) -		info->type = UBI_DYNAMIC_VOLUME; -	else { -		errmsg("bad value at \"%s\"", buf); -		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_lebs); -	if (ret) -		return -1; -	ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->leb_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->leb_size * info->rsvd_lebs; - -	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; -} - -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; - -	if (vol_node2nums(lib, node, &dev_num, &vol_id)) -		return -1; - -	return ubi_get_vol_info1(desc, dev_num, vol_id, info); -} diff --git a/ubi-utils/old-tools/src/libubi_int.h b/ubi-utils/old-tools/src/libubi_int.h deleted file mode 100644 index 6490864..0000000 --- a/ubi-utils/old-tools/src/libubi_int.h +++ /dev/null @@ -1,135 +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 - -/* Error messages */ -#define errmsg(fmt, ...) do {                                      \ -        fprintf(stderr, "libubi error: " fmt "\n", ##__VA_ARGS__); \ -} while(0) - -/* - * The below are pre-define UBI file and directory names. - * - * Note, older kernels put 'ubiX_Y' directories straight to '/sys/class/ubi/'. - * New kernels puts 'ubiX_Y' directories to '/sys/class/ubi/ubiX/', which is - * saner. And for compatibility reasons it also puts symlinks to 'ubiX_Y' - * directories to '/sys/class/ubi/'. For now libubi assumes old layout. - */ - -#define SYSFS_UBI         "class/ubi" -#define SYSFS_CTRL        "class/misc/ubi_ctrl/" - -#define CTRL_DEV          "dev" - -#define UBI_VER           "version" -#define UBI_DEV_NAME_PATT "ubi%d" - -#define DEV_DEV           "dev" -#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 DEV_MTD_NUM       "mtd_num" - -#define UBI_VOL_NAME_PATT "ubi%d_%d" -#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_ctrl: UBI control device directory in sysfs - * @ctrl_dev: UBI control device major/minor numbers sysfs file - * @sysfs_ubi: UBI directory in sysfs - * @ubi_dev: UBI device sysfs directory pattern - * @ubi_version: UBI version file sysfs path - * @dev_dev: UBI device 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 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_ctrl; -	char *ctrl_dev; -	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 *dev_mtd_num; -	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; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBI_INT_H__ */ diff --git a/ubi-utils/old-tools/src/libubigen.c b/ubi-utils/old-tools/src/libubigen.c deleted file mode 100644 index d2cd087..0000000 --- a/ubi-utils/old-tools/src/libubigen.c +++ /dev/null @@ -1,486 +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 <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <mtd/ubi-header.h> - -#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 peb_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 peb_size) -{ -	return (byte % peb_size) == 0 -		? (byte / peb_size) -		: (byte / peb_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->peb_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->peb_size, u->fp_out); -	if (written != u->peb_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, "<empty>"); -		return; -	} -	if (!u->ec) { -		fprintf(stderr, "<ec-empty>"); -		err = 1; -	} -	if (!u->v) { -		fprintf(stderr, "<v-empty>"); -		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, "peb_size     : 0x%08x\n", u->peb_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 peb_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->peb_size = peb_size ? peb_size : DEFAULT_BLOCKSIZE; -	res->data_pad = (res->peb_size - data_offset) % alignment; -	res->leb_size = res->peb_size - data_offset - res->data_pad; -	res->leb_total = byte_to_blk(data_size, res->leb_size); -	res->alignment = alignment; - -	if ((res->peb_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->peb_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-tools/src/libubimirror.c b/ubi-utils/old-tools/src/libubimirror.c deleted file mode 100644 index d06770e..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <memory.h> -#include <limits.h> -#include <fcntl.h> - -#include <libubi.h> -#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-tools/src/list.c b/ubi-utils/old-tools/src/list.c deleted file mode 100644 index 6eb716b..0000000 --- a/ubi-utils/old-tools/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 <stdlib.h> -#include <assert.h> -#include <stdio.h> - -#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-tools/src/list.h b/ubi-utils/old-tools/src/list.h deleted file mode 100644 index e8452a2..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> - -#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-tools/src/mkbootenv.c b/ubi-utils/old-tools/src/mkbootenv.c deleted file mode 100644 index 952f651..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <getopt.h> -#include <unistd.h> -#include <errno.h> -#include <mtd/ubi-header.h> - -#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=<fname>     Write the output data to <output> 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 <output>] [--copyright] [--output=<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-tools/src/nand2bin.c b/ubi-utils/old-tools/src/nand2bin.c deleted file mode 100644 index 8c95b27..0000000 --- a/ubi-utils/old-tools/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. - * 1.7 Made NAND ECC layout configurable, the holes which were previously - *     filled with 0x00 are untouched now and will be 0xff just like MTD - *     behaves when writing the oob (haver) - */ - -#include <config.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "config.h" -#include "nandecc.h" -#include "ecclayouts.h" - -#define PROGRAM_VERSION "1.7" - -#define ARRAY_SIZE(a)    (sizeof(a) / sizeof((a)[0])) -#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 oobsize; -	int bad_marker_offs_in_oob; -	size_t blocksize; -	int split_blocks; -	size_t in_len;		/* size of input file */ -	int correct_ecc; -	struct nand_ecclayout *nand_oob; - -	/* 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, -	.nand_oob = &ibm_nand_oob_64, -	.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 = -"  -l, --ecc-placement=<MTD,IBM> OOB placement scheme (default is IBM).\n" -"  -o, --output=<output>      Data output file\n" -"  -O, --oob=<oob>            OOB output file\n" -"  -p, --pagesize=<pagesize>  NAND pagesize\n" -"  -b, --blocksize=<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 <output>] [-O <oob>] [-p <pagesize>]\n" -"          [--output=<output>] [--oob=<oob>] [--pagesize=<pagesize>] [--help]\n" -"          [--usage] input.mif\n"; - -static int verbose = 0; - -static struct option long_options[] = { -	{ .name = "ecc-layout", .has_arg = 1, .flag = NULL, .val = 'l' }, -	{ .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) -{ -	unsigned int i, oob_idx = 0; -	const char *ecc_layout = NULL; - -	while (1) { -		int key; - -		key = getopt_long(argc, argv, "b:el:o:O:p:sv?", long_options, NULL); -		if (key == -1) -			break; - -		switch (key) { -		case 'b': /* --blocksize<blocksize> */ -			args->blocksize = str_to_num(optarg); -			break; -		case 'e': /* --correct-ecc */ -			args->correct_ecc = 1; -			break; -		case 'l': /* --ecc-layout=<...> */ -			ecc_layout = optarg; -			break; -		case 'o': /* --output=<output.bin> */ -			args->output_file = optarg; -			break; -		case 'O': /* --oob=<oob.bin> */ -			args->oob_file = optarg; -			break; -		case 'p': /* --pagesize<pagesize> */ -			args->pagesize = str_to_num(optarg); -			break; -		case 's': /* --split-blocks */ -			args->split_blocks = 1; -			break; -		case 'v': /* --verbose */ -			verbose++; -			break; -		case 'V': -			printf("%s\n", PROGRAM_VERSION); -			exit(0); -			break; -		case '?': /* help */ -			printf("Usage: nand2bin [OPTION...] input.mif\n"); -			printf("%s%s", doc, optionsstr); -			printf("\nReport bugs to %s\n", -			       PACKAGE_BUGREPORT); -			exit(0); -			break; -		default: -			printf("%s", usage); -			exit(-1); -		} -	} - -	if (optind < argc) -		args->arg1 = argv[optind++]; - -	switch (args->pagesize) { -	case 512: -		args->oobsize = 16; -		args->bad_marker_offs_in_oob = 5; -		oob_idx = 0; -		break; -	case 2048: -		args->oobsize = 64; -		args->bad_marker_offs_in_oob = 0; -		oob_idx = 1; -		break; -	default: -		fprintf(stderr, "Unsupported page size: %d\n", args->pagesize); -		return -EINVAL; -	} - -	/* Figure out correct oob layout if it differs from default */ -	if (ecc_layout) { -		for (i = 0; i < ARRAY_SIZE(oob_placement); i++) -			if (strcmp(ecc_layout, oob_placement[i].name) == 0) -				args->nand_oob = -					oob_placement[i].nand_oob[oob_idx]; -	} -	return 0; -} - -/* - * We must only compare the relevant bytes in the OOB area. All other - * bytes can be ignored. The information we need to do this is in - * nand_oob. - */ -static int oob_cmp(struct nand_ecclayout *nand_oob, uint8_t *oob, -		   uint8_t *calc_oob) -{ -	unsigned int i; -	for (i = 0; i < nand_oob->eccbytes; i++) -		if (oob[nand_oob->eccpos[i]] != calc_oob[nand_oob->eccpos[i]]) -			return 1; -	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(struct args *args, uint8_t *buf, uint8_t *oobbuf) -{ -	size_t i, j; -	int eccpoi; -	uint8_t ecc_code[3] = { 0, }; /* temp */ - -	/* Calculate ECC */ -	memset(oobbuf, 0xff, args->oobsize); -	for (eccpoi = 0, i = 0; i < args->pagesize; i += 256, eccpoi += 3) { -		nand_calculate_ecc(&buf[i], ecc_code); -		for (j = 0; j < 3; j++) -			oobbuf[args->nand_oob->eccpos[eccpoi + j]] = ecc_code[j]; -	} -	return 0; -} - -static int decompose_image(struct args *args, FILE *in_fp, -			   FILE *bin_fp, FILE *oob_fp) -{ -	unsigned int i, eccpoi; -	int read, rc, page = 0; -	uint8_t *buf = malloc(args->pagesize); -	uint8_t *oob = malloc(args->oobsize); -	uint8_t *calc_oob = malloc(args->oobsize); -	uint8_t *calc_buf = malloc(args->pagesize); -	uint8_t *page_buf; -	int pages_per_block = args->blocksize / args->pagesize; -	int badpos = args->bad_marker_offs_in_oob; -	uint8_t ecc_code[3] = { 0, }; /* temp */ -	uint8_t calc_ecc_code[3] = { 0, }; /* temp */ - -	if (!buf || !oob || !calc_oob || !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, args->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(args, buf, calc_oob); -		memcpy(calc_buf, buf, args->pagesize); - -		if (verbose && oob_cmp(args->nand_oob, oob, calc_oob) != 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, args->oobsize); - -			printf("Calculated OOB Data:\n"); -			hexdump(stdout, calc_oob, args->oobsize); -		} - -		/* Do correction on subpage base */ -		for (i = 0, eccpoi = 0; i < args->pagesize; i += 256, eccpoi += 3) { -			int j; - -			for (j = 0; j < 3; j++) { -				ecc_code[j] = oob[args->nand_oob->eccpos[eccpoi + j]]; -				calc_ecc_code[j] = -					calc_oob[args->nand_oob->eccpos[eccpoi + j]]; -			} -			rc = nand_correct_data(calc_buf + i, ecc_code, -					       calc_ecc_code); -			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, args->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; -	int pages_per_block = args->blocksize / args->pagesize; -	int block_len = pages_per_block * (args->pagesize + args->oobsize); -	int blocks = args->in_len / block_len; -	char bname[256] = { 0, }; -	int badpos = args->bad_marker_offs_in_oob; -	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 + args->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, args->oobsize); -			printf("--\n"); -			hexdump(stdout, buf + 2 * args->pagesize + -				args->oobsize, args->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 (lstat(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-tools/src/nandcorr.c b/ubi-utils/old-tools/src/nandcorr.c deleted file mode 100644 index caa07e2..0000000 --- a/ubi-utils/old-tools/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-tools/src/nandecc.c b/ubi-utils/old-tools/src/nandecc.c deleted file mode 100644 index 71660ef..0000000 --- a/ubi-utils/old-tools/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-tools/src/nandecc.h b/ubi-utils/old-tools/src/nandecc.h deleted file mode 100644 index bcf1982..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> - -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-tools/src/pddcustomize.c b/ubi-utils/old-tools/src/pddcustomize.c deleted file mode 100644 index 515efd6..0000000 --- a/ubi-utils/old-tools/src/pddcustomize.c +++ /dev/null @@ -1,509 +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 - * - * 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 - */ - -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <limits.h> -#include <errno.h> -#include <mtd/ubi-header.h> - -#include "config.h" -#include "bootenv.h" -#include "error.h" -#include "example_ubi.h" -#include "libubi.h" -#include "ubimirror.h" - -#define PROGRAM_VERSION "1.5" - -#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=<input>        Binary input file. For debug purposes.\n" -"  -l, --list                 List card bootenv/pdd values.\n" -"  -o, --output=<output>      Binary output file. For debug purposes.\n" -"  -s, --side=<seqnum>        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 <input>] [-o <output>] [-s <seqnum>]\n" -"           [--both] [--copyright] [--input=<input>] [--list]\n" -"           [--output=<output>] [--side=<seqnum>] [--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); -		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-tools/src/peb.c b/ubi-utils/old-tools/src/peb.c deleted file mode 100644 index 160a463..0000000 --- a/ubi-utils/old-tools/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 <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#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 peb_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 = peb_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-tools/src/peb.h b/ubi-utils/old-tools/src/peb.h deleted file mode 100644 index 246bce8..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> -#include <stdio.h> - -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-tools/src/pfi.c b/ubi-utils/old-tools/src/pfi.c deleted file mode 100644 index fa835e2..0000000 --- a/ubi-utils/old-tools/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. - * - * <oliloh@de.ibm.com> Wed Feb	8 11:38:22 CET 2006: Initial creation. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <errno.h> - -#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-tools/src/pfi.h b/ubi-utils/old-tools/src/pfi.h deleted file mode 100644 index 8c5cc07..0000000 --- a/ubi-utils/old-tools/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 <oliloh@de.ibm.com> - *         Andreas Arnez <arnez@de.ibm.com> - *         Joern Engel <engeljoe@de.ibm.com> - *         Frank Haverkamp <haverkam@de.ibm.com> - * - * @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 <stdio.h>		/* 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 <asm/errno.h>. - */ -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 <asm/errno.h>. - * - * 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-tools/src/pfi2bin.c b/ubi-utils/old-tools/src/pfi2bin.c deleted file mode 100644 index 3300df2..0000000 --- a/ubi-utils/old-tools/src/pfi2bin.c +++ /dev/null @@ -1,681 +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 <stdlib.h> -#include <stdint.h> -#include <getopt.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include <ubigen.h> -#include <mtd/ubi-header.h> - -#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=<level> */ -				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-tools/src/pfiflash.c b/ubi-utils/old-tools/src/pfiflash.c deleted file mode 100644 index 754fe33..0000000 --- a/ubi-utils/old-tools/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 <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <errno.h> - -#include <pfiflash.h> -#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=<file>       Write a logfile to <file>.\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=<type>    Specify the pdd-update algorithm. <type> is either\n" -"                             'keep', 'merge' or 'overwrite'.\n" -"  -r, --raw-flash=<dev>      Flash the raw data. Use the specified mtd device.\n" -"  -s, --side=<seqnum>        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 <file>] [-p <type>] [-r <dev>] [-s <seqnum>]\n" -"            [--copyright] [--logfile=<file>] [--verbose] [--complete]\n" -"            [--pdd-update=<type>] [--raw-flash=<dev>] [--side=<seqnum>]\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-tools/src/pfiflash.h b/ubi-utils/old-tools/src/pfiflash.h deleted file mode 100644 index 039705d..0000000 --- a/ubi-utils/old-tools/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 <oliloh@de.ibm.com> - * - * @brief The pfiflash library offers an interface for using the - * pfiflash * utility. - */ - -#include <stdio.h>		/* 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-tools/src/pfiflash_error.h b/ubi-utils/old-tools/src/pfiflash_error.h deleted file mode 100644 index 0f27f4a..0000000 --- a/ubi-utils/old-tools/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 <dowsett@de.ibm.com> - * Contact: Andreas Arnez <arnez@de.ibm.com> - */ - -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-tools/src/reader.c b/ubi-utils/old-tools/src/reader.c deleted file mode 100644 index 0ea8c6d..0000000 --- a/ubi-utils/old-tools/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 <string.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#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-tools/src/reader.h b/ubi-utils/old-tools/src/reader.h deleted file mode 100644 index 715e464..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> -#include <stdio.h> - -#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-tools/src/ubigen.c b/ubi-utils/old-tools/src/ubigen.c deleted file mode 100644 index 9fcafab..0000000 --- a/ubi-utils/old-tools/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 <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <getopt.h> -#include <unistd.h> -#include <sys/stat.h> -#include <mtd/ubi-header.h> - -#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=<num>      Set the alignment size to <num> (default 1).\n" -"                             Values can be specified as bytes, 'ki' or 'Mi'.\n" -"  -B, --blocksize=<num>      Set the eraseblock size to <num> (default 128\n" -"                             KiB).\n" -"                             Values can be specified as bytes, 'ki' or 'Mi'.\n" -"  -E, --erasecount=<num>     Set the erase count to <num> (default 0)\n" -"  -I, --id=<num>             The UBI volume id.\n" -"  -O, --offset=<num>         Offset from start of an erase block to the UBI\n" -"                             volume header.\n" -"  -T, --type=<num>           The UBI volume type:\n" -"                             1 = dynamic, 2 = static\n" -"  -X, --setver=<num>         Set UBI version number to <num> (default 1)\n" -"\n" -" Input/Output:\n" -"  -i, --infile=<filename>    Read input from file.\n" -"  -o, --outfile=<filename>   Write output to file (default is stdout).\n" -"\n" -" Special options:\n" -"  -U, --broken-update=<leb>  Create an ubi image which simulates a broken\n" -"                             update.\n" -"                             <leb> 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 <num>] [-B <num>] [-E <num>] [-I <num>]\n" -"          [-O <num>] [-T <num>] [-X <num>] [-i <filename>] [-o <filename>]\n" -"          [-U <leb>] [--copyright] [--debug] [--verbose] [--alignment=<num>]\n" -"          [--blocksize=<num>] [--erasecount=<num>] [--id=<num>]\n" -"          [--offset=<num>] [--type=<num>] [--setver=<num>]\n" -"          [--infile=<filename>] [--outfile=<filename>]\n" -"          [--broken-update=<leb>] [--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-tools/src/ubigen.h b/ubi-utils/old-tools/src/ubigen.h deleted file mode 100644 index 07f845f..0000000 --- a/ubi-utils/old-tools/src/ubigen.h +++ /dev/null @@ -1,150 +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 <stdio.h> /* FILE */ -#include <stdint.h> -#include <mtd/ubi-header.h> -#include <mtd_swab.h> - -#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-tools/src/ubimirror.c b/ubi-utils/old-tools/src/ubimirror.c deleted file mode 100644 index 2cc4596..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <errno.h> -#include <mtd/ubi-header.h> - -#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=<seqnum>        Use the side <seqnum> 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 <seqnum>] [--copyright] [--side=<seqnum>]\n" -"            [--help] [--usage] [--version] <source> <destination>\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...] " -					"<source> <destination>\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, err_buf); -		if( rc < 0 ) -			rc = -rc; -	} - out: - err: -	return rc; -} diff --git a/ubi-utils/old-tools/src/ubimirror.h b/ubi-utils/old-tools/src/ubimirror.h deleted file mode 100644 index d7ae2ad..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> - -/** - * @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-tools/src/ubiupdate.c b/ubi-utils/old-tools/src/ubiupdate.c deleted file mode 100644 index 75222d4..0000000 --- a/ubi-utils/old-tools/src/ubiupdate.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * An utility to update UBI volumes. - * - * Authors: Frank Haverkamp - *          Joshua W. Boyer - *          Artem Bityutskiy - */ - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.3" -#define PROGRAM_NAME    "ubiupdate" - -struct args { -	int truncate; -	const char *node; -	const char *img; -}; - -static struct args myargs = { -	.truncate = 0, -	.node = NULL, -	.img = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION -			 " - a tool to write data to UBI volumes."; - -static const char *optionsstr = -"-n, --vol_id=<volume id>   ID of UBI volume to update\n" -"-t, --truncate             truncate volume (wipe it out)\n" -"-h, --help                 print help message\n" -"-V, --version              print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI volume node file name> [-t] [-h] [-V] [--truncate] [--help]\n" -"\t\t[--version] <image file>\n\n" -"Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - write file \"fs.img\" to UBI volume /dev/ubi0_1\n" -"Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1"; - -struct option long_options[] = { -	{ .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, -	{ .name = "help",     .has_arg = 0, .flag = NULL, .val = 'h' }, -	{ .name = "version",  .has_arg = 0, .flag = NULL, .val = 'V' }, -	{ NULL, 0, NULL, 0} -}; - -static int parse_opt(int argc, char * const argv[]) -{ -	while (1) { -		int key; - -		key = getopt_long(argc, argv, "n:thV", long_options, NULL); -		if (key == -1) -			break; - -		switch (key) { -		case 't': -			myargs.truncate = 1; -			break; - -		case 'h': -			fprintf(stderr, "%s\n\n", doc); -			fprintf(stderr, "%s\n\n", usage); -			fprintf(stderr, "%s\n", optionsstr); -			exit(0); - -		case 'V': -			fprintf(stderr, "%s\n", PROGRAM_VERSION); -			exit(0); - -		case ':': -			errmsg("parameter is missing"); -			return -1; - -		default: -			fprintf(stderr, "Use -h for help\n"); -			exit(-1); -		} -	} - -	if (optind == argc) { -		errmsg("UBI device name was not specified (use -h for help)"); -		return -1; -	} else if (optind != argc - 2) { -		errmsg("specify UBI device name and image file name as first 2 " -		       "parameters (use -h for help)"); -		return -1; -	} - -	myargs.node = argv[optind]; -	myargs.img  = argv[optind + 1]; - -	return 0; -} - -static int truncate_volume(libubi_t libubi) -{ -	int err, fd; - -	fd = open(myargs.node, O_RDWR); -	if (fd == -1) { -		errmsg("cannot open \"%s\"", myargs.node); -		perror("open"); -		return -1; -	} - -	err = ubi_update_start(libubi, fd, 0); -	if (err) { -		errmsg("cannot truncate volume \"%s\"", myargs.node); -		perror("ubi_update_start"); -		close(fd); -		return -1; -	} - -	close(fd); -	return 0; -} - -static int ubi_write(int fd, const void *buf, int len) -{ -	int ret; - -	while (len) { -		ret = write(fd, buf, len); -		if (ret < 0) { -			if (errno == EINTR) { -				warnmsg("do not interrupt me!"); -				continue; -			} -			errmsg("cannot write %d bytes to volume \"%s\"", -			       len, myargs.node); -			perror("write"); -			return -1; -		} - -		if (ret == 0) { -			errmsg("cannot write %d bytes to volume \"%s\"", -			       len, myargs.node); -			return -1; -		} - -		len -= ret; -		buf += ret; -	} - -	return 0; -} - -static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) -{ -	int err, fd, ifd; -	long long bytes; -	struct stat st; -	char *buf; - -	buf = malloc(vol_info->leb_size); -	if (!buf) { -		errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); -		return -1; -	} - -	err = stat(myargs.img, &st); -	if (err < 0) { -		errmsg("stat failed on \"%s\"", myargs.node); -		goto out_free; -	} - -	bytes = st.st_size; -	if (bytes > vol_info->rsvd_bytes) { -		errmsg("\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)", -		       myargs.img, bytes, myargs.node, vol_info->rsvd_bytes); -		goto out_free; -	} - -	fd = open(myargs.node, O_RDWR); -	if (fd == -1) { -		errmsg("cannot open UBI volume \"%s\"", myargs.node); -		perror("open"); -		goto out_free; -	} - -	ifd = open(myargs.img, O_RDONLY); -	if (ifd == -1) { -		errmsg("cannot open \"%s\"", myargs.img); -		perror("open"); -		goto out_close1; -	} - -	err = ubi_update_start(libubi, fd, bytes); -	if (err) { -		errmsg("cannot start volume \"%s\" update", myargs.node); -		perror("ubi_update_start"); -		goto out_close; -	} - -	while (bytes) { -		int tocopy = vol_info->leb_size; - -		if (tocopy > bytes) -			tocopy = bytes; - -		err = read(ifd, buf, tocopy); -		if (err != tocopy) { -			if (errno == EINTR) { -				warnmsg("do not interrupt me!"); -				continue; -			} else { -				errmsg("cannot read %d bytes from \"%s\"", -				       tocopy, myargs.img); -				perror("read"); -				goto out_close; -			} -		} - -		err = ubi_write(fd, buf, tocopy); -		if (err) -			goto out_close; -		bytes -= tocopy; -	} - -	close(ifd); -	close(fd); -	free(buf); -	return 0; - -out_close: -	close(ifd); -out_close1: -	close(fd); -out_free: -	free(buf); -	return -1; -} - -int main(int argc, char * const argv[]) -{ -	int err; -	libubi_t libubi; -	struct ubi_vol_info vol_info; - -	err = parse_opt(argc, argv); -	if (err) -		return -1; - -	if (!myargs.img && !myargs.truncate) { -		errmsg("incorrect arguments, use -h for help"); -		return -1; -	} - -	libubi = libubi_open(); -	if (libubi == NULL) { -		perror("Cannot open libubi"); -		goto out_libubi; -	} - -	err = ubi_node_type(libubi, myargs.node); -	if (err == 1) { -		errmsg("\"%s\" is an UBI device node, not an UBI volume node", -		       myargs.node); -		goto out_libubi; -	} else if (err < 0) { -		errmsg("\"%s\" is not an UBI volume node", myargs.node); -		goto out_libubi; -	} - -	err = ubi_get_vol_info(libubi, myargs.node, &vol_info); -	if (err) { -		errmsg("cannot get information about UBI volume \"%s\"", -		       myargs.node); -		perror("ubi_get_dev_info"); -		goto out_libubi; -	} - -	if (myargs.truncate) -		err = truncate_volume(libubi); -	else -		err = update_volume(libubi, &vol_info); -	if (err) -		goto out_libubi; - -	libubi_close(libubi); -	return 0; - -out_libubi: -	libubi_close(libubi); -	return -1; -} diff --git a/ubi-utils/old-tools/src/unubi.c b/ubi-utils/old-tools/src/unubi.c deleted file mode 100644 index 8a022a3..0000000 --- a/ubi-utils/old-tools/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 <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <mtd/ubi-header.h> -#include <mtd_swab.h> - -#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=<volume-id>  Extract and rebuild volume\n" -"\n" -" OPTIONS\n" -"  -b, --blocksize=<block-size>   Specify size of eraseblocks in image in bytes\n" -"                             (default 128KiB)\n" -"  -d, --dir=<output-dir>     Specify output directory\n" -"  -D, --debug                Enable debug output\n" -"  -s, --headersize=<header-size>   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 <volume-id>] [-b <block-size>] [-d <output-dir>]\n" -"            [-s <header-size>] [--analyze] [--info-table]\n" -"            [--rebuild=<volume-id>] [--blocksize=<block-size>]\n" -"            [--dir=<output-dir>] [--headersize=<header-size>] [--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_%04u"	/* split volume */ -#define FN_VOLWH	"%s/volume%03u"			/* whole volume */ -#define FN_VITBL	"%s/vol_info_table%u"		/* 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=<block-size> */ -			args->bsize = str_to_num(optarg); -			break; -		case 's': /* --header-size=<header-size> */ -			args->hsize = str_to_num(optarg); -			break; -		case 'd': /* --dir=<output-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=<volume-id> */ -			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, "%u\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]; -		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-tools/src/unubi_analyze.c b/ubi-utils/old-tools/src/unubi_analyze.c deleted file mode 100644 index 182100e..0000000 --- a/ubi-utils/old-tools/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 <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <mtd_swab.h> - -#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, "%u %llu %llu", count, -			be64_to_cpu(cur->ec.ec), -			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, "%d", count); -		} - -		cur = cur->next; -		count++; -	} -	fprintf(fpplot, ")\n"); - -	fprintf(fpplot, "set ylabel \"erase count\"\n"); -	fprintf(fpplot, "set xrange [-1:%u]\n", eraseblocks + 1); -	fprintf(fpplot, "# set yrange [-1:%llu]\n", -		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, "%u %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, "\"%d\" %d 0", step, count); -		} -		else -			fprintf(fpplot, "\"%d\" %d 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:%u]\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-tools/src/unubi_analyze.h b/ubi-utils/old-tools/src/unubi_analyze.h deleted file mode 100644 index 8588219..0000000 --- a/ubi-utils/old-tools/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 <stdio.h> -#include <stdint.h> -#include <mtd/ubi-header.h> - -#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__ */ | 
