sdfs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. #include <zephyr/types.h>
  2. #include <strings.h>
  3. #include <stddef.h>
  4. #include <sys/types.h>
  5. #include <device.h>
  6. #include <sdfs.h>
  7. #include <fs/fs.h>
  8. #include <fs/fs_sys.h>
  9. #include <storage/flash_map.h>
  10. #include <partition/partition.h>
  11. #include <linker/linker-defs.h>
  12. #include "sdfs_nand_sd.h"
  13. #include "sdfs_data_nor.h"
  14. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  15. #include <drivers/flash.h>
  16. #include <board_cfg.h>
  17. #endif
  18. #define K_SDFS_ADDR (((unsigned int)__rom_region_start)+((unsigned int)_flash_used))
  19. static struct sd_file g_sd_file_heap[CONFIG_SD_FILE_MAX];
  20. static bool b_k_sdfs;
  21. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  22. static uint32_t g_k_sdfs_system_addr;
  23. static const struct device *global_nor_dev;
  24. #endif
  25. #define SDFS_INVALID_PART_ID (0xFF)
  26. #define SDFS_INVALID_PART(x) ((x) == SDFS_INVALID_PART_ID)
  27. #define memcpy_flash_data memcpy
  28. #if 0
  29. #define sd_alloc k_malloc
  30. #define sd_free k_free
  31. #else
  32. struct sd_file * sd_alloc(int size)
  33. {
  34. int i;
  35. unsigned int key;
  36. key = irq_lock();
  37. for(i = 0; i < CONFIG_SD_FILE_MAX; i++){
  38. if(g_sd_file_heap[i].used == 0){
  39. g_sd_file_heap[i].used = 1; //use
  40. break;
  41. }
  42. }
  43. irq_unlock(key);
  44. if(i == CONFIG_SD_FILE_MAX)
  45. return NULL;
  46. else
  47. return &g_sd_file_heap[i];
  48. }
  49. void sd_free(struct sd_file * sd_file)
  50. {
  51. unsigned int key;
  52. key = irq_lock();
  53. memset(sd_file, 0, sizeof(*sd_file));
  54. irq_unlock(key);
  55. }
  56. #endif
  57. //#define CONFIG_SD_FS_VADDR_START g_vaddr_start
  58. //static unsigned int g_vaddr_start = 0x0;
  59. static struct sd_dir * sd_find_dir_by_addr(const char *filename, void *buf_size_32, uint32_t adfs_addr)
  60. {
  61. int num, total, offset;
  62. struct sd_dir *sd_dir = buf_size_32;
  63. memcpy_flash_data(buf_size_32, (void *)adfs_addr, sizeof(*sd_dir));
  64. //printk("sd_dir->fname %s CONFIG_SD_FS_START 0x%x \n",sd_dir->fname,CONFIG_SD_FS_VADDR_START);
  65. if(memcmp(sd_dir->fname, "sdfs.bin", 8) != 0)
  66. {
  67. printk("sdfs.bin invalid, offset=0x%x\n", adfs_addr);
  68. return NULL;
  69. }
  70. total = sd_dir->offset;
  71. for(offset = adfs_addr + sizeof(*sd_dir), num = 0; num < total; offset += 32)
  72. {
  73. memcpy_flash_data(buf_size_32, (void *)offset, 32);
  74. //printk("%d,file=%s, size=0x%x\n", num, sd_dir->fname, sd_dir->size);
  75. if(strncasecmp(filename, sd_dir->fname, 12) == 0)
  76. {
  77. return sd_dir;
  78. }
  79. num++;
  80. }
  81. return NULL;
  82. }
  83. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  84. static struct sd_dir *sd_find_dir_by_part(const char *filename, void *buf_size_32, uint8_t part)
  85. {
  86. int num, total, offset, total_file_size;
  87. struct sd_dir *sd_dir = buf_size_32, *ret_sd_dir = NULL;
  88. const struct partition_entry *part_entry;
  89. int ret;
  90. uint8_t *sd_dir_buf_ptr = NULL;
  91. part_entry = partition_get_stf_part(STORAGE_ID_NOR, part + PARTITION_FILE_ID_SDFS_PART_BASE);
  92. if (!part_entry)
  93. return NULL;
  94. ret = flash_read(global_nor_dev, part_entry->offset, buf_size_32, sizeof(struct sd_dir));
  95. if (ret < 0) {
  96. printk("nor read offset:0x%x size:%d error:%d\n",
  97. part_entry->offset, sizeof(struct sd_dir), ret);
  98. return NULL;
  99. }
  100. if (memcmp(sd_dir->fname, "sdfs.bin", 8) != 0) {
  101. printk("sdfs.bin invalid, offset=0x%x\n", part_entry->offset);
  102. return NULL;
  103. }
  104. total = sd_dir->offset;
  105. total_file_size = (total + 1) * sizeof(struct sd_dir);
  106. sd_dir_buf_ptr = k_malloc(total_file_size);
  107. if (!sd_dir_buf_ptr) {
  108. printk("failed to malloc size:%d\n", total_file_size);
  109. return NULL;
  110. }
  111. ret = flash_read(global_nor_dev, part_entry->offset, sd_dir_buf_ptr, total_file_size);
  112. if (ret < 0) {
  113. printk("nor read offset:0x%x size:%d error:%d\n",
  114. part_entry->offset + sizeof(*sd_dir), total_file_size, ret);
  115. goto out;
  116. }
  117. for (offset = (uint32_t)sd_dir_buf_ptr + sizeof(*sd_dir), num = 0; num < total; offset += 32) {
  118. memcpy_flash_data(buf_size_32, (void *)offset, 32);
  119. //printk("%d,file=%s, size=0x%x\n", num, sd_dir->fname, sd_dir->size);
  120. if (strncasecmp(filename, sd_dir->fname, 12) == 0) {
  121. /* add partition offset */
  122. sd_dir->offset += part_entry->offset;
  123. ret_sd_dir = sd_dir;
  124. break;
  125. }
  126. num++;
  127. }
  128. out:
  129. k_free(sd_dir_buf_ptr);
  130. return ret_sd_dir;
  131. }
  132. #endif
  133. static struct sd_dir * sd_find_dir(const char *filename, void *buf_size_32, uint8_t part)
  134. {
  135. struct sd_dir *sd_d = NULL;
  136. /* find file from ksdfs which padding by kernel firstly */
  137. if (b_k_sdfs && SDFS_INVALID_PART(part)){
  138. sd_d = sd_find_dir_by_addr(filename, buf_size_32, K_SDFS_ADDR);
  139. if(sd_d) {
  140. sd_d->offset += K_SDFS_ADDR;
  141. return sd_d;
  142. }
  143. }
  144. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  145. if (g_k_sdfs_system_addr && SDFS_INVALID_PART(part)) {
  146. sd_d = sd_find_dir_by_addr(filename, buf_size_32, g_k_sdfs_system_addr);
  147. if (sd_d) {
  148. sd_d->offset += g_k_sdfs_system_addr;
  149. return sd_d;
  150. }
  151. }
  152. if (!SDFS_INVALID_PART(part)) {
  153. sd_d = sd_find_dir_by_part(filename, buf_size_32, part);
  154. return sd_d;
  155. }
  156. #else
  157. sd_d = sd_find_dir_by_addr(filename, buf_size_32, CONFIG_SD_FS_VADDR_START);
  158. if(sd_d) {
  159. sd_d->offset += CONFIG_SD_FS_VADDR_START;
  160. return sd_d;
  161. }
  162. #endif
  163. return sd_d;
  164. }
  165. const char* const sd_volume_strs[] = {
  166. _SDFS_VOL_STRS
  167. };
  168. static const char *sd_get_part_type(const char *filename, uint8_t *stor_id, uint8_t *part)
  169. {
  170. const char *pc, *ret_ptr = NULL;
  171. int i;
  172. *stor_id = STORAGE_ID_NOR;
  173. *part = SDFS_INVALID_PART_ID;
  174. if(filename[0] != '/')
  175. return filename;
  176. filename += 1;
  177. pc = strchr(filename, ':');
  178. if(pc == NULL) // /*|| pc[2] != '/'*/
  179. return NULL;
  180. for(i = 0; i < STORAGE_ID_MAX; i++){
  181. if(!strncmp(filename, sd_volume_strs[i], strlen(sd_volume_strs[i])))
  182. break;
  183. }
  184. if(i == STORAGE_ID_MAX)
  185. return NULL;
  186. *stor_id = i;
  187. #ifdef CONFIG_BOARD_NANDBOOT
  188. if (i == STORAGE_ID_NAND)
  189. *stor_id = STORAGE_ID_BOOTNAND;
  190. #endif
  191. /* /[NOR|NAND|SD]:[A:Z]/s */
  192. if ((pc[1] >= 'A') && (pc[1] <= 'Z') /*&& (pc[2] == '/')*/) {
  193. *part = pc[1] - 'A';
  194. ret_ptr = pc + 3;
  195. } else {
  196. *part = SDFS_INVALID_PART_ID;
  197. ret_ptr = pc + 1;
  198. }
  199. return ret_ptr;
  200. }
  201. struct sd_file * sd_fopen (const char *filename)
  202. {
  203. struct sd_dir *sd_dir;
  204. uint8_t buf_size_32[32];
  205. struct sd_file *sd_file;
  206. uint8_t stor_id, part;
  207. const char *fname;
  208. fname = sd_get_part_type(filename, &stor_id, &part);
  209. if(fname == NULL){
  210. printk("sdfs file %s invalid\n", filename);
  211. return NULL;
  212. }
  213. printk("sdfs:stor_id=%d, p=%d\n",stor_id, part);
  214. if(stor_id == STORAGE_ID_NOR)
  215. sd_dir = sd_find_dir(fname, (void *)buf_size_32, part);
  216. else if(stor_id == STORAGE_ID_DATA_NOR)
  217. sd_dir = data_nor_sd_find_dir(stor_id, part, fname, (void *)buf_size_32);
  218. else
  219. sd_dir = nand_sd_find_dir(stor_id, part, fname, (void *)buf_size_32);
  220. if(sd_dir == NULL)
  221. {
  222. printk("%s no this file %s\n", __FUNCTION__, filename);
  223. return NULL;
  224. }
  225. sd_file = sd_alloc(sizeof(*sd_file));
  226. if(sd_file == NULL)
  227. {
  228. printk("%s malloc(%d) failed\n", __FUNCTION__, (int)sizeof(*sd_file));
  229. return NULL;
  230. }
  231. sd_file->start = sd_dir->offset;
  232. sd_file->size = sd_dir->size;
  233. sd_file->readptr = sd_file->start;
  234. sd_file->file_id = part;
  235. sd_file->storage_id = stor_id;
  236. return sd_file;
  237. }
  238. void sd_fclose(struct sd_file *sd_file)
  239. {
  240. sd_free(sd_file);
  241. }
  242. int sd_fread(struct sd_file *sd_file, void *buffer, int len)
  243. {
  244. if ((sd_file->readptr - sd_file->start + len) > sd_file->size) {
  245. len = sd_file->size - (sd_file->readptr - sd_file->start);
  246. }
  247. if(len <= 0) {
  248. return 0;
  249. }
  250. if(sd_file->storage_id != STORAGE_ID_NOR) {
  251. if(sd_file->storage_id == STORAGE_ID_DATA_NOR)
  252. return data_nor_sd_fread(sd_file->storage_id, sd_file, buffer, len);
  253. else
  254. return nand_sd_sd_fread(sd_file->storage_id, sd_file, buffer, len);
  255. }
  256. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  257. if (SDFS_INVALID_PART(sd_file->file_id)) {
  258. memcpy_flash_data(buffer, (void *)sd_file->readptr, len);
  259. } else {
  260. if (flash_read(global_nor_dev, (uint32_t)sd_file->readptr, buffer, len) < 0) {
  261. printk("failed to read offset:0x%x size:%d\n", (uint32_t)sd_file->readptr, len);
  262. return 0;
  263. }
  264. }
  265. #else
  266. memcpy_flash_data(buffer, (void *)sd_file->readptr, len);
  267. #endif
  268. sd_file->readptr += len;
  269. return len;
  270. }
  271. int sd_ftell(struct sd_file *sd_file)
  272. {
  273. return (sd_file->readptr - sd_file->start);
  274. }
  275. int sd_fseek(struct sd_file *sd_file, int offset, unsigned char whence)
  276. {
  277. if (whence == FS_SEEK_SET)
  278. {
  279. if (offset > sd_file->size)
  280. return -1;
  281. sd_file->readptr = sd_file->start + offset;
  282. return 0;
  283. }
  284. if (whence == FS_SEEK_CUR)
  285. {
  286. if(sd_file->readptr + offset < sd_file->start
  287. || sd_file->readptr + offset > sd_file->start + sd_file->size)
  288. {
  289. return -1;
  290. }
  291. sd_file->readptr += offset;
  292. return 0;
  293. }
  294. if (whence == FS_SEEK_END)
  295. {
  296. if(offset > 0 || offset + sd_file->size < 0)
  297. return -1;
  298. sd_file->readptr = sd_file->start + sd_file->size + offset;
  299. return 0;
  300. }
  301. return -EINVAL;
  302. }
  303. int sd_fsize(const char *filename)
  304. {
  305. struct sd_file *fd = sd_fopen(filename);
  306. int file_size;
  307. if (!fd) {
  308. return -EINVAL;
  309. }
  310. file_size = fd->size;
  311. sd_fclose(fd);
  312. return file_size;
  313. }
  314. int sd_fmap(const char *filename, void** addr, int* len)
  315. {
  316. int map_addr, map_len;
  317. struct sd_file *fd = sd_fopen(filename);
  318. if (!fd) {
  319. return -EINVAL;
  320. }
  321. if(fd->storage_id != STORAGE_ID_NOR)
  322. return -EINVAL;
  323. map_addr = fd->start;
  324. map_len = fd->size;
  325. #ifdef CONFIG_NOR_CODE_IN_RAM
  326. extern unsigned int spi_nor_get_xip_offset(void);
  327. unsigned int xip_offset, tlen;
  328. if(!SDFS_INVALID_PART(fd->file_id)){
  329. xip_offset = spi_nor_get_xip_offset();
  330. if((fd->start < xip_offset) || (fd->start >= (16*1024*1024)))
  331. return -EINVAL;
  332. map_addr = 0x10000000 + fd->start - xip_offset;
  333. tlen = (16*1024*1024) - fd->start;
  334. if(map_len > tlen)
  335. map_len = tlen;
  336. }
  337. #else
  338. #ifdef CONFIG_SPI_XIP_READ
  339. if(!SDFS_INVALID_PART(fd->file_id)){
  340. map_addr += CONFIG_SPI_XIP_VADDR;
  341. }
  342. #endif
  343. #endif
  344. if (addr)
  345. *addr = (void *)map_addr;
  346. if (len)
  347. *len = map_len;
  348. sd_fclose(fd);
  349. return 0;
  350. }
  351. static unsigned int CheckSum32(void *data, unsigned int len)
  352. {
  353. uint32_t i, cs = 0;
  354. uint32_t *p = (uint32_t *)data;
  355. for(i = 0; i < len/4; i++)
  356. cs += p[i];
  357. return cs;
  358. }
  359. int sdfs_xip_check_valid(unsigned int xip_addr_start)
  360. {
  361. struct sd_dir *sd_dir_head, *sd_fhead;
  362. uint32_t *pdat;
  363. uint32_t dir_checksum, dir_num, checksum0, checksum1, i, st;
  364. int ret = 0;
  365. printk("xip sdfs check:xip off=0x%x\n", xip_addr_start);
  366. st = k_cycle_get_32();
  367. sd_dir_head = (struct sd_dir*)xip_addr_start;
  368. if (memcmp(sd_dir_head->fname, "sdfs.bin", 8) != 0 ) {
  369. printk("sdfs name fail\n");
  370. return -EINVAL;
  371. }
  372. dir_checksum = sd_dir_head->reserved[1];
  373. dir_num = sd_dir_head->offset;
  374. sd_fhead = sd_dir_head + 1;
  375. printk("dir:num=%d, size=%d, ck=0x%x,0x%x\n", dir_num, sd_dir_head->size, dir_num, sd_dir_head->checksum);
  376. checksum0 = 0;
  377. for (i = 1; i <= dir_num; i++, sd_fhead++) {
  378. checksum0 += CheckSum32((u32_t*)sd_fhead, sizeof(struct sd_dir));
  379. pdat = (uint32_t *)(xip_addr_start+sd_fhead->offset);
  380. checksum1 = CheckSum32(pdat, sd_fhead->size);
  381. printk("%d check start: off=0x%x, size=0x%x, ck=0x%x\n", i, sd_fhead->offset, sd_fhead->size, sd_fhead->checksum);
  382. if (checksum1 != sd_fhead->checksum) {
  383. printk("check fail:0x%x!=0x%x\n", checksum1, sd_fhead->checksum);
  384. ret = i;
  385. break;
  386. }
  387. }
  388. if ((0 == ret) && (checksum0 != dir_checksum)) {
  389. printk("dir check fail:0x%x!=0x%x\n", checksum0, dir_checksum);
  390. ret = -2;
  391. }
  392. st = k_cyc_to_ms_floor32(k_cycle_get_32()-st);
  393. if(ret){
  394. printk("sdfs check fail, %d ms\n", st);
  395. }else{
  396. printk("sdfs check ok, %d ms \n", st);
  397. }
  398. return ret;
  399. }
  400. static int sd_fs_init(const struct device *dev)
  401. {
  402. struct sd_dir sd_dir;
  403. printk("sdfs: init mapping to 0x%x, koff=0x%x\n", CONFIG_SD_FS_VADDR_START, K_SDFS_ADDR);
  404. memcpy_flash_data(&sd_dir, (void *)K_SDFS_ADDR, sizeof(sd_dir));
  405. if(memcmp(sd_dir.fname, "sdfs.bin", 8) == 0){
  406. printk("ksdfs.bin ok\n");
  407. b_k_sdfs = true;
  408. }else{
  409. b_k_sdfs = false;
  410. }
  411. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  412. const struct partition_entry *part_sdfs = partition_get_part(PARTITION_FILE_ID_SDFS);
  413. const struct partition_entry *part_system = partition_get_part(PARTITION_FILE_ID_SYSTEM);
  414. if (!part_sdfs || !part_system) {
  415. printk("part_sdfs %p ,part_system %p invalid \n", part_sdfs, part_system);
  416. return -1;
  417. }
  418. if ((part_sdfs->offset < part_system->offset)) {
  419. printk("sdfs partition offset(0x%x) invalid \n", part_sdfs->offset);
  420. return -1;
  421. }
  422. g_k_sdfs_system_addr = CONFIG_FLASH_BASE_ADDRESS + part_sdfs->offset - part_system->offset;
  423. sdfs_xip_check_valid(g_k_sdfs_system_addr);
  424. global_nor_dev = device_get_binding(CONFIG_SDFS_NOR_DEV_NAME);
  425. if (!global_nor_dev) {
  426. printk("failed to get nor device:%s\n", CONFIG_SDFS_NOR_DEV_NAME);
  427. return -1;
  428. }
  429. #else
  430. int err = partition_file_mapping(PARTITION_FILE_ID_SDFS, CONFIG_SD_FS_VADDR_START);
  431. if (err) {
  432. printk("sdfs: cannot mapping part file_id %d", PARTITION_FILE_ID_SDFS);
  433. return -1;
  434. }
  435. #endif
  436. return 0;
  437. }
  438. SYS_INIT(sd_fs_init, PRE_KERNEL_1, 80);
  439. #ifdef CONFIG_FILE_SYSTEM
  440. static int sdfs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
  441. {
  442. struct sd_file * sdf;
  443. if (zfp == NULL || file_name == NULL) {
  444. return -EINVAL;
  445. }
  446. if (zfp->filep) {
  447. /* file has been opened */
  448. return -EEXIST;
  449. }
  450. sdf = sd_fopen(file_name);
  451. if(sdf == NULL)
  452. return -EINVAL;
  453. zfp->filep = (void *)sdf;
  454. return 0;
  455. }
  456. static int sdfs_close(struct fs_file_t *zfp)
  457. {
  458. if (zfp == NULL) {
  459. return -EINVAL;
  460. }
  461. if (zfp->filep) {
  462. sd_fclose((struct sd_file *)zfp->filep);
  463. zfp->filep = NULL;
  464. } else {
  465. return -EIO;
  466. }
  467. return 0;
  468. }
  469. static ssize_t sdfs_read(struct fs_file_t *zfp, void *ptr, size_t size)
  470. {
  471. if (zfp == NULL || ptr == NULL) {
  472. return -EINVAL;
  473. }
  474. return sd_fread((struct sd_file *)zfp->filep, ptr, size);
  475. }
  476. static int sdfs_seek(struct fs_file_t *zfp, off_t offset, int whence)
  477. {
  478. if (!zfp) {
  479. return -EINVAL;
  480. }
  481. return sd_fseek((struct sd_file *)zfp->filep, offset, whence);
  482. }
  483. static off_t sdfs_tell(struct fs_file_t *zfp)
  484. {
  485. if (!zfp) {
  486. return -EINVAL;
  487. }
  488. return sd_ftell((struct sd_file *)zfp->filep);
  489. }
  490. static int sdfs_stat(struct fs_mount_t *mountp,
  491. const char *path, struct fs_dirent *entry)
  492. {
  493. int ret;
  494. if (mountp == NULL || path == NULL || entry == NULL) {
  495. return -EINVAL;
  496. }
  497. ret = sd_fsize(path);
  498. if(ret < 0) {
  499. printk("%s not exist\n", path);
  500. return -EINVAL;
  501. }
  502. entry->type = FS_DIR_ENTRY_FILE;
  503. entry->size = ret;
  504. return 0;
  505. }
  506. static int sdfs_statvfs(struct fs_mount_t *mountp,
  507. const char *path, struct fs_statvfs *stat)
  508. {
  509. if (mountp == NULL || path == NULL || stat == NULL) {
  510. return -EINVAL;
  511. }
  512. memset(stat, 0, sizeof(struct fs_statvfs));
  513. stat->f_bsize = 512;
  514. return 0;
  515. }
  516. static int sdfs_mount(struct fs_mount_t *mountp)
  517. {
  518. uint8_t stor_id, part;
  519. const char *fname;
  520. const struct partition_entry *parti;
  521. if (mountp == NULL) {
  522. return -EINVAL;
  523. }
  524. fname = sd_get_part_type(mountp->mnt_point, &stor_id, &part);
  525. if(fname == NULL){
  526. printk("sdfs mount fail,%s\n", mountp->mnt_point);
  527. return -EINVAL;
  528. }
  529. parti = partition_get_stf_part(stor_id, part+PARTITION_FILE_ID_SDFS_PART_BASE);
  530. if(parti == NULL){
  531. printk("sdfs mount get parit fail,%s\n", mountp->mnt_point);
  532. return -EINVAL;
  533. }
  534. //sdfs_verify(mountp->mnt_point);
  535. return 0;
  536. }
  537. static int sdfs_unmount(struct fs_mount_t *mountp)
  538. {
  539. if (mountp == NULL) {
  540. return -EINVAL;
  541. }
  542. return 0;
  543. }
  544. static int sdfs_fsystem_verify(const char *mnt_point, uint8_t *cache_buf, int cbuf_len)
  545. {
  546. uint8_t stor_id, part;
  547. const char *fname;
  548. const struct partition_entry *parti;
  549. struct sd_dir *sd_dir_head, *sd_fhead;
  550. struct sd_file *sd_file, *sd_dir_file;
  551. uint32_t dir_checksum, dir_num, checksum0, checksum1, i, file_size, data_bytes, st;
  552. uint8_t *dir_buf, *data_buf;
  553. int ret = 0;
  554. st = k_cycle_get_32();
  555. if (mnt_point == NULL || cbuf_len < 1024) {
  556. return -EINVAL;
  557. }
  558. fname = sd_get_part_type(mnt_point, &stor_id, &part);
  559. if(fname == NULL){
  560. printk("sdfs verify fail,not find %s\n", mnt_point);
  561. return -EINVAL;
  562. }
  563. parti = partition_get_stf_part(stor_id, part+PARTITION_FILE_ID_SDFS_PART_BASE);
  564. if(parti == NULL){
  565. printk("sdfs verify get parit fail,%s\n", mnt_point);
  566. return -EINVAL;
  567. }
  568. sd_dir_file = sd_alloc(sizeof(*sd_dir_file));
  569. sd_file = sd_alloc(sizeof(*sd_dir_file));
  570. if(sd_dir_file == NULL || sd_file == NULL){
  571. printk("%s malloc sd_file failed\n", __FUNCTION__);
  572. return -EINVAL;
  573. }
  574. sd_dir_file->start = parti->offset;
  575. sd_dir_file->size = 0x400;
  576. sd_dir_file->readptr = parti->offset;
  577. sd_dir_file->file_id = part;
  578. sd_dir_file->storage_id = stor_id;
  579. sd_file->file_id = part;
  580. sd_file->storage_id = stor_id;
  581. dir_buf = cache_buf;
  582. data_buf = cache_buf+512;
  583. cbuf_len -= 512;
  584. sd_fread(sd_dir_file, dir_buf, 512);
  585. sd_dir_head = (struct sd_dir*)dir_buf;
  586. if (memcmp(sd_dir_head->fname, "sdfs.bin", 8) != 0 ) {
  587. printk("dir name fail\n");
  588. sd_free(sd_dir_file);
  589. sd_free(sd_file);
  590. return -EINVAL;
  591. }
  592. dir_checksum = sd_dir_head->reserved[1];
  593. dir_num = sd_dir_head->offset;
  594. sd_fhead = sd_dir_head + 1;
  595. sd_dir_file->size = (dir_num+1) * (sizeof(struct sd_dir)); // update dir file size
  596. printk("dir:num=%d, size=%d, ck=0x%x,0x%x\n", dir_num, sd_dir_head->size, dir_num, sd_dir_head->checksum);
  597. checksum0 = 0;
  598. for (i = 1; i <= dir_num; i++, sd_fhead++) {
  599. if (0 == (i % (512 / sizeof(struct sd_dir)))) {
  600. if(sd_fread(sd_dir_file, dir_buf, 512) <= 0 ){
  601. printk("dir read fail\n");
  602. ret=-1;
  603. break;
  604. }
  605. sd_fhead = (struct sd_dir*)dir_buf;
  606. }
  607. checksum0 += CheckSum32((u32_t*)sd_fhead, sizeof(struct sd_dir));
  608. sd_file->start = sd_dir_file->start + sd_fhead->offset;
  609. sd_file->size = sd_fhead->size;
  610. sd_file->readptr = sd_file->start;
  611. file_size = sd_file->size;
  612. checksum1 = 0;
  613. printk("%d check start: off=0x%x, size=0x%x, ck=0x%x\n",i, sd_file->start, file_size, sd_fhead->checksum);
  614. while (file_size) {
  615. if (file_size > cbuf_len) {
  616. data_bytes = cbuf_len;
  617. }else {
  618. data_bytes = file_size;
  619. }
  620. if(sd_fread(sd_file, data_buf, data_bytes) <= 0 ){
  621. printk("sd read =%d fail\n", data_bytes);
  622. break;
  623. }
  624. checksum1 += CheckSum32((u32_t*)data_buf, data_bytes);
  625. file_size -= data_bytes;
  626. }
  627. if (checksum1 != sd_fhead->checksum) {
  628. printk("check fail:0x%x!=0x%x\n", checksum1, sd_fhead->checksum);
  629. ret = i;
  630. break;
  631. }
  632. }
  633. if ((0 == ret) && (checksum0 != dir_checksum)) {
  634. printk("dir check fail:0x%x!=0x%x\n", checksum0, dir_checksum);
  635. ret = -2;
  636. }
  637. st = k_cyc_to_ms_floor32(k_cycle_get_32()-st);
  638. if(ret){
  639. printk("%s check fail, %d ms\n", mnt_point, st);
  640. }else{
  641. printk("%s check ok, %d ms \n", mnt_point, st);
  642. }
  643. sd_free(sd_dir_file);
  644. sd_free(sd_file);
  645. return ret;
  646. }
  647. #define SDFS_MAX_LEN_CH (1024*2+512)
  648. #ifdef CONFIG_SOC_NO_PSRAM
  649. __in_section_unique(sdfs.cache.pool)
  650. #endif
  651. static int cache_buf[SDFS_MAX_LEN_CH/4];
  652. int sdfs_verify(const char *mnt_point)
  653. {
  654. return sdfs_fsystem_verify(mnt_point, (uint8_t*)cache_buf, SDFS_MAX_LEN_CH);
  655. }
  656. unsigned int sdfs_chksum(const char *mnt_point)
  657. {
  658. uint8_t stor_id, part;
  659. const char *fname;
  660. const struct partition_entry *parti;
  661. struct sd_dir *sd_dir_head;
  662. struct sd_file *sd_dir_file;
  663. if (mnt_point == NULL) {
  664. return 0;
  665. }
  666. fname = sd_get_part_type(mnt_point, &stor_id, &part);
  667. if(fname == NULL){
  668. return 0;
  669. }
  670. parti = partition_get_stf_part(stor_id, part+PARTITION_FILE_ID_SDFS_PART_BASE);
  671. if(parti == NULL){
  672. return 0;
  673. }
  674. sd_dir_file = sd_alloc(sizeof(*sd_dir_file));
  675. if(sd_dir_file == NULL){
  676. return 0;
  677. }
  678. sd_dir_file->start = parti->offset;
  679. sd_dir_file->size = 0x400;
  680. sd_dir_file->readptr = parti->offset;
  681. sd_dir_file->file_id = part;
  682. sd_dir_file->storage_id = stor_id;
  683. sd_fread(sd_dir_file, cache_buf, sizeof(struct sd_dir));
  684. sd_dir_head = (struct sd_dir*)cache_buf;
  685. sd_free(sd_dir_file);
  686. return sd_dir_head->checksum;
  687. }
  688. /* File system interface */
  689. const struct fs_file_system_t sdfs_fs = {
  690. .open = sdfs_open,
  691. .close = sdfs_close,
  692. .read = sdfs_read,
  693. .lseek = sdfs_seek,
  694. .tell = sdfs_tell,
  695. .mount = sdfs_mount,
  696. .unmount = sdfs_unmount,
  697. .stat = sdfs_stat,
  698. .statvfs = sdfs_statvfs,
  699. };
  700. static int fs_sdfs_init(const struct device *dev)
  701. {
  702. int ret;
  703. ret = fs_register(FS_SDFS, &sdfs_fs);
  704. printk("sdfs fs_register=%d\n", ret);
  705. //sdfs_verify("/NAND:A");
  706. return 0;
  707. }
  708. SYS_INIT(fs_sdfs_init, POST_KERNEL, 99);
  709. #endif