Browse Source

add: 添加vfs_inline管理内嵌的脚本,添加vfs_romfs为替代vfs_luadb做准备

Wendal Chen 3 năm trước cách đây
mục cha
commit
e6828ec9ae

+ 3 - 3
luat/include/luat_fs.h

@@ -1,5 +1,5 @@
 /******************************************************************************
- *  ADC设备操作抽象层
+ *  文件系统操作抽象层
  *  @author wendal
  *  @since 0.1.5
  *****************************************************************************/
@@ -69,11 +69,11 @@ int luat_fs_lsdir(char const* _DirName, luat_fs_dirent_t* ents, size_t offset, s
 #ifdef LUAT_USE_FS_VFS
 
 #ifndef LUAT_VFS_FILESYSTEM_MAX
-#define LUAT_VFS_FILESYSTEM_MAX 4
+#define LUAT_VFS_FILESYSTEM_MAX 8
 #endif
 
 #ifndef LUAT_VFS_FILESYSTEM_MOUNT_MAX
-#define LUAT_VFS_FILESYSTEM_MOUNT_MAX 4
+#define LUAT_VFS_FILESYSTEM_MOUNT_MAX 8
 #endif
 
 #ifndef LUAT_VFS_FILESYSTEM_FD_MAX

+ 1 - 1
luat/include/luat_luadb.h

@@ -32,7 +32,7 @@ typedef struct luadb_fs
     uint16_t version;  // 文件系统版本号,当前支持v1/v2
     uint16_t filecount; // 文件总数,实际少于100
     luadb_fd_t fds[LUAT_LUADB_MAX_OPENFILE]; // 句柄数组
-    luadb_file_t *inlines;
+    // luadb_file_t *inlines;
     luadb_file_t files[1]; // 文件数组
 } luadb_fs_t;
 

+ 192 - 0
luat/vfs/luat_fs_inline.c

