sdfs.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  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. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  14. #include <drivers/flash.h>
  15. #include <board_cfg.h>
  16. #endif
  17. #define K_SDFS_ADDR (((unsigned int)__rom_region_start)+((unsigned int)_flash_used))
  18. static struct sd_file g_sd_file_heap[CONFIG_SD_FILE_MAX];
  19. static bool b_k_sdfs;
  20. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  21. static uint32_t g_k_sdfs_system_addr;
  22. static const struct device *global_nor_dev;
  23. #endif
  24. #define SDFS_INVALID_PART_ID (0xFF)
  25. #define SDFS_INVALID_PART(x) ((x) == SDFS_INVALID_PART_ID)
  26. #define memcpy_flash_data memcpy
  27. #if 0
  28. #define sd_alloc k_malloc
  29. #define sd_free k_free
  30. #else
  31. struct sd_file * sd_alloc(int size)
  32. {
  33. int i;
  34. unsigned int key;
  35. key = irq_lock();
  36. for(i = 0; i < CONFIG_SD_FILE_MAX; i++){
  37. if(g_sd_file_heap[i].start == 0){
  38. g_sd_file_heap[i].start = 1; //use
  39. break;
  40. }
  41. }
  42. irq_unlock(key);
  43. if(i == CONFIG_SD_FILE_MAX)
  44. return NULL;
  45. else
  46. return &g_sd_file_heap[i];
  47. }
  48. void sd_free(struct sd_file * sd_file)
  49. {
  50. unsigned int key;
  51. key = irq_lock();
  52. memset(sd_file, 0, sizeof(*sd_file));
  53. irq_unlock(key);
  54. }
  55. #endif
  56. //#define CONFIG_SD_FS_VADDR_START g_vaddr_start
  57. //static unsigned int g_vaddr_start = 0x0;
  58. static struct sd_dir * sd_find_dir_by_addr(const char *filename, void *buf_size_32, uint32_t adfs_addr)
  59. {
  60. int num, total, offset;
  61. struct sd_dir *sd_dir = buf_size_32;
  62. memcpy_flash_data(buf_size_32, (void *)adfs_addr, sizeof(*sd_dir));
  63. //printk("sd_dir->fname %s CONFIG_SD_FS_START 0x%x \n",sd_dir->fname,CONFIG_SD_FS_VADDR_START);
  64. if(memcmp(sd_dir->fname, "sdfs.bin", 8) != 0)
  65. {
  66. printk("sdfs.bin invalid, offset=0x%x\n", adfs_addr);
  67. return NULL;
  68. }
  69. total = sd_dir->offset;
  70. for(offset = adfs_addr + sizeof(*sd_dir), num = 0; num < total; offset += 32)
  71. {
  72. memcpy_flash_data(buf_size_32, (void *)offset, 32);
  73. //printk("%d,file=%s, size=0x%x\n", num, sd_dir->fname, sd_dir->size);
  74. if(strncasecmp(filename, sd_dir->fname, 12) == 0)
  75. {
  76. return sd_dir;
  77. }
  78. num++;
  79. }
  80. return NULL;
  81. }
  82. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  83. static struct sd_dir *sd_find_dir_by_part(const char *filename, void *buf_size_32, uint8_t part)
  84. {
  85. int num, total, offset, total_file_size;
  86. struct sd_dir *sd_dir = buf_size_32, *ret_sd_dir = NULL;
  87. const struct partition_entry *part_entry;
  88. int ret;
  89. uint8_t *sd_dir_buf_ptr = NULL;
  90. part_entry = partition_get_stf_part(STORAGE_ID_NOR, part + PARTITION_FILE_ID_SDFS_PART_BASE);
  91. if (!part_entry)
  92. return NULL;
  93. ret = flash_read(global_nor_dev, part_entry->offset, buf_size_32, sizeof(struct sd_dir));
  94. if (ret < 0) {
  95. printk("nor read offset:0x%x size:%d error:%d\n",
  96. part_entry->offset, sizeof(struct sd_dir), ret);
  97. return NULL;
  98. }
  99. if (memcmp(sd_dir->fname, "sdfs.bin", 8) != 0) {
  100. printk("sdfs.bin invalid, offset=0x%x\n", part_entry->offset);
  101. return NULL;
  102. }
  103. total = sd_dir->offset;
  104. total_file_size = (total + 1) * sizeof(struct sd_dir);
  105. sd_dir_buf_ptr = k_malloc(total_file_size);
  106. if (!sd_dir_buf_ptr) {
  107. printk("failed to malloc size:%d\n", total_file_size);
  108. return NULL;
  109. }
  110. ret = flash_read(global_nor_dev, part_entry->offset, sd_dir_buf_ptr, total_file_size);
  111. if (ret < 0) {
  112. printk("nor read offset:0x%x size:%d error:%d\n",
  113. part_entry->offset + sizeof(*sd_dir), total_file_size, ret);
  114. goto out;
  115. }
  116. for (offset = (uint32_t)sd_dir_buf_ptr + sizeof(*sd_dir), num = 0; num < total; offset += 32) {
  117. memcpy_flash_data(buf_size_32, (void *)offset, 32);
  118. //printk("%d,file=%s, size=0x%x\n", num, sd_dir->fname, sd_dir->size);
  119. if (strncasecmp(filename, sd_dir->fname, 12) == 0) {
  120. /* add partition offset */
  121. sd_dir->offset += part_entry->offset;
  122. ret_sd_dir = sd_dir;
  123. break;
  124. }
  125. num++;
  126. }
  127. out:
  128. k_free(sd_dir_buf_ptr);
  129. return ret_sd_dir;
  130. }
  131. #endif
  132. static struct sd_dir * sd_find_dir(const char *filename, void *buf_size_32, uint8_t part)
  133. {
  134. struct sd_dir *sd_d = NULL;
  135. /* find file from ksdfs which padding by kernel firstly */
  136. if (b_k_sdfs && SDFS_INVALID_PART(part)){
  137. sd_d = sd_find_dir_by_addr(filename, buf_size_32, K_SDFS_ADDR);
  138. if(sd_d) {
  139. sd_d->offset += K_SDFS_ADDR;
  140. return sd_d;
  141. }
  142. }
  143. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  144. if (g_k_sdfs_system_addr && SDFS_INVALID_PART(part)) {
  145. sd_d = sd_find_dir_by_addr(filename, buf_size_32, g_k_sdfs_system_addr);
  146. if (sd_d) {
  147. sd_d->offset += g_k_sdfs_system_addr;
  148. return sd_d;
  149. }
  150. }
  151. if (!SDFS_INVALID_PART(part)) {
  152. sd_d = sd_find_dir_by_part(filename, buf_size_32, part);
  153. return sd_d;
  154. }
  155. #else
  156. sd_d = sd_find_dir_by_addr(filename, buf_size_32, CONFIG_SD_FS_VADDR_START);
  157. if(sd_d) {
  158. sd_d->offset += CONFIG_SD_FS_VADDR_START;
  159. return sd_d;
  160. }
  161. #endif
  162. return sd_d;
  163. }
  164. const char* const sd_volume_strs[] = {
  165. _SDFS_VOL_STRS
  166. };
  167. static const char *sd_get_part_type(const char *filename, uint8_t *stor_id, uint8_t *part)
  168. {
  169. const char *pc, *ret_ptr = NULL;
  170. int i;
  171. *stor_id = STORAGE_ID_NOR;
  172. *part = SDFS_INVALID_PART_ID;
  173. if(filename[0] != '/')
  174. return filename;
  175. filename += 1;
  176. pc = strchr(filename, ':');
  177. if(pc == NULL) // /*|| pc[2] != '/'*/
  178. return NULL;
  179. for(i = 0; i < STORAGE_ID_MAX; i++){
  180. if(!strncmp(filename, sd_volume_strs[i], strlen(sd_volume_strs[i])))
  181. break;
  182. }
  183. if(i == STORAGE_ID_MAX)
  184. return NULL;
  185. *stor_id = i;
  186. /* /[NOR|NAND|SD]:[A:Z]/s */
  187. if ((pc[1] >= 'A') && (pc[1] <= 'Z') /*&& (pc[2] == '/')*/) {
  188. *part = pc[1] - 'A';
  189. ret_ptr = pc + 3;
  190. } else {
  191. *part = SDFS_INVALID_PART_ID;
  192. ret_ptr = pc + 1;
  193. }
  194. return ret_ptr;
  195. }
  196. struct sd_file * sd_fopen (const char *filename)
  197. {
  198. struct sd_dir *sd_dir;
  199. uint8_t buf_size_32[32];
  200. struct sd_file *sd_file;
  201. uint8_t stor_id, part;
  202. const char *fname;
  203. fname = sd_get_part_type(filename, &stor_id, &part);
  204. if(fname == NULL){
  205. printk("sdfs file %s invalid\n", filename);
  206. return NULL;
  207. }
  208. printk("sdfs:stor_id=%d, p=%d\n",stor_id, part);
  209. if(stor_id == STORAGE_ID_NOR)
  210. sd_dir = sd_find_dir(fname, (void *)buf_size_32, part);
  211. else
  212. sd_dir = nand_sd_find_dir(stor_id, part, fname, (void *)buf_size_32);
  213. if(sd_dir == NULL)
  214. {
  215. printk("%s no this file %s\n", __FUNCTION__, filename);
  216. return NULL;
  217. }
  218. sd_file = sd_alloc(sizeof(*sd_file));
  219. if(sd_file == NULL)
  220. {
  221. printk("%s malloc(%d) failed\n", __FUNCTION__, (int)sizeof(*sd_file));
  222. return NULL;
  223. }
  224. sd_file->start = sd_dir->offset;
  225. sd_file->size = sd_dir->size;
  226. sd_file->readptr = sd_file->start;
  227. sd_file->file_id = part;
  228. sd_file->storage_id = stor_id;
  229. return sd_file;
  230. }
  231. void sd_fclose(struct sd_file *sd_file)
  232. {
  233. sd_free(sd_file);
  234. }
  235. int sd_fread(struct sd_file *sd_file, void *buffer, int len)
  236. {
  237. unsigned int size_in_512, read_size;
  238. if ((sd_file->readptr - sd_file->start + len) > sd_file->size)
  239. {
  240. len = sd_file->size - (sd_file->readptr - sd_file->start);
  241. }
  242. if(len <= 0)
  243. return 0;
  244. read_size = len;
  245. if(sd_file->storage_id != STORAGE_ID_NOR)
  246. return nand_sd_sd_fread(sd_file->storage_id, sd_file, buffer, read_size);
  247. size_in_512 = 512 - (sd_file->readptr % 512);
  248. size_in_512 = size_in_512 > len ? len : size_in_512;
  249. if(size_in_512 > 0)
  250. {
  251. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  252. if (SDFS_INVALID_PART(sd_file->file_id)) {
  253. memcpy_flash_data(buffer, (void *)sd_file->readptr, size_in_512);
  254. } else {
  255. if (flash_read(global_nor_dev, (uint32_t)sd_file->readptr, buffer, size_in_512) < 0) {
  256. printk("failed to read offset:0x%x size:%d\n",
  257. (uint32_t)sd_file->readptr, size_in_512);
  258. return 0;
  259. }
  260. }
  261. #else
  262. memcpy_flash_data(buffer, (void *)sd_file->readptr, size_in_512);
  263. #endif
  264. buffer = (uint8_t *)buffer + size_in_512;
  265. sd_file->readptr += size_in_512;
  266. len -= size_in_512;
  267. }
  268. for(; len > 0; buffer = (uint8_t *)buffer + size_in_512, sd_file->readptr += size_in_512, len -= size_in_512)
  269. {
  270. size_in_512 = len > 512 ? 512 : len;
  271. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  272. if (SDFS_INVALID_PART(sd_file->file_id)) {
  273. memcpy_flash_data(buffer, (void *)sd_file->readptr, size_in_512);
  274. } else {
  275. if (flash_read(global_nor_dev, (uint32_t)sd_file->readptr, buffer, size_in_512) < 0) {
  276. printk("failed to read offset:0x%x size:%d\n",
  277. (uint32_t)sd_file->readptr, size_in_512);
  278. return 0;
  279. }
  280. }
  281. #else
  282. memcpy_flash_data(buffer, (void *)sd_file->readptr, size_in_512);
  283. #endif
  284. }
  285. return read_size;
  286. }
  287. int sd_ftell(struct sd_file *sd_file)
  288. {
  289. return (sd_file->readptr - sd_file->start);
  290. }
  291. int sd_fseek(struct sd_file *sd_file, int offset, unsigned char whence)
  292. {
  293. if (whence == FS_SEEK_SET)
  294. {
  295. if (offset > sd_file->size)
  296. return -1;
  297. sd_file->readptr = sd_file->start + offset;
  298. return 0;
  299. }
  300. if (whence == FS_SEEK_CUR)
  301. {
  302. if(sd_file->readptr + offset < sd_file->start
  303. || sd_file->readptr + offset > sd_file->start + sd_file->size)
  304. {
  305. return -1;
  306. }
  307. sd_file->readptr += offset;
  308. return 0;
  309. }
  310. if (whence == FS_SEEK_END)
  311. {
  312. if(offset > 0 || offset + sd_file->size < 0)
  313. return -1;
  314. sd_file->readptr = sd_file->start + sd_file->size + offset;
  315. return 0;
  316. }
  317. return -EINVAL;
  318. }
  319. int sd_fsize(const char *filename)
  320. {
  321. struct sd_file *fd = sd_fopen(filename);
  322. int file_size;
  323. if (!fd) {
  324. return -EINVAL;
  325. }
  326. file_size = fd->size;
  327. sd_fclose(fd);
  328. return file_size;
  329. }
  330. int sd_fmap(const char *filename, void** addr, int* len)
  331. {
  332. struct sd_file *fd = sd_fopen(filename);
  333. if (!fd) {
  334. return -EINVAL;
  335. }
  336. if(fd->storage_id != STORAGE_ID_NOR)
  337. return -EINVAL;
  338. if (addr)
  339. *addr = (void *)fd->start;
  340. if (len)
  341. *len = fd->size;
  342. sd_fclose(fd);
  343. return 0;
  344. }
  345. static int sd_fs_init(const struct device *dev)
  346. {
  347. struct sd_dir sd_dir;
  348. printk("sdfs: init mapping to 0x%x, koff=0x%x\n", CONFIG_SD_FS_VADDR_START, K_SDFS_ADDR);
  349. memcpy_flash_data(&sd_dir, (void *)K_SDFS_ADDR, sizeof(sd_dir));
  350. if(memcmp(sd_dir.fname, "sdfs.bin", 8) == 0){
  351. printk("ksdfs.bin ok\n");
  352. b_k_sdfs = true;
  353. }else{
  354. b_k_sdfs = false;
  355. }
  356. #ifdef CONFIG_SDFS_NOR_NOT_XIP
  357. const struct partition_entry *part_sdfs = partition_get_part(PARTITION_FILE_ID_SDFS);
  358. const struct partition_entry *part_system = partition_get_part(PARTITION_FILE_ID_SYSTEM);
  359. if ((part_sdfs->offset < part_system->offset)
  360. || ((part_sdfs->offset - part_system->offset) >= CONFIG_SDFS_NOR_NOT_XIP_MAX_COPY_OFFSET)
  361. || ((part_sdfs->offset - part_system->offset + part_sdfs->size) > CONFIG_SDFS_NOR_NOT_XIP_MAX_COPY_OFFSET)) {
  362. printk("sdfs partition offset(0x%x) invalid", part_sdfs->offset);
  363. return -1;
  364. }
  365. g_k_sdfs_system_addr = CONFIG_FLASH_BASE_ADDRESS + part_sdfs->offset - part_system->offset;
  366. global_nor_dev = device_get_binding(CONFIG_SDFS_NOR_DEV_NAME);
  367. if (!global_nor_dev) {
  368. printk("failed to get nor device:%s\n", CONFIG_SDFS_NOR_DEV_NAME);
  369. return -1;
  370. }
  371. #else
  372. int err = partition_file_mapping(PARTITION_FILE_ID_SDFS, CONFIG_SD_FS_VADDR_START);
  373. if (err) {
  374. printk("sdfs: cannot mapping part file_id %d", PARTITION_FILE_ID_SDFS);
  375. return -1;
  376. }
  377. #endif
  378. return 0;
  379. }
  380. SYS_INIT(sd_fs_init, PRE_KERNEL_1, 80);
  381. #ifdef CONFIG_FILE_SYSTEM
  382. static int sdfs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
  383. {
  384. struct sd_file * sdf;
  385. if (zfp == NULL || file_name == NULL) {
  386. return -EINVAL;
  387. }
  388. if (zfp->filep) {
  389. /* file has been opened */
  390. return -EEXIST;
  391. }
  392. sdf = sd_fopen(file_name);
  393. if(sdf == NULL)
  394. return -EINVAL;
  395. zfp->filep = (void *)sdf;
  396. return 0;
  397. }
  398. static int sdfs_close(struct fs_file_t *zfp)
  399. {
  400. if (zfp == NULL) {
  401. return -EINVAL;
  402. }
  403. if (zfp->filep) {
  404. sd_fclose((struct sd_file *)zfp->filep);
  405. zfp->filep = NULL;
  406. } else {
  407. return -EIO;
  408. }
  409. return 0;
  410. }
  411. static ssize_t sdfs_read(struct fs_file_t *zfp, void *ptr, size_t size)
  412. {
  413. if (zfp == NULL || ptr == NULL) {
  414. return -EINVAL;
  415. }
  416. return sd_fread((struct sd_file *)zfp->filep, ptr, size);
  417. }
  418. static int sdfs_seek(struct fs_file_t *zfp, off_t offset, int whence)
  419. {
  420. if (!zfp) {
  421. return -EINVAL;
  422. }
  423. return sd_fseek((struct sd_file *)zfp->filep, offset, whence);
  424. }
  425. static off_t sdfs_tell(struct fs_file_t *zfp)
  426. {
  427. if (!zfp) {
  428. return -EINVAL;
  429. }
  430. return sd_ftell((struct sd_file *)zfp->filep);
  431. }
  432. static int sdfs_stat(struct fs_mount_t *mountp,
  433. const char *path, struct fs_dirent *entry)
  434. {
  435. int ret;
  436. if (mountp == NULL || path == NULL || entry == NULL) {
  437. return -EINVAL;
  438. }
  439. ret = sd_fsize(path);
  440. if(ret < 0) {
  441. printk("%s not exist\n", path);
  442. return -EINVAL;
  443. }
  444. entry->type = FS_DIR_ENTRY_FILE;
  445. entry->size = ret;
  446. return 0;
  447. }
  448. static int sdfs_statvfs(struct fs_mount_t *mountp,
  449. const char *path, struct fs_statvfs *stat)
  450. {
  451. if (mountp == NULL || path == NULL || stat == NULL) {
  452. return -EINVAL;
  453. }
  454. memset(stat, 0, sizeof(struct fs_statvfs));
  455. stat->f_bsize = 512;
  456. return 0;
  457. }
  458. static int sdfs_mount(struct fs_mount_t *mountp)
  459. {
  460. uint8_t stor_id, part;
  461. const char *fname;
  462. const struct partition_entry *parti;
  463. if (mountp == NULL) {
  464. return -EINVAL;
  465. }
  466. fname = sd_get_part_type(mountp->mnt_point, &stor_id, &part);
  467. if(fname == NULL){
  468. printk("sdfs mount fail,%s\n", mountp->mnt_point);
  469. return -EINVAL;
  470. }
  471. parti = partition_get_stf_part(stor_id, part+PARTITION_FILE_ID_SDFS_PART_BASE);
  472. if(parti == NULL){
  473. printk("sdfs mount get parit fail,%s\n", mountp->mnt_point);
  474. return -EINVAL;
  475. }
  476. return 0;
  477. }
  478. static int sdfs_unmount(struct fs_mount_t *mountp)
  479. {
  480. if (mountp == NULL) {
  481. return -EINVAL;
  482. }
  483. return 0;
  484. }
  485. /* File system interface */
  486. const struct fs_file_system_t sdfs_fs = {
  487. .open = sdfs_open,
  488. .close = sdfs_close,
  489. .read = sdfs_read,
  490. .lseek = sdfs_seek,
  491. .tell = sdfs_tell,
  492. .mount = sdfs_mount,
  493. .unmount = sdfs_unmount,
  494. .stat = sdfs_stat,
  495. .statvfs = sdfs_statvfs,
  496. };
  497. static int fs_sdfs_init(const struct device *dev)
  498. {
  499. int ret;
  500. ret = fs_register(FS_SDFS, &sdfs_fs);
  501. printk("sdfs fs_register=%d\n", ret);
  502. return 0;
  503. }
  504. SYS_INIT(fs_sdfs_init, POST_KERNEL, 99);
  505. #endif