2 * An image maker that creates a file that creates a Yaffs2 image file
3 * can be programmed into NAND.
4 * This assumes that the device has the following properties:
7 * * Yaffs is using inband tags.
9 * Note that this utility first generates a "working file" which is
10 * a simulation of the NAND. It then generates an output file which
11 * can be programmed into flash.
18 #include <sys/types.h>
27 #undef CONFIG_YAFFS_PROVIDE_DEFS
28 #undef CONFIG_YAFFSFS_PROVIDE_VALUES
33 #include "yaffs_nandsim_file.h"
34 #include "yaffs_guts.h"
38 * These are the sizes in the simulator file.
40 #define PAGE_DATA_SIZE 2048
41 #define PAGE_SPARE_SIZE 64
42 #define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
44 /* Some stub definitions to get building to work. */
45 int simulate_power_failure = 0;
48 static char *input_dir;
49 static char *output_file;
50 static char *working_file;
52 static void usage(const char *prog_name)
54 printf("Usage: %s options\n", prog_name);
55 printf("\t-i name input_directory\n");
56 printf("\t-o name output_file\n");
57 printf("\t-w name working_file\n");
60 static void parse_args(int argc, char *argv[])
65 while ((c = getopt(argc, argv, "i:o:w:h")) != -1) {
68 case 'h': usage(argv[0]); break;
69 case 'i': input_dir = strdup(optarg); break;
70 case 'o': output_file = strdup(optarg); break;
71 case 'w': working_file = strdup(optarg); break;
77 static int process_file(const char *from_path, const char *to_path, unsigned mode)
81 unsigned char buffer[8000];
87 hin = open(from_path, O_RDONLY);
89 perror ("opening input file");
92 hout = yaffs_open(to_path, O_CREAT | O_TRUNC | O_RDWR, 0666);
95 printf("failed to create yaffs file %s\n", to_path);
99 while ((nread = read(hin, buffer, sizeof(buffer))) > 0) {
100 nwritten = yaffs_write(hout, buffer, nread);
102 if (nwritten != nread) {
103 printf("Only wrote %d bytes out of %d\n", nwritten, nread);
109 ret = yaffs_fdatasync(hout);
111 printf("data sytnc failed\n");
115 ret = yaffs_fchmod(hout, mode);
117 printf("chmod failed\n");
121 ret = yaffs_close(hout);
123 printf("close failed\n");
130 static int process_directory(const char *from_dir, const char *to_dir)
135 struct dirent *entry;
137 printf("Processing directory %s into %s\n", from_dir, to_dir);
139 dir = opendir(from_dir);
141 printf("opendir failed on %s", from_dir);
145 while((entry = readdir(dir)) != NULL && error >= 0) {
152 //printf("Got entry %s\n", entry->d_name);
154 /* Ignore . and .. */
155 if(strcmp(entry->d_name, ".") == 0 ||
156 strcmp(entry->d_name, "..") == 0)
159 if (snprintf(from_path, sizeof(from_path),
160 "%s/%s", from_dir,entry->d_name) >= (int)sizeof(from_path)) {
161 printf("path too long for %s/%s\n", from_dir, entry->d_name);
165 if (snprintf(to_path, sizeof(to_path),
166 "%s/%s",to_dir,entry->d_name) >= (int)sizeof(to_path)) {
167 printf("path too long for %s/%s\n",to_dir,entry->d_name);
172 if (lstat(from_path,&stats) < 0)
179 mode = stats.st_mode & 0777;
181 if (S_ISDIR(stats.st_mode)) {
182 printf("Directory create %s, mode %03o\n", to_path, mode);
183 ret = yaffs_mkdir(to_path, mode);
184 printf("Directory create %s, mode %03o : result %d\n",
188 printf("directory creation failed\n");
191 process_directory(from_path, to_path);
192 } else if (S_ISREG(stats.st_mode)) {
193 ret = process_file(from_path, to_path, mode);
194 printf("Copy file %s to %s, mode %03o : result %d\n",
195 from_path, to_path, mode, ret);
197 printf("file copy failed\n");
202 printf("Unhandled object type %d\n", stats.st_mode);
212 int is_all_ff(unsigned char *buffer, int n)
225 * Write the data to output, skipping over the spare bytes.
226 * Stop writing when we get to blank flash.
228 int generate_output_file(const char *working_file, const char *output_file)
230 unsigned char buffer[PAGE_SIZE];
237 inh = open(working_file, O_RDONLY);
238 outh = open(output_file, O_CREAT | O_TRUNC | O_RDWR, 0666);
240 while ((nread = read(inh, buffer, PAGE_SIZE)) > 0) {
241 if (nread != PAGE_SIZE) {
242 printf("working file not properly sized\n");
246 if(is_all_ff(buffer, PAGE_DATA_SIZE)) {
247 printf("End of data found\n");
251 nwritten = write(outh, buffer, PAGE_DATA_SIZE);
253 if (nwritten != PAGE_DATA_SIZE) {
254 printf("short write\n");
268 int main(int argc, char *argv[])
270 struct yaffs_dev * dev;
273 parse_args(argc, argv);
275 if (!input_dir || !output_file || !working_file) {
276 printf("Need input directory , output file and working file\n");
281 * Create the Yaffs working file using the simulator.
283 unlink(working_file);
284 dev = yaffs_nandsim_install_drv("yroot",
291 printf("Failed to create yaffs working file\n");
296 * Disable checkpointing to create an image without checkpoint data.
298 dev->param.skip_checkpt_rd = 1;
299 dev->param.skip_checkpt_wr = 1;
301 ret = yaffs_mount("yroot");
303 printf("yaffs_mount returned %d\n", ret);
305 printf("Generating image from %s into file %s using working file %s\n",
306 input_dir, output_file, working_file);
307 process_directory(input_dir, "yroot");
309 yaffs_unmount("yroot");
311 ret = generate_output_file(working_file, output_file);
313 printf("wrote %d bytes to output\n", ret);