@@ -0,0 +1,192 @@
+#include "luat_base.h"
+#include "luat_fs.h"
+#include "luat_malloc.h"
+#define LUAT_LOG_TAG "fs"
+#include "luat_log.h"
+
+#include "luat_luadb.h"
+
+typedef struct luat_fs_inline
+{
+    char* ptr;
+    uint32_t  size;
+    uint32_t  offset;
+}luat_fs_inline_t;
+
+#ifdef LUAT_CONF_VM_64bit
+extern const luadb_file_t luat_inline2_libs_64bit_size64[];
+extern const luadb_file_t luat_inline2_libs_64bit_size32[];
+#else
+extern const luadb_file_t luat_inline2_libs[];
+#endif
+
+#ifdef LUAT_USE_FS_VFS
+
+FILE* luat_vfs_inline_fopen(void* userdata, const char *filename, const char *mode) {
+    //LLOGD("open inline %s", filename);
+    luadb_file_t* file = NULL;
+#ifdef LUAT_CONF_VM_64bit
+    file = luat_inline2_libs_64bit_size64;
+    file = luat_inline2_libs_64bit_size32;
+#else
+    file = luat_inline2_libs;
+#endif
+
+    if (!strcmp("r", mode) || !strcmp("rb", mode)) {
+        luat_fs_inline_t* fd = luat_heap_malloc(sizeof(luat_fs_inline_t));
+        if (fd == NULL) {
+            LLOGE("out of memory when malloc luat_fs_inline_t");
+            return NULL;
+        }
+        while (file != NULL && file->ptr != NULL) {
+            if (!memcmp(file->name, filename, strlen(filename)+1)) {
+                break;
+            }
+            file ++;
+        }
+        if (file == NULL || file->ptr == NULL) {
+            //LLOGD("Not Found %s", filename);
+            return NULL;
+        }
+        fd->ptr = file->ptr;
+        fd->size = file->size;
+        fd->offset = 0;
+        return (FILE*)fd;
+    }
+    //LLOGD("Not Found %s", filename);
+    return NULL;
+}
+
+int luat_vfs_inline_getc(void* userdata, FILE* stream) {
+    //LLOGD("getc %p %p", userdata, stream);
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    //LLOGD("getc %p %p %d %d", userdata, stream, fd->offset, fd->size);
+    if (fd->offset < fd->size) {
+        uint8_t c = (uint8_t)fd->ptr[fd->offset];
+        fd->offset ++;
+        //LLOGD("getc %02X", c);
+        return c;
+    }
+    return -1;
+}
+
+int luat_vfs_inline_fseek(void* userdata, FILE* stream, long int offset, int origin) {
+    //LLOGD("fseek %p %p %d %d", userdata, stream, offset, origin);
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    if (origin == SEEK_CUR) {
+        fd->offset += offset;
+        return 0;
+    }
+    else if (origin == SEEK_SET) {
+        fd->offset = offset;
+        return 0;
+    }
+    else {
+        fd->offset = fd->size - offset;
+        return 0;
+    }
+}
+
+int luat_vfs_inline_ftell(void* userdata, FILE* stream) {
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    //LLOGD("tell %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    return fd->offset;
+}
+
+int luat_vfs_inline_fclose(void* userdata, FILE* stream) {
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    //LLOGD("fclose %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    luat_heap_free(fd);
+    return 0;
+}
+int luat_vfs_inline_feof(void* userdata, FILE* stream) {
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    //LLOGD("feof %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    return fd->offset >= fd->size ? 1 : 0;
+}
+int luat_vfs_inline_ferror(void* userdata, FILE *stream) {
+    return 0;
+}
+size_t luat_vfs_inline_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
+    luat_fs_inline_t* fd = (luat_fs_inline_t*)stream;
+    //LLOGD("fread %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    //LLOGD("fread2 %p %p %d %d", userdata, stream, size * nmemb, fd->offset);
+    size_t read_size = size*nmemb;
+    if (fd->offset + read_size > fd->size) {
+        read_size = fd->size - fd->offset;
+    }
+    memcpy(ptr, fd->ptr + fd->offset, read_size);
+    fd->offset += read_size;
+    return read_size;
+}
+
+int luat_vfs_inline_fexist(void* userdata, const char *filename) {
+    //LLOGD("open fexist %s", filename);
+    luadb_file_t* file = NULL;
+#ifdef LUAT_CONF_VM_64bit
+    file = luat_inline2_libs_64bit_size64;
+    file = luat_inline2_libs_64bit_size32;
+#else
+    file = luat_inline2_libs;
+#endif
+
+    while (file != NULL && file->ptr != NULL) {
+        if (!memcmp(file->name, filename, strlen(filename)+1)) {
+            return 1;
+        }
+        file ++;
+    }
+    //LLOGD("Not Found %s", filename);
+    return 0;
+}
+
+size_t luat_vfs_inline_fsize(void* userdata, const char *filename) {
+    luat_fs_inline_t *fd = (luat_fs_inline_t*)(userdata);
+    //LLOGD("fsize %p %p %d %d", userdata, fd);
+    return fd->size;
+}
+
+int luat_vfs_inline_mount(void** userdata, luat_fs_conf_t *conf) {
+    *userdata = (luat_fs_inline_t*)conf->busname;
+    return 0;
+}
+
+int luat_vfs_inline_info(void* userdata, const char* path, luat_fs_info_t *conf) {
+    memcpy(conf->filesystem, "inline", strlen("inline")+1);
+    conf->type = 0;
+    conf->total_block = 0;
+    conf->block_used = 0;
+    conf->block_size = 512;
+    return 0;
+}
+
+#define T(name) .name = luat_vfs_inline_##name
+const struct luat_vfs_filesystem vfs_fs_inline = {
+    .name = "inline",
+    .opts = {
+        .mkfs = NULL,
+        T(mount),
+        .umount = NULL,
+        .mkdir = NULL,
+        .rmdir = NULL,
+        .lsdir = NULL,
+        .remove = NULL,
+        .rename = NULL,
+        T(fsize),
+        T(fexist),
+        T(info)
+    },
+    .fopts = {
+        T(fopen),
+        T(getc),
+        T(fseek),
+        T(ftell),
+        T(fclose),
+        T(feof),
+        T(ferror),
+        T(fread),
+        .fwrite = NULL
+    }
+};
+#endif
+

+ 23 - 23
luat/vfs/luat_fs_luadb.c

@@ -10,12 +10,12 @@
 #undef LLOGD
 #define LLOGD(...) 
 
