From 5d0ee5037b5311ce50b743e2ecd9221f057eb125 Mon Sep 17 00:00:00 2001 From: Patrick Wood Date: Tue, 17 Sep 2013 18:30:27 -0400 Subject: [PATCH] nand-part: create one nand-part program to handle both A10 and A20 Build one nand-part program to handle both A10 and A20 mbr header formats. Changed -f option to take an "a10" or "a20" argument to specify which mbr format to force. Signed-off-by: Patrick Wood --- Makefile | 11 ++-- nand-common.h | 8 +++ nand-part.h => nand-part-a10.h | 2 + nand-part-a20.h | 2 + nand-part-main.c | 115 +++++++++++++++++++++++++++++++++ nand-part.c | 91 ++++---------------------- 6 files changed, 148 insertions(+), 81 deletions(-) create mode 100644 nand-common.h rename nand-part.h => nand-part-a10.h (97%) create mode 100644 nand-part-main.c diff --git a/Makefile b/Makefile index 2086b9f..ea8480f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CFLAGS += -std=c99 -D_POSIX_C_SOURCE=200112L CFLAGS += -Iinclude/ TOOLS = fexc bin2fex fex2bin bootinfo fel pio -TOOLS += nand-part nand-part-a20 +TOOLS += nand-part MISC_TOOLS = phoenix_info @@ -37,12 +37,15 @@ LIBUSB_LIBS = `pkg-config --libs $(LIBUSB)` fel: fel.c $(CC) $(CFLAGS) $(LIBUSB_CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS) +nand-part: nand-part-main.c nand-part.c nand-part-a10.h nand-part-a20.h + $(CC) $(CFLAGS) -c -o nand-part-main.o nand-part-main.c + $(CC) $(CFLAGS) -c -o nand-part-a10.o nand-part.c -D A10 + $(CC) $(CFLAGS) -c -o nand-part-a20.o nand-part.c -D A20 + $(CC) $(LDFLAGS) -o $@ nand-part-main.o nand-part-a10.o nand-part-a20.o $(LIBS) + %: %.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS) -nand-part-a20: nand-part.c nand-part-a20.h - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ nand-part.c -D A20 $(LIBS) - fel-pio.bin: fel-pio.elf fel-pio.nm $(CROSS_COMPILE)objcopy -O binary fel-pio.elf fel-pio.bin diff --git a/nand-common.h b/nand-common.h new file mode 100644 index 0000000..afe533e --- /dev/null +++ b/nand-common.h @@ -0,0 +1,8 @@ +#include "types.h" + +extern int nand_part_a10 (int argc, char **argv, const char *cmd, int fd, int force); +extern int nand_part_a20 (int argc, char **argv, const char *cmd, int fd, int force); +extern int checkmbrs_a10 (int fd); +extern int checkmbrs_a20 (int fd); +extern void usage (const char *cmd); +extern __u32 calc_crc32(void * buffer, __u32 length); diff --git a/nand-part.h b/nand-part-a10.h similarity index 97% rename from nand-part.h rename to nand-part-a10.h index c35b458..b4cfe3d 100644 --- a/nand-part.h +++ b/nand-part-a10.h @@ -27,6 +27,8 @@ #define MBR_MAGIC "softw311" #define MBR_VERSION 0x100 +#define nand_part nand_part_a10 +#define checkmbrs checkmbrs_a10 #define MAX_PART_COUNT 15 //max part count #define MBR_COPY_NUM 4 //mbr backup count diff --git a/nand-part-a20.h b/nand-part-a20.h index 1e032ce..e603ceb 100644 --- a/nand-part-a20.h +++ b/nand-part-a20.h @@ -27,6 +27,8 @@ #define MBR_MAGIC "softw411" #define MBR_VERSION 0x200 +#define nand_part nand_part_a20 +#define checkmbrs checkmbrs_a20 #define MAX_PART_COUNT 120 //max part count #define MBR_COPY_NUM 4 //mbr backup count diff --git a/nand-part-main.c b/nand-part-main.c new file mode 100644 index 0000000..d2246ff --- /dev/null +++ b/nand-part-main.c @@ -0,0 +1,115 @@ +/* + * mbr.c + * (C) Copyright 2012 + * Patrick H Wood, All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include "nand-common.h" + +void usage(const char *cmd) +{ + printf("usage: %s nand-device 'name2 len2 [usertype2]' ['name3 len3 [usertype3]'] ...\n", cmd); + printf("or %s nand-device [-f] start1 'name1 len1 [usertype1]' ['name2 len2 [usertype2]'] ...\n", cmd); +} + +typedef struct tag_CRC32_DATA +{ + __u32 CRC; //int的大小是32位 + __u32 CRC_32_Tbl[256]; //用来保存码表 +}CRC32_DATA_t; + +__u32 calc_crc32(void * buffer, __u32 length) +{ + __u32 i, j; + CRC32_DATA_t crc32; // + __u32 CRC32 = 0xffffffff; //设置初始值 + crc32.CRC = 0; + + for( i = 0; i < 256; ++i)//用++i以提高效率 + { + crc32.CRC = i; + for( j = 0; j < 8 ; ++j) + { + //这个循环实际上就是用"计算法"来求取CRC的校验码 + if(crc32.CRC & 1) + crc32.CRC = (crc32.CRC >> 1) ^ 0xEDB88320; + else //0xEDB88320就是CRC-32多项表达式的值 + crc32.CRC >>= 1; + } + crc32.CRC_32_Tbl[i] = crc32.CRC; + } + + CRC32 = 0xffffffff; //设置初始值 + for( i = 0; i < length; ++i) + { + CRC32 = crc32.CRC_32_Tbl[(CRC32^((unsigned char*)buffer)[i]) & 0xff] ^ (CRC32>>8); + } + //return CRC32; + return CRC32^0xffffffff; +} + +int main (int argc, char **argv) +{ + char *nand = "/dev/nand"; + const char *cmd = argv[0]; + int fd; + int force = 0; // force write even if magics and CRCs don't match + + argc--; + argv++; + + if (argc > 1) { + if (!strcmp(argv[0], "-f")) { + if (!strcasecmp(argv[1], "a10")) + force = 10; + else if (!strcasecmp(argv[1], "a20")) + force = 20; + else { + usage(cmd); + return -1; + } + argc -= 2; + argv += 2; + } + } + + if (argc > 0) { + nand = argv[0]; + argc--; + argv++; + } + fd = open(nand, O_RDWR); + if (fd < 0) { + usage(cmd); + return -2; + } + if (force == 10) + return nand_part_a10 (argc, argv, cmd, fd, force); + if (force == 20) + return nand_part_a20 (argc, argv, cmd, fd, force); + + if (checkmbrs_a10(fd)) + return nand_part_a10 (argc, argv, cmd, fd, force); + if (checkmbrs_a20(fd)) + return nand_part_a20 (argc, argv, cmd, fd, force); +} diff --git a/nand-part.c b/nand-part.c index 17cb568..e1640dc 100644 --- a/nand-part.c +++ b/nand-part.c @@ -52,10 +52,13 @@ #include #include #include /* BLKRRPART */ -#ifdef A20 +#include "nand-common.h" + +// so far, only known formats are for A10 and A20 +#if defined(A10) +# include "nand-part-a10.h" +#elif defined(A20) # include "nand-part-a20.h" -#else -# include "nand-part.h" #endif #define MAX_NAME 16 @@ -65,43 +68,7 @@ static void printmbrheader(MBR *mbr) printf("mbr: version 0x%08x, magic %8.8s\n", mbr->version, mbr->magic); } -typedef struct tag_CRC32_DATA -{ - __u32 CRC; //int的大小是32位 - __u32 CRC_32_Tbl[256]; //用来保存码表 -}CRC32_DATA_t; - -__u32 calc_crc32(void * buffer, __u32 length) -{ - __u32 i, j; - CRC32_DATA_t crc32; // - __u32 CRC32 = 0xffffffff; //设置初始值 - crc32.CRC = 0; - - for( i = 0; i < 256; ++i)//用++i以提高效率 - { - crc32.CRC = i; - for( j = 0; j < 8 ; ++j) - { - //这个循环实际上就是用"计算法"来求取CRC的校验码 - if(crc32.CRC & 1) - crc32.CRC = (crc32.CRC >> 1) ^ 0xEDB88320; - else //0xEDB88320就是CRC-32多项表达式的值 - crc32.CRC >>= 1; - } - crc32.CRC_32_Tbl[i] = crc32.CRC; - } - - CRC32 = 0xffffffff; //设置初始值 - for( i = 0; i < length; ++i) - { - CRC32 = crc32.CRC_32_Tbl[(CRC32^((unsigned char*)buffer)[i]) & 0xff] ^ (CRC32>>8); - } - //return CRC32; - return CRC32^0xffffffff; -} - -MBR *_get_mbr(int fd, int mbr_num, int force) +static MBR *_get_mbr(int fd, int mbr_num, int force) { MBR *mbr; @@ -145,7 +112,7 @@ MBR *_get_mbr(int fd, int mbr_num, int force) return NULL; } -__s32 _free_mbr(MBR *mbr) +static __s32 _free_mbr(MBR *mbr) { if(mbr) { @@ -156,7 +123,7 @@ __s32 _free_mbr(MBR *mbr) return 0; } -void printmbr(MBR *mbr) +static void printmbr(MBR *mbr) { unsigned int part_cnt; @@ -173,7 +140,7 @@ void printmbr(MBR *mbr) mbr->array[part_cnt].user_type); } } -void checkmbrs(int fd) +int checkmbrs(int fd) { int i; MBR *mbrs[MBR_COPY_NUM]; @@ -191,7 +158,7 @@ void checkmbrs(int fd) if (mbrs[i]) _free_mbr(mbrs[i]); } - return; + return 0; } printmbr(mbr); @@ -199,9 +166,10 @@ void checkmbrs(int fd) if (mbrs[i]) _free_mbr(mbrs[i]); } + return 1; } -int writembrs(int fd, char names[][MAX_NAME], __u32 start, __u32 *lens, unsigned int *user_types, int nparts, int partoffset, int force) +static int writembrs(int fd, char names[][MAX_NAME], __u32 start, __u32 *lens, unsigned int *user_types, int nparts, int partoffset, int force) { unsigned int part_cnt = 0; int i; @@ -287,46 +255,15 @@ int writembrs(int fd, char names[][MAX_NAME], __u32 start, __u32 *lens, unsigned return 1; } -void usage(const char *cmd) +int nand_part (int argc, char **argv, const char *cmd, int fd, int force) { - printf("usage: %s nand-device 'name2 len2 [usertype2]' ['name3 len3 [usertype3]'] ...\n", cmd); - printf("or %s nand-device [-f] start1 'name1 len1 [usertype1]' ['name2 len2 [usertype2]'] ...\n", cmd); -} - -int main (int argc, char **argv) -{ - int fd; - int force = 0; // force write even if magics and CRCs don't match int partoffset = 0; int i; - char *nand = "/dev/nand"; - char *cmd = argv[0]; char names[MAX_PART_COUNT][MAX_NAME]; __u32 lens[MAX_PART_COUNT]; unsigned int user_types[MAX_PART_COUNT]; __u32 start; - argc--; - argv++; - - if (argc > 0) { - if (!strcmp(argv[0], "-f")) { - force++; - argc--; - argv++; - } - } - - if (argc > 0) { - nand = argv[0]; - argc--; - argv++; - } - fd = open(nand, O_RDWR); - if (fd < 0) { - usage(cmd); - return -1; - } // parse name/len arguments memset((void *) user_types, 0, sizeof(user_types));