⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkuffs.c

📁 nandflash文件系统源代码
💻 C
字号:
/*
    Copyright (C) 2005-2008  Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/
/**
 * \file uffs_test.c
 * \brief uffs test main entry
 * \author Ricky Zheng
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "cmdline.h"
#include "uffs_fileem.h"

extern struct cli_commandset * get_helper_cmds(void);
extern void femu_init_uffs_device(uffs_Device *dev);

#ifdef USE_NATIVE_MEMORY_ALLOCATOR
static int conf_memory_pool_size_kb = 100; /* default allocate 100k memory. */
static void *memory_pool = NULL;
#endif

static int conf_command_line_mode = 0;
static int conf_verbose_mode = 0;

static int conf_exec_script = 0;
static char script_file_name[256];

#define DEFAULT_EMU_FILENAME "uffsemfile.bin"
const char * conf_emu_filename = DEFAULT_EMU_FILENAME;


/* default basic parameters of the NAND device */
int conf_pages_per_block = 32;
int conf_pages_data_size = 256;
int conf_pages_spare_size = 8;
int conf_total_blocks =	128;		//2M
int conf_sim_manid = MAN_ID_SAMSUNG;	//default: simulate Samsung's NAND flash

#define PAGE_SIZE					(conf_pages_data_size + conf_pages_spare_size)
#define BLOCK_DATA_SIZE				(conf_pages_per_block * conf_pages_data_size)
#define TOTAL_DATA_SIZE				(conf_total_blocks * BLOCK_DATA_SIZE)
#define BLOCK_SIZE					(conf_pages_per_block * PAGE_SIZE)
#define TOTAL_SIZE					(BLOCK_SIZE * conf_total_blocks)

#define MAX_MOUNT_TABLES		10
#define MAX_MOUNT_POINT_NAME	32
static struct uffs_mountTableSt conf_mounts[MAX_MOUNT_TABLES] = {0};
static uffs_Device conf_devices[MAX_MOUNT_TABLES] = {0};
static char mount_point_name[MAX_MOUNT_TABLES][MAX_MOUNT_POINT_NAME] = {0};

static struct uffs_storageAttrSt emu_storage = {0};
static struct uffs_FileEmuSt emu_private = {0};



#ifdef USE_NATIVE_MEMORY_ALLOCATOR
BOOL cmdMeminfo(const char *tail)
{
	const char *mount = "/";
	int i;
	HEAP_MM *mm;
	int count = 0;
	int blocks = 0;

	uffs_Device *dev;
	
	if (tail) mount = cli_getparam(tail, NULL);
	dev = uffs_GetDevice(mount);

	if (!dev) {
		printf("can't get device from mount point %s\n", mount);
		return TRUE;
	}
	
	for (i = 0; i < HEAP_HASH_SIZE; i++) {
		mm = dev->mem.tbl[i];
		while (mm) {
			printf("%d, ", mm->size);
			count += mm->size;
			blocks++;
			mm = mm->next;
		}
	}
	printf("\n>>> total allocated %d blocks (%d bytes), max %d bytes. <<<\n", blocks, count, dev->mem.maxused);
	
	uffs_PutDevice(dev);

	return TRUE;
}
#endif


static struct cli_commandset cmdset[] = 
{
#ifdef USE_NATIVE_MEMORY_ALLOCATOR
    { cmdMeminfo,	"mem",			"<mount>",			"show native memory allocator infomation" },
#endif
    { NULL, NULL, NULL, NULL }
};


static void setup_emu_storage(struct uffs_storageAttrSt *attr)
{
	attr->dev_type =	UFFS_DEV_EMU;			/* dev_type */
	attr->maker = conf_sim_manid;				/* simulate manufacture ID */
	attr->id = 0xe3;							/* chip id, can be ignored. */
	attr->total_blocks = conf_total_blocks;			/* total blocks */
	attr->block_data_size = BLOCK_DATA_SIZE;	/* block data size */
	attr->page_data_size = conf_pages_data_size;		/* page data size */
	attr->spare_size = conf_pages_spare_size;			/* page spare size */
	attr->pages_per_block = conf_pages_per_block;	/* pages per block */
	attr->block_status_offs = 5;                /* block status offset is 5th byte in spare */
}

static void setup_emu_private(uffs_FileEmu *emu)
{
	memset(emu, 0, sizeof(uffs_FileEmu));
	emu->emu_filename = conf_emu_filename;
}

