1
0
Эх сурвалжийг харах

add romfs support.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@887 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 жил өмнө
parent
commit
a3ca8e33db

+ 10 - 0
components/dfs/SConscript

@@ -16,6 +16,12 @@ filesystems/elmfat/dfs_elm.c
 filesystems/elmfat/ff.c
 """)
 
+# DFS-ROMFS options
+romfs = Split("""
+filesystems/romfs/dfs_romfs.c
+filesystems/romfs/romfs.c
+""")
+
 # DFS-YAFFS2 options
 yaffs2_main = Split("""
 filesystems/yaffs2/direct/yaffscfg.c
@@ -69,6 +75,10 @@ if 'RT_USING_DFS_NFS' in dir(rtconfig) and rtconfig.RT_USING_DFS_NFS:
     src_local = src_local + nfs
     path = path + [RTT_ROOT + '/components/dfs/filesystems/nfs']
 
+if 'RT_USING_DFS_ROMFS' in dir(rtconfig) and rtconfig.RT_USING_DFS_ROMFS:
+    src_local = src_local + romfs
+    path = path + [RTT_ROOT + '/components/dfs/filesystems/romfs']
+
 # group definitions
 group = {}
 group['name'] = 'Filesystem'

+ 219 - 0
components/dfs/filesystems/romfs/dfs_romfs.c

