doc_loadbios.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #define PROGRAM_NAME "doc_loadbios"
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <fcntl.h>
  6. #include <time.h>
  7. #include <string.h>
  8. #include <sys/stat.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/mount.h>
  11. #include <mtd/mtd-user.h>
  12. unsigned char databuf[512];
  13. int main(int argc,char **argv)
  14. {
  15. mtd_info_t meminfo;
  16. int ifd,ofd;
  17. struct stat statbuf;
  18. erase_info_t erase;
  19. unsigned long retlen, ofs, iplsize, ipltailsize;
  20. unsigned char *iplbuf;
  21. iplbuf = NULL;
  22. if (argc < 3) {
  23. fprintf(stderr,"You must specify a device,"
  24. " the source firmware file and the offset\n");
  25. return 1;
  26. }
  27. // Open and size the device
  28. if ((ofd = open(argv[1],O_RDWR)) < 0) {
  29. perror("Open flash device");
  30. return 1;
  31. }
  32. if ((ifd = open(argv[2], O_RDONLY)) < 0) {
  33. perror("Open firmware file\n");
  34. close(ofd);
  35. return 1;
  36. }
  37. if (fstat(ifd, &statbuf) != 0) {
  38. perror("Stat firmware file");
  39. goto error;
  40. }
  41. #if 0
  42. if (statbuf.st_size > 65536) {
  43. printf("Firmware too large (%ld bytes)\n",statbuf.st_size);
  44. goto error;
  45. }
  46. #endif
  47. if (ioctl(ofd,MEMGETINFO,&meminfo) != 0) {
  48. perror("ioctl(MEMGETINFO)");
  49. goto error;
  50. }
  51. iplsize = (ipltailsize = 0);
  52. if (argc >= 4) {
  53. /* DoC Millennium has IPL in the first 1K of flash memory */
  54. /* You may want to specify the offset 1024 to store
  55. the firmware next to IPL. */
  56. iplsize = strtoul(argv[3], NULL, 0);
  57. ipltailsize = iplsize % meminfo.erasesize;
  58. }
  59. if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) {
  60. perror("lseek");
  61. goto error;
  62. }
  63. if (ipltailsize) {
  64. iplbuf = malloc(ipltailsize);
  65. if (iplbuf == NULL) {
  66. fprintf(stderr, "Not enough memory for IPL tail buffer of"
  67. " %lu bytes\n", (unsigned long) ipltailsize);
  68. goto error;
  69. }
  70. printf("Reading IPL%s area of length %lu at offset %lu\n",
  71. (iplsize - ipltailsize) ? " tail" : "",
  72. (long unsigned) ipltailsize,
  73. (long unsigned) (iplsize - ipltailsize));
  74. if (read(ofd, iplbuf, ipltailsize) != ipltailsize) {
  75. perror("read");
  76. goto error;
  77. }
  78. }
  79. erase.length = meminfo.erasesize;
  80. for (ofs = iplsize - ipltailsize ;
  81. ofs < iplsize + statbuf.st_size ;
  82. ofs += meminfo.erasesize) {
  83. erase.start = ofs;
  84. printf("Performing Flash Erase of length %lu at offset %lu\n",
  85. (long unsigned) erase.length, (long unsigned) erase.start);
  86. if (ioctl(ofd,MEMERASE,&erase) != 0) {
  87. perror("ioctl(MEMERASE)");
  88. goto error;
  89. }
  90. }
  91. if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) {
  92. perror("lseek");
  93. goto error;
  94. }
  95. if (ipltailsize) {
  96. printf("Writing IPL%s area of length %lu at offset %lu\n",
  97. (iplsize - ipltailsize) ? " tail" : "",
  98. (long unsigned) ipltailsize,
  99. (long unsigned) (iplsize - ipltailsize));
  100. if (write(ofd, iplbuf, ipltailsize) != ipltailsize) {
  101. perror("write");
  102. goto error;
  103. }
  104. }
  105. printf("Writing the firmware of length %lu at %lu... ",
  106. (unsigned long) statbuf.st_size,
  107. (unsigned long) iplsize);
  108. do {
  109. retlen = read(ifd, databuf, 512);
  110. if (retlen < 512)
  111. memset(databuf+retlen, 0xff, 512-retlen);
  112. if (write(ofd, databuf, 512) != 512) {
  113. perror("write");
  114. goto error;
  115. }
  116. } while (retlen == 512);
  117. printf("Done.\n");
  118. if (iplbuf != NULL)
  119. free(iplbuf);
  120. close(ifd);
  121. close(ofd);
  122. return 0;
  123. error:
  124. if (iplbuf != NULL)
  125. free(iplbuf);
  126. close(ifd);
  127. close(ofd);
  128. return 1;
  129. }