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