@@ -0,0 +1,219 @@
+#include <rtthread.h>
+#include <dfs.h>
+#include <dfs_fs.h>
+#include "dfs_romfs.h"
+
+int dfs_romfs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
+{
+	struct romfs_dirent* root_dirent;
+
+	if (data == RT_NULL) return -DFS_STATUS_EIO;
+
+	root_dirent = (struct romfs_dirent*)data;
+	fs->data = root_dirent;
+
+	return DFS_STATUS_OK;
+}
+
+int dfs_romfs_unmount(struct dfs_filesystem* fs)
+{
+	return DFS_STATUS_OK;
+}
+
+int dfs_romfs_ioctl(struct dfs_fd* file, int cmd,	void* args)
+{
+	return -DFS_STATUS_EIO;
+}
+
+struct romfs_dirent* dfs_romfs_lookup(struct romfs_dirent* root_dirent, const char* path)
+{
+	rt_size_t index;
+	const char *subpath, *subpath_end;
+	struct romfs_dirent* dirent;
+
+	dirent = root_dirent;
+
+	if (path[0] == '/' && path[1] == '\0') return dirent;
+
+	/* get the end position of this subpath */
+	subpath_end = path;
+	/* skip /// */
+	while (*subpath_end && *subpath_end == '/') subpath_end ++;
+	subpath = subpath_end;
+	while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
+
+	while (dirent != RT_NULL)
+	{
+		/* search in folder */
+		for (index = 0; index < dirent->size; index ++)
+		{
+			if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
+			{
+				/* skip /// */
+				while (*subpath_end && *subpath_end == '/') subpath_end ++;
+				subpath = subpath_end;
+				while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
+
+				if (!(*subpath)) return dirent;
+
+				if (dirent[index].type == ROMFS_DIRENT_DIR)
+				{
+					dirent = (struct romfs_dirent*)dirent[index].data;
+					break;
+				}
+				else return dirent;
+			}
+		}
+	}
+
+	/* not found */
+	return RT_NULL;
+}
+
+int dfs_romfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
+{
+	rt_size_t length;
+	struct romfs_dirent* dirent;
+
+	dirent = (struct romfs_dirent *)file->data;
+	RT_ASSERT(dirent != RT_NULL);
+
+	if (count < file->size - file->pos)
+		length = count;
+	else
+		length = file->size - file->pos;
+
+	if (length > 0)
+		memcpy(buf, &(dirent->data[file->pos]), length);
+
+	return length;
+}
+
+int dfs_romfs_lseek(struct dfs_fd* file, rt_off_t offset)
+{
+	if (offset < file->size)
+	{
+		file->pos = offset;
+		return file->pos;
+	}
+
+	return -DFS_STATUS_EIO;
+}
+
+int dfs_romfs_close(struct dfs_fd* file)
+{
+	file->data = RT_NULL;
+	return DFS_STATUS_OK;
+}
+
+int dfs_romfs_open(struct dfs_fd* file)
+{
+	struct romfs_dirent* root_dirent;
+	struct romfs_dirent* dirent;
+
+	root_dirent = (struct romfs_dirent*)file->fs->data;
+
+	if (file->flags & DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC)
+		return -DFS_STATUS_EINVAL;
+
+	dirent = dfs_romfs_lookup(root_dirent, file->path);
+	if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
+
+	if (file->flags & DFS_O_DIRECTORY)
+		file->data = dirent;
+
+	file->size = dirent->size;
+	file->pos = 0;
+	return DFS_STATUS_OK;
+}
+
+int dfs_romfs_stat(struct dfs_filesystem* fs, const char *path, struct _stat *st)
+{
+	struct romfs_dirent* root_dirent;
+	struct romfs_dirent* dirent;
+
+	root_dirent = (struct romfs_dirent*)fs->data;
+	dirent = dfs_romfs_lookup(root_dirent, path);
+
+	if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
+
+	st->st_dev = 0;
+	st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
+	DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
+	if (dirent->type == ROMFS_DIRENT_DIR)
+	{
+		st->st_mode &= ~DFS_S_IFREG;
+		st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
+	}
+
+	st->st_size = dirent->size;
+	st->st_mtime = 0;
+	st->st_blksize = 512;
+
+	return DFS_STATUS_OK;
+}
+
+int dfs_romfs_getdents(struct dfs_fd* file, struct _dirent* dirp, rt_uint32_t count)
+{
+	rt_size_t index;
+	const char *name;
+	struct _dirent* d;
+	struct romfs_dirent *dirent, *sub_dirent;
+
+	dirent = (struct romfs_dirent*) file->data;
+
+	/* make integer count */
+	count = (count / sizeof(struct _dirent)) * sizeof(struct _dirent);
+	if ( count == 0 ) return -DFS_STATUS_EINVAL;
+	
+	index = 0;
+	sub_dirent = &dirent[file->pos];
+	for (index = 0; index < count; index ++)
+	{
+		d = dirp + index;
+
+		sub_dirent = &dirent[file->pos];
+		name = sub_dirent->name;
+
+		/* fill dirent */
+		d->d_type &= DFS_DT_REG;
+		d->d_namlen = rt_strlen(name);
+		d->d_reclen = (rt_uint16_t)sizeof(struct _dirent);
+		rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
+
+		/* move to next position */
+		++ file->pos; 
+		if (file->pos > file->size) break;
+	}
+
+	return index * sizeof(struct _dirent);
+}
+
+static const struct dfs_filesystem_operation _romfs = 
+{
+	"rom",
+	dfs_romfs_mount,
+	dfs_romfs_unmount,
+	RT_NULL,
+	RT_NULL,
+
+	dfs_romfs_open,
+	dfs_romfs_close,
+	dfs_romfs_ioctl,
+	dfs_romfs_read,
+	RT_NULL,
+	RT_NULL,
+	dfs_romfs_lseek,
+	dfs_romfs_getdents,
+	RT_NULL,
+	dfs_romfs_stat,
+	RT_NULL,
+};
+
+int dfs_romfs_init(void)
+{
+    /* register rom file system */
+    dfs_register(&_romfs);
+	return 0;
+}
+

+ 20 - 0
components/dfs/filesystems/romfs/dfs_romfs.h

@@ -0,0 +1,20 @@
+#ifndef __DFS_ROMFS_H__
+#define __DFS_ROMFS_H__
+
+#include <rtthread.h>
+
+#define ROMFS_DIRENT_FILE	0x00
+#define ROMFS_DIRENT_DIR	0x01
+
+struct romfs_dirent
+{
+	rt_uint32_t		 type;	/* dirent type */
+
+	const char		 *name;	/* dirent name */
+	const rt_uint8_t *data;	/* file date ptr */
+	rt_size_t		 size;	/* file size */
+};
+
+int dfs_romfs_init(void);
+
+#endif

