/StarDroid/BootLoader/Google-BootLoader-Source/nandwrite/nandwrite.c

https://github.com/Simo2553/AndroidPortings · C · 195 lines · 137 code · 29 blank · 29 comment · 31 complexity · f8b7f64c6d0f84a3d0e4c4c199e68356 MD5 · raw file

  1. /*
  2. * Copyright (C) 2008 The Android Open Source Project
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  18. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  19. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  21. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  22. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  23. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  24. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  25. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #include <boot/boot.h>
  29. #include <boot/board.h>
  30. #include <boot/flash.h>
  31. #define FLASH_PAGE_SIZE 2048
  32. #define FLASH_PAGE_BITS 11
  33. int startswith(const char *str, const char *prefix)
  34. {
  35. while(*prefix){
  36. if(*prefix++ != *str++) return 0;
  37. }
  38. return 1;
  39. }
  40. void verify_flash(ptentry *p, void *addr, unsigned len, int extra)
  41. {
  42. int offset = 0;
  43. void *buf = alloc(FLASH_PAGE_SIZE + extra);
  44. int verify_extra = extra;
  45. if(verify_extra > 4)
  46. verify_extra = 16;
  47. while(len > 0) {
  48. flash_read_ext(p, extra, offset, buf, FLASH_PAGE_SIZE);
  49. if(memcmp(addr, buf, FLASH_PAGE_SIZE + verify_extra)) {
  50. dprintf("verify failed at %x\n", offset);
  51. jtag_fail("verify failed");
  52. return;
  53. }
  54. offset += FLASH_PAGE_SIZE;
  55. addr += FLASH_PAGE_SIZE;
  56. len -= FLASH_PAGE_SIZE;
  57. if(extra) {
  58. addr += extra;
  59. len -= extra;
  60. }
  61. }
  62. dprintf("verify done %d extra bytes\n", verify_extra);
  63. jtag_okay("verify done");
  64. }
  65. void handle_flash(const char *name, unsigned addr, unsigned len)
  66. {
  67. int r;
  68. ptentry *p;
  69. dprintf("image @ %x (%d bytes)\n", addr, len);
  70. dprintf("write to '%s' partition\n", name);
  71. p = flash_find_ptn(name);
  72. if(p == 0) {
  73. jtag_fail("partition not found");
  74. return;
  75. } else {
  76. if(flash_init()) {
  77. jtag_fail("flash_init() failed");
  78. return;
  79. }
  80. dprintf("erasing flash @ %d (len=%d)\n", p->start, p->length);
  81. flash_erase(p);
  82. if(len) {
  83. dprintf("writing flash at @ %d\n", p->start);
  84. if(!strcmp(name, "system") || !strcmp(name, "userdata")) {
  85. r = flash_write(p, 64, (void*) addr, len);
  86. } else {
  87. len = (len + FLASH_PAGE_SIZE - 1) & (~(FLASH_PAGE_SIZE-1));
  88. r = flash_write(p, 0, (void*) addr, len);
  89. }
  90. //verify_flash(p, addr, len, (!strcmp(name, "system") || !strcmp(name, "userdata")) ? 64 : 0);
  91. if(r) {
  92. jtag_fail("partition write failed");
  93. } else {
  94. jtag_okay("partition written");
  95. }
  96. return;
  97. } else {
  98. jtag_okay("partition erased");
  99. return;
  100. }
  101. }
  102. }
  103. void hexdump(void *ptr, unsigned len)
  104. {
  105. unsigned char *b = ptr;
  106. int count = 0;
  107. dprintf("%x: ", (unsigned) b);
  108. while(len-- > 0) {
  109. dprintf("%b ", *b++);
  110. if(++count == 16) {
  111. dprintf("\n%x: ", (unsigned) b);
  112. count = 0;
  113. }
  114. }
  115. if(count != 0) dprintf("\n");
  116. }
  117. static unsigned char *tmpbuf = 0;
  118. void handle_dump(const char *name, unsigned offset)
  119. {
  120. ptentry *p;
  121. if(tmpbuf == 0) {
  122. tmpbuf = alloc(4096);
  123. }
  124. dprintf("dump '%s' partition\n", name);
  125. p = flash_find_ptn(name);
  126. if(p == 0) {
  127. jtag_fail("partition not found");
  128. return;
  129. }
  130. if(flash_init()) {
  131. jtag_fail("flash_init() failed");
  132. return;
  133. }
  134. #if 0
  135. /* XXX reimpl */
  136. if(flash_read_page(p->start * 64, tmpbuf, tmpbuf + 2048)){
  137. jtag_fail("flash_read() failed");
  138. return;
  139. }
  140. #endif
  141. dprintf("page %d data:\n", p->start * 64);
  142. hexdump(tmpbuf, 256);
  143. dprintf("page %d extra:\n", p->start * 64);
  144. hexdump(tmpbuf, 16);
  145. jtag_okay("done");
  146. }
  147. void handle_command(const char *cmd, unsigned a0, unsigned a1, unsigned a2)
  148. {
  149. if(startswith(cmd,"flash:")){
  150. handle_flash(cmd + 6, a0, a1);
  151. return;
  152. }
  153. if(startswith(cmd,"dump:")){
  154. handle_dump(cmd + 5, a0);
  155. return;
  156. }
  157. jtag_fail("unknown command");
  158. }
  159. int _main(void)
  160. {
  161. arm11_clock_init();
  162. dprintf_set_putc(jtag_dputc);
  163. board_init();
  164. jtag_cmd_loop(handle_command);
  165. return 0;
  166. }