-#ifdef LUAT_CONF_VM_64bit
-extern const luadb_file_t luat_inline2_libs_64bit_size64[];
-extern const luadb_file_t luat_inline2_libs_64bit_size32[];
-#else
-extern const luadb_file_t luat_inline2_libs[];
-#endif
+// #ifdef LUAT_CONF_VM_64bit
+// extern const luadb_file_t luat_inline2_libs_64bit_size64[];
+// extern const luadb_file_t luat_inline2_libs_64bit_size32[];
+// #else
+// extern const luadb_file_t luat_inline2_libs[];
+// #endif
 
 //---
 static uint8_t readU8(const char* ptr, int *index) {
@@ -52,14 +52,14 @@ static luadb_file_t* find_by_name(luadb_fs_t *fs, const char *path) {
             return &(fs->files[i]);
         }
     }
-    luadb_file_t *ext = fs->inlines;
-    while (ext->ptr != NULL)
-    {
-        if (!strcmp(path, ext->name)) {
-            return ext;
-        }
-        ext += 1;
-    }
+    // luadb_file_t *ext = fs->inlines;
+    // while (ext->ptr != NULL)
+    // {
+    //     if (!strcmp(path, ext->name)) {
+    //         return ext;
+    //     }
+    //     ext += 1;
+    // }
     return NULL;
 }
 
