rfdformat.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * rfdformat.c
  3. *
  4. * Copyright (C) 2005 Sean Young <sean@mess.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This is very easy: just erase all the blocks and put the magic at
  12. * the beginning of each block.
  13. */
  14. #define PROGRAM_NAME "rfdformat"
  15. #define _XOPEN_SOURCE 500 /* For pread/pwrite */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <sys/ioctl.h>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. #include <getopt.h>
  24. #include <mtd/mtd-user.h>
  25. #include <linux/types.h>
  26. #include "common.h"
  27. static void display_help(int status)
  28. {
  29. printf("Usage: %s [OPTIONS] MTD-device\n"
  30. "Formats NOR flash for resident flash disk\n"
  31. "\n"
  32. "-h --help display this help and exit\n"
  33. "-V --version output version information and exit\n",
  34. PROGRAM_NAME);
  35. exit(status);
  36. }
  37. static void display_version(void)
  38. {
  39. common_print_version();
  40. printf("This is free software; see the source for copying conditions. There is NO\n"
  41. "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
  42. exit(0);
  43. }
  44. static void process_options(int argc, char *argv[], const char **mtd_filename)
  45. {
  46. int error = 0;
  47. for (;;) {
  48. int option_index = 0;
  49. static const char *short_options = "hV";
  50. static const struct option long_options[] = {
  51. { "help", no_argument, 0, 'h' },
  52. { "version", no_argument, 0, 'V', },
  53. { NULL, 0, 0, 0 }
  54. };
  55. int c = getopt_long(argc, argv, short_options,
  56. long_options, &option_index);
  57. if (c == EOF)
  58. break;
  59. switch (c) {
  60. case 'h':
  61. display_help(EXIT_SUCCESS);
  62. break;
  63. case 'V':
  64. display_version();
  65. break;
  66. case '?':
  67. error = 1;
  68. break;
  69. }
  70. }
  71. if ((argc - optind) != 1 || error)
  72. display_help(EXIT_FAILURE);
  73. *mtd_filename = argv[optind];
  74. }
  75. int main(int argc, char *argv[])
  76. {
  77. static const uint8_t magic[] = { 0x93, 0x91 };
  78. int fd, block_count, i;
  79. struct mtd_info_user mtd_info;
  80. char buf[512];
  81. const char *mtd_filename;
  82. process_options(argc, argv, &mtd_filename);
  83. fd = open(mtd_filename, O_RDWR);
  84. if (fd == -1) {
  85. perror(mtd_filename);
  86. return 1;
  87. }
  88. if (ioctl(fd, MEMGETINFO, &mtd_info)) {
  89. perror(mtd_filename);
  90. close(fd);
  91. return 1;
  92. }
  93. if (mtd_info.type != MTD_NORFLASH) {
  94. fprintf(stderr, "%s: not NOR flash\n", mtd_filename);
  95. close(fd);
  96. return 2;
  97. }
  98. if (mtd_info.size > 32*1024*1024) {
  99. fprintf(stderr, "%s: flash larger than 32MiB not supported\n",
  100. mtd_filename);
  101. close(fd);
  102. return 2;
  103. }
  104. block_count = mtd_info.size / mtd_info.erasesize;
  105. if (block_count < 2) {
  106. fprintf(stderr, "%s: at least two erase units required\n",
  107. mtd_filename);
  108. close(fd);
  109. return 2;
  110. }
  111. for (i=0; i<block_count; i++) {
  112. struct erase_info_user erase_info;
  113. erase_info.start = i * mtd_info.erasesize;
  114. erase_info.length = mtd_info.erasesize;
  115. if (ioctl(fd, MEMERASE, &erase_info) != 0) {
  116. snprintf(buf, sizeof(buf), "%s: erase", mtd_filename);
  117. perror(buf);
  118. close(fd);
  119. return 2;
  120. }
  121. if (pwrite(fd, magic, sizeof(magic), i * mtd_info.erasesize)
  122. != sizeof(magic)) {
  123. snprintf(buf, sizeof(buf), "%s: write", mtd_filename);
  124. perror(buf);
  125. close(fd);
  126. return 2;
  127. }
  128. }
  129. close(fd);
  130. return 0;
  131. }