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 <patrickhwood@gmail.com>
This commit is contained in:
parent
c0f39a2417
commit
5d0ee5037b
11
Makefile
11
Makefile
@ -4,7 +4,7 @@ CFLAGS += -std=c99 -D_POSIX_C_SOURCE=200112L
|
|||||||
CFLAGS += -Iinclude/
|
CFLAGS += -Iinclude/
|
||||||
|
|
||||||
TOOLS = fexc bin2fex fex2bin bootinfo fel pio
|
TOOLS = fexc bin2fex fex2bin bootinfo fel pio
|
||||||
TOOLS += nand-part nand-part-a20
|
TOOLS += nand-part
|
||||||
|
|
||||||
MISC_TOOLS = phoenix_info
|
MISC_TOOLS = phoenix_info
|
||||||
|
|
||||||
@ -37,12 +37,15 @@ LIBUSB_LIBS = `pkg-config --libs $(LIBUSB)`
|
|||||||
fel: fel.c
|
fel: fel.c
|
||||||
$(CC) $(CFLAGS) $(LIBUSB_CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS)
|
$(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
|
%: %.c
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS)
|
$(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
|
fel-pio.bin: fel-pio.elf fel-pio.nm
|
||||||
$(CROSS_COMPILE)objcopy -O binary fel-pio.elf fel-pio.bin
|
$(CROSS_COMPILE)objcopy -O binary fel-pio.elf fel-pio.bin
|
||||||
|
|
||||||
|
|||||||
8
nand-common.h
Normal file
8
nand-common.h
Normal file
@ -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);
|
||||||
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#define MBR_MAGIC "softw311"
|
#define MBR_MAGIC "softw311"
|
||||||
#define MBR_VERSION 0x100
|
#define MBR_VERSION 0x100
|
||||||
|
#define nand_part nand_part_a10
|
||||||
|
#define checkmbrs checkmbrs_a10
|
||||||
|
|
||||||
#define MAX_PART_COUNT 15 //max part count
|
#define MAX_PART_COUNT 15 //max part count
|
||||||
#define MBR_COPY_NUM 4 //mbr backup count
|
#define MBR_COPY_NUM 4 //mbr backup count
|
||||||
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#define MBR_MAGIC "softw411"
|
#define MBR_MAGIC "softw411"
|
||||||
#define MBR_VERSION 0x200
|
#define MBR_VERSION 0x200
|
||||||
|
#define nand_part nand_part_a20
|
||||||
|
#define checkmbrs checkmbrs_a20
|
||||||
|
|
||||||
#define MAX_PART_COUNT 120 //max part count
|
#define MAX_PART_COUNT 120 //max part count
|
||||||
#define MBR_COPY_NUM 4 //mbr backup count
|
#define MBR_COPY_NUM 4 //mbr backup count
|
||||||
|
|||||||
115
nand-part-main.c
Normal file
115
nand-part-main.c
Normal file
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
91
nand-part.c
91
nand-part.c
@ -52,10 +52,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mount.h> /* BLKRRPART */
|
#include <sys/mount.h> /* 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"
|
# include "nand-part-a20.h"
|
||||||
#else
|
|
||||||
# include "nand-part.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NAME 16
|
#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);
|
printf("mbr: version 0x%08x, magic %8.8s\n", mbr->version, mbr->magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct tag_CRC32_DATA
|
static MBR *_get_mbr(int fd, int mbr_num, int force)
|
||||||
{
|
|
||||||
__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)
|
|
||||||
{
|
{
|
||||||
MBR *mbr;
|
MBR *mbr;
|
||||||
|
|
||||||
@ -145,7 +112,7 @@ MBR *_get_mbr(int fd, int mbr_num, int force)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
__s32 _free_mbr(MBR *mbr)
|
static __s32 _free_mbr(MBR *mbr)
|
||||||
{
|
{
|
||||||
if(mbr)
|
if(mbr)
|
||||||
{
|
{
|
||||||
@ -156,7 +123,7 @@ __s32 _free_mbr(MBR *mbr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printmbr(MBR *mbr)
|
static void printmbr(MBR *mbr)
|
||||||
{
|
{
|
||||||
unsigned int part_cnt;
|
unsigned int part_cnt;
|
||||||
|
|
||||||
@ -173,7 +140,7 @@ void printmbr(MBR *mbr)
|
|||||||
mbr->array[part_cnt].user_type);
|
mbr->array[part_cnt].user_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void checkmbrs(int fd)
|
int checkmbrs(int fd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
MBR *mbrs[MBR_COPY_NUM];
|
MBR *mbrs[MBR_COPY_NUM];
|
||||||
@ -191,7 +158,7 @@ void checkmbrs(int fd)
|
|||||||
if (mbrs[i])
|
if (mbrs[i])
|
||||||
_free_mbr(mbrs[i]);
|
_free_mbr(mbrs[i]);
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printmbr(mbr);
|
printmbr(mbr);
|
||||||
@ -199,9 +166,10 @@ void checkmbrs(int fd)
|
|||||||
if (mbrs[i])
|
if (mbrs[i])
|
||||||
_free_mbr(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;
|
unsigned int part_cnt = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -287,46 +255,15 @@ int writembrs(int fd, char names[][MAX_NAME], __u32 start, __u32 *lens, unsigned
|
|||||||
return 1;
|
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 partoffset = 0;
|
||||||
int i;
|
int i;
|
||||||
char *nand = "/dev/nand";
|
|
||||||
char *cmd = argv[0];
|
|
||||||
char names[MAX_PART_COUNT][MAX_NAME];
|
char names[MAX_PART_COUNT][MAX_NAME];
|
||||||
__u32 lens[MAX_PART_COUNT];
|
__u32 lens[MAX_PART_COUNT];
|
||||||
unsigned int user_types[MAX_PART_COUNT];
|
unsigned int user_types[MAX_PART_COUNT];
|
||||||
__u32 start;
|
__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
|
// parse name/len arguments
|
||||||
memset((void *) user_types, 0, sizeof(user_types));
|
memset((void *) user_types, 0, sizeof(user_types));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user