static int init_uffs_fs(void)
{
	static int bIsFileSystemInited = 0;
	struct uffs_mountTableSt *mtbl = &(conf_mounts[0]);

	if(bIsFileSystemInited) return -4;
	bIsFileSystemInited = 1;

#ifdef USE_NATIVE_MEMORY_ALLOCATOR
	memory_pool = malloc(conf_memory_pool_size_kb * 1024);
	if (memory_pool)
		uffs_InitHeapMemory(memory_pool, conf_memory_pool_size_kb * 1024);
	else {
		uffs_Perror(UFFS_ERR_SERIOUS, "Can't alloc memory (size = %dKB) for uffs.\n", conf_memory_pool_size_kb);
		return -1;
	}
#endif

	setup_emu_storage(&emu_storage);
	setup_emu_private(&emu_private);
	emu_storage.private = &emu_private;
	
	while(mtbl->dev) {
		mtbl->dev->attr = &emu_storage;
#ifdef USE_NATIVE_MEMORY_ALLOCATOR
		uffs_SetupNativeMemoryAllocator(&mtbl->dev->mem);
#endif
		uffs_fileem_setup_device(mtbl->dev);
		uffs_RegisterMountTable(mtbl);
		mtbl++;
	}

	return uffs_initMountTable() == U_SUCC ? 0 : -1;
}

static int release_uffs_fs(void)
{
	int ret;
	ret = uffs_releaseMountTable();
#ifdef USE_NATIVE_MEMORY_ALLOCATOR
	if (memory_pool) {
		free(memory_pool);
		memory_pool = NULL;
	}
#endif
	return ret;
}

/* mount point arg: /sys/,100,-1 */
static int parse_mount_point(char *arg, int m_idx)
{
	int start = 0, end = -1;
	char *p = arg;
	struct uffs_mountTableSt *mtbl = &(conf_mounts[m_idx]);

	while(*p && *p != ',' && *p != ' ' && *p != '\t') p++;
	if (*p == 0 || p == arg) return -1;
	mtbl->mountPoint = &(mount_point_name[m_idx][0]);
	memcpy((char *)mtbl->mountPoint, arg, p - arg);
	((char *)(mtbl->mountPoint))[p - arg] = 0;

	p++;
	arg = p;
	while(*p && *p != ',' && *p != ' ' && *p != '\t') p++;
	if (p != arg) {
		if (sscanf(arg, "%i", &start) < 1) return -1;
		p++;
		arg = p;
		while(*p && *p != ',' && *p != ' ' && *p != '\t') p++;
		if (p != arg) {
			if (sscanf(arg, "%i", &end) < 1) return -1;
		}
	}
	mtbl->startBlock = start;
	mtbl->endBlock = end;
	mtbl->dev = &(conf_devices[m_idx]);

	return 0;
}

static int parse_options(int argc, char *argv[])
{
    int iarg;
    int usage = 0;
	int m_idx = 0;
    static char em_file[128];

    for (iarg = 1; iarg < argc && !usage; iarg++) {
        const char *arg = argv[iarg];
        
        if (arg[0] == '-')
        {
            if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
            {
                usage++;
            }
            else if (!strcmp(arg, "-f") || !strcmp(arg, "--file"))
            {
                if (++iarg >= argc) usage++;
				else {
					strcpy(em_file, argv[iarg]);
					conf_emu_filename = (const char *)em_file;
				}
            }
            else if (!strcmp(arg, "-c") || !strcmp(arg, "--command-line"))
            {
				conf_command_line_mode = 1;
            }
            else if (!strcmp(arg, "-p") || !strcmp(arg, "--page-size"))
            {
                if (++iarg >= argc) usage++;
                else if (sscanf(argv[iarg], "%i", &conf_pages_data_size) < 1) usage++;
				if (conf_pages_data_size <= 0 || (conf_pages_data_size % 512)) usage++;
            }
            else if (!strcmp(arg, "-s") || !strcmp(arg, "--spare-size"))
            {
                if (++iarg >= argc) usage++;
                else if (sscanf(argv[iarg], "%i", &conf_pages_spare_size) < 1) usage++;
				if (conf_pages_spare_size < 16 || (conf_pages_spare_size % 4)) usage++;
            }
            else if (!strcmp(arg, "-b") || !strcmp(arg, "--block-pages"))
            {
                if (++iarg >= argc) usage++;
                else if (sscanf(argv[iarg], "%i", &conf_pages_per_block) < 1) usage++;
				if (conf_pages_per_block < 2) usage++;
            }
            else if (!strcmp(arg, "-t") || !strcmp(arg, "--total-blocks"))
            {
                if (++iarg >= argc) usage++;
                else if (sscanf(argv[iarg], "%i", &conf_total_blocks) < 1) usage++;
				if (conf_total_blocks < 2) usage++;
            }
			else if (!strcmp(arg, "-i") || !strcmp(arg, "--id-man"))
			{
				if (++iarg > argc) usage++;
				else if (sscanf(argv[iarg], "%x", &conf_sim_manid) < 1) usage++;
			}
            else if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose"))
            {
				conf_verbose_mode = 1;
            }
            else if (!strcmp(arg, "-m") || !strcmp(arg, "--mount"))
            {
				if (++iarg > argc) usage++;
				else if (parse_mount_point(argv[iarg], m_idx) < 0) usage++;
				m_idx++;
            }
			else if (!strcmp(arg, "-e") || !strcmp(arg, "--exec"))
			{
				if (++iarg > argc) usage++;
				else {
					strcpy(script_file_name, argv[iarg]);
					conf_exec_script = 1;
				}
			}
#ifdef USE_NATIVE_MEMORY_ALLOCATOR			
			else if (!strcmp(arg, "-a") || !strcmp(arg, "--alloc"))
			{
				if (++iarg > argc) usage++;
				else if (sscanf(argv[iarg], "%d", &conf_memory_pool_size_kb) < 1) usage++;
				if (conf_memory_pool_size_kb <= 0) usage++;
			}
#endif
            else
            {
                printf("Unknown option: %s, try %s --help\n", arg, argv[0]);
				return -1;
            }
        }
        else
        {
            printf("Unexpected parameter: %s, try %s --help\n", arg, argv[0]);
			return -1;
        }
    }
    
    if (usage)
    {
        printf("Usage: %s [options]\n", argv[0]);
        printf("  -h  --help                        show usage\n");
        printf("  -c  --command-line                command line mode\n");
        printf("  -v  --verbose                     verbose mode\n");
        printf("  -f  --file           <file>       uffs image file\n");
        printf("  -p  --page-size      <n>          page data size, default=512\n");
        printf("  -s  --spare-size     <n>          page spare size, default=16\n");
        printf("  -b  --block-pages    <n>          pages per block\n");
        printf("  -t  --total-blocks   <n>          total blocks\n");
        printf("  -m  --mount          <mount_point,start,end> , for example: -m /,0,-1\n");
		printf("  -i  --id-man         <id>         set manufacture ID, default=0xEC\n");
        printf("  -e  --exec           <file>       execute a script file\n");
#ifdef USE_NATIVE_MEMORY_ALLOCATOR		
		printf("  -a  --alloc          <size>       allocate size(KB) of memory for uffs, default 100\n");
#endif		
        printf("\n");

        return -1;
    }

	if (m_idx == 0) {
		parse_mount_point("/,0,-1", 0);
	}

	return 0;
}


