xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/uffs/src/utils/mkuffs.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero   This file is part of UFFS, the Ultra-low-cost Flash File System.
3*10465441SEvalZero 
4*10465441SEvalZero   Copyright (C) 2005-2009 Ricky Zheng <[email protected]>
5*10465441SEvalZero 
6*10465441SEvalZero   UFFS is free software; you can redistribute it and/or modify it under
7*10465441SEvalZero   the GNU Library General Public License as published by the Free Software
8*10465441SEvalZero   Foundation; either version 2 of the License, or (at your option) any
9*10465441SEvalZero   later version.
10*10465441SEvalZero 
11*10465441SEvalZero   UFFS is distributed in the hope that it will be useful, but WITHOUT
12*10465441SEvalZero   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*10465441SEvalZero   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*10465441SEvalZero   or GNU Library General Public License, as applicable, for more details.
15*10465441SEvalZero 
16*10465441SEvalZero   You should have received a copy of the GNU General Public License
17*10465441SEvalZero   and GNU Library General Public License along with UFFS; if not, write
18*10465441SEvalZero   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19*10465441SEvalZero   Boston, MA  02110-1301, USA.
20*10465441SEvalZero 
21*10465441SEvalZero   As a special exception, if other files instantiate templates or use
22*10465441SEvalZero   macros or inline functions from this file, or you compile this file
23*10465441SEvalZero   and link it with other works to produce a work based on this file,
24*10465441SEvalZero   this file does not by itself cause the resulting work to be covered
25*10465441SEvalZero   by the GNU General Public License. However the source code for this
26*10465441SEvalZero   file must still be made available in accordance with section (3) of
27*10465441SEvalZero   the GNU General Public License v2.
28*10465441SEvalZero 
29*10465441SEvalZero   This exception does not invalidate any other reasons why a work based
30*10465441SEvalZero   on this file might be covered by the GNU General Public License.
31*10465441SEvalZero */
32*10465441SEvalZero 
33*10465441SEvalZero /**
34*10465441SEvalZero  * \file uffs_test.c
35*10465441SEvalZero  * \brief uffs test main entry
36*10465441SEvalZero  * \author Ricky Zheng
37*10465441SEvalZero  */
38*10465441SEvalZero 
39*10465441SEvalZero #include <stdio.h>
40*10465441SEvalZero #include <string.h>
41*10465441SEvalZero #include <stdlib.h>
42*10465441SEvalZero #include "uffs_config.h"
43*10465441SEvalZero #include "uffs/uffs_os.h"
44*10465441SEvalZero #include "uffs/uffs_public.h"
45*10465441SEvalZero #include "uffs/uffs_fs.h"
46*10465441SEvalZero #include "uffs/uffs_utils.h"
47*10465441SEvalZero #include "uffs/uffs_core.h"
48*10465441SEvalZero #include "uffs/uffs_mtb.h"
49*10465441SEvalZero 
50*10465441SEvalZero #include "cmdline.h"
51*10465441SEvalZero #include "uffs_fileem.h"
52*10465441SEvalZero 
53*10465441SEvalZero #define PFX NULL
54*10465441SEvalZero #define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
55*10465441SEvalZero #define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
56*10465441SEvalZero 
57*10465441SEvalZero #if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0
main()58*10465441SEvalZero int main()
59*10465441SEvalZero {
60*10465441SEvalZero 	MSGLN("Static memory allocator is not supported.");
61*10465441SEvalZero 	return 0;
62*10465441SEvalZero }
63*10465441SEvalZero #else
64*10465441SEvalZero 
65*10465441SEvalZero extern struct cli_commandset * get_helper_cmds(void);
66*10465441SEvalZero extern struct cli_commandset * get_test_cmds(void);
67*10465441SEvalZero extern void femu_init_uffs_device(uffs_Device *dev);
68*10465441SEvalZero 
69*10465441SEvalZero static int conf_command_line_mode = 0;
70*10465441SEvalZero static int conf_verbose_mode = 0;
71*10465441SEvalZero 
72*10465441SEvalZero static int conf_exec_script = 0;
73*10465441SEvalZero static char script_command[256];
74*10465441SEvalZero 
75*10465441SEvalZero #define DEFAULT_EMU_FILENAME "uffsemfile.bin"
76*10465441SEvalZero const char * conf_emu_filename = DEFAULT_EMU_FILENAME;
77*10465441SEvalZero 
78*10465441SEvalZero 
79*10465441SEvalZero /* default basic parameters of the NAND device */
80*10465441SEvalZero #define PAGES_PER_BLOCK_DEFAULT			32
81*10465441SEvalZero #define PAGE_DATA_SIZE_DEFAULT			512
82*10465441SEvalZero #define PAGE_SPARE_SIZE_DEFAULT			16
83*10465441SEvalZero #define STATUS_BYTE_OFFSET_DEFAULT		5
84*10465441SEvalZero #define TOTAL_BLOCKS_DEFAULT			128
85*10465441SEvalZero #define ECC_OPTION_DEFAULT				UFFS_ECC_SOFT
86*10465441SEvalZero //#define ECC_OPTION_DEFAULT			UFFS_ECC_HW
87*10465441SEvalZero //#define ECC_OPTION_DEFAULT			UFFS_ECC_HW_AUTO
88*10465441SEvalZero 
89*10465441SEvalZero #define MAX_MOUNT_TABLES		10
90*10465441SEvalZero #define MAX_MOUNT_POINT_NAME	32
91*10465441SEvalZero 
92*10465441SEvalZero static int conf_pages_per_block = PAGES_PER_BLOCK_DEFAULT;
93*10465441SEvalZero static int conf_page_data_size = PAGE_DATA_SIZE_DEFAULT;
94*10465441SEvalZero static int conf_page_spare_size = PAGE_SPARE_SIZE_DEFAULT;
95*10465441SEvalZero static int conf_status_byte_offset = STATUS_BYTE_OFFSET_DEFAULT;
96*10465441SEvalZero static int conf_total_blocks = TOTAL_BLOCKS_DEFAULT;
97*10465441SEvalZero static int conf_ecc_option = ECC_OPTION_DEFAULT;
98*10465441SEvalZero static int conf_ecc_size = 0; // 0 - Let UFFS choose the size
99*10465441SEvalZero 
100*10465441SEvalZero static const char *g_ecc_option_strings[] = UFFS_ECC_OPTION_STRING;
101*10465441SEvalZero 
102*10465441SEvalZero static struct uffs_MountTableEntrySt conf_mounts[MAX_MOUNT_TABLES] = {{0}};
103*10465441SEvalZero static uffs_Device conf_devices[MAX_MOUNT_TABLES] = {{0}};
104*10465441SEvalZero static char mount_point_name[MAX_MOUNT_TABLES][MAX_MOUNT_POINT_NAME] = {{0}};
105*10465441SEvalZero 
setup_storage(struct uffs_StorageAttrSt * attr)106*10465441SEvalZero static void setup_storage(struct uffs_StorageAttrSt *attr)
107*10465441SEvalZero {
108*10465441SEvalZero 	attr->total_blocks = conf_total_blocks;				/* total blocks */
109*10465441SEvalZero 	attr->page_data_size = conf_page_data_size;			/* page data size */
110*10465441SEvalZero 	attr->spare_size = conf_page_spare_size;			/* page spare size */
111*10465441SEvalZero 	attr->pages_per_block = conf_pages_per_block;		/* pages per block */
112*10465441SEvalZero 
113*10465441SEvalZero 	attr->block_status_offs = conf_status_byte_offset;	/* block status offset is 5th byte in spare */
114*10465441SEvalZero 	attr->ecc_opt = conf_ecc_option;					/* ECC option */
115*10465441SEvalZero 	attr->ecc_size = conf_ecc_size;						/* ECC size */
116*10465441SEvalZero 	attr->layout_opt = UFFS_LAYOUT_UFFS;				/* let UFFS handle layout */
117*10465441SEvalZero }
118*10465441SEvalZero 
119*10465441SEvalZero 
setup_device(uffs_Device * dev)120*10465441SEvalZero static void setup_device(uffs_Device *dev)
121*10465441SEvalZero {
122*10465441SEvalZero 	dev->Init = femu_InitDevice;
123*10465441SEvalZero 	dev->Release = femu_ReleaseDevice;
124*10465441SEvalZero 	dev->attr = femu_GetStorage();
125*10465441SEvalZero }
126*10465441SEvalZero 
setup_emu_private(uffs_FileEmu * emu)127*10465441SEvalZero static void setup_emu_private(uffs_FileEmu *emu)
128*10465441SEvalZero {
129*10465441SEvalZero 	memset(emu, 0, sizeof(uffs_FileEmu));
130*10465441SEvalZero 	emu->emu_filename = conf_emu_filename;
131*10465441SEvalZero }
132*10465441SEvalZero 
init_uffs_fs(void)133*10465441SEvalZero static int init_uffs_fs(void)
134*10465441SEvalZero {
135*10465441SEvalZero 	static int bIsFileSystemInited = 0;
136*10465441SEvalZero 	struct uffs_MountTableEntrySt *mtbl = &(conf_mounts[0]);
137*10465441SEvalZero 	struct uffs_ConfigSt cfg = {
138*10465441SEvalZero 		0,			// bc_caches - default
139*10465441SEvalZero 		0,			// page_buffers - default
140*10465441SEvalZero 		0,			// dirty_pages - default
141*10465441SEvalZero 		0,			// dirty_groups - default
142*10465441SEvalZero 		0,			// reserved_free_blocks - default
143*10465441SEvalZero 	};
144*10465441SEvalZero 
145*10465441SEvalZero 	if (bIsFileSystemInited)
146*10465441SEvalZero 		return -4;
147*10465441SEvalZero 
148*10465441SEvalZero 	bIsFileSystemInited = 1;
149*10465441SEvalZero 
150*10465441SEvalZero 	while (mtbl->dev) {
151*10465441SEvalZero 
152*10465441SEvalZero 		memcpy(&mtbl->dev->cfg, &cfg, sizeof(struct uffs_ConfigSt));
153*10465441SEvalZero 
154*10465441SEvalZero #if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
155*10465441SEvalZero 		uffs_MemSetupSystemAllocator(&mtbl->dev->mem);
156*10465441SEvalZero #endif
157*10465441SEvalZero 		setup_device(mtbl->dev);
158*10465441SEvalZero 		uffs_RegisterMountTable(mtbl);
159*10465441SEvalZero 		mtbl++;
160*10465441SEvalZero 	}
161*10465441SEvalZero 
162*10465441SEvalZero 	// mount partitions
163*10465441SEvalZero 	for (mtbl = &(conf_mounts[0]); mtbl->mount != NULL; mtbl++) {
164*10465441SEvalZero 		uffs_Mount(mtbl->mount);
165*10465441SEvalZero 	}
166*10465441SEvalZero 
167*10465441SEvalZero 	return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1;
168*10465441SEvalZero }
169*10465441SEvalZero 
release_uffs_fs(void)170*10465441SEvalZero static int release_uffs_fs(void)
171*10465441SEvalZero {
172*10465441SEvalZero 	int ret = 0;
173*10465441SEvalZero 	uffs_MountTable *mtb;
174*10465441SEvalZero 
175*10465441SEvalZero 	for (mtb = &(conf_mounts[0]); ret == 0 && mtb->mount != NULL; mtb++) {
176*10465441SEvalZero 		uffs_UnMount(mtb->mount);
177*10465441SEvalZero 	}
178*10465441SEvalZero 
179*10465441SEvalZero 	if (ret == 0)
180*10465441SEvalZero 		ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1);
181*10465441SEvalZero 
182*10465441SEvalZero 	return ret;
183*10465441SEvalZero }
184*10465441SEvalZero 
185*10465441SEvalZero /* mount point arg: /sys/,100,-1 */
parse_mount_point(char * arg,int m_idx)186*10465441SEvalZero static int parse_mount_point(char *arg, int m_idx)
187*10465441SEvalZero {
188*10465441SEvalZero 	int start = 0, end = -1;
189*10465441SEvalZero 	char *p = arg;
190*10465441SEvalZero 	struct uffs_MountTableEntrySt *mtbl = &(conf_mounts[m_idx]);
191*10465441SEvalZero 
192*10465441SEvalZero 	while(*p && *p != ',' && *p != ' ' && *p != '\t')
193*10465441SEvalZero 		p++;
194*10465441SEvalZero 
195*10465441SEvalZero 	if (*p == 0 || p == arg)
196*10465441SEvalZero 		return -1;
197*10465441SEvalZero 
198*10465441SEvalZero 	mtbl->mount = &(mount_point_name[m_idx][0]);
199*10465441SEvalZero 	memcpy((char *)mtbl->mount, arg, p - arg);
200*10465441SEvalZero 	((char *)(mtbl->mount))[p - arg] = 0;
201*10465441SEvalZero 
202*10465441SEvalZero 	p++;
203*10465441SEvalZero 	arg = p;
204*10465441SEvalZero 	while(*p && *p != ',' && *p != ' ' && *p != '\t')
205*10465441SEvalZero 		p++;
206*10465441SEvalZero 
207*10465441SEvalZero 	if (p != arg) {
208*10465441SEvalZero 		if (sscanf(arg, "%i", &start) < 1)
209*10465441SEvalZero 			return -1;
210*10465441SEvalZero 		p++;
211*10465441SEvalZero 		arg = p;
212*10465441SEvalZero 
213*10465441SEvalZero 		while(*p && *p != ',' && *p != ' ' && *p != '\t')
214*10465441SEvalZero 			p++;
215*10465441SEvalZero 
216*10465441SEvalZero 		if (p != arg) {
217*10465441SEvalZero 			if (sscanf(arg, "%i", &end) < 1)
218*10465441SEvalZero 				return -1;
219*10465441SEvalZero 		}
220*10465441SEvalZero 	}
221*10465441SEvalZero 	mtbl->start_block = start;
222*10465441SEvalZero 	mtbl->end_block = end;
223*10465441SEvalZero 	mtbl->dev = &(conf_devices[m_idx]);
224*10465441SEvalZero 
225*10465441SEvalZero 	return 0;
226*10465441SEvalZero }
227*10465441SEvalZero 
parse_options(int argc,char * argv[])228*10465441SEvalZero static int parse_options(int argc, char *argv[])
229*10465441SEvalZero {
230*10465441SEvalZero     int iarg;
231*10465441SEvalZero     int usage = 0;
232*10465441SEvalZero 	int m_idx = 0;
233*10465441SEvalZero     static char em_file[128];
234*10465441SEvalZero 	int i;
235*10465441SEvalZero 
236*10465441SEvalZero     for (iarg = 1; iarg < argc && !usage; iarg++) {
237*10465441SEvalZero         const char *arg = argv[iarg];
238*10465441SEvalZero 
239*10465441SEvalZero         if (arg[0] == '-') {
240*10465441SEvalZero             if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
241*10465441SEvalZero                 usage++;
242*10465441SEvalZero             }
243*10465441SEvalZero             else if (!strcmp(arg, "-f") || !strcmp(arg, "--file")) {
244*10465441SEvalZero                 if (++iarg >= argc)
245*10465441SEvalZero 					usage++;
246*10465441SEvalZero 				else {
247*10465441SEvalZero 					strcpy(em_file, argv[iarg]);
248*10465441SEvalZero 					conf_emu_filename = (const char *)em_file;
249*10465441SEvalZero 				}
250*10465441SEvalZero             }
251*10465441SEvalZero             else if (!strcmp(arg, "-c") || !strcmp(arg, "--command-line")) {
252*10465441SEvalZero 				conf_command_line_mode = 1;
253*10465441SEvalZero             }
254*10465441SEvalZero             else if (!strcmp(arg, "-p") || !strcmp(arg, "--page-size")) {
255*10465441SEvalZero                 if (++iarg >= argc)
256*10465441SEvalZero 					usage++;
257*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_page_data_size) < 1)
258*10465441SEvalZero 					usage++;
259*10465441SEvalZero 				if (conf_page_data_size <= 0 || conf_page_data_size > UFFS_MAX_PAGE_SIZE) {
260*10465441SEvalZero 					MSGLN("ERROR: Invalid page data size");
261*10465441SEvalZero 					usage++;
262*10465441SEvalZero 				}
263*10465441SEvalZero             }
264*10465441SEvalZero             else if (!strcmp(arg, "-s") || !strcmp(arg, "--spare-size")) {
265*10465441SEvalZero                 if (++iarg >= argc)
266*10465441SEvalZero 					usage++;
267*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_page_spare_size) < 1)
268*10465441SEvalZero 					usage++;
269*10465441SEvalZero 				if (conf_page_spare_size < sizeof(struct uffs_TagStoreSt) + 1 ||
270*10465441SEvalZero 					(conf_page_spare_size % 4) != 0 || conf_page_spare_size > UFFS_MAX_SPARE_SIZE) {
271*10465441SEvalZero 					MSGLN("ERROR: Invalid spare size");
272*10465441SEvalZero 					usage++;
273*10465441SEvalZero 				}
274*10465441SEvalZero             }
275*10465441SEvalZero             else if (!strcmp(arg, "-o") || !strcmp(arg, "--status-offset")) {
276*10465441SEvalZero                 if (++iarg >= argc)
277*10465441SEvalZero 					usage++;
278*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_status_byte_offset) < 1)
279*10465441SEvalZero 					usage++;
280*10465441SEvalZero 				if (conf_status_byte_offset < 0)
281*10465441SEvalZero 					usage++;
282*10465441SEvalZero             }
283*10465441SEvalZero             else if (!strcmp(arg, "-b") || !strcmp(arg, "--block-pages")) {
284*10465441SEvalZero                 if (++iarg >= argc)
285*10465441SEvalZero 					usage++;
286*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_pages_per_block) < 1)
287*10465441SEvalZero 					usage++;
288*10465441SEvalZero 				if (conf_pages_per_block < 2)
289*10465441SEvalZero 					usage++;
290*10465441SEvalZero             }
291*10465441SEvalZero             else if (!strcmp(arg, "-t") || !strcmp(arg, "--total-blocks")) {
292*10465441SEvalZero                 if (++iarg >= argc)
293*10465441SEvalZero 					usage++;
294*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_total_blocks) < 1)
295*10465441SEvalZero 					usage++;
296*10465441SEvalZero 				if (conf_total_blocks < 2)
297*10465441SEvalZero 					usage++;
298*10465441SEvalZero             }
299*10465441SEvalZero             else if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
300*10465441SEvalZero 				conf_verbose_mode++;
301*10465441SEvalZero             }
302*10465441SEvalZero             else if (!strcmp(arg, "-m") || !strcmp(arg, "--mount")) {
303*10465441SEvalZero 				if (++iarg > argc)
304*10465441SEvalZero 					usage++;
305*10465441SEvalZero 				else if (parse_mount_point(argv[iarg], m_idx) < 0)
306*10465441SEvalZero 					usage++;
307*10465441SEvalZero 				m_idx++;
308*10465441SEvalZero             }
309*10465441SEvalZero 			else if (!strcmp(arg, "-e") || !strcmp(arg, "--exec")) {
310*10465441SEvalZero 				if (++iarg > argc)
311*10465441SEvalZero 					usage++;
312*10465441SEvalZero 				else {
313*10465441SEvalZero 					sprintf(script_command, "script %s", argv[iarg]);
314*10465441SEvalZero 					conf_exec_script = 1;
315*10465441SEvalZero 				}
316*10465441SEvalZero 			}
317*10465441SEvalZero 			else if (!strcmp(arg, "-x") || !strcmp(arg, "--ecc-option")) {
318*10465441SEvalZero 				if (++iarg > argc)
319*10465441SEvalZero 					usage++;
320*10465441SEvalZero 				else {
321*10465441SEvalZero 					for (i = 0; i < ARRAY_SIZE(g_ecc_option_strings); i++) {
322*10465441SEvalZero 						if (!strcmp(argv[iarg], g_ecc_option_strings[i])) {
323*10465441SEvalZero 							conf_ecc_option = i;
324*10465441SEvalZero 							break;
325*10465441SEvalZero 						}
326*10465441SEvalZero 					}
327*10465441SEvalZero 					if (i == ARRAY_SIZE(g_ecc_option_strings)) {
328*10465441SEvalZero 						MSGLN("ERROR: Invalid ECC option");
329*10465441SEvalZero 						usage++;
330*10465441SEvalZero 					}
331*10465441SEvalZero 				}
332*10465441SEvalZero 			}
333*10465441SEvalZero 			else if (!strcmp(arg, "-z") || !strcmp(arg, "--ecc-size")) {
334*10465441SEvalZero                 if (++iarg >= argc)
335*10465441SEvalZero 					usage++;
336*10465441SEvalZero                 else if (sscanf(argv[iarg], "%i", &conf_ecc_size) < 1)
337*10465441SEvalZero 					usage++;
338*10465441SEvalZero 				if (conf_ecc_size < 0 || conf_ecc_size > UFFS_MAX_ECC_SIZE) {
339*10465441SEvalZero 					MSGLN("ERROR: Invalid ecc size");
340*10465441SEvalZero 					usage++;
341*10465441SEvalZero 				}
342*10465441SEvalZero 			}
343*10465441SEvalZero             else {
344*10465441SEvalZero                 MSGLN("Unknown option: %s, try %s --help", arg, argv[0]);
345*10465441SEvalZero 				return -1;
346*10465441SEvalZero             }
347*10465441SEvalZero         }
348*10465441SEvalZero         else {
349*10465441SEvalZero             MSGLN("Unexpected parameter: %s, try %s --help", arg, argv[0]);
350*10465441SEvalZero 			return -1;
351*10465441SEvalZero         }
352*10465441SEvalZero     }
353*10465441SEvalZero 
354*10465441SEvalZero     if (usage) {
355*10465441SEvalZero         MSGLN("Usage: %s [options]", argv[0]);
356*10465441SEvalZero         MSGLN("  -h  --help                                show usage");
357*10465441SEvalZero         MSGLN("  -c  --command-line                        command line mode");
358*10465441SEvalZero         MSGLN("  -v  --verbose                             verbose mode");
359*10465441SEvalZero         MSGLN("  -f  --file           <file>               uffs image file");
360*10465441SEvalZero         MSGLN("  -p  --page-size      <n>                  page data size, default=%d", PAGE_DATA_SIZE_DEFAULT);
361*10465441SEvalZero         MSGLN("  -s  --spare-size     <n>                  page spare size, default=%d", PAGE_SPARE_SIZE_DEFAULT);
362*10465441SEvalZero 		MSGLN("  -o  --status-offset  <n>                  status byte offset, default=%d", STATUS_BYTE_OFFSET_DEFAULT);
363*10465441SEvalZero         MSGLN("  -b  --block-pages    <n>                  pages per block, default=%d", PAGES_PER_BLOCK_DEFAULT);
364*10465441SEvalZero         MSGLN("  -t  --total-blocks   <n>                  total blocks");
365*10465441SEvalZero         MSGLN("  -m  --mount          <mount_point,start,end> , for example: -m /,0,-1");
366*10465441SEvalZero 		MSGLN("  -x  --ecc-option     <none|soft|hw|auto>  ECC option, default=%s", g_ecc_option_strings[ECC_OPTION_DEFAULT]);
367*10465441SEvalZero 		MSGLN("  -z  --ecc-size       <n>                  ECC size, default=0 (auto)");
368*10465441SEvalZero         MSGLN("  -e  --exec           <file>               execute a script file");
369*10465441SEvalZero         MSGLN("");
370*10465441SEvalZero 
371*10465441SEvalZero         return -1;
372*10465441SEvalZero     }
373*10465441SEvalZero 
374*10465441SEvalZero 	if (m_idx == 0) {
375*10465441SEvalZero 		// if not given mount information, use default ('/' for whole partition)
376*10465441SEvalZero 		parse_mount_point("/,0,-1", 0);
377*10465441SEvalZero 	}
378*10465441SEvalZero 
379*10465441SEvalZero 	return 0;
380*10465441SEvalZero }
381*10465441SEvalZero 
382*10465441SEvalZero 
print_mount_points(void)383*10465441SEvalZero static void print_mount_points(void)
384*10465441SEvalZero {
385*10465441SEvalZero 	struct uffs_MountTableEntrySt *m;
386*10465441SEvalZero 
387*10465441SEvalZero 	m = &(conf_mounts[0]);
388*10465441SEvalZero 	while (m->dev) {
389*10465441SEvalZero 		MSGLN ("Mount point: %s, start: %d, end: %d", m->mount, m->start_block, m->end_block);
390*10465441SEvalZero 		m++;
391*10465441SEvalZero 	}
392*10465441SEvalZero }
393*10465441SEvalZero 
print_params(void)394*10465441SEvalZero static void print_params(void)
395*10465441SEvalZero {
396*10465441SEvalZero 	MSGLN("Parameters summary:");
397*10465441SEvalZero 	MSGLN("  uffs image file: %s", conf_emu_filename);
398*10465441SEvalZero 	MSGLN("  page size: %d", conf_page_data_size);
399*10465441SEvalZero 	MSGLN("  page spare size: %d", conf_page_spare_size);
400*10465441SEvalZero 	MSGLN("  pages per block: %d", conf_pages_per_block);
401*10465441SEvalZero 	MSGLN("  total blocks: %d", conf_total_blocks);
402*10465441SEvalZero 	MSGLN("  ecc option: %d (%s)", conf_ecc_option, g_ecc_option_strings[conf_ecc_option]);
403*10465441SEvalZero 	MSGLN("  ecc size: %d%s", conf_ecc_size, conf_ecc_size == 0 ? " (auto)" : "");
404*10465441SEvalZero 	MSGLN("  bad block status offset: %d", conf_status_byte_offset);
405*10465441SEvalZero 	MSGLN("");
406*10465441SEvalZero }
407*10465441SEvalZero 
408*10465441SEvalZero #ifdef UNIX
409*10465441SEvalZero #include <execinfo.h>
410*10465441SEvalZero #include <signal.h>
crash_handler(int sig)411*10465441SEvalZero void crash_handler(int sig)
412*10465441SEvalZero {
413*10465441SEvalZero   void *array[10];
414*10465441SEvalZero   size_t size;
415*10465441SEvalZero 
416*10465441SEvalZero   // get void*'s for all entries on the stack
417*10465441SEvalZero   size = backtrace(array, 10);
418*10465441SEvalZero 
419*10465441SEvalZero   // print out all the frames to stderr
420*10465441SEvalZero   fprintf(stderr, "Error: signal %d:\n", sig);
421*10465441SEvalZero   backtrace_symbols_fd(array, size, 2);
422*10465441SEvalZero   exit(1);
423*10465441SEvalZero }
424*10465441SEvalZero #endif
425*10465441SEvalZero 
main(int argc,char * argv[])426*10465441SEvalZero int main(int argc, char *argv[])
427*10465441SEvalZero {
428*10465441SEvalZero 	int ret;
429*10465441SEvalZero 
430*10465441SEvalZero #ifdef UNIX
431*10465441SEvalZero 	signal(SIGSEGV, crash_handler);
432*10465441SEvalZero #endif
433*10465441SEvalZero 
434*10465441SEvalZero 	uffs_SetupDebugOutput(); 	// setup debug output as early as possible
435*10465441SEvalZero 
436*10465441SEvalZero 	if (parse_options(argc, argv) < 0) {
437*10465441SEvalZero 		return -1;
438*10465441SEvalZero 	}
439*10465441SEvalZero 
440*10465441SEvalZero 	if (conf_verbose_mode) {
441*10465441SEvalZero 		#if 1
442*10465441SEvalZero 		MSGLN("Internal data structure size:");
443*10465441SEvalZero 		MSGLN("  TreeNode: %d", sizeof(TreeNode));
444*10465441SEvalZero 		MSGLN("  struct BlockListSt: %d", sizeof(struct BlockListSt));
445*10465441SEvalZero 		MSGLN("  struct DirhSt: %d", sizeof(struct DirhSt));
446*10465441SEvalZero 		MSGLN("  struct FilehSt: %d", sizeof(struct FilehSt));
447*10465441SEvalZero 		MSGLN("  struct FdataSt: %d", sizeof(struct FdataSt));
448*10465441SEvalZero 		MSGLN("  struct uffs_TagStoreSt: %d", sizeof(struct uffs_TagStoreSt));
449*10465441SEvalZero 		MSGLN("  uffs_Buf: %d", sizeof(uffs_Buf));
450*10465441SEvalZero 		MSGLN("  struct uffs_BlockInfoSt: %d", sizeof(struct uffs_BlockInfoSt));
451*10465441SEvalZero 		MSGLN("");
452*10465441SEvalZero 		#endif
453*10465441SEvalZero 		print_params();
454*10465441SEvalZero 		print_mount_points();
455*10465441SEvalZero 	}
456*10465441SEvalZero 
457*10465441SEvalZero 	// setup file emulator storage with parameters from command line
458*10465441SEvalZero 	setup_storage(femu_GetStorage());
459*10465441SEvalZero 
460*10465441SEvalZero 	// setup file emulator private data
461*10465441SEvalZero 	setup_emu_private(femu_GetPrivate());
462*10465441SEvalZero 
463*10465441SEvalZero 	ret = init_uffs_fs();
464*10465441SEvalZero 	if (ret != 0) {
465*10465441SEvalZero 		MSGLN ("Init file system fail: %d", ret);
466*10465441SEvalZero 		return -1;
467*10465441SEvalZero 	}
468*10465441SEvalZero 
469*10465441SEvalZero 	cli_add_commandset(get_helper_cmds());
470*10465441SEvalZero 	cli_add_commandset(get_test_cmds());
471*10465441SEvalZero 	if (conf_command_line_mode) {
472*10465441SEvalZero 		if (conf_exec_script) {
473*10465441SEvalZero 			cli_interpret(script_command);
474*10465441SEvalZero 		}
475*10465441SEvalZero 		cli_main_entry();
476*10465441SEvalZero 	}
477*10465441SEvalZero 	else {
478*10465441SEvalZero 		if (conf_exec_script) {
479*10465441SEvalZero 			cli_interpret(script_command);
480*10465441SEvalZero 		}
481*10465441SEvalZero 		else {
482*10465441SEvalZero 			cli_main_entry();
483*10465441SEvalZero 		}
484*10465441SEvalZero 	}
485*10465441SEvalZero 
486*10465441SEvalZero 	release_uffs_fs();
487*10465441SEvalZero 
488*10465441SEvalZero 	return 0;
489*10465441SEvalZero }
490*10465441SEvalZero #endif
491*10465441SEvalZero 
492*10465441SEvalZero 
493*10465441SEvalZero 
494