@@ -317,15 +317,15 @@ _after_head:
 
     if (fail == 0) {
         LLOGD("LuaDB check files .... ok");
-        #ifdef LUAT_CONF_VM_64bit
-        //#if (sizeof(size_t) == 8)
-        //fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size64;
-        //#else
-        fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size32;
-        //#endif
-        #else
-        fs->inlines = (luadb_file_t *)luat_inline2_libs;
-        #endif
+        // #ifdef LUAT_CONF_VM_64bit
+        // //#if (sizeof(size_t) == 8)
+        // //fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size64;
+        // //#else
+        // fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size32;
+        // //#endif
+        // #else
+        // fs->inlines = (luadb_file_t *)luat_inline2_libs;
+        // #endif
         return fs;
     }
     else {

+ 248 - 0
luat/vfs/luat_fs_romfs.c

@@ -0,0 +1,248 @@
+#include "luat_base.h"
+#include "luat_fs.h"
+
+
+#include "luat_malloc.h"
+#define LUAT_LOG_TAG "fs"
+#include "luat_log.h"
+
+typedef struct romfs_file
+{
+    uint32_t next_offset;
+    uint32_t spec;
+    uint32_t size;
+    uint32_t checksum;
+    char name[16];
+}romfs_file_t;
+
+typedef struct romfs_fd
+{
+    romfs_file_t* file;
+    size_t offset;
+}romfs_fd_t;
+
+
+typedef struct luat_fs_romfs
+{
+    size_t count;
+    romfs_file_t *files[256 - 1];
+}luat_fs_romfs_t;
+
+typedef struct romfs_head
+{
+    char magic[8];
+    size_t count;
+    size_t checksum;
+    char volume[16];
+}romfs_head_t;
+
+
+#define FDATA(fd) ((char*)(fd)+sizeof(romfs_file_t))
+#define FSIZE(fd) (fd->file->size)
+
+#ifdef LUAT_USE_FS_VFS
+
+FILE* luat_vfs_romfs_fopen(void* userdata, const char *filename, const char *mode) {
+    //LLOGD("open romfs %s", filename);
+    romfs_file_t* file = NULL;
+    luat_fs_romfs_t* fs = (luat_fs_romfs_t*)userdata;
+    if (!strcmp("r", mode) || !strcmp("rb", mode)) {
+        for (size_t i = 0; i < fs->count; i++)
+        {
+            if (!strcmp(fs->files[i]->name, filename)) {
+                file = fs->files[i];
+                break;
+            }
+        }
+        if (file == NULL) {
+            return NULL;
+        }
+        
+        romfs_fd_t* fd = luat_heap_malloc(sizeof(romfs_fd_t));
+        if (fd == NULL) {
+            LLOGE("out of memory when malloc luat_fs_romfs_t");
+            return NULL;
+        }
+        //LLOGD("fd %p userdata %p", fd, userdata);
+        memcpy(fd, userdata, sizeof(romfs_fd_t));
+        fd->offset = 0;
+        fd->file = file;
+        return (FILE*)fd;
+    }
+    return NULL;
+}
+
+int luat_vfs_romfs_getc(void* userdata, FILE* stream) {
+    //LLOGD("getc %p %p", userdata, stream);
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    //LLOGD("getc %p %p %d %d", userdata, stream, fd->offset, fd->size);
+    if (fd->offset < fd->file->size) {
+        uint8_t c = FDATA(fd)[fd->offset];
+        fd->offset ++;
+        //LLOGD("getc %02X", c);
+        return c;
+    }
+    return -1;
+}
+
+int luat_vfs_romfs_fseek(void* userdata, FILE* stream, long int offset, int origin) {
+    //LLOGD("fseek %p %p %d %d", userdata, stream, offset, origin);
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    if (origin == SEEK_CUR) {
+        fd->offset += offset;
+        return 0;
+    }
+    else if (origin == SEEK_SET) {
+        fd->offset = offset;
+        return 0;
+    }
+    else {
+        fd->offset = fd->file->size - offset;
+        return 0;
+    }
+}
+
+int luat_vfs_romfs_ftell(void* userdata, FILE* stream) {
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    //LLOGD("tell %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    return fd->offset;
+}
+
+int luat_vfs_romfs_fclose(void* userdata, FILE* stream) {
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    //LLOGD("fclose %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    luat_heap_free(fd);
+    return 0;
+}
+
+int luat_vfs_romfs_feof(void* userdata, FILE* stream) {
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    //LLOGD("feof %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    return fd->offset >= fd->file->size ? 1 : 0;
+}
+
+int luat_vfs_romfs_ferror(void* userdata, FILE *stream) {
+    return 0;
+}
+
+size_t luat_vfs_romfs_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
+    romfs_fd_t* fd = (romfs_fd_t*)stream;
+    //LLOGD("fread %p %p %d %d", userdata, stream, fd->size, fd->offset);
+    //LLOGD("fread2 %p %p %d %d", userdata, stream, size * nmemb, fd->offset);
+    size_t read_size = size*nmemb;
+    if (fd->offset + read_size > FSIZE(fd)) {
+        read_size = FSIZE(fd) - fd->offset;
+    }
+    memcpy(ptr, FDATA(fd) + fd->offset, read_size);
+    fd->offset += read_size;
+    return read_size;
+}
+
+int luat_vfs_romfs_fexist(void* userdata, const char *filename) {
+    luat_fs_romfs_t* fs = (luat_fs_romfs_t*)userdata;
+    for (size_t i = 0; i < fs->count; i++)
+    {
+        if (!strcmp(fs->files[i]->name, filename)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+size_t luat_vfs_romfs_fsize(void* userdata, const char *filename) {
+    romfs_fd_t *fd = (romfs_fd_t*)(userdata);
+    //LLOGD("fsize %p %p %d %d", userdata, fd);
+    return fd->file->size;
+}
+
+int luat_vfs_romfs_mount(void** userdata, luat_fs_conf_t *conf) {
+    romfs_head_t* head = (romfs_head_t*)conf->busname;
+    if (memcmp(head->magic, "-rom1fs-", 8)) {
+        LLOGI("Not ROMFS at %p", head);
+        return -1;
+    }
+    luat_fs_romfs_t *romfs = luat_heap_malloc(sizeof(luat_fs_romfs_t));
+    if (romfs == NULL) {
+        LLOGE("out of memory when malloc luat_fs_romfs_t");
+        return -1;
+    }
+    memset(romfs, 0, sizeof(luat_fs_romfs_t));
+    
+    romfs_file_t* file = (romfs_file_t*)(((uint8_t*)conf->busname) + sizeof(romfs_head_t));
+    // TODO 支持更多文件
+    for (size_t i = 0; romfs->count < 255; i++)
+    {
+        if (file->next_offset == 0)
+            break;
+        if (!memcmp(".", file->name, 2) || !memcmp("..", file->name, 3)) {
+            // pass
+        }
+        else {
+            romfs->files[romfs->count] = file;
+            romfs->count ++;
+        }
+        file = (romfs_file_t*)(((uint8_t*)conf->busname) + sizeof(romfs_head_t) + (file->next_offset & 0xFFF0));
+    }
+    *userdata = romfs;
+    return 0;
+}
+
+int luat_vfs_romfs_umount(void* userdata, luat_fs_conf_t *conf) {
+    return 0;
+}
+
+int luat_vfs_romfs_info(void* userdata, const char* path, luat_fs_info_t *conf) {
+    memcpy(conf->filesystem, "romfs", strlen("romfs")+1);
+    conf->type = 0;
+    conf->total_block = 0;
+    conf->block_used = 0;
+    conf->block_size = 512;
+    return 0;
+}
+
+int luat_vfs_romfs_lsdir(void* userdata, char const* _DirName, luat_fs_dirent_t* ents, size_t offset, size_t len) {
+    luat_fs_romfs_t* fs = (luat_fs_romfs_t*)userdata;
+    if (fs->count > offset) {
+        if (offset + len > fs->count)
+            len = fs->count - offset;
+        for (size_t i = 0; i < len; i++)
+        {
+            ents[i].d_type = 0;
+            strcpy(ents[i].d_name, fs->files[i+offset]->name);
+        }
+        return len;
+    }
+    return 0;
+}
+
+#define T(name) .name = luat_vfs_romfs_##name
+const struct luat_vfs_filesystem vfs_fs_romfs = {
+    .name = "romfs",
+    .opts = {
+        .mkfs = NULL,
+        T(mount),
+        T(umount),
+        .mkdir = NULL,
+        .rmdir = NULL,
+        .lsdir = NULL,
+        .remove = NULL,
+        .rename = NULL,
+        T(fsize),
+        T(fexist),
+        T(info),
+        T(lsdir)
+    },
+    .fopts = {
+        T(fopen),
+        T(getc),
+        T(fseek),
+        T(ftell),
+        T(fclose),
+        T(feof),
+        T(ferror),
+        T(fread),
+        .fwrite = NULL
+    }
+};
+#endif
+

+ 12 - 5
luat/vfs/luat_vfs.c

@@ -20,10 +20,13 @@
 #undef ferror
 #endif
 
+extern const struct luat_vfs_filesystem vfs_fs_inline;
+
 static luat_vfs_t vfs= {0};
 
 int luat_vfs_init(void* params) {
     memset(&vfs, 0, sizeof(vfs));
+    luat_vfs_reg(&vfs_fs_inline);
     return 0;
 }
 
@@ -102,6 +105,12 @@ int luat_fs_mount(luat_fs_conf_t *conf) {
                         vfs.mounted[j].fs = vfs.fsList[i];
                         vfs.mounted[j].ok = 1;
                         memcpy(vfs.mounted[j].prefix, conf->mount_point, strlen(conf->mount_point) + 1);
+                        if (j == 0) {
+                            // 挂载内嵌文件系统
+                            vfs.mounted[j+1].fs = &vfs_fs_inline;
+                            vfs.mounted[j+1].ok = 1;
+                            memcpy(vfs.mounted[j+1].prefix, "/lua/", strlen("/lua/") + 1);
+                        }
                     }
                     else
                         LLOGD("mount error ret %d", ret);
@@ -117,7 +126,7 @@ int luat_fs_mount(luat_fs_conf_t *conf) {
 }
 int luat_fs_umount(luat_fs_conf_t *conf) {
     for (size_t j = 0; j < LUAT_VFS_FILESYSTEM_MOUNT_MAX; j++) {
-        if (vfs.mounted[j].ok == 0)
+        if (vfs.mounted[j].ok == 0 || vfs.mounted[j].fs->opts.umount == NULL)
             continue;
         if (strcmp(vfs.mounted[j].prefix, conf->mount_point) == 0) {
             // TODO 关闭对应的FD
@@ -127,9 +136,10 @@ int luat_fs_umount(luat_fs_conf_t *conf) {
     LLOGE("no such mount point %s", conf->mount_point);
     return -1;
 }
+
 int luat_fs_info(const char* path, luat_fs_info_t *conf) {
     luat_vfs_mount_t * mf = getmount(path);
-    if (mf != NULL) {
+    if (mf != NULL && mf->fs->opts.info != NULL) {
         return mf->fs->opts.info(mf->userdata, ((char*)path) + strlen(mf->prefix), conf);
     }
     LLOGE("no such mount point %s", path);
@@ -295,9 +305,6 @@ int luat_fs_readline(char * buf, int bufsize, FILE * stream){
     return get_len;
 }
 
-// TODO 文件夹相关的API
-//int luat_fs_diropen(char const* _FileName);
-
 int luat_fs_mkdir(char const* _DirName) {
     luat_vfs_mount_t *mount = getmount(_DirName);
     if (mount == NULL || mount->fs->opts.mkdir == NULL) return 0;