+ 90 - 0
components/dfs/filesystems/romfs/mkromfs.py

@@ -0,0 +1,90 @@
+import sys
+import os
+import string
+
+basename = ''
+
+def mkromfs_output(out):
+    print '%s' % out,
+
+def mkromfs_file(filename, arrayname):
+    f = open(filename, "rb")
+    arrayname = arrayname.replace('.', '_')
+    mkromfs_output('const static unsigned char %s[] = {\n' % arrayname)
+
+    count = 0
+    while True:
+        byte = f.read(1)
+        
+        if not byte:
+            break
+        
+        mkromfs_output('0x%02x,' % ord(byte))
+        
+        count = count + 1
+        if count == 16:
+            count = 0
+            mkromfs_output('\n')
+    
+    mkromfs_output('};\n\n')
+    f.close()
+
+def mkromfs_dir(dirname, is_root = False):
+    list = os.listdir(dirname)
+    path = os.path.abspath(dirname)
+    
+    # make for directory 
+    for item in list:
+        fullpath = os.path.join(path, item)
+        if os.path.isdir(fullpath):
+            mkromfs_dir(fullpath)
+    
+    # make for files
+    for item in list:
+        fullpath = os.path.join(path, item)
+        if os.path.isfile(fullpath):
+            subpath = fullpath[len(basename):]
+            array = subpath.split('\\')
+            arrayname = string.join(array, '_')
+            mkromfs_file(fullpath, arrayname)
+
+    subpath = path[len(basename):]
+    dir = subpath.split('\\')
+    direntname = string.join(dir, '_')
+    if is_root:
+        mkromfs_output('const struct romfs_dirent romfs_root[] = {\n')
+    else:
+        mkromfs_output(('const static struct romfs_dirent %s[] = {\n' % direntname))
+    
+    for item in list:
+        fullpath = os.path.join(path, item)
+	fn = fullpath[len(dirname):]
+	if fn[0] == '\\':
+	    fn = fn[1:]
+	fn = fn.replace('\\', '/')
+
+        subpath = fullpath[len(basename):]
+        items = subpath.split('\\')
+        item_name = string.join(items, '_')
+        item_name = item_name.replace('.', '_')
+        subpath = subpath.replace('\\', '/')
+        if subpath[0] == '/':
+            subpath = subpath[1:]
+
+        if os.path.isfile(fullpath):
+            mkromfs_output(('\t{ROMFS_DIRENT_FILE, "%s", %s, sizeof(%s)},\n' % (fn, item_name, item_name)))
+        else:
+            mkromfs_output(('\t{ROMFS_DIRENT_DIR, "%s", %s, sizeof(%s)/sizeof(%s[0])},\n' % (fn, item_name, item_name, item_name)))
+    
+    mkromfs_output('};\n\n')
+
+if __name__ == "__main__":
+    try:
+        basename = os.path.abspath(sys.argv[1])
+        filename = os.path.abspath(sys.argv[2])
+    except IndexError:
+        print "Usage: %s <dirname> <filename>" % sys.argv[0]
+        raise SystemExit
+
+    mkromfs_output("#include <dfs_romfs.h>\n\n")
+    mkromfs_dir(basename, is_root = True)

+ 18 - 0
components/dfs/filesystems/romfs/romfs.c

@@ -0,0 +1,18 @@
+#include <dfs_romfs.h>
+
+const static unsigned char _dummy_dummy_txt[] = {
+0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 
+0x0a, };
+
+const static struct romfs_dirent _dummy[] = {
+	{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_dummy_txt, sizeof(_dummy_dummy_txt)},
+};
+
+const static unsigned char _dummy_txt[] = {
+0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 
+0x0a, };
+
+const struct romfs_dirent romfs_root[] = {
+	{ROMFS_DIRENT_DIR, "dummy", _dummy, sizeof(_dummy)/sizeof(_dummy[0])},
+	{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_txt, sizeof(_dummy_txt)},
+};