ubiformat.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. /*
  2. * Copyright (C) 2008 Nokia Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  12. * the GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /*
  19. * An utility to format MTD devices into UBI and flash UBI images.
  20. *
  21. * Author: Artem Bityutskiy
  22. */
  23. /*
  24. * Maximum amount of consequtive eraseblocks which are considered as normal by
  25. * this utility. Otherwise it is assume that something is wrong with the flash
  26. * or the driver, and eraseblocks are stopped being marked as bad.
  27. */
  28. #define MAX_CONSECUTIVE_BAD_BLOCKS 4
  29. #define PROGRAM_NAME "ubiformat"
  30. #include <sys/stat.h>
  31. #include <unistd.h>
  32. #include <stdint.h>
  33. #include <stdlib.h>
  34. #include <getopt.h>
  35. #include <fcntl.h>
  36. #include <mtd/ubi-media.h>
  37. #include <libubi.h>
  38. #include <libmtd.h>
  39. #include <libscan.h>
  40. #include <libubigen.h>
  41. #include <mtd_swab.h>
  42. #include <crc32.h>
  43. #include "common.h"
  44. /* The variables below are set by command line arguments */
  45. struct args {
  46. unsigned int yes:1;
  47. unsigned int quiet:1;
  48. unsigned int verbose:1;
  49. unsigned int override_ec:1;
  50. unsigned int manual_subpage;
  51. int subpage_size;
  52. int vid_hdr_offs;
  53. int ubi_ver;
  54. uint32_t image_seq;
  55. off_t image_sz;
  56. long long ec;
  57. const char *image;
  58. const char *node;
  59. int node_fd;
  60. };
  61. static struct args args =
  62. {
  63. .ubi_ver = 1,
  64. };
  65. static const char doc[] = PROGRAM_NAME " version " VERSION
  66. " - a tool to format MTD devices and flash UBI images";
  67. static const char optionsstr[] =
  68. "-s, --sub-page-size=<bytes> minimum input/output unit used for UBI\n"
  69. " headers, e.g. sub-page size in case of NAND\n"
  70. " flash (equivalent to the minimum input/output\n"
  71. " unit size by default)\n"
  72. "-O, --vid-hdr-offset=<offs> offset if the VID header from start of the\n"
  73. " physical eraseblock (default is the next\n"
  74. " minimum I/O unit or sub-page after the EC\n"
  75. " header)\n"
  76. "-f, --flash-image=<file> flash image file, or '-' for stdin\n"
  77. "-S, --image-size=<bytes> bytes in input, if not reading from file\n"
  78. "-e, --erase-counter=<value> use <value> as the erase counter value for all\n"
  79. " eraseblocks\n"
  80. "-x, --ubi-ver=<num> UBI version number to put to EC headers\n"
  81. " (default is 1)\n"
  82. "-Q, --image-seq=<num> 32-bit UBI image sequence number to use\n"
  83. " (by default a random number is picked)\n"
  84. "-y, --yes assume the answer is \"yes\" for all question\n"
  85. " this program would otherwise ask\n"
  86. "-q, --quiet suppress progress percentage information\n"
  87. "-v, --verbose be verbose\n"
  88. "-h, -?, --help print help message\n"
  89. "-V, --version print program version\n";
  90. static const char usage[] =
  91. "Usage: " PROGRAM_NAME " <MTD device node file name> [-s <bytes>] [-O <offs>] [-n]\n"
  92. "\t\t\t[-Q <num>] [-f <file>] [-S <bytes>] [-e <value>] [-x <num>] [-y] [-q] [-v] [-h]\n"
  93. "\t\t\t[--sub-page-size=<bytes>] [--vid-hdr-offset=<offs>] [--no-volume-table]\n"
  94. "\t\t\t[--flash-image=<file>] [--image-size=<bytes>] [--erase-counter=<value>]\n"
  95. "\t\t\t[--image-seq=<num>] [--ubi-ver=<num>] [--yes] [--quiet] [--verbose]\n"
  96. "\t\t\t[--help] [--version]\n\n"
  97. "Example 1: " PROGRAM_NAME " /dev/mtd0 -y - format MTD device number 0 and do\n"
  98. " not ask questions.\n"
  99. "Example 2: " PROGRAM_NAME " /dev/mtd0 -q -e 0 - format MTD device number 0,\n"
  100. " be quiet and force erase counter value 0.";
  101. static const struct option long_options[] = {
  102. { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' },
  103. { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' },
  104. { .name = "flash-image", .has_arg = 1, .flag = NULL, .val = 'f' },
  105. { .name = "image-size", .has_arg = 1, .flag = NULL, .val = 'S' },
  106. { .name = "yes", .has_arg = 0, .flag = NULL, .val = 'y' },
  107. { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' },
  108. { .name = "quiet", .has_arg = 0, .flag = NULL, .val = 'q' },
  109. { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' },
  110. { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' },
  111. { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' },
  112. { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' },
  113. { .name = "image-seq", .has_arg = 1, .flag = NULL, .val = 'Q' },
  114. { NULL, 0, NULL, 0},
  115. };
  116. static int parse_opt(int argc, char * const argv[])
  117. {
  118. util_srand();
  119. args.image_seq = rand();
  120. while (1) {
  121. int key, error = 0;
  122. unsigned long int image_seq;
  123. key = getopt_long(argc, argv, "nh?Vyqve:x:s:O:f:S:Q:", long_options, NULL);
  124. if (key == -1)
  125. break;
  126. switch (key) {
  127. case 's':
  128. args.subpage_size = util_get_bytes(optarg);
  129. if (args.subpage_size <= 0)
  130. return errmsg("bad sub-page size: \"%s\"", optarg);
  131. if (!is_power_of_2(args.subpage_size))
  132. return errmsg("sub-page size should be power of 2");
  133. break;
  134. case 'O':
  135. args.vid_hdr_offs = simple_strtoul(optarg, &error);
  136. if (error || args.vid_hdr_offs <= 0)
  137. return errmsg("bad VID header offset: \"%s\"", optarg);
  138. break;
  139. case 'e':
  140. args.ec = simple_strtoull(optarg, &error);
  141. if (error || args.ec < 0)
  142. return errmsg("bad erase counter value: \"%s\"", optarg);
  143. if (args.ec >= EC_MAX)
  144. return errmsg("too high erase %llu, counter, max is %u", args.ec, EC_MAX);
  145. args.override_ec = 1;
  146. break;
  147. case 'f':
  148. args.image = optarg;
  149. break;
  150. case 'S':
  151. args.image_sz = util_get_bytes(optarg);
  152. if (args.image_sz <= 0)
  153. return errmsg("bad image-size: \"%s\"", optarg);
  154. break;
  155. case 'y':
  156. args.yes = 1;
  157. break;
  158. case 'q':
  159. args.quiet = 1;
  160. break;
  161. case 'x':
  162. args.ubi_ver = simple_strtoul(optarg, &error);
  163. if (error || args.ubi_ver < 0)
  164. return errmsg("bad UBI version: \"%s\"", optarg);
  165. break;
  166. case 'Q':
  167. image_seq = simple_strtoul(optarg, &error);
  168. if (error || image_seq > 0xFFFFFFFF)
  169. return errmsg("bad UBI image sequence number: \"%s\"", optarg);
  170. args.image_seq = image_seq;
  171. break;
  172. case 'v':
  173. args.verbose = 1;
  174. break;
  175. case 'V':
  176. common_print_version();
  177. exit(EXIT_SUCCESS);
  178. case 'h':
  179. printf("%s\n\n", doc);
  180. printf("%s\n\n", usage);
  181. printf("%s\n", optionsstr);
  182. exit(EXIT_SUCCESS);
  183. case '?':
  184. printf("%s\n\n", doc);
  185. printf("%s\n\n", usage);
  186. printf("%s\n", optionsstr);
  187. return -1;
  188. case ':':
  189. return errmsg("parameter is missing");
  190. default:
  191. fprintf(stderr, "Use -h for help\n");
  192. return -1;
  193. }
  194. }
  195. if (args.quiet && args.verbose)
  196. return errmsg("using \"-q\" and \"-v\" at the same time does not make sense");
  197. if (optind == argc)
  198. return errmsg("MTD device name was not specified (use -h for help)");
  199. else if (optind != argc - 1)
  200. return errmsg("more then one MTD device specified (use -h for help)");
  201. args.node = argv[optind];
  202. return 0;
  203. }
  204. static int want_exit(void)
  205. {
  206. return prompt("continue?", false) == true ? 0 : 1;
  207. }
  208. static int answer_is_yes(const char *msg)
  209. {
  210. return prompt(msg ? : "continue?", false);
  211. }
  212. static void print_bad_eraseblocks(const struct mtd_dev_info *mtd,
  213. const struct ubi_scan_info *si)
  214. {
  215. int first = 1, eb;
  216. if (si->bad_cnt == 0)
  217. return;
  218. normsg_cont("%d bad eraseblocks found, numbers: ", si->bad_cnt);
  219. for (eb = 0; eb < mtd->eb_cnt; eb++) {
  220. if (si->ec[eb] != EB_BAD)
  221. continue;
  222. if (first) {
  223. printf("%d", eb);
  224. first = 0;
  225. } else
  226. printf(", %d", eb);
  227. }
  228. printf("\n");
  229. }
  230. static int change_ech(struct ubi_ec_hdr *hdr, uint32_t image_seq,
  231. long long ec)
  232. {
  233. uint32_t crc;
  234. /* Check the EC header */
  235. if (be32_to_cpu(hdr->magic) != UBI_EC_HDR_MAGIC)
  236. return errmsg("bad UBI magic %#08x, should be %#08x",
  237. be32_to_cpu(hdr->magic), UBI_EC_HDR_MAGIC);
  238. crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC);
  239. if (be32_to_cpu(hdr->hdr_crc) != crc)
  240. return errmsg("bad CRC %#08x, should be %#08x\n",
  241. crc, be32_to_cpu(hdr->hdr_crc));
  242. hdr->image_seq = cpu_to_be32(image_seq);
  243. hdr->ec = cpu_to_be64(ec);
  244. crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC);
  245. hdr->hdr_crc = cpu_to_be32(crc);
  246. return 0;
  247. }
  248. static int drop_ffs(const struct mtd_dev_info *mtd, const void *buf, int len)
  249. {
  250. int i;
  251. for (i = len - 1; i >= 0; i--)
  252. if (((const uint8_t *)buf)[i] != 0xFF)
  253. break;
  254. /* The resulting length must be aligned to the minimum flash I/O size */
  255. len = i + 1;
  256. len = (len + mtd->min_io_size - 1) / mtd->min_io_size;
  257. len *= mtd->min_io_size;
  258. return len;
  259. }
  260. static int open_file(off_t *sz)
  261. {
  262. int fd;
  263. if (!strcmp(args.image, "-")) {
  264. if (args.image_sz == 0)
  265. return errmsg("must use '-S' with non-zero value when reading from stdin");
  266. *sz = args.image_sz;
  267. fd = dup(STDIN_FILENO);
  268. if (fd < 0)
  269. return sys_errmsg("failed to dup stdin");
  270. } else {
  271. struct stat st;
  272. if (stat(args.image, &st))
  273. return sys_errmsg("cannot open \"%s\"", args.image);
  274. *sz = st.st_size;
  275. fd = open(args.image, O_RDONLY);
  276. if (fd == -1)
  277. return sys_errmsg("cannot open \"%s\"", args.image);
  278. }
  279. return fd;
  280. }
  281. static int read_all(int fd, void *buf, size_t len)
  282. {
  283. while (len > 0) {
  284. ssize_t l = read(fd, buf, len);
  285. if (l == 0)
  286. return errmsg("eof reached; %zu bytes remaining", len);
  287. else if (l > 0) {
  288. buf += l;
  289. len -= l;
  290. } else if (errno == EINTR || errno == EAGAIN)
  291. continue;
  292. else
  293. return sys_errmsg("reading failed; %zu bytes remaining", len);
  294. }
  295. return 0;
  296. }
  297. /*
  298. * Returns %-1 if consecutive bad blocks exceeds the
  299. * MAX_CONSECUTIVE_BAD_BLOCKS and returns %0 otherwise.
  300. */
  301. static int consecutive_bad_check(int eb)
  302. {
  303. static int consecutive_bad_blocks = 1;
  304. static int prev_bb = -1;
  305. if (prev_bb == -1)
  306. prev_bb = eb;
  307. if (eb == prev_bb + 1)
  308. consecutive_bad_blocks += 1;
  309. else
  310. consecutive_bad_blocks = 1;
  311. prev_bb = eb;
  312. if (consecutive_bad_blocks >= MAX_CONSECUTIVE_BAD_BLOCKS) {
  313. if (!args.quiet)
  314. printf("\n");
  315. return errmsg("consecutive bad blocks exceed limit: %d, bad flash?",
  316. MAX_CONSECUTIVE_BAD_BLOCKS);
  317. }
  318. return 0;
  319. }
  320. /* TODO: we should actually torture the PEB before marking it as bad */
  321. static int mark_bad(const struct mtd_dev_info *mtd, struct ubi_scan_info *si, int eb)
  322. {
  323. int err;
  324. if (!args.yes)
  325. if (!answer_is_yes("mark it as bad?"))
  326. return -1;
  327. if (!args.quiet)
  328. normsg_cont("marking block %d bad", eb);
  329. if (!args.quiet)
  330. printf("\n");
  331. if (!mtd->bb_allowed) {
  332. if (!args.quiet)
  333. printf("\n");
  334. return errmsg("bad blocks not supported by this flash");
  335. }
  336. err = mtd_mark_bad(mtd, args.node_fd, eb);
  337. if (err)
  338. return err;
  339. si->bad_cnt += 1;
  340. si->ec[eb] = EB_BAD;
  341. return consecutive_bad_check(eb);
  342. }
  343. static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd,
  344. const struct ubigen_info *ui, struct ubi_scan_info *si)
  345. {
  346. int fd, img_ebs, eb, written_ebs = 0, divisor, skip_data_read = 0;
  347. off_t st_size;
  348. fd = open_file(&st_size);
  349. if (fd < 0)
  350. return fd;
  351. img_ebs = st_size / mtd->eb_size;
  352. if (img_ebs > si->good_cnt) {
  353. sys_errmsg("file \"%s\" is too large (%lld bytes)",
  354. args.image, (long long)st_size);
  355. goto out_close;
  356. }
  357. if (st_size % mtd->eb_size) {
  358. sys_errmsg("file \"%s\" (size %lld bytes) is not multiple of ""eraseblock size (%d bytes)",
  359. args.image, (long long)st_size, mtd->eb_size);
  360. goto out_close;
  361. }
  362. verbose(args.verbose, "will write %d eraseblocks", img_ebs);
  363. divisor = img_ebs;
  364. for (eb = 0; eb < mtd->eb_cnt; eb++) {
  365. int err, new_len;
  366. char buf[mtd->eb_size];
  367. long long ec;
  368. if (!args.quiet && !args.verbose) {
  369. printf("\r" PROGRAM_NAME ": flashing eraseblock %d -- %2lld %% complete ",
  370. eb, (long long)(eb + 1) * 100 / divisor);
  371. fflush(stdout);
  372. }
  373. if (si->ec[eb] == EB_BAD) {
  374. divisor += 1;
  375. continue;
  376. }
  377. if (args.verbose) {
  378. normsg_cont("eraseblock %d: erase", eb);
  379. fflush(stdout);
  380. }
  381. err = mtd_erase(libmtd, mtd, args.node_fd, eb);
  382. if (err) {
  383. if (!args.quiet)
  384. printf("\n");
  385. sys_errmsg("failed to erase eraseblock %d", eb);
  386. if (errno != EIO)
  387. goto out_close;
  388. if (mark_bad(mtd, si, eb))
  389. goto out_close;
  390. continue;
  391. }
  392. if (!skip_data_read) {
  393. err = read_all(fd, buf, mtd->eb_size);
  394. if (err) {
  395. sys_errmsg("failed to read eraseblock %d from \"%s\"",
  396. written_ebs, args.image);
  397. goto out_close;
  398. }
  399. }
  400. skip_data_read = 0;
  401. if (args.override_ec)
  402. ec = args.ec;
  403. else if (si->ec[eb] <= EC_MAX)
  404. ec = si->ec[eb] + 1;
  405. else
  406. ec = si->mean_ec;
  407. if (args.verbose) {
  408. printf(", change EC to %lld", ec);
  409. fflush(stdout);
  410. }
  411. err = change_ech((struct ubi_ec_hdr *)buf, ui->image_seq, ec);
  412. if (err) {
  413. errmsg("bad EC header at eraseblock %d of \"%s\"",
  414. written_ebs, args.image);
  415. goto out_close;
  416. }
  417. if (args.verbose) {
  418. printf(", write data\n");
  419. fflush(stdout);
  420. }
  421. new_len = drop_ffs(mtd, buf, mtd->eb_size);
  422. err = mtd_write(libmtd, mtd, args.node_fd, eb, 0, buf, new_len,
  423. NULL, 0, 0);
  424. if (err) {
  425. sys_errmsg("cannot write eraseblock %d", eb);
  426. if (errno != EIO)
  427. goto out_close;
  428. err = mtd_torture(libmtd, mtd, args.node_fd, eb);
  429. if (err) {
  430. if (mark_bad(mtd, si, eb))
  431. goto out_close;
  432. }
  433. /*
  434. * We have to make sure that we do not read next block
  435. * of data from the input image or stdin - we have to
  436. * write buf first instead.
  437. */
  438. skip_data_read = 1;
  439. continue;
  440. }
  441. if (++written_ebs >= img_ebs)
  442. break;
  443. }
  444. if (!args.quiet && !args.verbose)
  445. printf("\n");
  446. close(fd);
  447. return eb + 1;
  448. out_close:
  449. close(fd);
  450. return -1;
  451. }
  452. static int format(libmtd_t libmtd, const struct mtd_dev_info *mtd,
  453. const struct ubigen_info *ui, struct ubi_scan_info *si,
  454. int start_eb, int novtbl)
  455. {
  456. int eb, err, write_size;
  457. struct ubi_ec_hdr *hdr;
  458. struct ubi_vtbl_record *vtbl;
  459. int eb1 = -1, eb2 = -1;
  460. long long ec1 = -1, ec2 = -1;
  461. int ret = -1;
  462. write_size = UBI_EC_HDR_SIZE + mtd->subpage_size - 1;
  463. write_size /= mtd->subpage_size;
  464. write_size *= mtd->subpage_size;
  465. hdr = malloc(write_size);
  466. if (!hdr)
  467. return sys_errmsg("cannot allocate %d bytes of memory", write_size);
  468. memset(hdr, 0xFF, write_size);
  469. for (eb = start_eb; eb < mtd->eb_cnt; eb++) {
  470. long long ec;
  471. if (!args.quiet && !args.verbose) {
  472. printf("\r" PROGRAM_NAME ": formatting eraseblock %d -- %2lld %% complete ",
  473. eb, (long long)(eb + 1 - start_eb) * 100 / (mtd->eb_cnt - start_eb));
  474. fflush(stdout);
  475. }
  476. if (si->ec[eb] == EB_BAD)
  477. continue;
  478. if (args.override_ec)
  479. ec = args.ec;
  480. else if (si->ec[eb] <= EC_MAX)
  481. ec = si->ec[eb] + 1;
  482. else
  483. ec = si->mean_ec;
  484. ubigen_init_ec_hdr(ui, hdr, ec);
  485. if (args.verbose) {
  486. normsg_cont("eraseblock %d: erase", eb);
  487. fflush(stdout);
  488. }
  489. err = mtd_erase(libmtd, mtd, args.node_fd, eb);
  490. if (err) {
  491. if (!args.quiet)
  492. printf("\n");
  493. sys_errmsg("failed to erase eraseblock %d", eb);
  494. if (errno != EIO)
  495. goto out_free;
  496. if (mark_bad(mtd, si, eb))
  497. goto out_free;
  498. continue;
  499. }
  500. if ((eb1 == -1 || eb2 == -1) && !novtbl) {
  501. if (eb1 == -1) {
  502. eb1 = eb;
  503. ec1 = ec;
  504. } else if (eb2 == -1) {
  505. eb2 = eb;
  506. ec2 = ec;
  507. }
  508. if (args.verbose)
  509. printf(", do not write EC, leave for vtbl\n");
  510. continue;
  511. }
  512. if (args.verbose) {
  513. printf(", write EC %lld\n", ec);
  514. fflush(stdout);
  515. }
  516. err = mtd_write(libmtd, mtd, args.node_fd, eb, 0, hdr,
  517. write_size, NULL, 0, 0);
  518. if (err) {
  519. if (!args.quiet && !args.verbose)
  520. printf("\n");
  521. sys_errmsg("cannot write EC header (%d bytes buffer) to eraseblock %d",
  522. write_size, eb);
  523. if (errno != EIO) {
  524. if (args.subpage_size != mtd->min_io_size)
  525. normsg("may be sub-page size is incorrect?");
  526. goto out_free;
  527. }
  528. err = mtd_torture(libmtd, mtd, args.node_fd, eb);
  529. if (err) {
  530. if (mark_bad(mtd, si, eb))
  531. goto out_free;
  532. }
  533. continue;
  534. }
  535. }
  536. if (!args.quiet && !args.verbose)
  537. printf("\n");
  538. if (novtbl) {
  539. ret = 0;
  540. goto out_free;
  541. }
  542. if (eb1 == -1 || eb2 == -1) {
  543. errmsg("no eraseblocks for volume table");
  544. goto out_free;
  545. }
  546. verbose(args.verbose, "write volume table to eraseblocks %d and %d", eb1, eb2);
  547. vtbl = ubigen_create_empty_vtbl(ui);
  548. if (!vtbl)
  549. goto out_free;
  550. err = ubigen_write_layout_vol(ui, eb1, eb2, ec1, ec2, vtbl,
  551. args.node_fd);
  552. free(vtbl);
  553. if (err) {
  554. errmsg("cannot write layout volume");
  555. goto out_free;
  556. }
  557. free(hdr);
  558. return 0;
  559. out_free:
  560. free(hdr);
  561. return ret;
  562. }
  563. int main(int argc, char * const argv[])
  564. {
  565. int err, verbose;
  566. libmtd_t libmtd;
  567. struct mtd_info mtd_info;
  568. struct mtd_dev_info mtd;
  569. libubi_t libubi;
  570. struct ubigen_info ui;
  571. struct ubi_scan_info *si;
  572. err = parse_opt(argc, argv);
  573. if (err)
  574. return -1;
  575. libmtd = libmtd_open();
  576. if (!libmtd)
  577. return errmsg("MTD subsystem is not present");
  578. err = mtd_get_info(libmtd, &mtd_info);
  579. if (err) {
  580. sys_errmsg("cannot get MTD information");
  581. goto out_close_mtd;
  582. }
  583. err = mtd_get_dev_info(libmtd, args.node, &mtd);
  584. if (err) {
  585. sys_errmsg("cannot get information about \"%s\"", args.node);
  586. goto out_close_mtd;
  587. }
  588. if (!is_power_of_2(mtd.min_io_size)) {
  589. errmsg("min. I/O size is %d, but should be power of 2",
  590. mtd.min_io_size);
  591. goto out_close_mtd;
  592. }
  593. if (!mtd_info.sysfs_supported) {
  594. /*
  595. * Linux kernels older than 2.6.30 did not support sysfs
  596. * interface, and it is impossible to find out sub-page
  597. * size in these kernels. This is why users should
  598. * provide -s option.
  599. */
  600. if (args.subpage_size == 0) {
  601. warnmsg("your MTD system is old and it is impossible "
  602. "to detect sub-page size. Use -s to get rid "
  603. "of this warning");
  604. normsg("assume sub-page to be %d", mtd.subpage_size);
  605. } else {
  606. mtd.subpage_size = args.subpage_size;
  607. args.manual_subpage = 1;
  608. }
  609. } else if (args.subpage_size && args.subpage_size != mtd.subpage_size) {
  610. mtd.subpage_size = args.subpage_size;
  611. args.manual_subpage = 1;
  612. }
  613. if (args.manual_subpage) {
  614. /* Do some sanity check */
  615. if (args.subpage_size > mtd.min_io_size) {
  616. errmsg("sub-page cannot be larger than min. I/O unit");
  617. goto out_close_mtd;
  618. }
  619. if (mtd.min_io_size % args.subpage_size) {
  620. errmsg("min. I/O unit size should be multiple of "
  621. "sub-page size");
  622. goto out_close_mtd;
  623. }
  624. }
  625. args.node_fd = open(args.node, O_RDWR);
  626. if (args.node_fd == -1) {
  627. sys_errmsg("cannot open \"%s\"", args.node);
  628. goto out_close_mtd;
  629. }
  630. /* Validate VID header offset if it was specified */
  631. if (args.vid_hdr_offs != 0) {
  632. if (args.vid_hdr_offs % 8) {
  633. errmsg("VID header offset has to be multiple of min. I/O unit size");
  634. goto out_close;
  635. }
  636. if (args.vid_hdr_offs + (int)UBI_VID_HDR_SIZE > mtd.eb_size) {
  637. errmsg("bad VID header offset");
  638. goto out_close;
  639. }
  640. }
  641. if (!mtd.writable) {
  642. errmsg("mtd%d (%s) is a read-only device", mtd.mtd_num, args.node);
  643. goto out_close;
  644. }
  645. /* Make sure this MTD device is not attached to UBI */
  646. libubi = libubi_open();
  647. if (libubi) {
  648. int ubi_dev_num;
  649. err = mtd_num2ubi_dev(libubi, mtd.mtd_num, &ubi_dev_num);
  650. libubi_close(libubi);
  651. if (!err) {
  652. errmsg("please, first detach mtd%d (%s) from ubi%d",
  653. mtd.mtd_num, args.node, ubi_dev_num);
  654. goto out_close;
  655. }
  656. }
  657. if (!args.quiet) {
  658. normsg_cont("mtd%d (%s), size ", mtd.mtd_num, mtd.type_str);
  659. util_print_bytes(mtd.size, 1);
  660. printf(", %d eraseblocks of ", mtd.eb_cnt);
  661. util_print_bytes(mtd.eb_size, 1);
  662. printf(", min. I/O size %d bytes\n", mtd.min_io_size);
  663. }
  664. if (args.quiet)
  665. verbose = 0;
  666. else if (args.verbose)
  667. verbose = 2;
  668. else
  669. verbose = 1;
  670. err = ubi_scan(&mtd, args.node_fd, &si, verbose);
  671. if (err) {
  672. errmsg("failed to scan mtd%d (%s)", mtd.mtd_num, args.node);
  673. goto out_close;
  674. }
  675. if (si->good_cnt == 0) {
  676. errmsg("all %d eraseblocks are bad", si->bad_cnt);
  677. goto out_free;
  678. }
  679. if (si->good_cnt < 2) {
  680. errmsg("too few non-bad eraseblocks (%d) on mtd%d",
  681. si->good_cnt, mtd.mtd_num);
  682. goto out_free;
  683. }
  684. if (!args.quiet) {
  685. if (si->ok_cnt)
  686. normsg("%d eraseblocks have valid erase counter, mean value is %lld",
  687. si->ok_cnt, si->mean_ec);
  688. if (si->empty_cnt)
  689. normsg("%d eraseblocks are supposedly empty", si->empty_cnt);
  690. if (si->corrupted_cnt)
  691. normsg("%d corrupted erase counters", si->corrupted_cnt);
  692. print_bad_eraseblocks(&mtd, si);
  693. }
  694. if (si->alien_cnt) {
  695. if (!args.yes || !args.quiet)
  696. warnmsg("%d of %d eraseblocks contain non-UBI data",
  697. si->alien_cnt, si->good_cnt);
  698. if (!args.yes && want_exit()) {
  699. if (args.yes && !args.quiet)
  700. printf("yes\n");
  701. goto out_free;
  702. }
  703. }
  704. if (!args.override_ec && si->empty_cnt < si->good_cnt) {
  705. int percent = (si->ok_cnt * 100) / si->good_cnt;
  706. /*
  707. * Make sure the majority of eraseblocks have valid
  708. * erase counters.
  709. */
  710. if (percent < 50) {
  711. if (!args.yes || !args.quiet) {
  712. warnmsg("only %d of %d eraseblocks have valid erase counter",
  713. si->ok_cnt, si->good_cnt);
  714. normsg("erase counter 0 will be used for all eraseblocks");
  715. normsg("note, arbitrary erase counter value may be specified using -e option");
  716. }
  717. if (!args.yes && want_exit()) {
  718. if (args.yes && !args.quiet)
  719. printf("yes\n");
  720. goto out_free;
  721. }
  722. args.ec = 0;
  723. args.override_ec = 1;
  724. } else if (percent < 95) {
  725. if (!args.yes || !args.quiet) {
  726. warnmsg("only %d of %d eraseblocks have valid erase counter",
  727. si->ok_cnt, si->good_cnt);
  728. normsg("mean erase counter %lld will be used for the rest of eraseblock",
  729. si->mean_ec);
  730. }
  731. if (!args.yes && want_exit()) {
  732. if (args.yes && !args.quiet)
  733. printf("yes\n");
  734. goto out_free;
  735. }
  736. args.ec = si->mean_ec;
  737. args.override_ec = 1;
  738. }
  739. }
  740. if (!args.quiet && args.override_ec)
  741. normsg("use erase counter %lld for all eraseblocks", args.ec);
  742. ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, mtd.subpage_size,
  743. args.vid_hdr_offs, args.ubi_ver, args.image_seq);
  744. if (si->vid_hdr_offs != -1 && ui.vid_hdr_offs != si->vid_hdr_offs) {
  745. /*
  746. * Hmm, what we read from flash and what we calculated using
  747. * min. I/O unit size and sub-page size differs.
  748. */
  749. if (!args.yes || !args.quiet) {
  750. warnmsg("VID header and data offsets on flash are %d and %d, "
  751. "which is different to requested offsets %d and %d",
  752. si->vid_hdr_offs, si->data_offs, ui.vid_hdr_offs,
  753. ui.data_offs);
  754. normsg_cont("use new offsets %d and %d? ",
  755. ui.vid_hdr_offs, ui.data_offs);
  756. }
  757. if (args.yes || answer_is_yes(NULL)) {
  758. if (args.yes && !args.quiet)
  759. printf("yes\n");
  760. } else
  761. ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, 0,
  762. si->vid_hdr_offs, args.ubi_ver,
  763. args.image_seq);
  764. normsg("use offsets %d and %d", ui.vid_hdr_offs, ui.data_offs);
  765. }
  766. if (args.image) {
  767. err = flash_image(libmtd, &mtd, &ui, si);
  768. if (err < 0)
  769. goto out_free;
  770. /*
  771. * ubinize has create a UBI_LAYOUT_VOLUME_ID volume for image.
  772. * So, we don't need to create again.
  773. */
  774. err = format(libmtd, &mtd, &ui, si, err, 1);
  775. if (err)
  776. goto out_free;
  777. } else {
  778. err = format(libmtd, &mtd, &ui, si, 0, 0);
  779. if (err)
  780. goto out_free;
  781. }
  782. ubi_scan_free(si);
  783. close(args.node_fd);
  784. libmtd_close(libmtd);
  785. return 0;
  786. out_free:
  787. ubi_scan_free(si);
  788. out_close:
  789. close(args.node_fd);
  790. out_close_mtd:
  791. libmtd_close(libmtd);
  792. return -1;
  793. }