static void print_mount_points(void)
{
	struct uffs_mountTableSt *mount;

	mount = &(conf_mounts[0]);
	while(mount->dev) {
		printf ("Mount point: %s, start: %d, end: %d\n", mount->mountPoint, mount->startBlock, mount->endBlock);
		mount++;
	}
}

static void print_params(void)
{
	printf("uffs image file: %s\n", conf_emu_filename);
	printf("page size: %d\n", conf_pages_data_size);
	printf("page spare size: %d\n", conf_pages_spare_size);
	printf("pages per block: %d\n", conf_pages_per_block);
	printf("total blocks: %d\n", conf_total_blocks);
}

static void exec_script()
{
	char line_buf[256];
	char *p;
	FILE *fp;

	fp = fopen(script_file_name, "r");
	if (fp) {
		memset(line_buf, 0, sizeof(line_buf));
		while (fgets(line_buf, sizeof(line_buf) - 1, fp)) {
			p = line_buf + sizeof(line_buf) - 1;
			while (*p == 0 && p > line_buf) p--;
			while ((*p == '\r' || *p == '\n') && p > line_buf) {
				*p-- = 0;
			}
			if (conf_verbose_mode) printf("%s\r\n", line_buf);
			cliInterpret(line_buf);
			memset(line_buf, 0, sizeof(line_buf));
		}
		fclose(fp);
	}
}

int main(int argc, char *argv[])
{

	int ret;

	if (parse_options(argc, argv) < 0) {
		return -1;
	}
	
	if (conf_verbose_mode) {
		print_mount_points();
		print_params();
		#if 0
		printf("TreeNode size: %d\n", sizeof(TreeNode));
		printf("struct blocklistSt: %d\n", sizeof(struct blocklistSt));
		printf("struct dirhSt: %d\n", sizeof(struct dirhSt));
		printf("struct filehSt: %d\n", sizeof(struct filehSt));
		printf("struct fdataSt: %d\n", sizeof(struct fdataSt));
		#endif
	}

	ret = init_uffs_fs();
	if (ret != 0) {
		printf ("Init file system fail: %d\n", ret);
		return -1;
	}

	if (uffs_InitObjectBuf() == U_SUCC) {
		cli_add_commandset(get_helper_cmds());
		cli_add_commandset(cmdset);
		if (conf_command_line_mode) {
			if (conf_exec_script) {
				exec_script();
			}
			cliMain();
		}
		else {
			if (conf_exec_script) {
				exec_script();
			}
			else {
				cliMain();
			}
		}

		uffs_ReleaseObjectBuf();
	}
	else {
		printf("Fail to init Object buffer.\n");
	}

	release_uffs_fs();
	return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -