luat_fota_air101.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "string.h"
  2. #include "wm_include.h"
  3. #include "wm_crypto_hard.h"
  4. #include "aes.h"
  5. #include "wm_osal.h"
  6. #include "wm_regs.h"
  7. #include "wm_debug.h"
  8. #include "wm_crypto_hard.h"
  9. #include "wm_internal_flash.h"
  10. #include "wm_pmu.h"
  11. #include "wm_fwup.h"
  12. #include "luat_base.h"
  13. #include "luat_crypto.h"
  14. #include "luat_malloc.h"
  15. #define LUAT_LOG_TAG "fota"
  16. #include "luat_log.h"
  17. #include "FreeRTOS.h"
  18. #include "task.h"
  19. #include "luat_fota.h"
  20. static const uint32_t MAGIC_NO = 0xA0FFFF9F;
  21. enum {
  22. FOTA_IDLE,
  23. FOTA_ONGO,
  24. FOTA_DONE
  25. };
  26. static int fota_state;
  27. static uint32_t fota_write_offset;
  28. static uint32_t ota_zone_size;
  29. static uint32_t upgrade_img_addr;
  30. static int check_image_head(IMAGE_HEADER_PARAM_ST* imghead, const char* tag);
  31. int luat_fota_init(uint32_t start_address, uint32_t len, luat_spi_device_t* spi_device, const char *path, uint32_t pathlen) {
  32. fota_state = FOTA_ONGO;
  33. fota_write_offset = 0;
  34. // 读取update区域位置及大小, 按4k对齐的方式, 清除对应的区域
  35. for (size_t i = 0; i < ota_zone_size / 4096; i++)
  36. {
  37. LLOGD("清除ota区域: %08X", upgrade_img_addr + i * 4096);
  38. tls_fls_erase((upgrade_img_addr + i * 4096) / INSIDE_FLS_SECTOR_SIZE);
  39. }
  40. LLOGI("OTA区域初始化完成");
  41. return 0;
  42. }
  43. int luat_fota_write(uint8_t *data, uint32_t len) {
  44. if (len + fota_write_offset > ota_zone_size) {
  45. LLOGE("OTA区域写满, 无法继续写入");
  46. return -1;
  47. }
  48. int ret = tls_fls_write_without_erase(upgrade_img_addr + fota_write_offset, data, len);
  49. fota_write_offset += len;
  50. return ret;
  51. }
  52. int luat_fota_done(void) {
  53. if (fota_write_offset == 0) {
  54. LLOGE("未写入任何数据, 无法完成OTA");
  55. return -1;
  56. }
  57. if (fota_write_offset < sizeof(IMAGE_HEADER_PARAM_ST)) {
  58. LLOGI("写入数据小于最小长度, 还不能判断");
  59. return 0;
  60. }
  61. // 写入长度已经超过最小长度, 判断是否是合法的镜像
  62. IMAGE_HEADER_PARAM_ST* imghead = (IMAGE_HEADER_PARAM_ST*)upgrade_img_addr;
  63. if (imghead->magic_no != MAGIC_NO) {
  64. LLOGE("image magic: %08x", imghead->magic_no);
  65. return -2;
  66. }
  67. if (imghead->img_len + sizeof(IMAGE_HEADER_PARAM_ST) < fota_write_offset) {
  68. LLOGI("fota数据还不够, 继续等数据");
  69. return 0;
  70. }
  71. // 写入长度足够, 判断是否是合法的镜像, 开始计算check sum
  72. if (check_image_head(imghead, "fota") == 0) {
  73. LLOGI("image check sum: %08x", imghead->hd_checksum);
  74. fota_state = FOTA_DONE;
  75. return 0;
  76. }
  77. return 0;
  78. }
  79. int luat_fota_end(uint8_t is_ok) {
  80. if (fota_state == FOTA_DONE) {
  81. return 0;
  82. }
  83. LLOGD("状态不正确, 要么数据没写完,要么校验没通过");
  84. return -1;
  85. }
  86. uint8_t luat_fota_wait_ready(void) {
  87. return 0;
  88. }
  89. static uint32_t img_checksum(const char* ptr, size_t len) {
  90. psCrcContext_t crcContext;
  91. unsigned int crcvalue = 0;
  92. unsigned int crccallen = 0;
  93. unsigned int i = 0;
  94. crccallen = len;
  95. tls_crypto_crc_init(&crcContext, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, 3);
  96. for (i = 0; i < crccallen/4; i++)
  97. {
  98. MEMCPY((unsigned char *)&crcvalue, (unsigned char *)ptr +i*4, 4);
  99. tls_crypto_crc_update(&crcContext, (unsigned char *)&crcvalue, 4);
  100. }
  101. crcvalue = 0;
  102. tls_crypto_crc_final(&crcContext, &crcvalue);
  103. return crcvalue;
  104. }
  105. static int check_image_head(IMAGE_HEADER_PARAM_ST* imghead, const char* tag) {
  106. if (imghead == NULL) {
  107. return -1;
  108. }
  109. if (imghead->magic_no != MAGIC_NO) {
  110. LLOGE("%s image magic: %08x", tag, imghead->magic_no);
  111. return -2;
  112. }
  113. LLOGD("%s image img_addr: %08X", tag, imghead->img_addr);
  114. LLOGD("%s image img_len: %08X", tag, imghead->img_len);
  115. LLOGD("%s image img_header_addr: %08X", tag, imghead->img_header_addr);
  116. LLOGD("%s image upgrade_img_addr: %08X", tag, imghead->upgrade_img_addr);
  117. LLOGD("%s image org_checksum: %08X", tag, imghead->org_checksum);
  118. LLOGD("%s image upd_no: %08X", tag, imghead->upd_no);
  119. LLOGD("%s image ver: %.16s", tag, imghead->ver);
  120. LLOGD("%s image hd_checksum: %08X", tag, imghead->hd_checksum);
  121. LLOGD("%s image next: %08X", tag, imghead->next);
  122. // image attr
  123. LLOGD("%s image attr img_type: %d", tag, imghead->img_attr.b.img_type);
  124. LLOGD("%s image attr zip_type: %d", tag, imghead->img_attr.b.zip_type);
  125. LLOGD("%s image attr psram_io: %d", tag, imghead->img_attr.b.psram_io);
  126. LLOGD("%s image attr erase_block_en: %d", tag, imghead->img_attr.b.erase_block_en);
  127. LLOGD("%s image attr erase_always: %d", tag, imghead->img_attr.b.erase_always);
  128. // 先判断一下magicno
  129. if (imghead->magic_no != MAGIC_NO) {
  130. return -2;
  131. }
  132. // 计算一下header的checksum
  133. uint32_t cm = img_checksum((const char*)imghead, sizeof(IMAGE_HEADER_PARAM_ST) - 4);
  134. LLOGD("%s head checksum: %08X %08X", tag, cm, imghead->hd_checksum);
  135. if (cm != imghead->hd_checksum) {
  136. return -3;
  137. }
  138. cm = img_checksum((const char*)imghead->img_addr, imghead->img_len);
  139. LLOGD("%s data checksum: %08X %08X", tag, cm, imghead->org_checksum);
  140. if (cm != imghead->org_checksum) {
  141. return -4;
  142. }
  143. return 0;
  144. }
  145. void luat_fota_boot_check(void) {
  146. LLOGD("启动fota开机检查");
  147. LLOGD("sizeof(IMAGE_HEADER_PARAM_ST) %d %d %d", sizeof(IMAGE_HEADER_PARAM_ST), sizeof(Img_Attr_Type), sizeof(unsigned int));
  148. // 读取secboot区域的信息, 大小1kb
  149. IMAGE_HEADER_PARAM_ST* secimg = (IMAGE_HEADER_PARAM_ST*)0x8002000;
  150. // check_image_head(secimg, "secboot");
  151. IMAGE_HEADER_PARAM_ST* upimg = (IMAGE_HEADER_PARAM_ST*)secimg->upgrade_img_addr;
  152. IMAGE_HEADER_PARAM_ST* runimg = (secimg->next);
  153. // check_image_head(upimg, "update");
  154. // check_image_head(runimg, "user");
  155. // 计算出OTA区域大小, 运行区镜像的大小
  156. uint32_t ota_size = ((uint32_t)runimg) - ((uint32_t)upimg);
  157. LLOGD("ota zone size: 0x%08X %dkb", ota_size, ota_size/1024);
  158. // 当前运行区镜像的大小
  159. LLOGD("run image size: 0x%08X %dkb", runimg->img_len, runimg->img_len/1024);
  160. // 把相关参数存起来
  161. upgrade_img_addr = secimg->upgrade_img_addr;
  162. ota_zone_size = ((uint32_t)runimg) - ((uint32_t)upimg);
  163. ota_zone_size = (ota_zone_size + 0x3FF) & (~0x3FF);
  164. }