luat_vfs_romfs.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "luat_base.h"
  2. #include "luat_fs.h"
  3. #include "luat_mem.h"
  4. #define LUAT_LOG_TAG "romfs"
  5. #include "luat_log.h"
  6. #include "luat_romfs.h"
  7. #define ROMFS_DEBUG 0
  8. #if ROMFS_DEBUG == 0
  9. #undef LLOGD
  10. #define LLOGD(...)
  11. #endif
  12. static uint32_t toInt32(uint8_t buff[4]) {
  13. uint32_t ret = 0;
  14. ret += (buff[0] << 24);
  15. ret += (buff[1] << 16);
  16. ret += (buff[2] << 8);
  17. ret += (buff[3] << 0);
  18. return ret;
  19. }
  20. // typedef struct luat_fs_romfs
  21. // {
  22. // size_t count;
  23. // romfs_file_t *files[256 - 1];
  24. // }luat_fs_romfs_t;
  25. typedef struct romfs_head
  26. {
  27. char magic[8];
  28. size_t count;
  29. size_t checksum;
  30. char volume[16];
  31. } romfs_head_t;
  32. #define FDATA(fd) ((char *)(fd) + sizeof(romfs_file_t))
  33. #define FSIZE(fd) (fd->file->size)
  34. #ifdef LUAT_USE_FS_VFS
  35. static int romfs_find(luat_romfs_ctx* fs, const char* filename, romfs_file_t *file) {
  36. int ret = 0;
  37. int offset = sizeof(romfs_head_t);
  38. // LLOGD("romfs_find %s", filename);
  39. ret = fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
  40. while (1)
  41. {
  42. // LLOGD("name %s", file->name);
  43. if (!memcmp(".", file->name, 2) || !memcmp("..", file->name, 3))
  44. {
  45. // pass
  46. }
  47. else
  48. {
  49. if (strcmp(file->name, filename) == 0)
  50. {
  51. // LLOGD("found %s %08X %08X", file->name, toInt32(file->size), toInt32(file->next_offset));
  52. return offset;
  53. }
  54. }
  55. if ((toInt32(file->next_offset) & 0xFFFFFFF0) == 0)
  56. break;
  57. // LLOGD("file->next_offset %08X", toInt32(file->next_offset));
  58. offset = sizeof(romfs_head_t) + (toInt32(file->next_offset) & 0xFFFFFFF0);
  59. // LLOGD("Next offset %08X", offset);
  60. ret = fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
  61. if (ret < 0) {
  62. LLOGW("romfs ERROR find %d", ret);
  63. return -1;
  64. }
  65. }
  66. LLOGD("NOT found %s", filename);
  67. return 0;
  68. }
  69. FILE *luat_vfs_romfs_fopen(void *userdata, const char *filename, const char *mode)
  70. {
  71. // LLOGD("open romfs >> ============== %s", filename);
  72. // int ret = 0;
  73. size_t offset = 0;
  74. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  75. romfs_file_t tfile = {0};
  76. if (memcmp("r", mode, 1))
  77. {
  78. return NULL; // romfs 是只读文件系统
  79. }
  80. offset = romfs_find(fs, filename, &tfile);
  81. if (offset > 0) {
  82. romfs_fd_t *fd = luat_heap_malloc(sizeof(romfs_fd_t));
  83. if (fd == NULL)
  84. {
  85. LLOGE("out of memory when malloc luat_fs_romfs_t");
  86. return NULL;
  87. }
  88. fd->offset = 0;
  89. fd->addr = offset;
  90. // LLOGD("fopen addr %08X", fd->addr);
  91. memcpy(&fd->file, &tfile, sizeof(romfs_file_t));
  92. return (FILE *)fd;
  93. }
  94. return NULL;
  95. }
  96. int luat_vfs_romfs_getc(void *userdata, FILE *stream)
  97. {
  98. // LLOGD("getc %p %p", userdata, stream);
  99. romfs_fd_t *fd = (romfs_fd_t *)stream;
  100. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  101. // LLOGD("getc %p %p %d %d", userdata, stream, fd->offset, fd->size);
  102. char c = 0;
  103. if (fd->offset < toInt32(fd->file.size))
  104. {
  105. fs->read(fs->userdata, &c, fd->offset + fd->addr + sizeof(romfs_file_t), 1);
  106. fd->offset++;
  107. // LLOGD("getc %02X", c);
  108. return c;
  109. }
  110. return -1;
  111. }
  112. int luat_vfs_romfs_fseek(void *userdata, FILE *stream, long int offset, int origin)
  113. {
  114. // LLOGD("fseek %p %p %d %d", userdata, stream, offset, origin);
  115. romfs_fd_t *fd = (romfs_fd_t *)stream;
  116. if (origin == SEEK_CUR)
  117. {
  118. fd->offset += offset;
  119. return 0;
  120. }
  121. else if (origin == SEEK_SET)
  122. {
  123. fd->offset = offset;
  124. return 0;
  125. }
  126. else
  127. {
  128. fd->offset = toInt32(fd->file.size) - offset;
  129. return 0;
  130. }
  131. }
  132. int luat_vfs_romfs_ftell(void *userdata, FILE *stream)
  133. {
  134. romfs_fd_t *fd = (romfs_fd_t *)stream;
  135. // LLOGD("tell %p %p %d %d", userdata, stream, fd->size, fd->offset);
  136. return fd->offset;
  137. }
  138. int luat_vfs_romfs_fclose(void *userdata, FILE *stream)
  139. {
  140. romfs_fd_t *fd = (romfs_fd_t *)stream;
  141. // LLOGD("fclose %p %p %d %d", userdata, stream, fd->size, fd->offset);
  142. luat_heap_free(fd);
  143. return 0;
  144. }
  145. int luat_vfs_romfs_feof(void *userdata, FILE *stream)
  146. {
  147. romfs_fd_t *fd = (romfs_fd_t *)stream;
  148. // LLOGD("feof %p %p %d %d", userdata, stream, fd->size, fd->offset);
  149. return fd->offset >= toInt32(fd->file.size) ? 1 : 0;
  150. }
  151. int luat_vfs_romfs_ferror(void *userdata, FILE *stream)
  152. {
  153. return 0;
  154. }
  155. size_t luat_vfs_romfs_fread(void *userdata, void *ptr, size_t size, size_t nmemb, FILE *stream)
  156. {
  157. romfs_fd_t *fd = (romfs_fd_t *)stream;
  158. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  159. // LLOGD("fread %p %p %d %d", userdata, stream, fd->size, fd->offset);
  160. // LLOGD("fread2 %p %p %d %d", userdata, stream, size * nmemb, fd->offset);
  161. size_t read_size = size * nmemb;
  162. if (fd->offset + read_size > toInt32(fd->file.size))
  163. {
  164. read_size = toInt32(fd->file.size) - fd->offset;
  165. }
  166. // memcpy(ptr, FDATA(fd) + fd->offset, read_size);
  167. fs->read(fs->userdata, ptr, fd->offset + fd->addr + sizeof(romfs_file_t), read_size);
  168. fd->offset += read_size;
  169. return read_size;
  170. }
  171. int luat_vfs_romfs_fexist(void *userdata, const char *filename)
  172. {
  173. // LLOGD("open romfs %s", filename);
  174. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  175. romfs_file_t file = {0};
  176. int ret = romfs_find(fs, filename, &file);
  177. // LLOGD("found? %s %d", filename, ret);
  178. return ret > 0 ? 1 : 0;
  179. }
  180. size_t luat_vfs_romfs_fsize(void *userdata, const char *filename)
  181. {
  182. // LLOGD("open romfs %s", filename);
  183. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  184. romfs_file_t file = {0};
  185. int ret = romfs_find(fs, filename, &file);
  186. if (ret > 0) {
  187. return toInt32(file.size);
  188. }
  189. return 0;
  190. }
  191. int luat_vfs_romfs_mount(void **userdata, luat_fs_conf_t *conf)
  192. {
  193. // LLOGD("luat_vfs_romfs_mount ==================");
  194. luat_romfs_ctx* fs = (luat_romfs_ctx*)conf->busname;
  195. // LLOGD("luat_romfs_ctx %p", fs);
  196. // LLOGD("luat_romfs_ctx %p", fs->read);
  197. // LLOGD("luat_romfs_ctx %p", fs->userdata);
  198. romfs_head_t head = {0};
  199. fs->read(fs->userdata, (char*)&head, 0, sizeof(romfs_head_t));
  200. if (memcmp(head.magic, "-rom1fs-", 8))
  201. {
  202. LLOGI("Not ROMFS at %p", &head);
  203. return -1;
  204. }
  205. // LLOGD("romfs mounted");
  206. *userdata = conf->busname;
  207. return 0;
  208. }
  209. int luat_vfs_romfs_umount(void *userdata, luat_fs_conf_t *conf)
  210. {
  211. return 0;
  212. }
  213. int luat_vfs_romfs_info(void *userdata, const char *path, luat_fs_info_t *conf)
  214. {
  215. memcpy(conf->filesystem, "romfs", strlen("romfs") + 1);
  216. conf->type = 0;
  217. conf->total_block = 0;
  218. conf->block_used = 0;
  219. conf->block_size = 512;
  220. return 0;
  221. }
  222. int luat_vfs_romfs_lsdir(void *userdata, char const *_DirName, luat_fs_dirent_t *ents, size_t ent_offset, size_t len)
  223. {
  224. luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
  225. int offset = sizeof(romfs_head_t);
  226. // romfs_head_t head = {0};
  227. romfs_file_t tfile = {0};
  228. // fs->read(fs->addr, &head, sizeof(romfs_head_t));
  229. int counter = 0;
  230. int count_down = ent_offset;
  231. romfs_file_t *file = &tfile;
  232. fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
  233. while (1)
  234. {
  235. if (counter >= len)
  236. break;
  237. if (!memcmp(".", file->name, 2) || !memcmp("..", file->name, 3))
  238. {
  239. // pass
  240. }
  241. else if (count_down > 0)
  242. {
  243. count_down--;
  244. }
  245. else
  246. {
  247. ents[counter].d_type = 0;
  248. strcpy(ents[counter].d_name, file->name);
  249. counter++;
  250. }
  251. if ((toInt32(file->next_offset) & 0xFFFFFFF0) == 0)
  252. break;
  253. offset = sizeof(romfs_head_t) + (toInt32(file->next_offset) & 0xFFFFFFF0);
  254. fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
  255. }
  256. return 0;
  257. }
  258. #define T(name) .name = luat_vfs_romfs_##name
  259. const struct luat_vfs_filesystem vfs_fs_romfs = {
  260. .name = "romfs",
  261. .opts = {
  262. .mkfs = NULL,
  263. T(mount),
  264. .umount = NULL,
  265. .mkdir = NULL,
  266. .rmdir = NULL,
  267. .remove = NULL,
  268. .rename = NULL,
  269. T(fsize),
  270. T(fexist),
  271. T(info),
  272. T(lsdir)},
  273. .fopts = {T(fopen), T(getc), T(fseek), T(ftell), T(fclose), T(feof), T(ferror), T(fread), .fwrite = NULL}};
  274. #endif