implement minimal virtual file system
This commit is contained in:
parent
291eea1bfa
commit
eb7d9c8f58
|
@ -25,6 +25,7 @@ set(SOURCES
|
|||
src/job.c
|
||||
src/wren_utils.c
|
||||
src/utf8.c
|
||||
src/vfs/vfs.c
|
||||
)
|
||||
set(SOURCES_WREN
|
||||
wren/src/wren_compiler.c
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "job.h"
|
||||
#include "term.h"
|
||||
#include "ui.h"
|
||||
#include "vfs/vfs.h"
|
||||
#include "wren_utils.h"
|
||||
|
||||
static int tick_ctr = 0;
|
||||
|
@ -113,6 +114,9 @@ __attribute__((noreturn)) static void halt(void) {
|
|||
int main(int isappli, int optnum) {
|
||||
term_kprintf("main(%d, %d)", isappli, optnum);
|
||||
|
||||
vfs_init();
|
||||
halt();
|
||||
|
||||
timer_sched = timer_configure(TIMER_ANY, 10 * 1000, GINT_CALL(callback_sched)); // 100 Hz <=> 10 ms
|
||||
|
||||
timer_redraw = timer_configure(TIMER_ANY, 31250, GINT_CALL(callback_redraw)); // 32 Hz
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
.global __battery_type
|
||||
.global __set_backlight
|
||||
.global __set_quit_handler
|
||||
.global __name_to_str
|
||||
.global __str_to_name
|
||||
.global __find_first
|
||||
.global __find_next
|
||||
|
||||
.section ".text"
|
||||
|
||||
|
@ -38,6 +42,18 @@ __set_backlight:
|
|||
__set_quit_handler:
|
||||
syscall(0x1E6E)
|
||||
|
||||
__name_to_str:
|
||||
syscall(0x1ddb)
|
||||
|
||||
__str_to_name:
|
||||
syscall(0x1ddc)
|
||||
|
||||
__find_first:
|
||||
syscall(0x1db6)
|
||||
|
||||
__find_next:
|
||||
syscall(0x1db8)
|
||||
|
||||
syscall_table:
|
||||
.long 0x80020070
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
#include "vfs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gint/bfile.h>
|
||||
#include <gint/cpu.h>
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/kmalloc.h>
|
||||
|
||||
#include <printf.h>
|
||||
|
||||
#include "../term.h"
|
||||
|
||||
extern void _name_to_str(char *dest, const uint16_t *source, int n);
|
||||
extern void _str_to_name(uint16_t *dest, const char *source, int n);
|
||||
extern int _find_first(const uint16_t *pathname, int *FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo);
|
||||
extern int _find_next(int FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo);
|
||||
|
||||
static vfs_entry_t vfs_root;
|
||||
|
||||
static vfs_entry_t *vfs_new_dir(const char *name, vfs_entry_t *parent) {
|
||||
vfs_entry_t *newdir = kmalloc(sizeof(vfs_entry_t), NULL);
|
||||
|
||||
strcpy((char *)&newdir->name, name);
|
||||
newdir->parent = parent;
|
||||
newdir->type = vfs_dir;
|
||||
newdir->driver = 0;
|
||||
newdir->childs = NULL;
|
||||
newdir->next = NULL;
|
||||
|
||||
newdir->next = parent->childs;
|
||||
parent->childs = newdir;
|
||||
|
||||
return newdir;
|
||||
}
|
||||
|
||||
static vfs_entry_t *vfs_new_file(const char *name, vfs_entry_t *parent) {
|
||||
vfs_entry_t *newfile = kmalloc(sizeof(vfs_entry_t), NULL);
|
||||
|
||||
strcpy((char *)&newfile->name, name);
|
||||
newfile->parent = parent;
|
||||
newfile->type = vfs_file;
|
||||
newfile->driver = 0;
|
||||
newfile->childs = NULL;
|
||||
newfile->next = NULL;
|
||||
|
||||
newfile->next = parent->childs;
|
||||
parent->childs = newfile;
|
||||
|
||||
return newfile;
|
||||
}
|
||||
|
||||
static void vfs_debug_tree_(int indent, vfs_entry_t *subtree) {
|
||||
vfs_entry_t *child = subtree->childs;
|
||||
|
||||
while (child != NULL) {
|
||||
for (int i = 0; i < indent; i++)
|
||||
term_print(" ");
|
||||
|
||||
if (child->type == vfs_file)
|
||||
term_printf("%s\n", child->name);
|
||||
else if (child->type == vfs_dir) {
|
||||
term_printf("%s/\n", child->name);
|
||||
vfs_debug_tree_(indent + 1, child);
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void vfs_debug_tree(void) {
|
||||
term_print("/\n");
|
||||
vfs_debug_tree_(1, &vfs_root);
|
||||
}
|
||||
|
||||
static int shandle;
|
||||
static void populate_vfs(const char *path, vfs_entry_t *dir) {
|
||||
char glob[64];
|
||||
strcpy(glob, path);
|
||||
strcat(glob, "\\*");
|
||||
|
||||
uint16_t glob_c16[64];
|
||||
_str_to_name(glob_c16, glob, 64);
|
||||
|
||||
uint16_t foundfile[64];
|
||||
struct BFile_FileInfo fileinfo;
|
||||
int ret = _find_first(glob_c16, &shandle, foundfile, &fileinfo);
|
||||
while (ret == 0) {
|
||||
char foundfile_str[64];
|
||||
_name_to_str(foundfile_str, foundfile, 64);
|
||||
|
||||
if (foundfile_str[0] != '@' && strcmp(foundfile_str, ".") != 0 && strcmp(foundfile_str, "..") != 0) {
|
||||
if (fileinfo.type == BFile_Type_Directory) {
|
||||
vfs_new_dir(foundfile_str, dir);
|
||||
} else {
|
||||
vfs_new_file(foundfile_str, dir);
|
||||
}
|
||||
}
|
||||
|
||||
ret = _find_next(shandle, foundfile, &fileinfo);
|
||||
}
|
||||
BFile_FindClose(shandle);
|
||||
|
||||
// we do the recursive search when the search handle
|
||||
// has been closed to avoid using too much handles
|
||||
|
||||
vfs_entry_t *child = dir->childs;
|
||||
while (child != NULL) {
|
||||
if (child->type == vfs_dir) {
|
||||
char new_path[64];
|
||||
sprintf(new_path, "%s\\%s", path, child->name);
|
||||
|
||||
populate_vfs(new_path, child);
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_init(void) {
|
||||
// init fs root
|
||||
strcpy((char *)&vfs_root.name, "");
|
||||
vfs_root.parent = NULL;
|
||||
vfs_root.type = vfs_dir;
|
||||
vfs_root.driver = 0;
|
||||
vfs_root.childs = NULL;
|
||||
vfs_root.next = NULL;
|
||||
|
||||
vfs_entry_t *native = vfs_new_dir("native", &vfs_root);
|
||||
vfs_entry_t *flash = vfs_new_dir("flash", native);
|
||||
|
||||
cpu_atomic_start();
|
||||
// gint_world_switch_in(gint_world_addin, gint_world_os);
|
||||
populate_vfs("\\\\fls0", flash);
|
||||
// gint_world_switch_in(gint_world_os, gint_world_addin);
|
||||
cpu_atomic_end();
|
||||
|
||||
vfs_debug_tree();
|
||||
}
|
||||
|
||||
// const vfs_entry_t *vfs_get_root(void) { return &vfs_root; }
|
||||
|
||||
// vfs_entry* find_entry(const char* path) {
|
||||
// // TODO
|
||||
// }
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef UNS_VFS_H
|
||||
#define UNS_VFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum vfs_entry_type {
|
||||
vfs_file = 1,
|
||||
vfs_dir = 2,
|
||||
};
|
||||
|
||||
typedef struct vfs_entry {
|
||||
char name[64];
|
||||
struct vfs_entry *parent;
|
||||
|
||||
enum vfs_entry_type type;
|
||||
uint16_t driver;
|
||||
|
||||
// dir only
|
||||
struct vfs_entry *childs;
|
||||
struct vfs_entry *next;
|
||||
} vfs_entry_t;
|
||||
|
||||
void vfs_init(void);
|
||||
// const vfs_entry_t *vfs_get_root(void);
|
||||
|
||||
#endif // #ifndef UNS_VFS_H
|
Loading…
Reference in New Issue