build both A10 and A20 nand-part executables
allow setting of partition 1 size/offset if -f option is used, force writing of MBR header, even if CRC or header magic/version are incorrect (for recovery only)
This commit is contained in:
parent
1dfa8cf006
commit
dd94a2f117
5
Makefile
5
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
|
||||
TOOLS += nand-part nand-part-a20
|
||||
|
||||
MISC_TOOLS = phoenix_info
|
||||
|
||||
@ -40,6 +40,9 @@ fel: fel.c
|
||||
%: %.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
|
||||
|
||||
|
||||
80
nand-part-a20.h
Normal file
80
nand-part-a20.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* drivers/block/sun4i_nand/nfd/mbr.h
|
||||
*
|
||||
* (C) Copyright 2007-2012
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __MBR_H__
|
||||
#define __MBR_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define MBR_MAGIC ""
|
||||
|
||||
#define MAX_PART_COUNT 120 //max part count
|
||||
#define MBR_COPY_NUM 4 //mbr backup count
|
||||
|
||||
#define MBR_START_ADDRESS 0x0 //mbr start address
|
||||
#define MBR_SIZE 1024*16 //mbr size
|
||||
#define MBR_RESERVED (MBR_SIZE - 32 - (MAX_PART_COUNT * 128)) //mbr reserved space
|
||||
|
||||
// extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
// extern struct __NandStorageInfo_t NandStorageInfo;
|
||||
|
||||
#define DiskSize (SECTOR_CNT_OF_SINGLE_PAGE * PAGE_CNT_OF_PHY_BLK * BLOCK_CNT_OF_DIE * \
|
||||
DIE_CNT_OF_CHIP * NandStorageInfo.ChipCnt / 1024 * DATA_BLK_CNT_OF_ZONE)
|
||||
|
||||
|
||||
struct nand_disk{
|
||||
unsigned long size;
|
||||
unsigned long offset;
|
||||
unsigned char type;
|
||||
};
|
||||
|
||||
/* part info */
|
||||
typedef struct nand_tag_PARTITION{
|
||||
unsigned int addrhi; //起始地址, 以扇区为单位
|
||||
unsigned int addrlo; //
|
||||
unsigned int lenhi; //长度
|
||||
unsigned int lenlo; //
|
||||
unsigned char classname[16]; //次设备名
|
||||
unsigned char name[16]; //主设备名
|
||||
unsigned int user_type; //用户类型
|
||||
unsigned int keydata; //关键数据,要求量产不丢失
|
||||
unsigned int ro; //读写属性
|
||||
unsigned char res[68]; //保留数据,匹配分区信息128字节
|
||||
}__attribute__ ((packed))PARTITION;
|
||||
|
||||
/* mbr info */
|
||||
typedef struct nand_tag_MBR{
|
||||
unsigned int crc32; // crc 1k - 4
|
||||
unsigned int version; // 版本信息, 0x00000100
|
||||
unsigned char magic[8]; //"softw411"
|
||||
unsigned int copy; //分数
|
||||
unsigned int index; //第几个MBR备份
|
||||
unsigned int PartCount; //分区个数
|
||||
unsigned int stamp[1]; //对齐
|
||||
PARTITION array[MAX_PART_COUNT]; //
|
||||
unsigned char res[MBR_RESERVED];
|
||||
}__attribute__ ((packed)) MBR;
|
||||
|
||||
int mbr2disks(struct nand_disk* disk_array);
|
||||
|
||||
#endif //__MBR_H__
|
||||
125
nand-part.c
125
nand-part.c
@ -52,11 +52,18 @@
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h> /* BLKRRPART */
|
||||
#include "nand-part.h"
|
||||
#ifdef A20
|
||||
# include "nand-part-a20.h"
|
||||
#else
|
||||
# include "nand-part.h"
|
||||
#endif
|
||||
|
||||
#define MAX_NAME 16
|
||||
|
||||
void printmbrheader(MBR *mbr);
|
||||
static void printmbrheader(MBR *mbr)
|
||||
{
|
||||
printf("mbr: version 0x%08x, magic %8.8s\n", mbr->version, mbr->magic);
|
||||
}
|
||||
|
||||
typedef struct tag_CRC32_DATA
|
||||
{
|
||||
@ -94,11 +101,9 @@ __u32 calc_crc32(void * buffer, __u32 length)
|
||||
return CRC32^0xffffffff;
|
||||
}
|
||||
|
||||
MBR *_get_mbr(int fd, int mbr_num)
|
||||
MBR *_get_mbr(int fd, int mbr_num, int force)
|
||||
{
|
||||
MBR *mbr;
|
||||
const char * magic = "softw311";
|
||||
unsigned version = 0x100;
|
||||
|
||||
/*request mbr space*/
|
||||
mbr = malloc(sizeof(MBR));
|
||||
@ -115,16 +120,25 @@ MBR *_get_mbr(int fd, int mbr_num)
|
||||
/*checksum*/
|
||||
printf("check partition table copy %d: ", mbr_num);
|
||||
printmbrheader(mbr);
|
||||
if(strncmp((char *)mbr->magic, magic, 8))
|
||||
if (force) {
|
||||
strncpy((char *)mbr->magic, MBR_MAGIC, 8);
|
||||
#ifdef MBR_VERSION
|
||||
mbr->version = MBR_VERSION;
|
||||
#endif
|
||||
return mbr;
|
||||
}
|
||||
if(strncmp((char *)mbr->magic, MBR_MAGIC, 8))
|
||||
{
|
||||
printf("magic %8.8s is not %8s\n", mbr->magic, magic);
|
||||
printf("magic %8.8s is not %8s\n", mbr->magic, MBR_MAGIC);
|
||||
return NULL;
|
||||
}
|
||||
if(mbr->version != version)
|
||||
#ifdef MBR_VERSION
|
||||
if(mbr->version != MBR_VERSION)
|
||||
{
|
||||
printf("version 0x%08x is not 0x%08x\n", mbr->version, version);
|
||||
printf("version 0x%08x is not 0x%08x\n", mbr->version, MBR_VERSION);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if(*(__u32 *)mbr == calc_crc32((__u32 *)mbr + 1,MBR_SIZE - 4))
|
||||
{
|
||||
printf("OK\n");
|
||||
@ -146,14 +160,9 @@ __s32 _free_mbr(MBR *mbr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printmbrheader(MBR *mbr)
|
||||
{
|
||||
printf("mbr: version 0x%08x, magic %8.8s\n", mbr->version, mbr->magic);
|
||||
}
|
||||
|
||||
void printmbr(MBR *mbr)
|
||||
{
|
||||
int part_cnt;
|
||||
unsigned int part_cnt;
|
||||
|
||||
printmbrheader(mbr);
|
||||
for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)
|
||||
@ -172,14 +181,14 @@ void printmbr(MBR *mbr)
|
||||
}
|
||||
void checkmbrs(int fd)
|
||||
{
|
||||
int part_cnt = 0;
|
||||
unsigned int part_cnt = 0;
|
||||
int i;
|
||||
MBR *mbrs[MBR_COPY_NUM];
|
||||
MBR *mbr = NULL;
|
||||
|
||||
memset((void *) mbrs, 0, sizeof(mbrs));
|
||||
for (i = 0; i < MBR_COPY_NUM; i++) {
|
||||
mbrs[i] = _get_mbr(fd, i);
|
||||
mbrs[i] = _get_mbr(fd, i, 0);
|
||||
if (mbrs[i])
|
||||
mbr = mbrs[i];
|
||||
}
|
||||
@ -192,14 +201,7 @@ void checkmbrs(int fd)
|
||||
return;
|
||||
}
|
||||
|
||||
for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)
|
||||
{
|
||||
printf("partition %2d: name = %12s, partition start = %8d, partition size = %8d\n",
|
||||
part_cnt,
|
||||
mbr->array[part_cnt].name,
|
||||
mbr->array[part_cnt].addrlo,
|
||||
mbr->array[part_cnt].lenlo);
|
||||
}
|
||||
printmbr(mbr);
|
||||
for (i = 0; i < MBR_COPY_NUM; i++) {
|
||||
if (mbrs[i])
|
||||
_free_mbr(mbrs[i]);
|
||||
@ -207,11 +209,10 @@ void checkmbrs(int fd)
|
||||
printf("%d partitions\n", part_cnt);
|
||||
}
|
||||
|
||||
int writembrs(int fd, char names[][MAX_NAME], __u32 *lens, unsigned int *user_types, int nparts)
|
||||
int writembrs(int fd, char names[][MAX_NAME], __u32 start, __u32 *lens, unsigned int *user_types, int nparts, int force)
|
||||
{
|
||||
int part_cnt = 0;
|
||||
unsigned int part_cnt = 0;
|
||||
int i;
|
||||
__u32 start;
|
||||
char yn = 'n';
|
||||
MBR *mbrs[MBR_COPY_NUM];
|
||||
MBR *mbr = NULL;
|
||||
@ -219,7 +220,7 @@ int writembrs(int fd, char names[][MAX_NAME], __u32 *lens, unsigned int *user_ty
|
||||
|
||||
memset((void *) mbrs, 0, sizeof(mbrs));
|
||||
for (i = 0; i < MBR_COPY_NUM; i++) {
|
||||
mbrs[i] = _get_mbr(fd, i);
|
||||
mbrs[i] = _get_mbr(fd, i, force);
|
||||
if (mbrs[i])
|
||||
mbr = mbrs[i];
|
||||
}
|
||||
@ -242,39 +243,31 @@ int writembrs(int fd, char names[][MAX_NAME], __u32 *lens, unsigned int *user_ty
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(part_cnt = 1; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)
|
||||
fprintf(backup, "%d ", mbr->array[0].addrlo);
|
||||
for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)
|
||||
{
|
||||
fprintf(backup, "'%s %d' ", mbr->array[part_cnt].name,
|
||||
mbr->array[part_cnt].lenlo);
|
||||
fprintf(backup, "'%s %d %d' ", mbr->array[part_cnt].name,
|
||||
mbr->array[part_cnt].lenlo, mbr->array[part_cnt].user_type);
|
||||
}
|
||||
fprintf(backup, "\n");
|
||||
fclose(backup);
|
||||
|
||||
// don't muck with first partition
|
||||
mbr->PartCount = nparts + 1;
|
||||
start = mbr->array[0].addrlo + mbr->array[0].lenlo;
|
||||
mbr->PartCount = nparts;
|
||||
for(i = 0; i < nparts; i++) {
|
||||
strcpy((char *)mbr->array[i+1].name, names[i]);
|
||||
strcpy((char *)mbr->array[i+1].classname, "DISK");
|
||||
memset((void *) mbr->array[i+1].res, 0, sizeof(mbr->array[i+1].res));
|
||||
mbr->array[i+1].user_type = user_types[i];
|
||||
mbr->array[i+1].ro = 0;
|
||||
mbr->array[i+1].addrhi = 0;
|
||||
mbr->array[i+1].lenhi = 0;
|
||||
mbr->array[i+1].addrlo = start;
|
||||
mbr->array[i+1].lenlo = lens[i];
|
||||
strcpy((char *)mbr->array[i].name, names[i]);
|
||||
strcpy((char *)mbr->array[i].classname, "DISK");
|
||||
memset((void *) mbr->array[i].res, 0, sizeof(mbr->array[i].res));
|
||||
mbr->array[i].user_type = user_types[i];
|
||||
mbr->array[i].ro = 0;
|
||||
mbr->array[i].addrhi = 0;
|
||||
mbr->array[i].lenhi = 0;
|
||||
mbr->array[i].addrlo = start;
|
||||
mbr->array[i].lenlo = lens[i];
|
||||
start += lens[i];
|
||||
}
|
||||
|
||||
printf("\nready to write new partition tables:\n");
|
||||
for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)
|
||||
{
|
||||
printf("partition %2d: name = %12s, partition start = %8d, partition size = %8d\n",
|
||||
part_cnt,
|
||||
mbr->array[part_cnt].name,
|
||||
mbr->array[part_cnt].addrlo,
|
||||
mbr->array[part_cnt].lenlo);
|
||||
}
|
||||
printmbr(mbr);
|
||||
for (i = 0; i < MBR_COPY_NUM; i++) {
|
||||
if (mbrs[i])
|
||||
_free_mbr(mbrs[i]);
|
||||
@ -304,16 +297,26 @@ int writembrs(int fd, char names[][MAX_NAME], __u32 *lens, unsigned int *user_ty
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
int force = 0; // force write even if magics and CRCs don't match
|
||||
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--;
|
||||
@ -321,17 +324,25 @@ int main (int argc, char **argv)
|
||||
}
|
||||
fd = open(nand, O_RDWR);
|
||||
if (fd < 0) {
|
||||
printf("usage: %s nand-device 'name2 len2 [usertype2]' ['name3 len3 [usertype3]'] ...\n", cmd);
|
||||
printf("usage: %s nand-device start1 'name1 len1 [usertype1]' ['name2 len2 [usertype2]'] ...\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// parse name/len arguments
|
||||
memset((void *) user_types, 0, sizeof(user_types));
|
||||
if (argc > 0) {
|
||||
if (sscanf(argv[0], "%u", &start) != 1) {
|
||||
printf("bad start argument\n");
|
||||
printf("usage: %s nand-device start1 'name1 len1 [usertype1]' ['name2 len2' [usertype2]] ...\n", cmd);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (sscanf(argv[i], "%s %d %d", names[i], &lens[i], &user_types[i]) < 2) {
|
||||
printf("bad 'name len' argument\n");
|
||||
printf("usage: %s nand-device 'name2 len2 [usertype2]' ['name3 len3 [usertype3]'] ...\n", cmd);
|
||||
printf("usage: %s nand-device start1 'name1 len1 [usertype1]' ['name2 len2' [usertype2]] ...\n", cmd);
|
||||
close(fd);
|
||||
return -3;
|
||||
}
|
||||
@ -340,16 +351,16 @@ int main (int argc, char **argv)
|
||||
|
||||
checkmbrs(fd);
|
||||
|
||||
if (argc > MAX_PART_COUNT - 1) {
|
||||
if (argc > MAX_PART_COUNT) {
|
||||
printf("too many partitions specified (MAX 14)\n");
|
||||
printf("usage: %s nand-device 'name2 len2 [usertype2]' ['name3 len3 [usertype3]'] ...\n", cmd);
|
||||
printf("usage: %s nand-device start1 'name1 len1 [usertype1]' ['name2 len2 [usertype2]'] ...\n", cmd);
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
if (argc > 0) {
|
||||
if (writembrs(fd, names, lens, user_types, argc)) {
|
||||
if (writembrs(fd, names, start, lens, user_types, argc, force)) {
|
||||
printf("\nverifying new partition tables:\n");
|
||||
checkmbrs(fd);
|
||||
printf("rereading partition table... returned %d\n", ioctl(fd, BLKRRPART, 0));
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define MBR_MAGIC "softw311"
|
||||
#define MBR_VERSION 0x100
|
||||
|
||||
#define MAX_PART_COUNT 15 //max part count
|
||||
#define MBR_COPY_NUM 4 //mbr backup count
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user